[CMake] How to add dependency relations between libs and executable
Chuck Atkins
chuck.atkins at kitware.com
Tue Apr 19 13:56:34 EDT 2016
> cmake, the old top layer project is proj_a, which at the same layer with
> proj_b and proj_c, if I add an extra top layer as the root you mentioned,
the generated make file structure will be changed, top layer make file
will be root instead of proj_a.
>
> Is there any way to add the dependency at proj_a level?
>
If you want proj_a, proj_b, and proj_c to all be built by the same make
command, then it makes sense to have a top level organization that
encompasses them all. Also, if proj_a, proj_b and proj_c don't make sense
on their own and only when paired with each-other, then I would take the
"project(...)" command out of each of them and only leave the top level.
Basically, anything that has a project(...) command can be configured and
built all on it's own without the rest of the tree. In this case, it may
make sense to keep b and c as independent projects but a as not since it
needs b and c. So for example, similar to Anatoly's example:
*folder*
CMakeLists.txt:
project(root)
add_subdirectory(proj_b)
add_subdirectory(proj_c)
add_subdirectory(proj_a)
*folder/proj_a*
CMakeLists.txt:
add_executable(*A *main.cpp)
target_link_libraries(*A B C*)
*folder/proj_b*
CMakeLists.txt:
project(proj_b)
add_library(B proj_b.cpp)
*folder/proj_c*
CMakeLists.txt:
project(proj_c)
add_library(*C *proj_c.cpp)
With this structure, you can configure and build just project b or c:
$ mkdir build_c
$ cd build_c
$ cmake /path/to/folder/proj_c
...
$ make
...
You end up with libC.a . Similarly, you could do that for proj_b and get
libB.a. Or, if you configure the top level project instead:
$ mkdir build_all
$ cd build_all
$ cmake /path/to/folder
...
$ make
Scanning dependencies of target B
[ 16%] Building CXX object proj_b/CMakeFiles/B.dir/proj_b.o
[ 33%] Linking CXX static library libB.a
[ 33%] Built target B
Scanning dependencies of target C
[ 50%] Building CXX object proj_c/CMakeFiles/C.dir/proj_c.o
[ 66%] Linking CXX static library libC.a
[ 66%] Built target C
Scanning dependencies of target A
[ 83%] Building CXX object proj_a/CMakeFiles/A.dir/main.o
[100%] Linking CXX executable A
[100%] Built target A
$
You end up with proj_b/libB.a, proj_c/libC.a, and proj_a/A which is linked
with libB.a and libC.a. You can also do a parallel make with make
-j(whatever) adn the generated dependencies will make sure that targets and
individual files are built in the right order. Technically speaking, you
don't *need* to have a CMakeLists.txt at each level and you could put it
all in to one top level CMakeLists.txt but it's generally considered poor
CMake code to do so. A good rule of thumb is to have a CMakeLsits.txt file
at each level that a target (i.e. a library or executable) is built and a
top level CMakeLists.txt to tie it all together. This is the same sort of
approach you see with autoconf where it's typical to have a Makefile.am at
each level.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/cmake/attachments/20160419/65290eb6/attachment-0001.html>
More information about the CMake
mailing list