命令
cmake_minimum_required (VERSION 2.8)
CMake 最低版本号要求
project (Demo1)
设置项目名称
add_executable(Demo main.cc)
指定生成可执行程序
aux_source_directory(/project/src DIR_SRCS)
查找指定目录下的所有源文件,并将名称保存到 DIR_SRCS 变量,注意该命令不会递归查找。
这句话常和下面配合使用:
add_executable(Demo ${DIR_SRCS})
add_subdirectory(math)
添加 math 子目录,意思是调用子目录下的CMakeLists.txt文件
aux_source_directory(. DIR_LIB_SRCS)
add_library (MathFunctions ${DIR_LIB_SRCS})
生成链接库MathFunctions
默认是生成静态库,可以添加static\share选项指定。
如:
add_library (MathFunctions share ${DIR_LIB_SRCS})
既要生成静态,也要动态,可以添加两次。
set(SRC_LIST main.c t1.c t2.c)
设置变量SRC_LIST = main.c t1.c t2.c
set(CMAKE_CXX_STANDARD 11)
CMAKE_开头的都是cmake内置变量,这条语句是设置C++标准为C++11
MESSAGE(STATUS "THIS IS BINARY DIR " ${HELLO_BINARY_DIR})
打印信息
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display" ...)
这个指令用于向终端输出用户定义的信息,包含了三种类型:
- SEND_ERROR,产生错误,生成过程被跳过。
- SATUS,普通信息,输出前缀为–。
- FATAL_ERROR,立即终止所有 cmake 过程
安装命令根据文件类型不同意见有不同的写法:
1、安装目标文件
最常见的是通过ADD_EXECUTABLE或者ADD_LIBRARY定义的目标文件,即可执行二进制、动态库、静态库。
INSTALL(TARGETS myrun mylib mystaticlib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION libstatic
)
上面的例子会将:
- 可执行二进制 myrun 安装到
${CMAKE_INSTALL_PREFIX}/bin
目录 - 动态库 libmylib 安装到
${CMAKE_INSTALL_PREFIX}/lib
目录 - 静态库 libmystaticlib 安装到
${CMAKE_INSTALL_PREFIX}/libstatic
目录
特别注意的是你不需要关心 TARGETS 具体生成的路径,只需要写上 TARGETS 名称就可以了。
DESTINATION
指定安装的具体目录,可以是相对路径,也可以是绝对路径,相对路径是相对于内置变量CMAKE_INSTALL_PREFIX
。
目标文件 | 内容 | 安装目录变量 | 默认安装文件夹 |
---|---|---|---|
ARCHIVE | 静态库 | ${CMAKE_INSTALL_LIBDIR} | lib |
LIBRARY | 动态库 | ${CMAKE_INSTALL_LIBDIR} | lib |
RUNTIME | 可执行二进制文件 | ${CMAKE_INSTALL_BINDIR} | bin |
PUBLIC_HEADER | 与库关联的PUBLIC头文件 | ${CMAKE_INSTALL_INCLUDEDIR} | include |
PRIVATE_HEADER | 与库关联的PRIVATE头文件 | ${CMAKE_INSTALL_INCLUDEDIR} | include |
2、普通文件、目录安装
INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/t2)
–普通文件
INSTALL(PROGRAMS build/bin/hello runhello.sh DESTINATION bin)
– 非目标文件的可执行程序(如脚本)
INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/t2)
–目录
以相对路径给出的文件或者文件夹,将相对于当前源目录进行解释。
安装的时候可以指定权限,如果不指定权限:
- 对于FILES:
安装后的权限为:
OWNER_WRITE, OWNER_READ, GROUP_READ,和 WORLD_READ,即 644 权限。 - 对PROGRAMS
安装后权限为:
OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE,即 755 权限
详见:https://blog.csdn.net/qq_38410730/article/details/102837401
find_library(TESTFUNC_LIB testFunc HINTS ${PROJECT_SOURCE_DIR}/testFunc/lib)
add_executable (main ${SRC_LIST})
target_link_libraries (main ${TESTFUNC_LIB})
find_library
: 在指定目录下查找指定库,并把库的绝对路径存放到变量里,其第一个参数是变量名称,第二个参数是库名称,第三个参数是HINTS,第4个参数是路径,其它用法可以参考cmake文档。
target_link_libraries
: 把目标文件与库文件进行链接。
使用find_library的好处是在执行cmake …时就会去查找库是否存在,这样可以提前发现错误,不用等到链接时。
target_link_libraries
写法多变:
target_link_libraries(project utils) # 连接libhello.so库,默认优先链接动态库
target_link_libraries(project libutils.a) # 显示指定链接静态库
target_link_libraries(project libutils.so) # 显示指定链接动态库
target_link_libraries(project -lutils)
ps:在lib目录下有testFunc的静态库和动态库,find_library(TESTFUNC_LIB testFunc …默认是查找动态库,如果想直接指定使用动态库还是静态库,可以写成find_library(TESTFUNC_LIB libtestFunc.so …或者find_library(TESTFUNC_LIB libtestFunc.a …
add_compile_options(-std=c++11 -Wall)
添加编译选项
比如想传递个编译宏:
add_compile_options(-DDEBUG)
cmake支持传宏来控制编译,可以在执行cmake命令时传入:
cmake .. -DDEBUG=ON
这样子可以在cmake脚本中使用该宏,注意该宏不是编译宏(即不会传递到Makefile),如果想向编译传递,可以结合add_compile_options:
if (DEBUG)
add_compile_options(-DDEBUG)
endif()
cmake宏在编译时似乎必须传值,并且可以作为if语句判断条件,经过测试:
- 情况1:
可以传0,和非0数 - 情况2:
可以传OFF,和非OFF任意字符串。 - 情况3:
可以为空,但=必须加上。如:
cmake . -DDEBUG=
也可以在cmake脚本里设置宏的初值:
option(DEBUG "print one message" OFF)
经过测试,option比较坑,如果没有删除cmake产生的临时文件,修改option可能还是保持上一次的值。
所以如果option有变化,要么删除上次执行cmake时产生的缓存文件,要么把所有的option都显式的指定其值。
add_definitions
向 C/C++编译器添加-D 定义,比如:
add_definitions(-DENABLE_DEBUG -DENABLE_CONFIG_FILE)
,参数之间用空格分割。
如果你的代码中定义了#ifdef ENABLE_DEBUG #endif
,这个代码块就会生效。
如果要添加其他的编译器开关,可以通过 CMAKE_C_FLAGS
变量和 CMAKE_CXX_FLAGS
变
量设置。
ENABLE_TESTING
指令用来控制 Makefile 是否构建 test 目标,涉及工程所有目录。语法很简单,没有任何参数,ENABLE_TESTING(),一般情况这个指令放在工程的主CMakeLists.txt 中.
add_test指令的语法是:
add_test(testname Exename arg1 arg2 ...)
testname 是自定义的 test 名称,Exename 可以是构建的目标文件也可以是外部脚本等等。后面连接传递给可执行文件的参数。如果没有在同一个 CMakeLists.txt 中调用ENABLE_TESTING()
指令,任何 add_test都是无效的。
比如我们前面的Hello例子,可以在工程主 CMakeLists.txt 中添加
# 这里相当于定义一个指定的测试程序,以便make test调用.
add_test(mytest ${PROJECT_BINARY_DIR}/bin/Hello)
ENABLE_TESTING()
生成 Makefile 后,就可以运行 make test 来执行测试了。
内置变量
PROJECT_BINARY_DIR
,PROJECT_SOURCE_DIR
这两个变量分别指定了编译后二进制文件的路径和工程源文件的路径,其值是相同的,默认等于执行cmake命令时附带的路径。
CMAKE_INSTALL_PREFIX
指定安装目录前缀,默认是/usr/local。
内置变量可以通过执行cmake命令时指定-D选项来修改其默认值:
cmake -DCMAKE_INSTALL_PREFIX=/usr .
条件语句
可以通过if语句来判断变量是否为空,
find_file(CONFIG_FILE config ${PROJECT_SOURCE_DIR})
if(NOT CONFIG_FILE)
message(STATUS "config not found")
endif(NOT CONFIG_FILE)