user2914066
user2914066

Reputation: 181

Create CMakeLists library with subdirectory sources

project
 |
 |----- src  <-- Needs to be a library
 |       |
 |       |--- dir1 <-- Need not create a library
 |       |      |--- dir1_1.cpp
 |       |      |--- dir1_2.cpp
 |       |      |--- CMakeLists.txt
 |       |
 |       |
 |       | --- dir2 <-- has an executable for testing and needs to be a library
 |       |      |--- dir2.cpp
 |       |      |--- dir2.h
 |       |      |--- CMakeLists.txt
 |       |
 |       |
 |       | --- CMakeLists.txt 
 |
 |
 |
 |----- CMakeLists.txt

How do I create CMakeLists in src such that it includes files from dir1 and dir2, such that only dir2 is a sub-project. I want to use add_subdirectory in src/CMakeLists.txt to add source files from dir1 and dir2. This way it will be easier to add more folders in the future.

I saw the use of PARENT_SCOPE but it also has some drawbacks. Is there a better solution? Maybe by using target_sources or something?

Upvotes: 1

Views: 98

Answers (2)

Kevin
Kevin

Reputation: 18243

You can create a library, then later add its source files in a subdirectory using target_sources. This gives you the flexibility to add more sources to MyLib or add more sub-projects later on, via additional calls to add_subdirectory.

It might look something like this:

src/CMakeLists.txt:

# Create a library
add_library(MyLib SHARED)

# Traverse to the 'dir1' subdirectory to populate the sources for MyLib.
add_subdirectory(dir1)
# Traverse to 'dir2' to create a sub-project.
add_subdirectory(dir2)

dir1/src/CMakeLists.txt:

target_sources(MyLib PUBLIC
    dir1_1.cpp
    dir1_2.cpp
)
# Add any headers from this directory.
target_include_directories(MyLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

dir2/src/CMakeLists.txt:

project(MySubProject)

add_library(MyLib2 SHARED
    dir2.cpp
)
# Add any headers from this directory.
target_include_directories(MyLib2 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

add_executable(MyExe ...)

...

Upvotes: 1

RAM
RAM

Reputation: 2749

First of all, you should reconsider not making those subdirs self-contained modules, as modularity helps keep your projects cleaned.

Having said that, you can include in any variable defined in ./src/CMakeLists.txt any variable that's defined by ./src/dir1/CMakeLists.txt or ./src/dir2/CMakeLists.txt. Here's an example:

Here are the contents of ./src/dir1/CMakeLists.txt:

set(dir1_SOURCES 
    dir1/dir1_1.cpp 
    dir1/dir1_2.cpp 
)

Here are the contents of ./src/CMakeLists.txt:

add_subdirectory(dir1)

set(src_SOURCES 
    ${dir1_SOURCES} 
)

Upvotes: 1

Related Questions