Linking Static Libraries to Other Static Libraries

Linking static libraries to other static libraries

Static libraries do not link with other static libraries. The only way to do this is to use your librarian/archiver tool (for example ar on Linux) to create a single new static library by concatenating the multiple libraries.

Edit: In response to your update, the only way I know to select only the symbols that are required is to manually create the library from the subset of the .o files that contain them. This is difficult, time consuming and error prone. I'm not aware of any tools to help do this (not to say they don't exist), but it would make quite an interesting project to produce one.

Link static library in another static library

You can't "include a library in a library". You link both libraries to your application which is what you've apparently done already. You just have to follow the general rules of a c++ program: only one defintion of a symbol is allowed and you need to prevent potential name clashes.

Static libraries linked against other static libraries with CMake - one works, one doesn't. Why?

Can someone please explain how Project Foo works successfully, and Project Bar (doesn't) works as expected?

In short: Creating STATIC library doesn't involve linking step!

Details

In the Foo project you have an executable foo_runtime, which "works" because it is linked with proper libraries (e.g. with library foo_subproject_1 which defines foo_subproject_1_init_frobulation symbol).

An executable bar from Bar project doesn't perform that linking, so it fails. The line

target_link_libraries(bar foo_lib)

links with foo_lib, but this library doesn't defines the needed symbol foo_subproject_1_init_frobulation.

Note, that the line

target_link_libraries(foo_lib foo_subproject_1 foo_subproject_2)

in the Foo project doesn't perform actual linking: in general, building a static library doesn't involve linking step.

Given line just propagates include directories (and other compile-features) from foo_subproject_* libraries to the foo_lib one.

How to make it work

Because static library foo_lib doesn't track its dependency, you need to link bar with a library, which knows that. E.g., make foo_lib shared, or combine foo_subproject_* libraries into archive library, as suggested by the referenced question How to combine several C/C++ libraries into one?.

Alternatively, you may build Foo subproject within Bar one and, instead of creation of IMPORTED foo_lib target, use "normal" foo_lib target, created within Foo project. In that case, line

target_link_libraries(bar foo_lib)

would mean for CMake to (actually) link bar with foo_subproject_* libraries, because those libraries are "linked" (in CMake sense) into foo_lib. Again, the last "linking" has a meaning only for CMake: the file foo_lib.a doesn't aware about needing of foo_subproject_* libraries.

Linking static libraries, that share another static library

Static libraries should never include other static libraries (or third party code in general). A static library is just a bundle of .o files glued together. So if you have multiple copies of the same information, it's going to blow up.

Each static library should just have its own code in it. The final application is responsible for linking all the required libraries together (including libraries required by libraries). This way there is exactly one copy of each thing linked.

Static Libraries which depend on other static libraries

Please, try g++ -o main src/main.o -L. -Wl,--start-group -lslib1 -lslib2 -Wl,--end-group.

Group defined with --start-group, --end-group helps to resolve circular dependencies between libraries.

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



Related Topics



Leave a reply



Submit