Mazen Al Khatib
Mazen Al Khatib

Reputation: 308

CMakeLists with multiple CMakeLists under it in build tree

I have the following tree:

/all-targets
----CMakeLists.txt
----/target1
--------CMakeLists.txt
--------/include
--------/src
----/target2
--------CMakeLists.txt
--------/include
--------/src
----/target3
--------CMakeLists.txt
--------/include
--------/src

the top-level CMake should be able to link all the targets together without producing any executable or library file, only generating any project type with the correct structure/tree

the target1 needs to have a library/object file from target2 so it can be compiled.

I've read those: 1. Multiple CMakeLists 2. CMake - Depending on another cmake project

What I understand now is in the top-level CMakeLists.txt I can add add-subdirectory command to add the target1, target2, and target3 (child directories) but I still don't understand what should I add in /target1/CmakeLists.txt so it can be linked with target2 library file ? I don't think it's add-subdirectory because in this case the target2 directory is sibling not child/sub directory.

Would the top-level CmakeLists.txt file understand that I want only to create the project file linking the targets together without having an output (executable - library).

Upvotes: 0

Views: 1458

Answers (1)

Botje
Botje

Reputation: 30830

You haven't given us much to go on, but I can provide a general idea.

The top-level CMakeLists simply calls add_subdirectory on the various targets. These should be sorted such that no target depends on targets after it.

For target1 you can have the following:

add_library(target1_common STATIC oven.cpp pan.cpp tray.cpp)
target_include_directories(target1_common PUBLIC include)
add_executable(target1 target1_main.cpp)
target_link_libraries(target1 PRIVATE target1_common)

You said that target2 depends on some parts of target1, so:

add_library(target2_common STATIC table.cpp chair.cpp plate.cpp)
target_include_directories(target2_common PUBLIC include)
target_link_libraries(target2_common PUBLIC target1_common)

add_executable(target2 target2_main.cpp)
target_link_libaries(target2 PRIVATE target2_common)

The executables are linked PRIVATE because you will not further link to them, but PUBLIC will work as well.

EDIT: Added target_include_directories statements that automatically populate the header search path for target1_common and target2_common

Upvotes: 2

Related Questions