cmake 简单配置使用
基本使用
基本使用只需要三行即可,如下示例
1 2 3
| cmake_minimum_required(VERSION 3.22) project(demo) add_executable(demo main.cpp)
|
- cmake_minimum_required:表示编译项目 cmake 最低需要的版本号
- project:设置项目名称
- add_executable:生成可执行文件。第一个参数为可执行文件名称,第二个源文件,如果有多个源文件,需要使用空格间隔全都写上。
多个源文件
上面的基本使用,面对很多源文件的时候,需要手动一个一个添加就实在是太反人类了。所以我们需要让 cmake 去处理,如下示例:
首先给出文件目录结构
1 2 3 4 5 6 7 8 9
| . ├── CMakeLists.txt ├── lib1 │ ├── lib1.cpp │ └── lib1.hpp ├── lib2 │ ├── lib2.cpp │ └── lib2.hpp └── main.cpp
|
1 2 3 4 5 6 7 8 9 10 11
| cmake_minimum_required(VERSION 3.22) project(demo)
include_directories(lib1 lib2)
aux_source_directory(lib1 SRC_LIST) aux_source_directory(lib2 SRC_LIST) aux_source_directory(. SRC_LIST)
add_executable(demo ${SRC_LIST})
|
这里相比上面的示例新增了两个:include_directories
和aux_source_directory
- aux_source_directory:表示添加源代码文件夹,并把文件夹内的源代码文件名称路径保存到变量中。第一个参数为项目中的文件夹名称,第二个参数为变量,自定义命名即可
- include_directories:表示添加头文件搜索位置
最后add_executable
中只需要填写变量即可。这个变量是个列表,这样就不需要我们手动输入一堆文件名了。
如果你想排除某些源代码文件,那你只能使用 set 手动来写了,如下示例
1 2 3 4 5 6
| set(SRC_LIST lib1/lib1.cpp lib2/lib2.cpp)
set(SRC_LIST lib1/lib1.cpp lib2/lib2.cpp)
|
编译的时候,新建 build 目录,然后进入 build 目录执行 cmake ..
,然后执行make
来生成
设置编译后可执行文件位置
如下示例
1 2
| set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
|
库文件编译
先上文件目录结构
1 2 3 4 5 6 7 8
| # 目录结构 . ├── CMakeLists.txt ├── inc │ └── test_func.hpp ├── lib └── src └── test_func.cpp
|
这里我们把源文件和头文件分开放,编译后的库文件放到 lib 中,CMakeLists.txt 内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13
| cmake_minimum_required(VERSION 3.22) project(demo_test_lib)
set(SRC_LIST ${PROJECT_SOURCE_DIR}/src/test_func.cpp)
// 设置动态库文件生成后存放的位置 set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
add_library (test_func_shared SHARED ${SRC_LIST}) add_library (test_func_static STATIC ${SRC_LIST})
set_target_properties (test_func_shared PROPERTIES OUTPUT_NAME "test_func") set_target_properties (test_func_static PROPERTIES OUTPUT_NAME "test_func")
|
已经介绍过的参数,就直接略过了,下面介绍新的配置。
- add_library:表示生成库文件,第一个参数为变量名,第二个为库类型 SHARED(共享/动态),STAIC(静态),第三个参数为源代码文件列表,这里直接使用 set 设置了,也可以手动写,多个使用空格间隔
- set_target_properties:设置生成的动态库参数,上面的示例为重新设置生成的动态库名称,注意名称和实际文件名是不同的。后面我们会讲。
编译的时候,新建 build 目录,然后进入 build 目录执行 cmake ..
,然后执行make
来生成
多个库同时编译
准备两个需要编译的库代码,这里简单拷贝一份上面的库代码文件,简单修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| . ├── CMakeLists.txt ├── build ├── lib │ ├── test_func │ │ ├── CMakeLists.txt │ │ ├── inc │ │ │ └── test_func.hpp │ │ ├── lib │ │ └── src │ │ └── test_func.cpp │ └── test_func2 │ ├── CMakeLists.txt │ ├── inc │ │ └── test_func.hpp │ ├── lib │ └── src │ └── test_func.cpp
|
这里的文件树示例,仅保留 lib 下面的两个库文件
注意这里的两个库文件的,头文件名相同。这是在 c++ 中不允许的。这里演示偷懒就无所谓了
每个库都有一份上面我们演示过的 CMakeLists.txt 文件,也就是库编译配置,生成的 库文件 依然存放在对应库中的 lib 文件夹中
注意顶层有个 CMakeLists.txt 文件,该文件就是编译下面两个库的配置。内容如下
1 2 3 4 5 6
| cmake_minimum_required(VERSION 3.22) project(demo)
add_subdirectory(lib/test_func) add_subdirectory(lib/test_func2)
|
只需要使用 add_subdirectory 指明下面两个库的文件夹即可
- add_subdirectory:运行指定文件夹内部的 CMakeLists.txt
链接库文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| # 文件树 ├── CMakeLists.txt ├── Makefile ├── bin ├── lib │ ├── test_func │ │ ├── CMakeLists.txt │ │ ├── inc │ │ │ └── test_func.hpp │ │ ├── lib │ │ │ ├── libtest_func.a │ │ │ └── libtest_func.dylib │ │ └── src │ │ └── test_func.cpp └── src ├── CMakeLists.txt ├── lib1 │ ├── lib1.cpp │ └── lib1.hpp ├── lib2 │ ├── lib2.cpp │ └── lib2.hpp └── main.cpp
|
现在我们需要在 src/CMakeLists.txt 文件中配置链接库的相关操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| cmake_minimum_required(VERSION 3.22) project(demo)
include_directories(lib1 lib2)
aux_source_directory(lib1 SRC_LIST) aux_source_directory(lib2 SRC_LIST) aux_source_directory(. SRC_LIST)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../bin)
include_directories(${PROJECT_SOURCE_DIR}/../lib/test_func/inc)
find_library(TESTFUNC_LIB test_func ${PROJECT_SOURCE_DIR}/../lib/test_func/lib)
add_executable(demo ${SRC_LIST})
target_link_libraries (demo ${TESTFUNC_LIB})
|
添加编译参数
比如在终端中我们会添加-std=c++11
这种参数,在 cmake 中使用add_definitions
来设置参数,如下示例:
1 2 3
| add_definitions(-std=c++11) add_executable(main main.cpp)
|