Search code examples
c++static-librariescircular-dependencywafns-3

Linking with NS3 module with circular dependency to other library


I am trying to build custom NS3 module which depends on some static library. This static library depends on NS3 module.

Platform: Ubuntu 16.04 x64 Toolchain: GCC 5.4.0

I will refer to my custom NS3 module as mymodule

I will refer to the library which mymodule depends on as mylib

I will refer to the program which links with mymodule and mylib as myprog

wscript for mymodule:

def build(bld):
   module = bld.create_ns3_module('mymodule', ['network'])
   module.features = 'c cxx cxxstlib ns3module'
   module.source = [
     'model/mymodule.cc' ]

   # Make a dependency to some other static lib:
   bld.env.INCLUDES_MYLIB = [ "some/include/path" ]
   bld.env.LIB_MYLIB = ['mylib']
   bld.env.LIBPATH_MYLIB = [ "some/path" ]
   module.use.append('MYLIB')

   # Create a program which uses mymodule
   p = bld.create_ns3_program('myprog', ['core', 'mymodule'])
   p.source = 'prog.cpp'

   headers = bld(features='ns3header')
   headers.module = 'mymodule'
   headers.source = ['model/mymodule.h']

When I do ./waf build it fails: LD cannot link myprog because mylib has unresolved symbols. This failure is actually expected because mylib and mymodule are codependent and should be linked in non-standard way.

Workarounds:

  1. If I build myprog by hand and use -Wl,--start-group -lns3.26-mymodule-debug -lmylib -Wl,--end-group it links perfectly fine and works as expected.

  2. If I combine two static libs by hand (using ar -M script) and then run ./waf build it also works fine.

The question: How can I integrate one of the workarounds above into wscript?


Solution

  • it looks like a known problem with order of static libs inclusion. The behavior has changed in waf 1.9, due to this problem.

    One workaround might be to use the linkflags attribute of program. You should prefer the use of STLIB_MYLIB and STLIBPATH_MYLIB as mylib is static. In waf 1.9 with he correct order of libs it might suffice.

    Anyway, use -v to see the command line generated by waf, it might help !