CMake 编译时常用环境变量(vcpkg) ----总结
CMake 编译时常用 项目变量、系统变量、编译变量----总结
参考文献:
CMake文件CMakeLists.txt,语法精讲 - suntroop - 博客园 (cnblogs.com)
一、cmake 变量定义与引用
1.1 用户自定义变量的方式
主要有隐式定义和显式定义两种, 前面举了一个隐式定义的例子,就是 PROJECT 指令,他会隐式的定义“<projectname>_BINARY_DIR ”和“<projectname>_SOURCE_DIR ”两个变量。
使用 SET 指令, 就可以构建一个自定义变量了。比如:
SET ( MAIN_SRC main.SOURCE_PATH) #main.SOURCE_PATH代表main.cpp的路径
这样就可以通过 ${ MAIN_SRC } 来引用这个自定义变量了.
1.2 cmake 变量引用的方式
前面我们已经提到了,使用 ${ } 进行变量的引用。在 IF 等语句中,是直接使用变量名而不通过${ }取值.
注: 通过如下命令查看变量值。e.g. message (STATUS "=== CMAKE_PREFIX_PATH is: ${CMAKE_PREFIX_PATH}")
二、常用项目工程变量:
2.1. PROJECT_NAME
返回通过 project( ) 指令定义的项目名称。
2.2 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR
1. cmake执行目录与CMakeLists位于同一目录
cmake .
这样`PROJECT_BINARY_DIR`和`PROJECT_SOURCE_DIR`是等价的。也就是当前cmake执行目录。
2. cmake执行的目录build与根CMakeLists的目录src, 二者同级
如果执行cmake的时候,并不在源码的路径的话,比如
cd build/
cmake ../src
这样的好处是cmake生成的文件和编译出来的东西,就不放在源码路径下了,保证了源码路径的干净整洁。
比如可以在src的同级目录下建立build目录。
然后在build目录下执行`cmake ../src`。
这样编译出来的东西和cmake生成的东西,都放到了build目录下了。并且
PROJECT_BINARY_DIR = 全路径/build PROJECT_SOURCE_DIR = 全路径/src
三、控制构建的工具链变量
cmake_minimum_required(VERSION 3.28) # cmake 最低版本要求 # # 在 project() 命令前设置,如下宏定义: https://cmake.org/cmake/help/latest/manual/cmake-variables.7.html # -DCMAKE_TOOLCHAIN_FILE=C:\Users\Administrator\.vcpkg-clion\vcpkg(1)\scripts\buildsystems\vcpkg.cmake # -DVCPKG_TARGET_TRIPLET=x64-mingw-dynamic //x64-windows # #set(VCPKG_INSTALLED_DIR "E:/workForClion/DocWire/cmake-build-debug/vcpkg_installed") # 设置安装和使用库位置 清单模式下,默认为${CMAKE_BINARY_DIR}/vcpkg_installe, #在经典模式下,默认为${VCPKG_ROOT}/installed。 set(VCPKG_TARGET_TRIPLET "x64-mingw-dynamic" CACHE STRING "" FORCE) # 目标平台的三元组 set(CMAKE_TOOLCHAIN_FILE "C:/Users/Administrator/.vcpkg-clion/vcpkgGW/scripts/buildsystems/vcpkg.cmake") # 交叉编译的工具链(编译器、链接器等)配置文件 include("C:/Users/Administrator/.vcpkg-clion/vcpkgGWscripts/buildsystems/vcpkg.cmake") #list(APPEND CMAKE_PREFIX_PATH "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}") # 查找vcpkg 已安装库位置 ${CMAKE_PREFIX_PATH}\lib\cmake\Xxx\XxxConfig.cmake #list(APPEND CMAKE_MODULE_PATH "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}") # 查找CMake模块(如FindXXX.cmake)的额外路径 if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET) set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "" FORCE) endif() #MESSAGE(STATUS "=== VCPKG_INSTALLED_DIR = ${VCPKG_TARGET_TRIPLET}") MESSAGE(STATUS "=== VCPKG_TARGET_TRIPLET = ${VCPKG_TARGET_TRIPLET}") MESSAGE(STATUS "=== CMAKE_TOOLCHAIN_FILE = ${CMAKE_TOOLCHAIN_FILE}") message(STATUS "=== CMAKE_PREFIX_PATH is: ${CMAKE_PREFIX_PATH}") message(STATUS "=== CMAKE_MODULE_PATH is: ${CMAKE_MODULE_PATH}") #MESSAGE(STATUS "*** CMAKE_ROOT = ${CMAKE_ROOT}") # “D:/Program Files/JetBrains/CLion 2024.1.4/bin/cmake/win/x64/share/cmake-3.28” #MESSAGE(STATUS "*** CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}") # “C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe” #MESSAGE(STATUS "*** CMAKE_C_COMPILER = ${CMAKE_C_COMPILER}") # “C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe” add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/source-charset:utf-8>") project(HD_Compare) # ${PROJECT_NAME}
3.1 VCPKG_TARGET_TRIPLET: 目标平台的三元组
set(VCPKG_TARGET_TRIPLET "x64-mingw-dynamic" CACHE STRING "" FORCE) # 目标平台的三元组
3.2 工具链(编译器、链接器等)配置文件 CMAKE_TOOLCHAIN_FILE
set(CMAKE_TOOLCHAIN_FILE "C:/Users/Administrator/.vcpkg-clion/vcpkgGW/scripts/buildsystems/vcpkg.cmake") # 交叉编译的工具链(编译器、链接器等)配置文件 include("C:/Users/Administrator/.vcpkg-clion/vcpkgGWscripts/buildsystems/vcpkg.cmake")
3.3 CMAKE_PREFIX_PATH: vcpkg库或MinGW库路径前缀
查找 vcpkg 已安装库 <package> 位置: 与${CMAKE_PREFIX_PATH}无关, 由 ${CMAKE_TOOLCHAIN_FILE} 文件生成
C:\Users\suntr\.vcpkg-clion\vcpkg\packages\boost-safe-numerics_x64-mingw-dynamic\share\boost_safe_numerics\boost_safe_numerics-config.cmake
查找 MinGW 已安装库 <package> 位置: ${CMAKE_PREFIX_PATH}\lib\cmake\<package>\<package>Config.cmake
D:\msys64\mingw64\lib\cmake\boost_safe_numerics-1.87.0\boost_safe_numerics-config.cmake
这时候你就可以通过 find_package 指令来解析 <package>Config.cmake 配置文件,调用自己的包了。
以分号分隔的目录列表,指定find_package(), find_program(),find_library(),find_file()和 find_path()命令要搜索的安装前缀。
每个命令将根据其自身文档要求,添加适当的子目录(如bin、lib 或 include)。
此变量可能包含单个前缀或多个前缀,以分隔的前缀列表,UNIX :或Windows ;(与这些平台上的环境变量约定相同PATH)。
默认情况下,此值为空。它旨在由项目project设置。
list(APPEND CMAKE_PREFIX_PATH "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}") # 附加:查找vcpkg 已安装库位置 ${CMAKE_PREFIX_PATH}\lib\cmake\Xxx\XxxConfig.cmake
3.4 CMAKE_MODULE_PATH: CMake模块的额外路径
查找CMake模块(如FindXXX.cmake)的额外路径
以分号分隔的目录列表,使用正斜杠表示,指定要由 CMake 加载的模块的命令:include() 或者 find_package() 搜索路径,然后再检查 CMake 自带的默认模块。
默认情况下,它是空的。它旨在由项目project设置。
一个项目有一个包含各种 *.cmake文件的目录来协助开发是很常见的。将目录添加到 CMAKE_MODULE_PATH简化加载过程。
例如,项目的顶层CMakeLists.txt文件可能包含:
list(APPEND CMAKE_MODULE_PATH "${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}") # 附加:查找CMake模块(如FindXXX.cmake)的额外路径 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(Foo) # 解析加载 ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Foo.cmake find_package(Bar) # 解析加载 ${CMAKE_CURRENT_SOURCE_DIR}/cmake/FindBar.cmake
3.5. CMAKE_BINARY_DIR
PROJECT_BINARY_DIR
<projectname>_BINARY_DIR
这三个变量指代的内容是一致的,如果是内部编译,指得就是工程顶层目录;如果是外部编译,指的是工程编译发生的目录。
PROJECT_BINARY_DIR 跟其他指令稍有区别,现在,你可以理解为他们是一致的。
3.6 CMAKE_SOURCE_DIR
PROJECT_SOURCE_DIR
<projectname>_SOURCE_DIR
这三个变量指代的内容是一致的,不论采用何种编译方式,都是工程顶层目录。也就是在内部编译时,他跟 CMAKE_BINARY_DIR 等变量一致。
PROJECT_SOURCE_DIR 跟其他指令稍有区别,现在,你可以理解为他们是一致的。
3.7 CMAKE_CURRENT_SOURCE_DIR
指的是当前处理的 CMakeLists.txt 所在的路径,比如上面我们提到的 src 子目录。
3.8 CMAKE_CURRENT_BINARY_DIR
如果是内部编译,它跟 CMAKE_CURRENT_SOURCE_DIR 一致,如果是外部编译,他指的是 target 编译目录。
使用我们上面提到的 ADD_SUBDIRECTORY(src bin)可以更改这个变量的值。
使用 SET(EXECUTABLE_OUTPUT_PATH <新路径>) 并不会对这个变量造成影响,它仅仅修改了最终目标文件存放的路径。
3.9 CMAKE_CURRENT_LIST_FILE
输出调用这个变量的 CMakeLists.txt 的完整文件路径
3.10 CMAKE_CURRENT_LIST_LINE
输出这个变量所在的行
3.11 EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH
分别用来重新定义最终结果的存放目录。
3.12 CMAKE_INSTALL_PREFIX
cmake指定make install时的安装目录:通过设置 CMAKE_INSTALL_PREFIX 的值来控制。
是cmake 内置变量,linux平台默认值为 /usr/local, windows平台默认值是 C:/Program Files (x86)
四.cmake 调用环境变量的方式
使用 $ENV{NAME} 指令就可以调用系统的环境变量了。
比如: MESSAGE(STATUS “HOME dir: $ENV{HOME}”)
设置环境变量的方式是:
SET (ENV{变量名} 值)
1. CMAKE_INCLUDE_CURRENT_DIR
自动添加 CMAKE_CURRENT_BINARY_DIR 和 CMAKE_CURRENT_SOURCE_DIR 到当前处理的 CMakeLists.txt。相当于在每个 CMakeLists.txt 加入:
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
2. CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
将工程提供的头文件目录始终至于系统头文件目录的前面,当你定义的头文件确实跟系统发生冲突时可以提供一些帮助。
3. CMAKE_INCLUDE_PATH 和 CMAKE_LIBRARY_PATH
如果头文件和库文件没有存放在常规路径(/usr/include, /usr/local/include 等),则可以通过这些变量进行设置。
五.系统信息
1. CMAKE_MAJOR_VERSION CMAKE 主版本号,比如 2.4.6 中的 2
2. CMAKE_MINOR_VERSION CMAKE 次版本号,比如 2.4.6 中的 4
3. CMAKE_PATCH_VERSION CMAKE 补丁等级,比如 2.4.6 中的 6
4. CMAKE_SYSTEM 系统名称,比如 Linux-2.6.22
5. CMAKE_SYSTEM_NAME 不包含版本的系统名,比如 Linux
6. CMAKE_SYSTEM_VERSION 系统版本,比如 2.6.22
7. CMAKE_SYSTEM_PROCESSOR 处理器名称,比如 i686.
8. UNIX 在所有的类 UNIX 平台为 TRUE,包括 OS X 和 cygwin
9. WIN32 在所有的 win32 平台为 TRUE,包括 cygwin
六.主要的开关选项
1. CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS
用来控制 IF ELSE 语句的书写方式。
2. BUILD_SHARED_LIBS
这个开关用来控制默认的库编译方式,如果不进行设置,使用ADD_LIBRARY 并没有指定库类型的情况下,默认编译生成的库都是静态库。
如果 SET(BUILD_SHARED_LIBS ON) 后,默认生成的为动态库。
3. CMAKE_C_FLAGS
设置 C 编译选项,也可以通过指令 ADD_DEFINITIONS()添加。
4. CMAKE_CXX_FLAGS
设置 C++编译选项,也可以通过指令 ADD_DEFINITIONS()添加。