#337 [patch] add -multiinclude option (single_include=0)

Dave Vitek

This adds a -multiinclude command line flag to swig. Specifying this option causes swig to more faithfully emulate the C preprocessor in that it will permit repeatedly #including the same file.

The patch merely hooks up the pre-existing variable called single_include (in the preprocessor module) to a command line option.

In my case, the multi-includes are useful because we are using "super macros" to wrap a repetitive C interface with C++ classes.

1 Attachments


  • William Fulton

    William Fulton - 2013-04-18

    Can you give a small example of your 'super macros' as a testcase please? The new option needs to be added to the -help display in main.cxx and documented in the html docs.

  • Dave Vitek

    Dave Vitek - 2013-04-19

    I think I want to change this patch works slightly. One major drawback is that most of the SWIG library code wasn't written with this in mind, so you end up with repeat includes if you start using std_vector and friends. When updating the documentation, I noticed that the existing docs don't agree with reality:

    <P> Unlike, <TT>#include</TT>, <TT>%include</TT> includes each file once
    (and will not reload the file on subsequent <TT>%include</TT>
    declarations). Therefore, it is not necessary to use include-guards in
    SWIG interfaces.</P>

    Experiments show that #include and %include in fact behave identically in this regard. I think what I really want is for %include to continue behaving as-is, and for #include to behave as-documented. Does this sound sane?

  • William Fulton

    William Fulton - 2013-04-19

    With regard to the current documentation, I think it means #include in terms of the C preprocessor, not the SWIG preprocessor - the SWIG preprocessor completely ignores #include (unless -includeall is used).

    I think a better term for this feature would be recursiveinclude rather than multiinclude.

    How about you make this a whole lot more flexible and just use %include but enhance it with an option to recursively include all files that it comes across for any given %include:

    %include(recursive=1) "example.h"

    The above syntax is already parsed and you will get the option in the parse tree - view the parse tree with 'swig -debug-top 1'. The options are set in include_directive in parser.y.

    You could go one step further and implement additional flexibility:

    %include(recursivefile="myheader.h,xyz.h") "myheader.h"

    Indicating that only the two named files should get the recursive include treatment. Some more thought is needed as how to list the files as a comma is a valid filename character. Maybe this:

    %include(recursivefile="myheader.h", recursivefile="xyz.h") "myheader.h"

    Please check that the implementation works equally well when 'swig -E' is used.

  • Dave Vitek

    Dave Vitek - 2013-04-21

    I've attached a test case to help motivate discussion.

    I don't like the "multiinclude" terminology either. However, I'm not sure "recursive include" is better: I would expect "recursive" include to mean a file is including itself. Perhaps there's a third option?

    Let me see if I understand your %include suggestion correctly. In terms of the attached test case, the %include in the interface file would change, and the #include statements inside the header file would not change, but would behave differently as a consequence? This seems reasonable, although I haven't had time to dig into the code yet.

    It might strike some users as inconsistent that this can be controlled via enhanced %include syntax, but -includeall cannot be. For my use case, using the new option doesn't even make sense unless -includeall is also active.

  • William Fulton

    William Fulton - 2013-04-22

    Thanks for the example, I see what you are trying to achieve now and agree recursive is no better a name. Originally I thought it was targetting recursive file includes.

    Anyway, having given this some more thought, I think there are two points to be made.

    Firstly, -includeall is basically buggy and it should work the same as the C preprocessor behaviour. I can't think why it should deviate from C #include behaviour here - C header include guards will be in place if so desired. I don't think this bug has been spotted before as -includeall is not too common and your multiple include usage is also not very common. There is a small chance of breaking existing code by fixing this bug, but I think the number of affected users will be acceptably miniscule.

    Secondly, a more refined/controlled approach for -includeall would be very useful. Consider your example, if -includeall is dropped and #include is replaced by %include, then line 9 in multiincludetest.i can be changed from:

    #include "multiincludetest.h"


    %include(followall=1) "multiincludetest.h"

    so that all #include statements in multiincludetest.h get the normal C #include treatment in that all #include statements are followed. %include statements are not followed. The followall flag is basically -includeall but applies only to files within multiincludetest.h or files it #includes.

    An even more fine grained approach should also be implemented:

    %include(followfiles="multiincludetest2.h") "multiincludetest.h"

    Where no #include statements are followed in multiincludetest.h except for those mentioned in followfiles, that is, just multiincludetest2.h. Consider the case where multiinclude.h includes stdio.h or other system headers which are not desirable for wrapping, then the above approach would work nicely in not following stdio.h.

    %import could be enhanced similarly and the above refinements would be effectively ignored if -includeall/-importall is also specified (by mistake).


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks