文章目录
- 常用命令
- 1. 指定 cmake 的最小版本
- 2. 打印信息
- 2.1. 打印普通信息
- 2.2. 打印告警
- 2.3. 打印错误
- 3. 项目名称
- 4. 设置变量
- 5. 查找指定的库文件
- 6. 设置包含的目录
- 7. 设置链接库搜索目录
- 8. 指定编译包含的源文件
- 8.1 明确指定包含哪些源文件
- 8.2 搜索所有的 cpp 文件
- 8.3 自定义搜索规则
- 9. 设置编译类型
- 10. 设置 target 需要链接的库
- 11. 包含其它 cmake 文件
- 12. 重命名
- 12.1. 添加后缀
- 12.2. 添加版本号
- 12.3. 重命名
- 13. install安装
- 13.1 目标文件的安装
- 13.2 普通文件的安装
- 13.3 非目标文件的可执行程序安装(比如脚本之类)
- 13.4 目录的安装
- 条件控制
- 1. if…elseif…else…endif
- 2. while…endwhile
- 3. foreach…endforeach
- 常用变量
- 1. 预定义变量
- 2. 环境变量
- 3. 系统信息
- 4. 主要开关选项
- cmake指定特定版本gcc、g++
常用命令
1. 指定 cmake 的最小版本
cmake_minimum_required(VERSION 3.22.1)
2. 打印信息
2.1. 打印普通信息
message(${PROJECT_SOURCE_DIR})
message("some message")
2.2. 打印告警
message(WARNING "warnning message")
2.3. 打印错误
FATAL_ERROR 会导致编译失败,可配合条件判断使用
message(FATAL_ERROR "error message")
3. 项目名称
project(demo)
可选项,它会引入两个变量 demo_BINARY_DIR
和 demo_SOURCE_DIR
,
同时cmake自动定义两个变量 PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
。
4. 设置变量
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")
5. 查找指定的库文件
同类型的命令有:
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)
6. 设置包含的目录
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}")
7. 设置链接库搜索目录
link_directories(
${CMAKE_CURRENT_SOURCE_DIR}/libs
)
Linux 下还可以通过如下方式设置包含的目录
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_SOURCE_DIR}/libs")
8. 指定编译包含的源文件
8.1 明确指定包含哪些源文件
add_library(demo demo.cpp test.cpp util.cpp)
8.2 搜索所有的 cpp 文件
aux_source_directory(dir VAR) 发现一个目录下所有的源代码文件并将列表存储在一个变量中。
aux_source_directory(. SRC_LIST)
add_library(demo ${SRC_LIST})
8.3 自定义搜索规则
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})
9. 设置编译类型
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
10. 设置 target 需要链接的库
库的路径可以通过设置链接库搜索目录添加
target_link_libraries( ${TARGET}
${TORCH_LIBRARIES}
${OpenCV_LIBS}
dl
m
pthread
rt
)
11. 包含其它 cmake 文件
include(./common.cmake)
include(def)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
12. 重命名
此处的TARGET为生成的名字,以name为例
set(TARGET name)
12.1. 添加后缀
生成类似这样的动态库libname_message.so
set(CMAKE_RELEASE_POSTFIX "_message")
add_library(${TARGET} SHARED ${SRC_LIST})
生成类似这样的可执行文件name_message
add_executable(${TARGET} ${SRC_LIST})
set_target_properties(${TARGET} PROPERTIES RELEASE_POSTFIX "_message")
12.2. 添加版本号
生成类似这样的动态库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)
12.3. 重命名
如果不想用name,想换个名字;将“name”换成“hello”
set_target_properties (${TARGET} PROPERTIES OUTPUT_NAME "hello")
13. install安装
安装的方式有两种,一种是执行cmake的时候指定安装目录:
cmake -DCMAKE_INSTALL_PREFIX=../install ..
另一种是在CMakelist.txt 中设置安装的根路径:
set(CMAKE_INSTALL_PREFIX ../PATH)
INSTALL指令用于定义安装规则,安装的内容可以包括目标二进制、动态库、静态库以及
文件、目录、脚本等。
13.1 目标文件的安装
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}/<DESTINATION定义的路径>
简单的例子:
install(TARGETS ${TARGET}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION libstatic
)
13.2 普通文件的安装
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
)
13.3 非目标文件的可执行程序安装(比如脚本之类)
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
)
13.4 目录的安装
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(DIRECTORY icons scripts/
DESTINATION cpdir
PATTERN "CVS" EXCLUDE
PATTERN "scripts/*"
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ
)
这条指令的执行结果是:
将icons目录安装到 <prefix>/share/myproj,将scripts/中的内容安装到
<prefix>/share/myproj
不包含目录名为CVS的目录,对于scripts/*文件指定权限为 OWNER_EXECUTE
OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ.
条件控制
1. if…elseif…else…endif
逻辑判断和比较:
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()
2. while…endwhile
while(condition)
...
endwhile()
3. foreach…endforeach
foreach(loop_var RANGE start stop [step])
...
endforeach(loop_var)
start 表示起始数,stop 表示终止数,step 表示步长,示例:
foreach(i RANGE 1 9 2)
message(${i})
endforeach(i)
常用变量
1. 预定义变量
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:重新定义目标链接库文件的存放位置
2. 环境变量
使用环境变量
$ENV{Name}
写入环境变量
set(ENV{Name} value)
3. 系统信息
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
4. 主要开关选项
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指定特定版本gcc、g++
cmake -D CMAKE_C_COMPILER=/path/to/gcc/bin/gcc -D CMAKE_CXX_COMPILER=/path/to/gcc/bin/g++
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)