Search code examples
gccscons

How do you pass the --start-group and --end-group flags to gcc when using scons?


In scons, how do you implement the --start-group and --end-group gcc flags? These should wrap a particular set of LIBS, but I couldn't find a PREFIX/SUFFIX option that wraps the entire (or partial set of) input to LIBS.

In case you're wondering what gcc flags I'm talking about, read more here:

GCC: what are the --start-group and --end-group command line options?


Solution

  • You're right that there is no built in prefix/suffix for this wrapper. The command line options specifying the list of libraries passed to the link command is computed based on the LIBS environment variable and stored in the _LIBFLAGS environment variable. _LIBFLAGS is then used as a part of the complete linker command line.

    The defaults, defined in Tool/link.py in the SCons library, look something like:

    env['LINKCOM']  = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS'
    env['_LIBFLAGS']='${_stripixes(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, LIBPREFIXES, LIBSUFFIXES, __env__)}'
    

    Assuming that you want to wrap the entire set of libraries, then in your environment, you can edit either the LINKCOM or the _LIBFLAGS variables to add the options:

    # SConstruct
    
    env = Environment(
        CC = 'gcc',
        LINKCOM = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS -Wl,--start-group $_LIBFLAGS -Wl,--end-group'
    )
    
    #env.Prepend(_LIBFLAGS="-Wl,--start-group ")  # the trailing space is required
    #env.Append(_LIBFLAGS=" -Wl,--end-group")     # the leading space is required
    env.Program('foo', ['foo.c'], LIBS='m')
    

    I think editing LINKCOM is a little less invasive. In my trivial example, this generates:

    $ scons
    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Building targets ...
    gcc -o foo.o -c foo.c
    gcc -o foo foo.o -Wl,--start-group -lm -Wl,--end-group
    scons: done building targets.
    

    If you want to group just a subset of libraries, then you'll have to use separate LIBS variables for the "wrapped" and "unwrapped" libraries and duplicate the _LIBFLAGS function in a separate variable appended to LINKCOM.