3

My project has external library dependencies and I am using waf scripts to build it - C, C++.

I am trying to build static library which will have all the dependent libraries statically linked. For example, I use this to build dynamic shared object:

bld.program(features = 'c cxx cxxshlib'
            , target = 'program'
            , source =  sources
            , use = libs_list)

Shared object will have all the dependent libraries (specified with libs_list) linked. However, static library:

bld.program(features = 'c cxx cxxstlib'
            , target = 'program'
            , cppflags = '-DSTATIC_LIB'
            , source = sources
            , use = libs_list)

will not. Is there a way to overcome this? Or do I need to do this manually in post build function?

Mojo28
  • 335
  • 1
  • 3
  • 9

1 Answers1

1

Prior to waf 1.8, the static libraries used to share the same behavior of recursive dependencies with shared objects. Due to static libs order of use, I think this was removed. That means that if your shared object is dependant of other libs, waf will automatically include them, but for static libs, you have to list all the libraries in correct order yourself.

Here is how 'uselib' should be used :

def configure(conf):

    # for libs that have a pkg-config

    conf.check_cfg("expat", args = ["--libs"]) 

    # to use /some/path/libotherextlib.a or .so

    conf.env.LIB_OEL = ['otherextlib'] 
    conf.env.LIBPATH_OEL = ["/some/path"] 

def build(bld):

    lib_lists = ["expat", "oel"]

    bld.shlib(target = 'myshlib', source = sources, use = libs_list)
    bld.stlib(target = 'mystlib', source = sources, use = libs_list)

To modularize you can do :

bld.objects(source = sources1, name = "module1")
bld.objects(source = sources2, name = "module2")

modules = ["module1", "module2"]
bld.stlib(target = 'mystlib', use = modules)
bld.shlib(target = 'myshlib', use = modules)
neuro
  • 14,948
  • 3
  • 36
  • 59
  • Actually, this way, static lib will include all the recursive dependencies, because those are specified by keyword use. As you can see, libs_list is the same for both (if I understood you correctly). However, the problem occurs with the libraries which are external - libexpat.a for example. In my case, libexpat will be linked to shared object with -Lexpat, but not for static lib. I would like ar to include all of these external libraries. – Mojo28 Apr 27 '16 at 16:58
  • @mojo: hum use -v to see which commands are issued. If the command is ok your problem is probably due to the order of static libs in list. – neuro Apr 28 '16 at 08:15
  • Yeah, I used -v but no libs are mentioned, only object files. This is perhaps expected. The problem is that it is not so easy to merge static libraries into one with ar, default is to use object files only. Perhaps this is why this is not possible at all. I am also not sure if there is a nice way to get list of all dependent static libraries. I am trying to run ar manually. For this, I need list of all dependent static libraries. Currently, I am parsing context env to get all variables that start with STLIB_%s. I don't think this is the nicest way of doing stuff. – Mojo28 Apr 28 '16 at 09:29
  • I'm not sure to understand !? the 'use' feature use previously defined libs definition to work. If you don't see any lib in the command there something wrong ... – neuro Apr 28 '16 at 11:26
  • Are you sure? I don't think you can add library dependency to 'ar' in one command. use works for 'myshlib' since it is using g++ to link, but 'mystlib' simply ignores static libraries. You can also see here that it is not so easy to merge static libraries : http://stackoverflow.com/questions/3821916/how-to-merge-two-ar-static-libraries-into-one – Mojo28 Apr 28 '16 at 11:46
  • Ok. I was mistaken by the fact i usually use 'uselib' with executable. I use the 'objects' features of waf to achieve what you want to do. 'stlib' only encapsulate in a portable way – neuro Apr 28 '16 at 11:52