cmake_minimum_required(VERSION 3.22.1)
message(${PROJECT_SOURCE_DIR})
message("some message")
message(WARNING "warnning message")
FATAL_ERROR 会导致编译失败,可配合条件判断使用
message(FATAL_ERROR "error message")
project(demo)
可选项,它会引入两个变量 demo_BINARY_DIR
和 demo_SOURCE_DIR
,
同时cmake自动定义两个变量 PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
。
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wall -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3 -Wall -fPIC")
set(CMAKE_BUILD_TYPE Release)
set(TARGET test)
set(CMAKE_INSTALL_PREFIX "../install")
同类型的命令有:
find_file()
find_path()
find_program()
find_package()
find_library()
用法:
find_library(VAR name path)查找到指定的预编译库,并将它的路径存储在变量中。
默认的搜索路径为 cmake 包含的系统库,因此如果是 NDK 的公共库只需要指定库的 name 即可。
find_library(log-lib log )
set(CMAKE_PREFIX_PATH "/home/libtorch_170/share/cmake/Torch")
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
set(OpenCV_DIR "/home/opencv450/install/lib/cmake/opencv4")
find_package(OpenCV 4 REQUIRED)
include_directories(
${PROJECT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
)
Linux 下还可以通过如下方式设置包含的目录
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${CMAKE_CURRENT_SOURCE_DIR}")
link_directories(
${CMAKE_CURRENT_SOURCE_DIR}/libs
)
Linux 下还可以通过如下方式设置包含的目录
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs")
add_library(demo demo.cpp test.cpp util.cpp)
aux_source_directory(dir VAR) 发现一个目录下所有的源代码文件并将列表存储在一个变量中。
aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件
add_library(demo ${SRC_LIST})
file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_library(demo ${SRC_LIST})
# 或者
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
# 或者
aux_source_directory(. SRC_LIST)
aux_source_directory(protocol SRC_PROTOCOL_LIST)
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
add_executable(demo demo.cpp) # 生成可执行文件
add_library(common STATIC util.cpp) # 生成静态库
add_library(common SHARED util.cpp) # 生成动态库或共享库
add_library 默认生成是静态库,通过以上命令生成文件名字,
在 Linux 下是:
demo
libcommon.a
libcommon.so
在 Windows 下是:
demo.exe
common.lib
common.dll
库的路径可以通过设置链接库搜索目录添加
target_link_libraries( ${TARGET} #这是生成的目标
# 然后下面是生成目标所需要链接的库,如:
${TORCH_LIBRARIES}
${OpenCV_LIBS}
dl
m
pthread
rt
)
include(./common.cmake) # 指定包含文件的全路径
include(def) # 在搜索路径中搜索def.cmake文件
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) # 设置include的搜索路径
此处的TARGET为生成的名字,以name为例
set(TARGET name)
生成类似这样的动态库libname_message.so
set(CMAKE_RELEASE_POSTFIX "_message") #这条命令需要放在add_library之前
add_library(${TARGET} SHARED ${SRC_LIST})
生成类似这样的可执行文件name_message
add_executable(${TARGET} ${SRC_LIST})
set_target_properties(${TARGET} PROPERTIES RELEASE_POSTFIX "_message")
生成类似这样的动态库libname.so.x.y.z
最前面使用前缀lib,中间为库的名字,后缀为.so,后面跟着 3 个数字组成的版本号。"x"表示**主版本号,"y"表示次版本号,"z"表示发布版本号。
VERSION:完整版本号 SOVERSION:SONAME
set_target_properties(${TARGET} PROPERTIES VERSION 1.0.0 SOVERSION 1)
如果不想用name,想换个名字;将“name”换成“hello”
set_target_properties (${TARGET} PROPERTIES OUTPUT_NAME "hello")
安装的方式有两种,一种是执行cmake的时候指定安装目录:
cmake -DCMAKE_INSTALL_PREFIX=../install ..
另一种是在CMakelist.txt 中设置安装的根路径:
set(CMAKE_INSTALL_PREFIX ../PATH)
INSTALL指令用于定义安装规则,安装的内容可以包括目标二进制、动态库、静态库以及
文件、目录、脚本等。
INSTALL(TARGETS targets...
[[ARCHIVE|LIBRARY|RUNTIME]
[DESTINATION <dir>]
[PERMISSIONS permissions...]
[CONFIGURATIONS
[Debug|Release|...]]
[COMPONENT <component>]
[OPTIONAL]
] [...]
)
参数中的TARGETS后面跟的就是我们通过ADD_EXECUTABLE或者ADD_LIBRARY定义的
目标文件,可能是可执行二进制、动态库、静态库。
目标类型也就相对应的有三种,ARCHIVE特指静态库,LIBRARY特指动态库,RUNTIME
特指可执行目标二进制。
DESTINATION定义了安装的路径,如果路径以/开头,那么指的是绝对路径,这时候
CMAKE_INSTALL_PREFIX其实就无效了。如果你希望使用CMAKE_INSTALL_PREFIX来
定义安装路径,就要写成相对路径,即不要以/开头,那么安装后的路径就是
${CMAKE_INSTALL_PREFIX}/
简单的例子:
#如果 demo 是可执行文件则会安装到${CMAKE_INSTALL_PREFIX}/bin目录
#如果是动态库则会安装到${CMAKE_INSTALL_PREFIX}/lib目录
#如果是静态库则会安装到${CMAKE_INSTALL_PREFIX}/libstatic目录
install(TARGETS ${TARGET}
RUNTIME DESTINATION bin #可执行文件安装路径(追加)
LIBRARY DESTINATION lib #动态库文件安装路径(追加)
ARCHIVE DESTINATION libstatic #静态库文件安装路径(追加)
)
INSTALL(FILES files... DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL])
可用于安装一般文件,并可以指定访问权限,文件名是此指令所在路径下的相对路径。
如果默认不定义权限PERMISSIONS,安装后的权限为,OWNER_WRITE,OWNER_READ,
GROUP_READ,和WORLD_READ,即644权限。
简单的例子:
install (FILES ${PROJECT_SOURCE_DIR}/include/mpt_study.h ${PROJECT_SOURCE_DIR}/include/mpt_public.h #安装文件
DESTINATION include #普通文件安装路径(追加)
PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ #权限
)
INSTALL(PROGRAMS files... DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL])
跟上面的FILES指令使用方法一样,唯一的不同是安装后权限为:
OWNER_EXECUTE, GROUP_EXECUTE, 和WORLD_EXECUTE,即755权限
简单的例子:
install (PROGRAMS ${PROJECT_SOURCE_DIR}/compile.sh #安装文件
DESTINATION SHPATH #普通文件安装路径(追加)
PERMISSIONS OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE #权限
)
INSTALL(DIRECTORY dirs... DESTINATION <dir>
[FILE_PERMISSIONS permissions...]
[DIRECTORY_PERMISSIONS permissions...]
[USE_SOURCE_PERMISSIONS]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[[PATTERN <pattern> | REGEX <regex>]
[EXCLUDE] [PERMISSIONS permissions...]] [...])
这里主要介绍其中的DIRECTORY、PATTERN以及PERMISSIONS参数。
DIRECTORY后面连接的是所在Source目录的相对路径,但务必注意:
abc和abc/有很大的区别。
abc意味着abc这个目录会安装在目标路径下;
abc/意味着abc这个目录的内容会被安装在目标路径下;
如果目录名不以/结尾,那么这个目录将被安装为目标路径下的abc,如果目录名以/结尾,
代表将这个目录中的内容安装到目标路径,但不包括这个目录本身。
PATTERN用于使用正则表达式进行过滤,
PERMISSIONS用于指定PATTERN过滤后的文件权限。
简单的例子:
#install 目录安装
INSTALL(DIRECTORY icons scripts/ #安装目录文件 icons整个文件夹 scripts文件夹下的文件(不包含文件夹)
DESTINATION cpdir #目录安装路径
PATTERN "CVS" EXCLUDE #过滤掉 CVS
PATTERN "scripts/*" #选中所有文件
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ #权限
)
这条指令的执行结果是:
将icons目录安装到 /share/myproj,将scripts/中的内容安装到
/share/myproj
不包含目录名为CVS的目录,对于scripts/*文件指定权限为 OWNER_EXECUTE
OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ.
逻辑判断和比较:
if (expression):expression 不为空(0,N,NO,OFF,FALSE,NOTFOUND)时为真
if (not exp):与上面相反
if (var1 AND var2)
if (var1 OR var2)
if (COMMAND cmd):如果 cmd 确实是命令并可调用为真
if (EXISTS dir) if (EXISTS file):如果目录或文件存在为真
if (file1 IS_NEWER_THAN file2):当 file1 比 file2 新,或 file1/file2 中有一个不存在时为真,文件名需使用全路径
if (IS_DIRECTORY dir):当 dir 是目录时为真
if (DEFINED var):如果变量被定义为真
if (var MATCHES regex):给定的变量或者字符串能够匹配正则表达式 regex 时为真,此处 var 可以用 var 名,也可以用 ${var}
if (string MATCHES regex)
数字比较:
if (variable LESS number):LESS 小于
if (string LESS number)
if (variable GREATER number):GREATER 大于
if (string GREATER number)
if (variable EQUAL number):EQUAL 等于
if (string EQUAL number)
字母表顺序比较:
if (variable STRLESS string)
if (string STRLESS string)
if (variable STRGREATER string)
if (string STRGREATER string)
if (variable STREQUAL string)
if (string STREQUAL string)
示例:
if(MSVC)
set(LINK_LIBS common)
else()
set(boost_thread boost_log.a boost_system.a)
endif()
target_link_libraries(demo ${LINK_LIBS})
# 或者
if(UNIX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fpermissive -g")
else()
add_definitions(-D_SCL_SECURE_NO_WARNINGS
D_CRT_SECURE_NO_WARNINGS
-D_WIN32_WINNT=0x601
-D_WINSOCK_DEPRECATED_NO_WARNINGS)
endif()
if(${CMAKE_BUILD_TYPE} MATCHES "debug")
...
else()
...
endif()
while(condition)
...
endwhile()
foreach(loop_var RANGE start stop [step])
...
endforeach(loop_var)
start 表示起始数,stop 表示终止数,step 表示步长,示例:
foreach(i RANGE 1 9 2)
message(${i})
endforeach(i)
# 输出:13579
PROJECT_SOURCE_DIR:工程的根目录
PROJECT_BINARY_DIR:运行 cmake 命令的目录,通常是 ${PROJECT_SOURCE_DIR}/build
PROJECT_NAME:返回通过 project 命令定义的项目名称
CMAKE_CURRENT_SOURCE_DIR:当前处理的 CMakeLists.txt 所在的路径
CMAKE_CURRENT_BINARY_DIR:target 编译目录
CMAKE_CURRENT_LIST_DIR: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:重新定义目标链接库文件的存放位置
使用环境变量
$ENV{Name}
写入环境变量
set(ENV{Name} value) # 这里没有“$”符号
CMAKE_MAJOR_VERSION:cmake 主版本号,比如 3.4.1 中的 3
CMAKE_MINOR_VERSION:cmake 次版本号,比如 3.4.1 中的 4
CMAKE_PATCH_VERSION:cmake 补丁等级,比如 3.4.1 中的 1
CMAKE_SYSTEM:系统名称,比如 Linux-2.6.22
CMAKE_SYSTEM_NAME:不包含版本的系统名,比如 Linux
CMAKE_SYSTEM_VERSION:系统版本,比如 2.6.22
CMAKE_SYSTEM_PROCESSOR:处理器名称,比如 i686
UNIX:在所有的类 UNIX 平台下该值为 TRUE,包括 OS X 和 cygwin
WIN32:在所有的 win32 平台下该值为 TRUE,包括 cygwin
BUILD_SHARED_LIBS:这个开关用来控制默认的库编译方式,如果不进行设置,使用 add_library 又没有指定库类型的情况下,默认编译生成的库都是静态库。如果 set(BUILD_SHARED_LIBS ON) 后,默认生成的为动态库
CMAKE_C_FLAGS:设置 C 编译选项,也可以通过指令 add_definitions() 添加
CMAKE_CXX_FLAGS:设置 C++ 编译选项,也可以通过指令 add_definitions() 添加
add_definitions(-DENABLE_DEBUG -DABC) # 参数之间用空格分隔
cmake -D CMAKE_C_COMPILER=/path/to/gcc/bin/gcc -D CMAKE_CXX_COMPILER=/path/to/gcc/bin/g++