Cmake学习笔记
一、语法介绍
1.语法基本原则
- 变量使用
${}
方式获取值,但在IF
控制语句中直接使用变量名 - 指令(参数1 参数2 …):参数使用圆括弧括起来,参数之间使用空格或分号分开
- 指令大小写无关,参数和变量大小写相关,推荐全部使用大写方式
SET(SRC_LIST main.cpp)与SET(SRC_LIST “main.cpp”)等价,但当源文件名中含有空格时必须加引号
2.基本关键词
- PROJECT关键字
指定工程名字和支持语言,默认支持所有语言
PROJECT(HELLO) 指定工程名字且支持所有语言
PROJECT(HELLO CXX) 指定工程名字,支持C++
PROJECT(HELLO C CXX) 指定工程名字,支持C和C++
上面PROJECT关键字隐式定义了两个CMAKE变量:
1 | <projectname>_BINARY_DIR:上面的例子是HELLO_BINARY_DIR |
MESSAGE
关键字可以直接使用上述两个变量,若修改工程名则上述两个变量名也会改变;因此定义变量PROJECT_BINARY_DIR
和PROJECT_SOURCE_DIR
来替换上述两个变量
- SET关键字
设置变量的值,若变量值不止一个则使用空格分隔
SET(SRC_LIST main.cpp)
- MESSAGE关键字
向终端输出用户自定义信息,主要包含以下三种信息:
- SEND_ERROR:产生错误,生成过程被跳过
- STATUS:输出前缀为
--
的信息- FATAL_ERROR:立即终止所有cmake过程
- ADD_EXECUTABLE关键字
生成可执行文件
ADD_EXECUTABLE(hello ${SRC_LIST}) 生成可执行文件名为hello,源文件读取变量SRC_LIST中的内容
内部构建和外部构建
内部构建:直接在源文件所在目录执行
cmake .
从而生成的中间文件都在源文件所在目录外部构建:在源文件所在目录中创建build目录并在该目录中执行
cmake ..
从而使生成的中间文件都在build目录下工程目录下每个文件夹尽量都放一个CMakeLists.txt
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
该指令用于向当前工程中添加存放源文件的子目录,并且可以指定中间二进制和目标二进制文件的存放位置
EXCLUDE_FROM_ALL将写的目录从编译中排除,如程序中的example
ADD_SUBDIRECTORY(src bin):将src子目录加入工程并指定编译输出为bin目录;若不指定编译输出目录则编译结构都存放于build/src目录中
- 静态库和动态库创建
1 | ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC}) |
hello:生成的库名字,默认会在其前面添加lib,最终产生文件是libhello.so
SHARED:动态库 STATIC:静态库
${LIBHELLO_SRC}:源文件
SET_TARGET_PROPERTIES():设置输出名称,还能指定动态库版本和API版本,如:
SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.0 SOVERSION 1)
其中VERSION指代动态库版本,SOVERSION指代API版本
1 | # 同时创建动态库和静态库 |
安装
- 代码编译后使用
make install
安装 - 指定目录安装:
make install DESTDIR=/tmp/test
或./configure --prefix=/usr
CMake安装
CMAKE_INSTALL_PREFIX:安装路径
- 安装文件
1 | INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/) |
FILES:需要安装的文件
DESTINATION:绝对路径或相对路径
相对路径:${CMAKE_INSTALL_PREFIX}/share/doc/cmake/ 其中${CMAKE_INSTALL_PREFIX}默认为/usr/local
cmake -D CMAKE_INSTALL_PREFIX=/usr ..
表示在cmake时指定CMAKE_INSTALL_PREFIX变量的值即安装路径
- 安装脚本
1 | INSTALL(PROGRAMS runhello.sh DESTINATION bin) |
PROGRAMS:非目标文件的可执行程序安装(例如脚本)
上述bin也是相对路径,实际为/usr/local/bin
- 安装目录中的文件
1 | INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake) |
注意:doc和doc/区别如下
目录名不以/结尾(doc):该目录将会被安装到目标路径下
目录名以/结尾(doc/):该目录下的所有内容将会被安装到目标路径下
- 安装共享库和头文件
1 | //文件放到该目录下 |
共享库调用
向工程中添加多个特定头文件搜索路径,路径之间使用空格分隔
1 | INCLUDE_DIRECTORY(/usr/include/hello) |
解决:找到引用的函数问题
报错信息:undefined reference to`HelloFunc()’
LINK_DIRECTORIES: 添加非标准的共享库搜索路径(指定第三方库所在路径LINK_DIRECTORIES(/PATH))
TARGET_LINK_LIBRARIES: 添加需要链接的共享库(只需要给出动态链接库的名字就行)
在CMakeLists..txt中插入链接共享库,主要要插在executablel的后面
- debug版本(可调试版本)
cmake .. -D CMAKE_BUILD_TYPE=debug