目录
EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH
CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
CMAKE_INCLUDE_PATH和CMAKE_LIBRARY_PATH
CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS
cmake 变量引用的方式
CMake中的变量引用方式有两种:
-
${VAR_NAME}
:使用${}
可以获取CMake变量的值,例如${CMAKE_CURRENT_SOURCE_DIR}
可以获取当前正在处理的CMakeLists.txt所在的源码目录的绝对路径。 -
@VAR_NAME@
:在CMake中使用configure_file()命令生成文件时,可以使用@
符号包围变量名称来引用变量的值,例如configure_file(config.h.in config.h)
中,如果config.h.in文件中包含@MY_VARIABLE@
,那么在生成config.h时,CMake会将@MY_VARIABLE@
替换为MY_VARIABLE变量的值。
这两种方式可以混用,例如在CMakeLists.txt文件中使用${}
获取变量值,在使用configure_file()命令时再使用@
符号引用变量值。
在 IF 等语句中,是直接使用变量名而不通过${}取值
cmake 自定义变量的方式
在 CMakeLists.txt 文件中,可以使用 set 命令定义自定义变量。set 命令的语法如下:
set(VAR_NAME VAR_VALUE)
其中,VAR_NAME 是变量名,VAR_VALUE 是变量的值。
例如,定义一个名为 MY_VAR 的变量,值为 "Hello, World!",可以这样写:
set(MY_VAR "Hello, World!")
在后面的 CMake 代码中,就可以通过 ${MY_VAR} 的方式来引用该变量。例如:
message("The value of MY_VAR is ${MY_VAR}")
在执行 cmake 命令时,也可以使用 -D 选项来设置变量的值。例如:
cmake -DMY_VAR="Hello, World!" .
CMAKE_BINARY_DIR
PROJECT_BINARY_DIR
<projectname>_BINARY_DIR
CMAKE_BINARY_DIR
是CMake在执行生成指令之前,指定二进制文件目录的变量,通常是CMake生成二进制文件的根目录。
PROJECT_BINARY_DIR
是项目的二进制文件目录,它的值等于CMAKE_BINARY_DIR
。
<projectname>_BINARY_DIR
是通过project()
命令指定的项目名称加上"_BINARY_DIR"的形式定义的变量。它的值也等于CMAKE_BINARY_DIR
。
这三个变量都表示项目的二进制文件目录,但它们的用途略有不同。CMAKE_BINARY_DIR
是CMake内部使用的变量,而PROJECT_BINARY_DIR
和<projectname>_BINARY_DIR
可以用于用户定义的变量。
CMAKE_SOURCE_DIR
PROJECT_SOURCE_DIR
<projectname>_SOURCE_DIR
CMAKE_SOURCE_DIR
、PROJECT_SOURCE_DIR
和<projectname>_SOURCE_DIR
都代表项目的源代码根目录。
其中,CMAKE_SOURCE_DIR
是全局变量,表示CMakeLists.txt文件所在的目录,可以用于设置build目录的默认值;PROJECT_SOURCE_DIR
是由project()
命令设置的变量,表示项目根目录;<projectname>_SOURCE_DIR
是由project()
命令中指定的项目名称生成的变量,表示项目根目录。
BINARY_DIR和SOURCE_DIR的区别
在CMake中,BINARY_DIR
和SOURCE_DIR
都是常用的目录变量,但它们有着不同的含义。
BINARY_DIR
是指编译生成的目标文件所在的目录,也就是在执行cmake
命令时,用户可以通过-B
参数指定的目录。这个目录通常是一个build目录,即编译目录,用于存放编译生成的文件,而不应该放置源文件和其他用户文件。
SOURCE_DIR
是指CMakeLists.txt文件所在的目录,即源代码所在的目录。在执行cmake
命令时,用户可以通过-S
参数指定的目录。通常情况下,源代码应该放在这个目录下,并且不应该在这个目录下进行编译和生成文件的操作。
PROJECT_BINARY_DIR
和PROJECT_SOURCE_DIR
分别指的是项目的编译目录和源代码目录,这两个变量在使用时会根据项目的名称自动命名,比如项目名为myproject
,则变量名称分别为MYPROJECT_BINARY_DIR
和MYPROJECT_SOURCE_DIR
。这两个变量通常可以用于生成文件和测试文件等目录的指定。
CMAKE_CURRENT_SOURCE_DIR
CMAKE_CURRENT_SOURCE_DIR
是一个 CMake 内置变量,表示当前处理的 CMakeLists.txt
文件所在的目录的绝对路径。在处理一个 CMakeLists.txt
文件时,CMake 会自动设置这个变量的值为当前处理的 CMakeLists.txt
文件所在目录的绝对路径。
CMAKE_CURRENT_SOURCE_DIR
可以用于指定源文件的路径,如 add_executable
或 add_library
命令中的源文件列表。这个变量还可以用于在配置文件中指定文件的路径,如 configure_file
命令中的 @ONLY
参数。
需要注意的是,CMAKE_CURRENT_SOURCE_DIR
的值是随着处理的 CMakeLists.txt
文件的改变而改变的。因此,在子目录中调用 CMAKE_CURRENT_SOURCE_DIR
时,它会返回子目录的路径而不是顶层目录的路径。如果要获取顶层目录的路径,可以使用 PROJECT_SOURCE_DIR
或 <projectname>_SOURCE_DIR
变量。
CMAKE_CURRRENT_BINARY_DIR
CMAKE_CURRENT_BINARY_DIR
是一个 CMake 系统定义的变量,表示当前处理的二进制输出目录,即当前 CMakeLists.txt 文件的构建目录。它是相对于项目根目录而言的。
在 CMake 中,源码目录和构建目录通常是分开的,可以通过 ADD_SUBDIRECTORY
命令将其他的源码目录添加到当前项目中进行编译。而 CMAKE_CURRENT_BINARY_DIR
则表示当前的构建目录,即编译时生成的二进制文件所在的目录。
在使用 CMake 进行项目构建时,一般情况下不应该在源码目录中直接编译和输出,而是应该使用一个独立的构建目录。这样可以使得源码目录和构建目录完全独立,防止在源码目录中生成中间文件和构建文件,避免污染源码目录。因此,CMAKE_CURRENT_BINARY_DIR
变量的值通常会与源码目录分离,表示构建目录中当前的输出目录。
ADD_SUBDIRECTORY
ADD_SUBDIRECTORY
是 CMake 中的一个指令,用于向当前工程添加一个子目录,并且继续处理子目录中的 CMakeLists.txt
文件。
语法如下:
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
其中:
source_dir
:必选参数,指定子目录的源代码路径。binary_dir
:可选参数,指定存放二进制文件的目录路径。如果不指定,则默认与source_dir
相同。EXCLUDE_FROM_ALL
:可选参数,表示不将该子目录加入到构建树的默认构建目标中。
当执行 ADD_SUBDIRECTORY
指令后,CMake 会在当前构建目录下创建一个新的子目录,然后进入该子目录,并在该子目录中执行 source_dir
下的 CMakeLists.txt
文件。执行完毕后,CMake 会回到当前目录并继续执行当前目录下的 CMakeLists.txt
文件。
通过 ADD_SUBDIRECTORY
指令,可以将一个大型工程划分为多个小型子工程,方便管理和维护。每个子工程可以拥有自己的 CMakeLists.txt
文件,其构建流程可以独立控制。
SET(EXECUTABLE_OUTPUT_PATH)
SET(EXECUTABLE_OUTPUT_PATH) 命令用于指定编译出的可执行文件(二进制文件)的输出目录。
语法如下:
SET(EXECUTABLE_OUTPUT_PATH <新路径>)
其中,<新路径>
是新的可执行文件的输出路径。例如,若要将可执行文件输出到 bin
目录中,可以这样写:
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
这里,PROJECT_BINARY_DIR
表示 CMake 生成的项目文件所在的路径,${}
表示使用变量。
使用 SET(EXECUTABLE_OUTPUT_PATH <新路径>)
命令后,可执行文件就会被编译到指定的目录中。
CMAKE_CURRENT_LIST_FILE
CMAKE_CURRENT_LIST_FILE是一个cmake内置的变量,它保存了当前处理的CMakeLists.txt文件的完整路径和文件名。它可以在CMakeLists.txt文件中使用,用于获取当前正在处理的CMakeLists.txt文件的路径。例如,可以将其用作一些调试或日志记录目的,或者在当前的CMakeLists.txt文件中包含其他文件。
CMAKE_CURRENT_LIST_LINE
CMAKE_CURRENT_LIST_LINE
是 CMake 内置的一个变量,用于返回当前 CMake 文件的行号。在 CMake 文件中,每一行的内容都是一个命令,通过这个变量,我们可以方便地查看当前执行的命令在 CMake 文件中的行号。
例如,我们可以在 CMake 文件中输出当前执行的命令所在的行号,如下所示:
message("Current line number: ${CMAKE_CURRENT_LIST_LINE}")
当执行这个命令时,CMake 会输出当前命令所在的行号。
这个变量可以用于调试 CMake 脚本,定位问题所在。
CMAKE_MODULE_PATH
CMAKE_MODULE_PATH
是一个CMake的内置变量,它表示CMake在查找模块文件时应该搜索的路径列表。模块文件通常是一个CMake脚本,其目的是提供一个特定的功能,例如寻找特定的库或检查系统是否具有某些功能。
在执行include()
或find_package()
等命令时,CMake将在以下位置搜索模块文件:
- CMAKE_MODULE_PATH变量指定的目录;
- CMake内置的模块目录;
- 环境变量CMAKE_MODULE_PATH指定的目录;
- CMake安装目录的模块目录。
通过将路径添加到CMAKE_MODULE_PATH
中,可以方便地指定CMake应该搜索模块文件的位置。
EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH
EXECUTABLE_OUTPUT_PATH
和 LIBRARY_OUTPUT_PATH
是 CMake 中用于指定生成的可执行文件和库文件的输出路径的变量。
EXECUTABLE_OUTPUT_PATH
变量用于指定可执行文件的输出路径,即 CMake 生成可执行文件后输出的路径。一般情况下,这个路径是 projectname/bin
目录。
LIBRARY_OUTPUT_PATH
变量用于指定库文件的输出路径,即 CMake 生成库文件后输出的路径。一般情况下,这个路径是 projectname/lib
目录。
这两个变量可以通过 SET
命令来设置,例如:
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
这里将 EXECUTABLE_OUTPUT_PATH
设置为 ${PROJECT_BINARY_DIR}/bin
,LIBRARY_OUTPUT_PATH
设置为 ${PROJECT_BINARY_DIR}/lib
,即可让 CMake 在指定的目录下生成可执行文件和库文件。
PROJECT_NAME
PROJECT_NAME
是一个 CMake 内置的变量,表示当前项目的名称。该变量的值是在调用 project()
命令时通过 NAME
参数指定的。例如,以下命令指定项目名称为 my_project
:
project(my_project)
可以通过 ${PROJECT_NAME}
来引用该变量,例如:
message("Project name: ${PROJECT_NAME}")
该命令会输出当前项目的名称。
$ENV{NAME}
$ENV{NAME}
是CMake中获取环境变量的一种方法,其中NAME
是环境变量的名称。这种语法将在CMake脚本中展开为环境变量的值。例如,如果你想在CMake脚本中获取PATH
环境变量的值,可以这样写:
message("PATH=$ENV{PATH}")
这将在CMake构建期间打印PATH
环境变量的值。
SET(ENV{变量名} 值)
在CMake中,可以使用SET(ENV{变量名} 值)
命令来设置环境变量,其中变量名
为环境变量的名称,值
为要设置的值。这个命令会将环境变量设置为在当前CMake脚本执行过程中及其启动的所有子进程中都可用。请注意,该命令仅在当前CMake运行期间有效,并不会永久地更改系统环境变量。如果您需要永久更改系统环境变量,请在外部运行CMake脚本之前手动更改它们。
CMAKE_INCLUDE_CURRENT_DIR
CMAKE_INCLUDE_CURRENT_DIR
是一个cmake变量,它控制是否自动将${CMAKE_CURRENT_BINARY_DIR}
和${CMAKE_CURRENT_SOURCE_DIR}
添加到INCLUDE_DIRECTORIES
中,以便在使用cmake自动生成的头文件时,不必手动添加这些目录。
当启用CMAKE_INCLUDE_CURRENT_DIR
时,使用configure_file()
或file(GENERATE ...)
生成的头文件将自动添加到项目中。
默认情况下,CMAKE_INCLUDE_CURRENT_DIR
处于启用状态,但建议在使用时显式设置它,以便代码的可读性和可维护性。
例如,可以使用以下代码来显式启用CMAKE_INCLUDE_CURRENT_DIR
:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
是一个 CMake 变量,它是一个布尔类型,如果设置为 TRUE
,则将项目包含目录添加到其他包含目录之前。默认情况下,它是 FALSE
。
这个变量的主要作用是控制包含目录的优先级。例如,如果项目中有一个头文件和系统中的某个库中的头文件同名且不同,则可以使用 CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
将项目中的头文件优先于系统中的头文件。这样,编译器会优先使用项目中的头文件。
CMAKE_INCLUDE_PATH
和CMAKE_LIBRARY_PATH
CMAKE_INCLUDE_PATH
和CMAKE_LIBRARY_PATH
是CMake的两个环境变量,用于指定系统搜索头文件和库文件的默认路径。
CMAKE_INCLUDE_PATH
用于设置头文件的搜索路径,CMake在查找头文件时,会优先搜索CMAKE_INCLUDE_PATH
指定的目录。
CMAKE_LIBRARY_PATH
用于设置库文件的搜索路径,CMake在查找库文件时,会优先搜索CMAKE_LIBRARY_PATH
指定的目录。
这两个变量可以在CMakeLists.txt文件中设置,也可以在运行CMake之前设置环境变量,让CMake读取环境变量的值。
CMAKE_MAJOR_VERSION
CMAKE_MAJOR_VERSION
是 CMake 的一个系统变量,它表示当前 CMake 的主版本号。例如,如果 CMake 版本是 3.20.0,那么 CMAKE_MAJOR_VERSION
将会是 3。
可以使用以下方式在 CMakeLists.txt 文件中引用它:
message("CMake major version is ${CMAKE_MAJOR_VERSION}")
这将会输出以下信息:
CMake major version is 3
CMAKE_MINOR_VERSION
CMAKE_MINOR_VERSION
是CMake的次版本号。CMake的版本号遵循语义化版本控制规则,即主版本号.次版本号.修订号。其中,主版本号表明了兼容性破坏的变更,次版本号表明了向后兼容的新功能的添加,修订号则表示不向后兼容的缺陷修复。比如CMake 3.22.1,其主版本号为3,次版本号为22,修订号为1。CMAKE_MAJOR_VERSION
为3,CMAKE_MINOR_VERSION
为22,CMAKE_PATCH_VERSION
为1。
CMAKE_PATCH_VERSION
CMAKE_PATCH_VERSION
是CMake的一个内置变量,它存储了CMake的小版本号,即修订号。例如,如果CMake版本是3.19.4,那么CMAKE_PATCH_VERSION
的值将为4。可以通过${CMAKE_PATCH_VERSION}
引用该变量。
CMAKE_SYSTEM
CMAKE_SYSTEM是一个cmake内置的变量,用于表示当前的操作系统。CMAKE_SYSTEM包括以下几个常用的子变量:
- CMAKE_SYSTEM_NAME:操作系统名称,例如Linux、Windows等。
- CMAKE_SYSTEM_PROCESSOR:处理器名称,例如x86、x64等。
- CMAKE_SYSTEM_VERSION:操作系统版本号,例如Windows的10.0.19042。
可以使用message命令输出这些变量的值,例如:
message("System Name: " ${CMAKE_SYSTEM_NAME})
message("System Processor: " ${CMAKE_SYSTEM_PROCESSOR})
message("System Version: " ${CMAKE_SYSTEM_VERSION})
在跨平台的开发中,CMAKE_SYSTEM变量非常有用,可以通过判断不同的操作系统来设置不同的编译选项、链接选项、库路径等,以确保程序在不同平台上的编译和运行。
Cygwin
Cygwin是一个允许在Windows操作系统上运行类Unix操作系统应用程序的免费开源软件集合。它是一个Unix兼容的环境,其中包括许多Unix/Linux工具和应用程序,如bash shell、Emacs、GCC编译器、OpenSSH服务器和客户端等。Cygwin包括了一个DLL文件,提供了对POSIX系统调用的实现,使得许多Unix/Linux程序可以在Windows上运行,同时提供了对Windows API的访问。
CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS
CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS
是 CMake 的一个变量,用于控制是否允许使用旧版 CMake 脚本语法中的松散循环结构。在 CMake 3.0 及更高版本中,这个变量的默认值为 FALSE
,即不允许使用松散循环结构。如果要在 CMake 3.0 及更高版本中使用旧版语法中的松散循环结构,需要将这个变量设置为 TRUE
。
在旧版 CMake 脚本语法中,可以使用松散循环结构,即不使用括号来限定循环体。例如:
foreach(file ${SOURCES})
message("Processing file ${file}")
endforeach
在 CMake 3.0 及更高版本中,使用松散循环结构会导致警告信息。为了避免这些警告信息,可以将 CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS
设置为 TRUE
。
松散循环结构
松散循环结构是指在 CMake 的控制流语句中,允许多行语句作为循环体,而不需要使用大括号 {}
包围循环体。这样的循环结构可以使 CMake 脚本更加简洁易读。例如:
foreach(file
file1
file2
file3
)
message("Processing file ${file}")
endforeach()
这段代码中,循环体是 message()
命令,它们并没有使用大括号 {}
包围。在 CMake 中,可以通过设置 CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS
变量为 ON
来启用松散循环结构。
BUILD_SHARED_LIBS
BUILD_SHARED_LIBS
是 CMake 中的一个变量,用于控制是否构建共享库(shared library),它的默认值为 OFF,即默认不构建共享库。当设置为 ON 时,CMake 将构建共享库而不是静态库。
具体来说,BUILD_SHARED_LIBS
变量会影响到 CMake 生成的 Makefile、Visual Studio 解决方案等构建系统的设置,从而影响到最终的构建结果。
这个变量的使用场景一般是在需要构建动态链接库(shared library)时,可以通过设置它来指定构建方式。同时,它也可以在 CMakeLists.txt 中的条件语句中使用,例如可以根据这个变量的值来控制特定的构建选项。
下面是一个使用示例:
# 设置 BUILD_SHARED_LIBS 为 ON,构建共享库
set(BUILD_SHARED_LIBS ON)
# 在目标链接时,如果 BUILD_SHARED_LIBS 为 ON,则使用共享库
if(BUILD_SHARED_LIBS)
target_link_libraries(my_target PUBLIC my_library_shared)
else()
target_link_libraries(my_target PUBLIC my_library_static)
endif()
这个示例中,在设置了 BUILD_SHARED_LIBS
为 ON 后,使用了一个条件语句来判断变量的值,从而在链接时决定使用共享库还是静态库。
CMAKE_C_FLAGS
CMAKE_C_FLAGS
是用于C编译器的编译选项。它是一个字符串变量,可以在CMakeLists.txt
文件中设置,用于为C编译器设置额外的编译选项。例如,可以使用该变量来设置调试标志、警告标志或优化标志。
下面是一个使用CMAKE_C_FLAGS
的示例:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror")
这段代码是将变量 CMAKE_C_FLAGS
的值添加了一些编译选项。CMAKE_C_FLAGS
是 C 编译器的编译选项,用于在编译 C 代码时传递给编译器的选项。-Wall
选项表示开启编译器的所有警告,-Werror
表示将警告视为错误,即警告会导致编译失败。这段代码的作用是在编译 C 代码时开启所有警告,并将警告视为错误,以提高代码的质量和可靠性。
CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS
是一个CMake变量,用于存储传递给C++编译器的额外参数,例如编译选项。使用set(CMAKE_CXX_FLAGS "<flags>")
命令可以为此变量设置值。
以下是一个示例:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra")
这行代码设置了C++编译器的编译选项,其中-std=c++11
指定了使用C++11标准进行编译,-Wall
和-Wextra
开启了编译器的警告信息输出,可以帮助开发者在编译时发现一些潜在的问题。这里使用了set
命令将新的编译选项添加到已有的选项中,${CMAKE_CXX_FLAGS}
表示使用原先已经定义好的编译选项。
ADD_DEFINITIONS()
ADD_DEFINITIONS()
是 CMake 中的一个命令,它用于向编译器添加编译选项,例如定义宏,打开某些警告等。这个命令会将这些选项添加到所有目标的编译选项中,包括可执行文件、静态库、动态库等。
使用 ADD_DEFINITIONS()
命令可以向 C/C++ 编译器添加一些选项,例如:
ADD_DEFINITIONS(-DDEBUG -Wall)
在这个例子中,ADD_DEFINITIONS()
命令添加了两个选项:
-DDEBUG
表示添加名为DEBUG
的宏定义。-Wall
表示打开所有警告信息的开关。
这些选项会被应用到所有被编译的源文件中。
需要注意的是,ADD_DEFINITIONS()
命令会将选项添加到所有目标的编译选项中,这可能会对其他库或可执行文件产生影响,因此应该谨慎使用。如果只需要将选项添加到特定目标中,可以使用 TARGET_COMPILE_OPTIONS()
命令。