Search code examples
scons

Scons LIBS linking, how to remove duplicate LIBS?


We use indirection when specifying library dependencies, for instance,

env.Program(TARGET, SOURCE, LIBS = [ $LIBS_A, $LIBS_B, $LIBS_C ])

LIBS_A, LIBS_B, and LIBS_C are specified in other SConscript files.

Suppose:

LIBS_A/Sconscript has  LIBS_A = [ foo, bar, baz ]
LIBS_B/Sconscript has  LIBS_B = [ foo, bar, bat ]
LIBS_C/Sconscript has  LIBS_C = [ foo, bar, ben ]

Then the final linker line will have:

-lfoo -lbar -lbaz -lfoo -lbar -lbat -lfoo -lbar -lben

How can we remove duplicates and have the linker line read:

-lfoo -lbar -lbaz -lbat -lben

Solution

  • How's this. files fully listed.

    main.cxx

    #include <iostream>
    
    int main()
    {
      std::cout << "Hello World!";
    }
    

    SConstruct

    env=Environment()
    
    Export('env')
    
    for l in ['A','B','C']:
        env.SConscript("LIBS_%s/SConscript"%l)
    
    env.Program('myprogram',['main.cxx'], LIBS = list(set(env['LIBS_A'] + env['LIBS_B'] + env['LIBS_C'])))
    

    LIBS_A/SConscript Import('env')

    env['LIBS_A'] = ['foo','bar','baz']
    

    LIBS_B/SConscript Import('env')

    env['LIBS_B'] = ['foo','bar','bat']
    

    LIBS_C/SConscript Import('env')

    env['LIBS_C'] = ['foo','bar','ben']
    

    Yields:

    g++ -o myprogram main.o -lbaz -lbat -lfoo -lbar -lben

    If none of those would work for you, here's a more complicated way that should:

    class foo(object):
        def __init__(self, arg):
            self.arg = arg
    
        def __call__(self, target, source, env, for_signature):
            print "LIBS_A: %s  LIBS_B: %s"%(env['LIBS_A'],env['LIBS_B'])
            rc = list(set(env['LIBS_A']+env['LIBS_B']))
            print "Unique: %s"%rc
            print "SIG:%s"%for_signature
            return rc
    
    # Will call our foo method to uniquify LIBS_*
    env=Environment(FOO=foo, BAR="${FOO('$LIBS_A $LIBS_B')}")
    
    env.Command('foo.XXXXX','foo.in',action="echo LIBS: $LIBS",LIBS="$BAR",
                LIBS_A=['a','b','c','d','e','f','f','b'],
                LIBS_B=['b','d','e','g','x'])