CMake学习笔记-常用指令
CMake是使用C语言绕不开的坎,这里记录一下CMake常用的命令以供查阅。
一个最基本的CMakeLists.txt
工程目录文件:main.cpp
,CMakeLists.txt
CMakeLists.txt
:
1 | # CMakeLists.txt |
使用以下命令编译:
1 | cmake . |
语法基本原则
变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名
指令(参数 1 参数 2…) 参数使用括弧括起,参数之间使用空格或分号分开。
指令是大小写无关的,参数和变量是大小写相关的。
SET(SRC_LIST main.cpp) 可以写成 SET(SRC_LIST “main.cpp”),如果源文件名中含有空格,就必须要加双引号
内部构建与外部构建
内部构建就是直接在CMakeLists.txt
文件所在目录cmake .
。这样生成的临时文件都在根目录,比较乱。
外部构建。在其他文件夹使用cmake project_dir
。其中project_dir是工程路径。这样就不会在工程文件夹下生成临时文件了。
两个变量:
PROJECT_SOURCE_DIR
工程路径
PROJECT_BINARY_DIR
编译路径,使用cmake的路径。
编译Debug版本
默认编译为Release版本。
编译Debug(可供调试版本):
1 | cmake .. -DCMAKE_BUILD_TYPE=debug |
相关环境变量
可以通过修改环境变量实现生产环境。比如在linux的bash中:
1 | export CMAKE_INCLUDE_PATH=/usr/include/hello |
CMAKE_INCLUDE_PATH
,头文件路径。CMAKE_LIBRARY_PATH
,库文件路径。
PROJECT——指定工程名和语言
project
可以用来指定工程的名字和支持的语言,默认支持所有语言。
PROJECT (HELLO)
指定了工程的名字,并且支持所有语言—建议
PROJECT (HELLO CXX)
指定了工程的名字,并且支持语言是C++
PROJECT (HELLO C CXX)
指定了工程的名字,并且支持语言是C和C++
SET——指定变量
用来显示的指定变量。
SET(SRC_LIST main.cpp t1.cpp t2.cpp)
SRC_LIST就包含了后面三个。
MESSAGE——输出终端信息
向终端输出用户信息。主要包括三种:
SEND_ERROR
产生错误,生成过程被跳过STATUS
输出信息FATAL_ERROR
立即终止所有cmake过程
ADD_EXECUTABLE——生成可执行文件
用来指定生成可执行文件。
ADD_EXECUTABLE(hello ${SRC_LIST})
生成的可执行文件名是hello,源文件读取变量SRC_LIST中的内容。
工程名(PROJECT指定)与生成可执行文件hello没有任何关系。
ADD_SUBDIRECTORY ——指定源文件子目录
1 | ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) |
该指令用来向当前工程添加存放源文件的子目录(source_dir),并可以指定中间二进制和目标二进制的存放位置(binary_dir)。
EXCLUDE_FROM_ALL
函数是将写的目录从编译中排除,如程序中的example。
使用例子:
工程树:
1 | . |
外层CMakeLists.txt
1 | PROJECT(HELLO) |
src下的CMakeLists.txt
1 | ADD_EXECUTABLE(hello main.cpp) |
对于ADD_SUBDIRECTORY(src bin):
将 src 子目录加入工程并指定编译输出(包含编译中间结果)路径为build/bin 目录。如果不进行 bin 目录的指定,那么编译结果(包括中间结果)都将存放在build/src 目录。
如果想要将最终编译结果放到外面而不是子文件夹:
在SRC目录下的CMakeLists.txt(哪里要改变目标存放路径,就在哪里加入上述的定义)中添加:
1 | # 编译可执行文件的输出路径--放到了build下 |
ADD_LIBRARY——构建库
1 | ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) |
和ADD_EXECUTABLE()
一样。
hello
:就是正常的库名,生成的名字前面会加上lib,最终产生的文件是libhello.soSHARED
,动态库STATIC
,静态库${LIBHELLO_SRC}
:源文件
SET_TARGET_PROPERTIES——设置输出对象的参数
1 | #对hello_static的重名为hello |
INCLUDE_DIRECTORIES——添加头文件路径
添加头文件路径,首先可以直接在代码中使用绝对路径。
或者使用关键字添加头文件搜索目录。
1 | INCLUDE_DIRECTORIES(/usr/include/hello) |
INCLUDE_DIRECTORIES
这条指令可以用来向工程添加多个特定的头文件搜索路径,路径之间用空格分割
LINK_DIRECTORIES——添加第三方共享库路径
1 | LINK_DIRECTORIES(/home/myproject/libs) |
LINK_DIRECTORIES
添加非标准的共享库搜索路径。
或者直接添加共享库文件。
TARGET_LINK_LIBRARIES——添加需要链接的共享库
1 | TARGET_LINK_LIBRARIES(main libhello.a)` |
TARGET_LINK_LIBRARIES
添加需要链接的共享库。
INSTALL——安装
INSTALL可以安装:二进制,动态库,静态库,文件,脚本。
相关变量CMAKE_INSTALL_PREFIX
。
安装文件
1 | INSTALL(FILES file1 file2 DESTINATION path) |
FILES
:文件
DESTINATION
:
1、写绝对路径
2、可以写相对路径,相对路径实际路径是:${CMAKE_INSTALL_PREFIX}/<DESTINATION 定义的路径>
cmake -DCMAKE_INSTALL_PREFIX=/usr
在cmake的时候指定CMAKE_INSTALL_PREFIX变量的路径。
安装脚本
1 | INSTALL(PROGRAMS runhello.sh DESTINATION bin) |
PROGRAMS
:非目标文件的可执行程序安装(比如脚本之类)
安装文件夹中文件
- 在相应文件夹下创建CMakeLists.txt,其中使用INSTALL。
- 在工程目录通过
DIRECTORY
指定。
1 | INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake) |
DIRECTORY
后面连接的是所在 Source 目录的相对路径
注意:abc 和 abc/有很大的区别
目录名不以/结尾:这个目录将被安装为目标路径下的
目录名以/结尾:将这个目录中的内容安装到目标路径
安装共享库和头文件
1 | #本例将hello共享库安装到<prefix>/lib下 |