CMAKE实践读书笔记(5)P31-P33

目录

cmake 变量引用的方式

cmake 自定义变量的方式

BINARY_DIR和SOURCE_DIR的区别

CMAKE_CURRENT_SOURCE_DIR

CMAKE_CURRRENT_BINARY_DIR

ADD_SUBDIRECTORY

SET(EXECUTABLE_OUTPUT_PATH)

CMAKE_CURRENT_LIST_FILE

CMAKE_CURRENT_LIST_LINE

CMAKE_MODULE_PATH

EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH

PROJECT_NAME

$ENV{NAME}

SET(ENV{变量名} 值)

CMAKE_INCLUDE_CURRENT_DIR

CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE

CMAKE_INCLUDE_PATH和CMAKE_LIBRARY_PATH

CMAKE_MAJOR_VERSION

CMAKE_MINOR_VERSION

CMAKE_PATCH_VERSION

CMAKE_SYSTEM

Cygwin

CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS

松散循环结构

BUILD_SHARED_LIBS

CMAKE_C_FLAGS

CMAKE_CXX_FLAGS

ADD_DEFINITIONS()


cmake 变量引用的方式

CMake中的变量引用方式有两种:

  1. ${VAR_NAME}:使用${}可以获取CMake变量的值,例如${CMAKE_CURRENT_SOURCE_DIR}可以获取当前正在处理的CMakeLists.txt所在的源码目录的绝对路径。

  2. @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_DIRPROJECT_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_DIRSOURCE_DIR都是常用的目录变量,但它们有着不同的含义。

BINARY_DIR是指编译生成的目标文件所在的目录,也就是在执行cmake命令时,用户可以通过-B参数指定的目录。这个目录通常是一个build目录,即编译目录,用于存放编译生成的文件,而不应该放置源文件和其他用户文件。

SOURCE_DIR是指CMakeLists.txt文件所在的目录,即源代码所在的目录。在执行cmake命令时,用户可以通过-S参数指定的目录。通常情况下,源代码应该放在这个目录下,并且不应该在这个目录下进行编译和生成文件的操作。

PROJECT_BINARY_DIRPROJECT_SOURCE_DIR分别指的是项目的编译目录和源代码目录,这两个变量在使用时会根据项目的名称自动命名,比如项目名为myproject,则变量名称分别为MYPROJECT_BINARY_DIRMYPROJECT_SOURCE_DIR。这两个变量通常可以用于生成文件和测试文件等目录的指定。


CMAKE_CURRENT_SOURCE_DIR

CMAKE_CURRENT_SOURCE_DIR 是一个 CMake 内置变量,表示当前处理的 CMakeLists.txt 文件所在的目录的绝对路径。在处理一个 CMakeLists.txt 文件时,CMake 会自动设置这个变量的值为当前处理的 CMakeLists.txt 文件所在目录的绝对路径。

CMAKE_CURRENT_SOURCE_DIR 可以用于指定源文件的路径,如 add_executableadd_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将在以下位置搜索模块文件:

  1. CMAKE_MODULE_PATH变量指定的目录;
  2. CMake内置的模块目录;
  3. 环境变量CMAKE_MODULE_PATH指定的目录;
  4. CMake安装目录的模块目录。

通过将路径添加到CMAKE_MODULE_PATH中,可以方便地指定CMake应该搜索模块文件的位置。


EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH

EXECUTABLE_OUTPUT_PATHLIBRARY_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}/binLIBRARY_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_PATHCMAKE_LIBRARY_PATH

CMAKE_INCLUDE_PATHCMAKE_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() 命令。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值