如何编写CMakeLists.txt
How to write “CMakeLists.txt” for a big project with multiple subdirectories?
CMake官网提供了一个教程CMake Tutorial,比较简单,可以参考一下,对应的代码在github.com/Kitware/CMake。
CMake命令的介绍可以参考cmake-commands。
下面介绍一个从stackoverflow上面找到的例子,代码目录结构如下:
root/
+--- CMakeLists.txt // your root CMakeLists
+--- foo/
| +--- CMakeLists.txt // foo component's CMakeLists
| +--- foo.c
| +--- tests/
| +--- CMakeLists.txt // foo test's CMakeLists
| +--- foo_tests.c
+--- bar/
+--- CMakeLists.txt // bar component's CMakeLists
+--- bar.c
+--- bar_impl/ // no CMakeLists for this dir, it is part of bar
| +--- bar_impl.c
+--- tests/
+--- CMakeLists.txt // bar test's CMakeLists
+--- bar_tests.c
Project root CMakeLists.txt:
In your project root CMakeLists.txt
you specify minimum cmake requirement, the project name, and include the subdirectories which have your various components in them
root/CMakeLists.txt
:
cmake_minimum_required (VERSION 3.5)
project (my_project C)
add_subdirectory(foo)
add_subdirectory(bar)
Component CMakeLists.txt:
Then in each component subdirectory, you have another CMakeLists.txt
file where you add libraries, executables etc
root/foo/CMakeLists.txt
:
add_library(foo foo.c)
target_include_directories(foo PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(tests)
root/foo/tests/CMakeLists.txt
:
add_executable(foo_test foo_tests.c)
target_link_libraries(foo_test foo)
You follow this structure for bar etc...
root/foo/CMakeLists.txt
:
add_library(bar
bar.c
bar_impl/bar_impl.c)
target_include_directories(bar PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(bar foo)
add_subdirectory(tests)
root/bar/tests/CMakeLists.txt
:
add_executable(bar_test bar_tests.c)
target_link_libraries(bar_test bar)
Generating build files:
To bootstrap your build, you point cmake at your root/CMakeLists.txt
cd root
mkdir build
cd build
cmake ..
(or use your ide's build manager to generate its build configuration)
Note that if you have source files in several separate directories, yet they all belong in the same logical target, then you don't need a CMakeLists.txt
file for each directory - just list the subdirectory in the filename
Example:
foo/
+--- foo.c
+--- bar.c
+--- baz/
+--- baz.c
+--- bang.c
If you want a single target foo
for all the above files, you would create it as follows:
add_library(foo
foo.c
bar.c
baz/baz.c
baz/bang.c)
Or if you really wanted to use a variable to store the list of SRCS
set(SRCS
foo.c
bar.c
baz/baz.c
baz/bang.c)
add_library(foo ${SRCS})