《cmake practice》总结 cmake的构建过程与基本指令
〇、基本语法规则
0.1 变量
变量使用 ${VALUENAME} 方式取值,但是在IF控制语句中直接使用变量名。
CMAKE_BINARY_DIR
或PROJECT_BINARY_DIR
或<ProjectName>_BINARY_DIR
:均代表编译目录。如果是内部构建,就是指工程顶层目录;如果是外部构建,就是指工程编译发生的目录。CMAKE_SOURCE_DIR
或PROJECT_SOURCE_DIR
或<ProjectName>_SOURCE_DIR
:均代表工程顶层目录。CMAKE_CURRENT_SOURCE_DIR
:代表当前处理的 CMakeLists.txt 所在的路径。CMAKE_CURRENT_BINARY_DIR
:如果是内部构建,与CMAKE_CURRENT_SOURCE_DIR
相同;如果是外部构建,则代表目标编译目录。CMAKE_CURRENT_LIST_FILE
:这个变量所在的CMakeLists.txt的完整路径。CMAKE_CURRENT_LIST_LINE
:这个变量所在的行。CMAKE_MODULE_PATH
:定义cmake模块所在的路径EXECUTABLE_OUTPUT_PATH
和LIBRARY_OUTPUT_PATH
:分别重新定义最终结果的存放目录。PROJECT_NAME
:项目名称
0.2 指令规则
1. 基本语法为:指令(参数1 参数2 …)
2. 参数之间使用空格或分号隔开,例如ADD_EXECUTABLE(hello main.c;func.c)
3. 指令不区分大小写,参数和变量区分大小写,但推荐全部使用大写指令
4. 当文件名中含有空格时,必须使用双引号,例如SET(SRC_LIST "fu nc.c")
0.3 基本构建过程
1. 编写程序与CMakeLists.txt文件
2. 建立外部编译目录:mkdir build
3. 进入外部编译目录:cd build
4. 构建工程:cmake ..
5. 实际构建:make
6. 运行程序:./<Executable Filename>
7. 清理工程:make clean
一、基本指令
1. PROJECT指令
1 | PROJECT(projectname [CXX] [C] [Java]) |
定义工程名称,并可制订工程支持的语言,默认支持所有语言。此指令隐式的定义了两个变量 PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
。
2. SET指令
1 | SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]]) |
用来显式的定义变量。
在ADD_EXECUTABL
所在的CMakeLists.txt文件中,添加如例2的语句,可以修改最终目标二进制文件输出的路径为build/bin
3. MESSAGE指令
1 | MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display") |
用于向终端输出用户定义的信息,包括三种类型
- SEND_ERROR:产生错误,生成过程被跳过
- STATUS:输出前缀为-的信息
- FATAL_ERROR:立即终止所有cmake过程
4. ADD_EXECUTABLE指令
1 | ADD_EXECUTABLE(<Executable Filename> ${SRC_LIST}) |
定义工程会生成文件名为<Executable Filename>
的可执行文件,相关的源文件是SRC_LIST中定义的源文件列表。
5. ADD_SUBDIRECTORY指令
1 | ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) |
用于将子目录加入当前工程,并可以指定其二进制文件存放的位置。EXCLUDE_FROM_ALL
含义是将此目录从编译过程中排除。(例:将src子目录加入工程,并制订编译输出路径为bin,那么编译结果都将放在build/bin
中)
6. INSTALL指令
1 | INSTALL(TARGETS targets... [EXPORT <export-name>] |
INSTALL指令用于安装各种类型的文件,参数中的TARGETS就是要安装的文件,可以是二进制文件、动态库、静态库。在各个CMakeLists.txt中编写好INSTALL指令后就可以开始安装了。
安装的过程如下:
1 | cmake -DCMAKE_INSTALL_PREFIX=<Install Path> |
7. ADD_DEPENDENCIES指令
1 | ADD_DEPENDENCIES(target-name depend-target1 depend-target2 ...) |
定义target以来的其他target,确保在本项目编译前,其他target已经被构建
8. ADD_TEST与ENABLE_TESTING指令
1 | ADD_TEST(testname Exename arg1 arg2 ...) |
用于创建test目标,生成makefile后就可以通过make test进行测试了。
9. EXEC_PROGRAM
1 | EXEC_PROGRAM(Executable |
用于指定在特定的目录运行某个程序。
三、静态库与动态库的构建与使用
3.1 静态库和动态库的构建方法
1. 在工程目录下新建一个lib
文件夹,并将其添加进工程目录中。
1 | # 工程目录下的CMakeLists.txt |
2. 在lib
文件夹下创建源文件。
3. 在lib
目录下创建CMakeLists.txt
。
1 | SET(LIBHELLO_SRC hello.c) |
4. 安装共享库和头文件
1 | cd build |
3.2 外部共享库和头文件的使用
1. 在新工程目录下创建src
目录,并在其中编写源文件main.c
2. 编写工程目录下CMakeLists.txt
1 | PROJECT(NEWHELLO) |
3. 编写src
目录下的CMakeLists.txt
1 | ADD_EXECUTABLE(main main.c) |
4. 构建运行
1 | cd build |