- ./CMakeLists.txt
- 需要cmake版本大于等于3.13
- 隐含调用cmake_policy(VERSION 3.13)指定策略,指定版本低于2.4时策略使用2.4
- 判断是否作为子项目,获取父目录如果变量被定义则表示是子项目
- 添加编译子目录
- 第二个可选参数EXCLUDE_FROM_ALL,将目录从默认目标中排除,即需要明确指定才会编译
- 如果存在CMP0048策略,则使用CMP0048策略的新定义,对应有OLD
- cmake_policy(VERSION xxx)使用某版本的策略
- cmake_policy(GET CMP0048 var) 获取策略值 NEW、OLD、空
- cmake_policy(PUSH) cmake_policy(POP) 栈操作
- cmake版本比较
- 遍历指定目录中目标文件(.c .cpp .cxx等),并将列表合并到targsrcs
- 添加一个库目标,默认是static
- 第二个参数可选[SHARED|STATIC|MODULE]
- 第三个参数可选EXCLUDE_FROM_ALL 将目标从默认目标中排除,即需要手动指定目标才会编译
- 设置工程名、使用的语言
- 隐含路径都是顶层父路径
- 隐含定义输出目录 CMAKE_BINARY_DIR == 命令行-B指定的目录,或命令行当前目录
- 隐含定义输出目录 PROJECT_BINARY_DIR == ${CMAKE_BINARY_DIR}/src
- 隐含定义源码目录 CMAKE_SOURCE_DIR == 命令行-S(可以省略-S)指定的源码目录
- 隐含定义源码目录 PROJECT_SOURCE_DIR == CMAKE_SOURCE_DIR
- 根据模板生成文件,一般用于版本号设置
- set(HELLO_VERSION_MAJOR 1 PARENT_SCOPE) 将在父级的CMakeLists中定义或覆盖变量值
- 显示信息并继续 无、STATUS、WARNING、AUTHOR_WARNING、SEND_ERROR、
- 显示信息必须在引号前后有空格
- 显示信息并中断 FATAL_ERROR
- DEPRECATION 弃用警告
- CMAKE_WARN_DEPRECATED、CMAKE_ERROR_DEPRECATED 如果弃用则显示警告或错误
- 导入定义、方法、配置等
- CMAKE_CURRENT_LIST_DIR 当前文件目录
- GNUInstallDirs cmake预定义宏
- 导入gun 默认安装路径 CMAKE_INSTALL_xx(相对路径)和CMAKE_INSTALL_FULL_xx(绝对路径)
- BINDIR(bin) SBINDIR(sbin) LIBEXECDIR(libexec) SYSCONFDIR(etc) SHAREDSTATEDIR(com)
- LIBDIR(lib|lib64|lib/arch) INCLUDEDIR(include) OLDINCLUDEDIR(/usr/include)
- LOCALSTATEDIR(var) RUNSTATEDIR(LOCALSTATEDIR/run)
- DATAROOTDIR(share) DATADIR(DATAROOTDIR) INFODIR(DATAROOTDIR/info)
- LOCALEDIR(DATAROOTDIR/locale)
- MANDIR(DATAROOTDIR/man) DOCDIR(DATAROOTDIR/doc/PROJECT_NAME)
- 判断是否指定编译类型,如果没指定则指定位Release版本并强制刷新缓存
- cmake会缓存解析结果到编译目录的文件,除非重新赋值
- BUILD_SHARED_LIBS cmake变量,当编译目标为动态库时被自动定义
- CMAKE_COMPILER_IS_GNUCXX 编译器是GCXX
- 添加fPIC开关,编译位置无关的二进制
- 添加头文件路径
- 此处targsrcs为空列表,因为hellolib中第一次出现是子目录变量,不会出现在父目录
- 如果先进行父目录遍历,后添加hellolib会导致hellolib中变量不为空
- 添加一个可执行目标
- 第二个参数可选EXCLUDE_FROM_ALL,将目标从默认目标中排除,即需要手动指定目标才会编译
- 为目标添加依赖库
./CMakeLists.txt
- 编译脚本、一个目录一个
```
需要cmake版本大于等于3.13
隐含调用cmake_policy(VERSION 3.13)指定策略,指定版本低于2.4时策略使用2.4
cmake_minimum_required (VERSION 3.13)
判断是否作为子项目,获取父目录如果变量被定义则表示是子项目
get_directory_property(has_parent PARENT_DIRECTORY) if(NOT has_parent) set(HELLO_IN_PROJECT_BUILD false) endif()
添加编译子目录
第二个可选参数EXCLUDE_FROM_ALL,将目录从默认目标中排除,即需要明确指定才会编译
add_subdirectory(src)
## ./src/version.h.in
#ifndef VERSION_H #define VERSION_H
#define HELLO_V_MAJOR @HELLO_VERSION_MAJOR@ #define HELLO_V_MINOR @HELLO_VERSION_MINOR@
#endif//VERSION_H
## ./src/policy.cmake
如果存在CMP0048策略,则使用CMP0048策略的新定义,对应有OLD
cmake_policy(VERSION xxx)使用某版本的策略
cmake_policy(GET CMP0048 var) 获取策略值 NEW、OLD、空
cmake_policy(PUSH) cmake_policy(POP) 栈操作
if(POLICY CMP0048) cmake_policy(SET CMP0048 NEW) endif()
cmake版本比较
if (CMAKE_VERSION VERSION_LESS “3.9.0”) cmake_policy(SET CMP0023 OLD) else() cmake_policy(SET CMP0023 NEW) endif()
## ./src/helllib/CMakeLists.txt
遍历指定目录中目标文件(.c .cpp .cxx等),并将列表合并到targsrcs
aux_source_directory(. targsrcs)
添加一个库目标,默认是static
第二个参数可选[SHARED|STATIC|MODULE]
第三个参数可选EXCLUDE_FROM_ALL 将目标从默认目标中排除,即需要手动指定目标才会编译
add_library(hellolib ${targsrcs})
## ./src/CMakeLists.txt
设置工程名、使用的语言
隐含路径都是顶层父路径
隐含定义输出目录 CMAKE_BINARY_DIR == 命令行-B指定的目录,或命令行当前目录
隐含定义输出目录 PROJECT_BINARY_DIR == ${CMAKE_BINARY_DIR}/src
隐含定义源码目录 CMAKE_SOURCE_DIR == 命令行-S(可以省略-S)指定的源码目录
隐含定义源码目录 PROJECT_SOURCE_DIR == CMAKE_SOURCE_DIR
project(hello, C)
根据模板生成文件,一般用于版本号设置
set(HELLO_VERSION_MAJOR 1 PARENT_SCOPE) 将在父级的CMakeLists中定义或覆盖变量值
set(HELLO_VERSION_MAJOR 1) set(HELLO_VERSION_MINOR 0) configure_file(${CMAKE_SOURCE_DIR}/src/version.h.in ${CMAKE_SOURCE_DIR}/src/version.h)
显示信息并继续 无、STATUS、WARNING、AUTHOR_WARNING、SEND_ERROR、
显示信息必须在引号前后有空格
显示信息并中断 FATAL_ERROR
DEPRECATION 弃用警告
CMAKE_WARN_DEPRECATED、CMAKE_ERROR_DEPRECATED 如果弃用则显示警告或错误
message(STATUS “ Using CMake version: ${CMAKE_VERSION} “) message(STATUS “ Build Hello version: ${HELLO_VERSION_MAJOR}.${HELLO_VERSION_MINOR} “)
导入定义、方法、配置等
CMAKE_CURRENT_LIST_DIR 当前文件目录
include(${CMAKE_CURRENT_LIST_DIR}/policy.cmake)
GNUInstallDirs cmake预定义宏
导入gun 默认安装路径 CMAKE_INSTALL_xx(相对路径)和CMAKE_INSTALL_FULL_xx(绝对路径)
BINDIR(bin) SBINDIR(sbin) LIBEXECDIR(libexec) SYSCONFDIR(etc) SHAREDSTATEDIR(com)
LIBDIR(lib|lib64|lib/arch) INCLUDEDIR(include) OLDINCLUDEDIR(/usr/include)
LOCALSTATEDIR(var) RUNSTATEDIR(LOCALSTATEDIR/run)
DATAROOTDIR(share) DATADIR(DATAROOTDIR) INFODIR(DATAROOTDIR/info)
LOCALEDIR(DATAROOTDIR/locale)
MANDIR(DATAROOTDIR/man) DOCDIR(DATAROOTDIR/doc/PROJECT_NAME)
include(GNUInstallDirs)
判断是否指定编译类型,如果没指定则指定位Release版本并强制刷新缓存
cmake会缓存解析结果到编译目录的文件,除非重新赋值
if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE “Release” CACHE STRING “build type: Debug Release.” FORCE) endif()
BUILD_SHARED_LIBS cmake变量,当编译目标为动态库时被自动定义
CMAKE_COMPILER_IS_GNUCXX 编译器是GCXX
添加fPIC开关,编译位置无关的二进制
if (BUILD_SHARED_LIBS) if (CMAKE_COMPILER_IS_GNUCXX) add_definitions(“-fPIC”) endif() set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) endif()
添加头文件路径
include_directories(${CMAKE_CURRENT_LIST_DIR}/hellolib)
add_subdirectory(hellolib)
此处targsrcs为空列表,因为hellolib中第一次出现是子目录变量,不会出现在父目录
如果先进行父目录遍历,后添加hellolib会导致hellolib中变量不为空
aux_source_directory(. targsrcs) aux_source_directory(./sub01 targsrcs) aux_source_directory(./sub02 targsrcs)
添加一个可执行目标
第二个参数可选EXCLUDE_FROM_ALL,将目标从默认目标中排除,即需要手动指定目标才会编译
add_executable(hello ${targsrcs})
为目标添加依赖库
target_link_libraries(hello hellolib)
## cmake
- CMakeLists.txt 类似makefile是默认的文件
- 常用变量
PROJECT_NAME project指令设置的名字
CMAKE_BUILD_TYPE Debug、Release、RelWithDebInfo、MinSizeRel
CMAKE_C_FLAGS_DEBUG debug时使用的c编译选项
CMAKE_CXX_FLAGS_DEBUG debug时使用的c++编译选项
CMAKE_C_FLAGS_RELEASE release时使用的c编译选项
CMAKE_CXX_FLAGS_RELEASE release时使用的c++编译选项
CMAKE_CURRENT_SOURCE_DIR当前处理的CMakeLists.txt所在路径
CMAKE_C_COMPILER 指定c编译器
CMAKE_CXX_COMPILER 指定c++编译器
CMAKE_C_FLAGS 指定c的编译选择 类似add_definitions指令
CMAKE_CXX_FLAGS 指定c++的编译选择 类似add_definitions指令
BUILD_SHARED_LIBS 设置编译动态库,默认静态库
CMAKE_CURRRENT_BINARY_DIR
in-source 编译是当前处理CMakeLists.txt所在路径
out-of-source 编译指target目录
CMAKE_CURRENT_LIST_FILE 当前处理的CMakeLists.txt的完整路径
CMAKE_CURRENT_LIST_LINE 当前所在的CMakeLists.txt的行数
CMAKE_MODULE_PATH 通过set设置自定义cmake模块的路径,然后用include指令调用模块
EXECUTABLE_OUTPUT_PATH 定义可以执行文件的输出目录
LIBRARY_OUTPUT_PATH 定义库文件输出目录
CMAKE_INCLUDE_CURRENT_DIR 包含CMAKE_CURRENT_BINARY_DIR CMAKE_CURRENT_SOURCE_DIR目录
CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE 先搜索用户头文件目录
CMAKE_INCLUDE_PATH
CMAKE_LIBRARY_PATH
CMAKE_MAJOR_VERSION cmake主版本号
CMAKE_MINOR_VERSION cmake次版本号
CMAKE_PATCH_VERSION cmake补丁版本号
CMAKE_SYSTEM 系统的名称包含版本
CMAKE_SYSTEM_NAME 系统名称不含版本
CMAKE_SYSTEM_VERSION 系统版本
CMAKE_SYSTEM_PROCESSOR 处理器名称如x86 i686
CMAKE_EXPORT_COMPILE_COMMANDS 生成编译数据库,主要用于静态分析,如scan-build
UNIX 是否通过UNIX通用可移植接口认证(POSIX)
WIN32 是否为widow平台
CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS 设置ON后IF语法中ELSE和ENDIF括号为空
CMAKE_GENERATOR -G参数例如生成Xcode项目:输入-GXcode变量为Xcode
XCODE_VERSION xcoce的版本
CMAKE_POSITION_INDEPENDENT_CODE True False默认True为动态库添加-fPIC(内存位置无关的代码)
- 指令
cmake_minimum_required(VERSION 2.6 [FATAL_ERROR]) 设置最低版本,FATAL_ERROR设置时将直接失败
project(name, C) 设置工程名、语言
会隐式的定义PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR两个变量
CMAKE_BINARY_DIR == name_BINARY_DIR == 命令行中-B后的输出路径
PROJECT_BINARY_DIR
CMAKE_SOURCE_DIR == name_SOURCE_DIR == 命令行中-S后或者没有任何参数的源码路径
PROJECT_SOURCE_DIR
message(FATAL_ERROR "") 显示信息 //STATUS WARNING
set(xxx yyy) 创建变量xxx,值为yyy,第三参数CACHE type(FILEPATH PATH STRING BOOL) doc(描述)
$ENV{name} 获取环境变量
set(ENV{name} xxx) 设置环境变量
get_directory_property 获取目录属性,一般判断当前cmake是不是子模块get_directory_property(xx PARENT_DIRECTORY)
option(name "" ON) 默认为ON,可以在命令行-Dname=xxx, name将赋值xxx
add_definitions 添加宏add_definitions(-DDebug),新版本用add_compile_definitions代替
add_compile_options 添加其它编译选项
add_dependencies 设置target依赖的其他target
add_executable(name xx.c ..) 编译可执行文件
add_library(name [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] xx.c ..) name工程名 编译|静态|动态|dlopen|的库
set_target_properties(name1 name2 PROPERTIES PRO1 value1 PRO2 value2) 设置工程
add_subdirectory(dir [bin_dir] [EXCLUDE_FROM_ALL]) 向当前工程添加源码目录 指定中间二进制、目标二进制的位置
enable_testing() 指定生成测试目标
add_test(testname exename arg ..)
aux_source_directory(dir name) 将目录下所有源码文件列表存储在name变量中
exec_program(...) 在cmake执行过程中执行系统命令,不进入生成的工程或make文件中
include(file [optional]) 加载CMakeLists.txt或者模块
if(x)缩进elseif(x)缩进else(x)缩进endif(x)
if(${v}) 不是空、0、N、NO、OFF、FALSE、NOTFOUND、v_NOFOUND时为真
if(NOT ${v})
if(${v1} AND ${v2})
if(${v1} OR ${v2})
if(COMMAND cmd) cmd可以调用为真
if(EXISTS dir)
if(EXISTS f)
if(f1 IS_NEWER_THAN f2)
if(IS_DIRECTORY name)
if(${v} MATCHES regex)
if(string MATCHES regex)
if(${v} LESS number)
if(string LESS number)
if(${v} GREATER number)
if(string GREATER number)
if(${v} EQUAL number)
if(string EQUAL number)
if(${v} STRLESS string)
if(string STRLESS string)
if(${v} STRGREATER string)
if(string STRGREATER string)
if(${v} STREQUAL string)
if(string STREQUAL string)
if(<variable|string> VERSION_LESS <variable|string>)//major[.minor[.patch[.tweak]]]
if(<variable|string> VERSION_EQUAL <variable|string>)
if(<variable|string> VERSION_GREATER <variable|string>)
if(DEFINED v) 变量被定义为真
if(NOT DEFINED v) 变量被定义为假
while(x) 缩进 endwhile(x)
foreach(var x1 x2 ...) endforeach(var)
foreach(var RANGE x) endforeach(var)
foreach(var RANGE start stop [step]) endforeach(var)
file(WRITE fname "xxx" ..) 创建或覆盖已有文件, 写入多行文本
file(APPEND fname "xxx" ..) 附加到文件末尾,多行文本
file(READ fname vname [LIMIT x] [OFFSET x] [HEX]) 将指定偏移大小的内容存储在变量中
file(STRINGS fename vname [LIMIT_COUNT x] [LIMIT_INPUT x] [LIMIT_OUTPUT x] [LENGTH_MINIMUM x] [LENGTH_MAXIMUM x] [NEWLINE_CONSUME] [REGEX regex] [NO_HEX_CONVERSION]) 读ASCII字符串、文件中的二进制数据会忽略、回车换行会忽略,返回限制行数、限制字符串长度的list给变量
file(GLOB vname [RELATIVE path] [globbing expressions]..) 通过表达式生成文件列表到变量
file(GLOB_RECURSE vname [RELATIVE path] [FOLLOW_SYMLINKS] [globbing expressions]...) 类似GLOB但保护子目录
file(MAKE_DIRECTORY [dir...]) 创建目录,父目录不存在也会创建
file(RENAME <oldname> <newname>)
file(REMOVE [file1 ...]) 删除指定目录或文件,包括子路径
file(REMOVE_RECURSE [file1 ...]) 删除指定文件或目录,包括非空目录
file(RELATIVE_PATH vname dir file) 将从dir到文件的相对路径保存在变量中
file(TO_CMAKE_PATH path result) 将path转换为以/开头的
file(TO_NATIVE_PATH path result) 将path转换为系统格式
file(DOWNLOAD url file [TIMEOUT x] [STATUS vstatus] [LOG vlog] [EXPECTED_MD5 sum] [SHOW_PROGRESS])
file(COPY|INSTALL files... DESTINATION <dir> [FILE_PERMISSIONS permissions...] [DIRECTORY_PERMISSIONS permissions...] [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS] [FILES_MATCHING] [[PATTERN <pattern> | REGEX <regex>] [EXCLUDE] [PERMISSIONS permissions...]] [...])
find_file(vname, name, path1 ..) 在指定目录中查找name头文件路径并保存到vname
find_path(vname, name, path1 ..) 不含文件名
find_library(vname, name, path1 ..) 查找库路径
find_program(vname, name, path1 ..) 查找可执行程序
find_package(vname, [major.minor] [QUIET] [NO_MODULE] [ [ REQUIRED | COMPONENTS ] [ componets... ] ] ) 通过自定义模块路径查找Find${vname}.cmake并执行
macro(函数名) ... endmacro() 定义函数
get_cmake_property(xxx 属性名) 获取cmake全局属性,未找到xxx为NOTFOUND, VARIABLES当前目录中定义的所有变量
- 策略 POLICY cmake不同版本间函数或命令会有不同的行为,当行为在不同版本间不同时会给出一个策略号,通过设置策略号来使用新或旧的行为
POLICY号类似CMP0056 即CMP加数字
if(POLICY CMP0056) 即判断当前策略是否等于CMP0056
当调用cmake_minimum_required时(并且版本大于2.4)会隐含调用cmake_policy(VERSION, mimversion)将默认策略设置为指定版本
cmake_policy(VERSION, major[.minor[.patch[.tweak]]]) 显式将策略设置为指定版本(含有很多策略)
cmake_policy(SET CMP0056 NEW) 指定某策略使用新版本
cmake_policy(SET CMP0056 OLD) 指定某策略使用旧版本
cmake_policy(PUSH) cmake_policy(POP) 临时改变策略
- 自定义模块
RFID NDEF
### CMake 基本使用实例
最简单的CMakeLists.txt文件只需要两行,我们就从这个文件开始。CMakeLists 文件是这样的(tutorial.cxx源码)
cmake_minimum_required (VERSION 2.6) project(Tutorial) add_executable(Tutorial tutorial.cxx)
对于大写,小写,大小写混合的命令书写方法,CMake都支持。假如CMakeList.txt和tutorial.cxx文件都存放在~/cmake_tutorial目录
mkdir ~/cmake_tutorial/build cd ~/cmake_tutorial/build cmake -G “Unix Makefiles” .. 或 cmake .. make 或 cmake –build . –config Release ./Tutorial
### 添加版本号和配置头文件
我们给工程添加的第一个功能就是版本号。CMakeLists 文件如下:
cmake_minimum_required (VERSION 2.6) project(Tutorial)
set (Tutorial_VERSION_MAJOR 1) set (Tutorial_VERSION_MINOR 0)
configure_file ( “${PROJECT_SOURCE_DIR}/TutorialConfig.h.in” “${PROJECT_BINARY_DIR}/TutorialConfig.h” )
include_directories(“${PROJECT_BINARY_DIR}”) 添加头文件路径
add_executable(Tutorial tutorial.cxx)
在源代码目录中,我们新建TutorialConfig.h.in文件,内容如下:
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@ #define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
CMake 会使用 CMakeLists 文件中的Tutorial_VERSION_MAJOR 和 Tutorial_VERSION_MINOR 值替换配置文件的@Tutorial_VERSION_MAJOR@ 和 @Tutorial_VERSION_MINOR@。
### 添加一个库
我们把库源文件放到MathFunctions,这个单独的目录中。只需要一行的CMakeLists就足够了:
add_library(MathFunctions mysqrt.cxx)
为了使用新库,我们在顶层的CMakeLists文件中调用add_subdirectory,这样库才会被编译。我们还需要把MathFunctions目录添加到包含目录中,这样才能找到MathFunctions/mysqrt.h文件。最后,还需要把新库添加到可执行文件中。
include_directories (“${PROJECT_SOURCE_DIR}/MathFunctions”) add_subdirectory (MathFunctions)
add_executable (Tutorial tutorial.cxx) target_link_libraries (Tutorial MathFunctions)
### 添加一个选项,默认为ON
option (USE_MYMATH “Use tutorial provided math implementation” ON) if (USE_MYMATH) include_directories (“${PROJECT_SOURCE_DIR}/MathFunctions”) add_subdirectory (MathFunctions) set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions) endif (USE_MYMATH)
add_executable (Tutorial tutorial.cxx) target_link_libraries (Tutorial ${EXTRA_LIBS})
相应的TutorialConfig.h.in修改
#cmakedefine USE_MYMATH
在源码中
#ifdef USE_MYMATH #include “MathFunctions.h” #endif
### 添加安装
对于MathFunctions库,我们需要安装库文件和头文件,在MathFunctions/CMakeLists中间添加下面两行:
install (TARGETS MathFunctions DESTINATION bin) install (FILES MathFunctions.h DESTINATION include)
对于程序文件,我们在顶层CMakeLists文件中添加下面几行来安装可以执行文件和配置文件:
install (TARGETS Tutorial DESTINATION bin) install (FILES “${PROJECT_BINARY_DIR}/TutorialConfig.h” DESTINATION include)
CMake变量CMAKE_INSTALL_PREFIX用来确定文件安装的根目录。 命令行-DCMAKE_INSTALL_PREFIX=xxx
### 添加测试
在顶层CMakeLists文件的最后
add_test (TutorialRuns Tutorial 25) #是否正常运行,返回码为0
add_test (TutorialComp25 Tutorial 25) #检测是否答案正确 set_tests_properties (TutorialComp25 PROPERTIES PASS_REGULAR_EXPRESSION “25 is 5”)
add_test (TutorialNegative Tutorial -25) #检测负数是否计算正确 set_tests_properties (TutorialNegative PROPERTIES PASS_REGULAR_EXPRESSION “-25 is 0”)
add_test (TutorialSmall Tutorial 0.0001) #检测很小的数计算是否正确 set_tests_properties (TutorialSmall PROPERTIES PASS_REGULAR_EXPRESSION “0.0001 is 0.01”)
add_test (TutorialUsage Tutorial) #检测参数错误 set_tests_properties (TutorialUsage PROPERTIES PASS_REGULAR_EXPRESSION “Usage:.*number”)
macro (do_test arg result) #添加一个测试函数 add_test (TutorialComp${arg} Tutorial ${arg}) set_tests_properties (TutorialComp${arg} PROPERTIES PASS_REGULAR_EXPRESSION ${result}) endmacro (do_test)
do_test (25 “25 is 5”) #测试25的结果是不是5 do_test (-25 “-25 is 0”) #测试-25的结构是不是0
### 添加系统环境发现
根据目标平台是否支持某些特性,首先在最上层的CMakeLists.txt里面,使用CheckFunctionExists.cmake宏来检测函数。
include (CheckFunctionExists) check_function_exists (log HAVE_LOG) 检测系统中是否有log函数,只检测二进制库,不会检测头文件 check_function_exists (exp HAVE_EXP)
include(CheckIncludeFile) check_include_file(unistd.h HAVE_UNISTD_HEARD_FILE) 检测是否有头文件 可以是列表
include(CheckCSourceCompiles)
include(CheckTypeSize) check_type_size(int, INT_SIZE) 检测int的内存大小
在TutorialConfig.h.in定义以下变量
#cmakedefine HAVE_LOG #cmakedefine HAVE_EXP
一定要在log和exp检测完成后,才能使用configure_file命令。configure_file命令使用当前的设置生成配置文件。
### 添加一个文件生成器
在build过程中添加一个生成的源文件,如生成一个三角函数速查表,在MathFunctions的子目录,新建文件MakeTable.cxx来生成表格。
#include
生成的文件应该是有效的C代码段,在MathFunctions的CMakeLists.txt文件中添加生成MakeTable命令,并且执行它。
add_executable(MakeTable MakeTable.cxx) #生成速查表的可执行文件 add_custom_command ( #添加自定义命令 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h DEPENDS MakeTable ) include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) add_library(MathFunctions mysqrt.cxx ${CMAKE_CURRENT_BINARY_DIR}/Table.h )
### 构建安装包
在最上层的CMakeLists.txt的尾部添
include (InstallRequiredSystemLibraries) set (CPACK_RESOURCE_FILE_LICENSE “${CMAKE_CURRENT_SOURCE_DIR}/License.txt”) #设置pack变量 set (CPACK_PACKAGE_VERSION_MAJOR “${Tutorial_VERSION_MAJOR}”) set (CPACK_PACKAGE_VERSION_MINOR “${Tutorial_VERSION_MINOR}”) include (CPack)
正常的构建工程,会生成两个packconfig
cpack –config CPackConfig.cmake #二进制分发包 cpack –config CPackSourceConfig.cmake #源码分发包
### 添加测试报告到Kitware
在最上层的CMakeLists.txt中包含CTest模块。
include (CTest)
新建CTestConfig.cmake,在文件中定义本项目在仪表盘中的名称。
set (CTEST_PROJECT_NAME “Tutorial”)
CTest在执行时会读取这个文件
## cmake xcode build
cmake_minimum_required(VERSION 2.8.2)
project(Tutorial)
include_directories(thirdparty/ include/) set(SRC_FILES main.cc *.m) add_executable(Tutorial ${SRC_FILES})
set(CMAKE_OSX_SYSROOT iphoneos)# SDK的位置,iphoneos表示iphone当前版本的sdk target_link_libraries(Tutorial thirdparty/src/*.so)#三方库 set(CMAKE_EXE_LINKER_FLAGS “-framework Foundation -framework UIKit”)#系统库
set_property(TARGET Tutorial PROPERTY MACOSX_BUNDLE TRUE) set_property(TARGET Tutorial PROPERTY MACOSX_BUNDLE_ICON_FILE my_project_OSX.icns) set_property(TARGET Tutorial PROPERTY MACOSX_BUNDLE_INFO_PLIST Info.plist)
install(TARGETS Tutorial DESTINATION Tutorial.app)
if(CMAKE_VERSION VERSION_LESS 3.0.0) include(CMakeForceCompiler) CMAKE_FORCE_C_COMPILER(clang GNU) CMAKE_FORCE_CXX_COMPILER(clang++ GNU) endif(CMAKE_VERSION VERSION_LESS 3.0.0)
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD “c++11”) set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY “libc++”) set(CMAKE_OSX_ARCHITECTURES “$(ARCHS_STANDARD)”)
set_target_properties(Tutorial PROPERTIES XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH “NO”) set_target_properties(Tutorial PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY “iPhone Developer”) set(MACOSX_BUNDLE_GUI_IDENTIFIER “com.example.company.${PRODUCT_NAME:rfc1034identifier}”)
foreach(SRC_FILE ${SRC_FILES}) set_source_files_properties(${SRC_FILE} PROPERTIES COMPILE_FLAGS “-x objective-c++”) endforeach(SRC_FILE ${SRC_FILES})
## cmake build ios framework
- shell script
```make
cmake -GXcode -DCMAKE_INSTALL_PREFIX=xx -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS=-fembed-bitcode -DCMAKE_CXX_FLAGS=-fembed-bitcode//真机可添加bitcode
xcrun xcodebuild IPHONEOS_DEPLOYMENT_TARGET=8.0 ARCHS=[arm64,arm64e,armv7,armv7s,i386,x86_64] -sdk [iphoneos iphonesimulator] -configuration Release -jobs 4 -target ALL_BUILD build
mkdir -p x.framework/Versions/A/Headers
mkdir -p x.framework/Versions/A/Resources
cp -R arm64/include/dlib/* x.framework/Versions/A/Headers/
cp Info.plist x.framework/Versions/A/Resources/
lipo -create arm64/lib/xx.a xx/lib/xx.a . -o ./Versions/A/x
pushd x.framework/Versions
ln -sfh ../Versions/A Current
popd
pushd x.framework
ln -sfh ../x.framework/Versions/Current/Headers Headers
ln -sfh ../x.framework/Versions/Current/Resources Resources
ln -sfh ../x.framework/Versions/Current/x x
popd
- cmake ``` set_target_properties(dlib PROPERTIES FRAMEWORK TRUE FRAMEWORK_VERSION A MACOSX_FRAMEWORK_IDENTIFIER com.nomadli.dlib MACOSX_FRAMEWORK_INFO_PLIST Info.plist VERSION 16.4.0 # 版本号 SOVERSION 1.0.0 # API 版本 PUBLIC_HEADER dlib.h XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY “iPhone Developer” ) install(TARGETS dlib FRAMEWORK DESTINATION frameworks/ install(TARGETS dassce BUNDLE DESTINATION bundles/ PERMISSIONS
ARCHIVE | LIBRARY | RUNTIME | OBJECTS | FRAMEWORK | BUNDLE | PRIVATE_HEADER | PUBLIC_HEADER | RESOURCE |
OWNER_READ,OWNER_WRITE,OWNER_EXECUTE,GROUP_READ, GROUP_WRITE,GROUP_EXECUTE,WORLD_READ,WORLD_WRITE, WORLD_EXECUTE,SETUID,和SETGID ```
find_library
- find_package() 指定 MODULE 使用Find
.cmake查找,找不到则失败 - 查找CMAKE_PREFIX_PATH CMAKE_FRAMEWORK_PATH CMAKE_APPBUNDLE_PATH 设定NO_CMAKE_PATH取消
- 查找
_DIR或 _ROOT CMAKE_PREFIX_PATH CMAKE_FRAMEWORK_PATH CMAKE_APPBUNDLE_PATH 设置NO_CMAKE_ENVIRONMENT_PATH 取消 - HINT 指定的路径
- 系统环境变量PATH,/bin或/sbin结尾的,会自动转化为其父目录。设定NO_SYSTEM_ENVIRONMENT_PATH取消
- cmake的TARGET 设置NO_CMAKE_PACKAGE_REGISTRY或set(CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY ON)取消
- CMAKE_SYSTEM_PREFIX_PATH CMAKE_SYSTEM_FRAMEWORK_PATH CMAKE_SYSTEM_APPBUNDLE_PATH设置NO_CMAKE_SYSTEM_PATH取消
- cmake 系统config目录配置 设置NO_CMAKE_SYSTEM_PACKAGE_REGISTRY或set(CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY ON)取消
- PATHS 字段查找