cmake
有多个路径的话要给每个路径都创建CMakeLists。
创建工程名称的指令:
PROJECT(projectname [CXX] [C] [Java])
工程名之后的语言列表是可以省略的
两个预定义变量:
PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR
内部编译时这两个变量指向同一个路径
外部编译时不同
定义变量:
SET(VAR [VALUE])
VALUE可以有多个值,用空格隔开
MESSAGE指令可向终端输出信息:
MESSAGE([SEND_ERROR|STATUS|FATAL_ERROR] "message to display")
SEND_ERROR,会打印错误消息,并跳过生成过程
STATUS,打印带前缀-的消息
FATAL_ERROR,会立即终止
生成一个可执行文件:
ADD_EXECUTABLE(hello ${SRC_LIST})
取变量值使用${}
指令都应该大写,参数之间用空格隔开,如果参数中使用了空格,应该用双引号引起来
可以使用make clean清理构建结果
但是不能使用make distclean命令清理中间文件
外部编译就是在工程下创建一个文件夹
比如新建一个build文件夹,进入build文件夹,执行cmake ..就可以
这样就分离了源代码和构建的中间结果
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
向当前工程添加存放源代码的子目录,并且可以指定中间二进制和目标二进制文件存放位置,EXCLUDE_FROM_ALL会将该目录排除在编译过程外
ADD_SUBDIRECTORY(src bin)就会在构建目录下创建bin目录,相当与将src目录重命名为bin
在定义ADD_EXECUTABLE的文件中定义SET(EXECUTABLE_OUTPUT_PATH ${PRJECT_BINARY_DIR}/bin)可以指定生成的二进制文件位置
INSTALL指令来指定安装位置
执行cmake ..的时候可以指定-DCMAKE_INSTALL_PREFIX=/sth/sth/sth来设置路径前缀
INSTALL安装指令放在项目的CMakeLists.txt中
编译共享库和编译可执行文件是类似的,可以通过SET(LIBRARY_OUTPUT_PATH
ADD_LIBRARY(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ...)
libname不需要指定后缀
为了指定相同名称的静态库和动态库,可以使用指令SET_TARGET_PROPERTIES
SET_TARGET_PROPERTIES(target1 target2 ... PROPERTIES prop1 value1 prop2 value2 ...)
获取设置的属性名使用GET_TARGET_PROPERTY(VAR target property)指令
如果构建生成.a后.so被删除,则设置CLEAN_DIRECT_OUTPUT来解决:
SET_TARGET_PROPERTIES(hello PROPERTIES CLEAN_DIRECT_OUTPUT 1)
SET_TARGET_PROPERTIES(hello_static PROPERTIES CLEAN_DIRECT_OUTPUT 1)
设置版本号SET_TARGET_PROPERTIES(hello PROPERTIES VERSION 1.2 SOVERSION 1)
VERSION是动态链接库版本,SOVERSION是API版本
安装库时使用:
INSTALL(TARGETS hello hello_static
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib)
安装文件使用INSTALL(FILES hello.h DESTINATION include/hello)
使用外部库:
INCLUDE_DIRECTORIES([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)设置搜索的头文件路径
SET(CMAKE_INCLUDE_DIRECTORIES_BEFORE on)可以将添加的头文件搜索路径放在已有路径前面,AFTER类似
LINK_DIRECTORIES(dir1 dir2 ...)设置搜索共享库的路径,该命令必须放在ADD_EXECUTABLE前面
TARGET_LINK_LIBRARIES(target lib1 <debug | optimized> lib2 ...)为目标文件添加共享库
还可以使用通用的方法提供搜索路径,在bash的变量中定义CMAKE_INCLUDE_PATH=dir然后在cmake文件中使用FIND_PATH()指令指定搜索路径,同样的,CMAKE_LIBRARY_PATH=dir用来设置搜索库的路径,FIND_LIBRARY()用来搜索
引用变量时,在IF中引用不需要使用${}
CMAKE自带常量:
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一致,外部编译时指target目录,ADD_SUBDIRECTORY(src bin)就可以改变这个变量
CMAKE_CURRENT_LIST_FILE输出调用这个变量的CMakeLists.txt的完整路径
CMAKE_CURRENT_LIST_LINE该变量所在的行
CMAKE_MODULE_PATH定义cmake模块所在路径,使用SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)这样的方式设置值,然后可以用INCLUDE指令调用
EXECUTABLE_OUTPUT_PATH和LIBRARY_OUTPUT_PATH用来定义最终结果的存放目录
PROJECT_NAME为项目名称
$ENV{NAME}该指令用来调用系统环境变量
SET(ENV{变量名} 值)设置环境变量
CMAKE_INCLUDE_CURRENT_DIR自动添加CMAKE_CURRENT_BINARY_DIR和CMAKE_CURRENT_SOURCE_DIR到当前CMakeLists.txt中
CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE将工程设置的头文件目录在系统头文件目录前,冲突时会优先使用工程的
CMAKE_MAJOR_VERSION,CMAKE_MINOR_VERSION,CMAKE_PATCH_VERSION这三个代表了比如2.4.6中的2,4,6三个版本号
CMAKE_SYSTEM表示系统名称
CMAKE_SYSTEM_NAME表示不包含版本号的系统名
CMAKE_SYSTEM_VERSION系统版本号
CMAKE_SYSTEM_PROCESSOR处理器名称
UNIX类UNIX平台为TRUE
WIN32所有win32平台为TRUE
CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS控制IF ELSE的书写方式
BUILD_SHARED_LIBS是指为ON会默认编译动态库,否则为静态库
CMAKE_C_FLAGS设置C编译选项
CMAKE_CXX_FLAGS设置C++编译选项
基本指令
ADD_DEFINITIONS给编译器添加-D定义,多个参数用空格分开
如:ADD_DEFINITIONS(-DENABLE_DEBUG -DXXX)
ADD_DEPENDENCIES定义依赖的target
ADD_TEST和ENABLE_TESTING指令控制makefile是否构建test
ENABLE_TESTING()一般放在住CMakeLists.txt中
ADD_TEST使用方法:ADD_TEST(mytest ${PROJECT_BINARY_DIR}/bin/main)
在需要测试的目录的CMakeLists.txt中都要加ENABLE_TESTING()
AUX_SOURCE_DIRECTORY(dir VARIABLE)将dir目录下的源文件添加在VARIABLE变量中
CMAKE_MINIMUM_REQUIRED(VERSION versionNumber [FATAL_ERROR])设置cmake版本
EXEC_PROGRAM在cmake命令生成Makefile过程中执行命令,如ls查看某个路径的文件,可以用这个指令
FILE指令操作文件
INCLUDE指令用来载入CMakeLists.txt文件
FIND_FILE FIND_LIBRARY FIND_PATH FIND_PROGRAM FIND_PACKAGE用来查找路径
IF指令
IF(expression)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ELSE(expression)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDIF(expression)
出现IF的地方必须有ENDIF
WHILE指令
WHILE(condition)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDWHILE(condition)
`FOREACH`指令有三种形式
第一种
```cmake
FOREACH(loop_var arg1 arg2 ...)
COMMAND1(ARGS ...)
COMMAND2(ARGS ...)
...
ENDFOREACH(loop_var)
第二种
FOREACH(loop_var RANGE total)
ENDFOREACH(loop_var)
第三种
FOREACH(loop_var RANGE start stop [step])
ENDFOREACH(loop_var)