Reputation: 3437
I'm trying to learn CMake, but I can't get to grips with the tutorials that are available.
Let's say my project has the structure below, and I want to make my_lib available through its CMakeLists file and use it in my main.cpp, what would my CMakeLists files look like?
├── CMakeLists.txt
├── externals
│ └── my_lib
│ └── src
│ ├── CMakeLists.txt
│ ├── MyClass.h
│ └── MyClass.cpp
└── main.cpp
Should I use include_directories or add_subdirectory?
Upvotes: 1
Views: 439
Reputation: 78418
To match the directory structure you indicated, your CMakeLists.txt files could look like this:
/CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(Main)
add_subdirectory(externals/my_lib/src)
add_executable(my_main main.cpp)
target_link_libraries(my_main my_lib)
/externals/my_lib/src/CMakeLists.txt:
cmake_minimum_required(VERSION 3.0)
project(MyLib)
add_library(my_lib MyClass.cpp MyClass.h)
target_include_directories(my_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
Using PUBLIC
in the target_include_directories
call means that not only does your library have this as an "include path", but so does any target linking to it.
The downside with this setup however is that you're also going to expose any internal headers of my_lib
to consuming targets too. Say you also have an "Internal.h" as part of my_lib
which you don't want to expose. You can do this by moving the intentionally-public headers into a separate folder, e.g. "include":
├── CMakeLists.txt
├── externals
│ └── my_lib
│ ├── CMakeLists.txt
│ ├── include
│ │ └── MyClass.h
│ └── src
│ ├── Internal.h
│ └── MyClass.cpp
└── main.cpp
Your top-level CMakeLists.txt wouldn't change, but /externals/my_lib/CMakeLists.txt (which has moved up a level) now reads:
cmake_minimum_required(VERSION 3.0)
project(MyLib)
add_library(my_lib src/MyClass.cpp src/Internal.h include/MyClass.h)
target_include_directories(my_lib
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
)
Now, since your library's "src" folder is PRIVATE
to my_lib
, main.cpp won't be able to #include "Internal.h"
.
Upvotes: 2