Creating and using a library with CMake

2019-08-12 23:08发布

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?

标签: c++ cmake
1条回答
女痞
2楼-- · 2019-08-12 23:31

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".

查看更多
登录 后发表回答