Home > other >  How do I handle subdirectory dependencies in CMake?
How do I handle subdirectory dependencies in CMake?

Time:02-01

I have a project where I need to run one application on multiple boards. To do this I have two exectuables that share a main.c, but are compiled with a different board.c. The directory tree is as follows:

CMakeLists.txt
src/
├─ board/
│  ├─ board_a/
│  │  ├─ board.c
|  |  ├─ CMakeLists.txt
│  ├─ board_b/
│  │  ├─ board.c
|  |  ├─ CMakeLists.txt
├─ app/
│  ├─ main.c
├─ lib/
│  ├─ somelib/
│  │  ├─ somelib.h
│  │  ├─ somelib.c

In an attempt to make the root CMakeLists.txt smaller and more maintainable, I've created a CMakeLists.txt for both boards, and would like to compile each board as an object library for the main executable in the root CMakeLists.txt to add_subdirectory on and link in.

My problem is that board.c (as well as main.c) depends on somelib. How can I add this dependency to the subdirectory CMakeLists.txt? Is there a way I can do that without hard-coding a path to somelib? My feeling is that I should create a CMakeLists.txt in somelib, and I feel this would be easy if I were handling the library linking from the root CMakeLists.txt, but my confusion is that board is adjacent to lib. I'm relatively new to CMake and am not sure how to best structure these dependencies.

CodePudding user response:

My problem is that board.c (as well as main.c) depends on somelib. How can I add this dependency to the subdirectory CMakeLists.txt? Is there a way I can do that without hard-coding a path to somelib? My feeling is that I should create a CMakeLists.txt in somelib, and I feel this would be easy if I were handling the library linking from the root CMakeLists.txt, but my confusion is that board is adjacent to lib. I'm relatively new to CMake and am not sure how to best structure these dependencies.

This is very straightforward start by linking each board_<X> to somelib's target.

# in each board_<X>/CMakeLists.txt

add_library(board_<X> OBJECT ...)
target_link_libraries(board_<X> PUBLIC proj::somelib)

then create the target for somelib:

# src/lib/somelib/CMakeLists.txt

add_library(somelib somelib.c)
add_library(proj::somelib ALIAS somelib)

target_include_directories(
  somelib PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")

As long as the top-level CMakeLists.txt includes these subdirectories via add_subdirectory (multiple levels is fine), then other targets can #include <somelib.h> and CMake will handle linking.

  •  Tags:  
  • Related