Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

make one static library from whole project with cmake

Tags:

linux

cmake

c++-project, say, foo is maintained by the cmake. One wants to create one library libfoo.a (with all classes/methods/functions created at the whole source-tree) to make possible creating programs that could linked to the library with -lfoo.

ok, let's consider now a toy example, and the prolbem will be clear. Directory foo (root of the project) contains directories a, and b. Two CmakeLists.txt are created:

# a/CMakeLists.txt
add_library(A <a_sources>)
# b/CMakeLists.txt
add_library(B <b_sources>)

And one CMakeLists.txt for root directory:

add_subdirectory(a)
add_subdirectory(b)
add_library(foo <foo_sources>
target_link_libraries(foo A B)

That was a surprise for me: after building libfoo.a contains only methods from foo_sources, and a_sources,b_sources are excluded. That is ok in the case when executables are built with the same project: while creating executables cmake "guesses" that a and b must be linked if it is linked to foo. But in the case executable is created "outside" project to use library foo one must link with -lfoo -la -lb, now imagine a project with lots of subdirectories - how to deal with it? so question is "how to create one library, aggregating methods from whole project with means of cmake?"

Googling led me to relatively recently embedded (appeared in 2.8.8) OBJECT library opportunity. Nice example of using it is shown here. Now the problem above can be solved with that:

# a/CMakeLists.txt
add_library(A OBJECT <a_sources>)
# b/CMakeLists.txt
add_library(B OBJECT <b_sources>)
# foo/CMakeLists.txt
add_subdirectory(a)
add_subdirectory(b)
add_library(foo <foo_sources> $<TARGET_OBJECTS:A> $<TARGET_OBJECTS:B>)

problem seems to be solved, unfortunately, not quite.

if dependency chain is longer than 2, for example, foo depends on A, which depends on B, problem still remains. That is because,

Object libraries may contain only sources (and headers) that compile to object files.

and

Object libraries cannot be imported, exported, installed, or linked.

(quotes are taken from the same link)

I've tried several combinations of target_link_library(), add_library(), add_library(... OBJECT ..) trying to link A and B to foo without success (error during cmake-process.)

I must be loosing something simple, please help, thank you! I am not sure is it important: project is maintained at the linux.

like image 764
Max Avatar asked Dec 01 '12 18:12

Max


1 Answers

I think you're getting tangled up in the term "depends on". If you're building a library named foo and it has two parts, A and B, it doesn't matter whether A depends on B; the library should contain both. The CMake code you've shown will build foo properly.

like image 50
Pete Becker Avatar answered Nov 15 '22 11:11

Pete Becker