cartographer源码学习之functions.cmake

include(CMakeParseArguments)

include(CMakeParseArguments) 是CMake语言中的一个命令,它用于引入CMakeParseArguments模块。这个模块提供了一些函数和宏,用于解析和处理CMake命令行参数。

具体来说,CMakeParseArguments模块提供了一个cmake_parse_arguments()函数,可以用来定义和解析自定义CMake命令的参数。通过使用这个函数,你可以在自定义的CMake命令中指定参数的名称、类型、默认值等信息,并在命令被调用时解析和使用这些参数。

macro(_parse_arguments ARGS)
  set(OPTIONS)
  set(ONE_VALUE_ARG)
  set(MULTI_VALUE_ARGS SRCS)
  cmake_parse_arguments(ARG
    "${OPTIONS}" "${ONE_VALUE_ARG}" "${MULTI_VALUE_ARGS}" ${ARGS})
endmacro(_parse_arguments)

这段代码定义了一个名为_parse_arguments的宏。宏的作用是使用cmake_parse_arguments()函数解析输入的参数,并将解析结果保存到名为ARG的变量中。

具体而言,这个宏接受一个参数ARGS,它是一个字符串列表,包含了需要解析的参数。在宏内部,首先定义了三个变量:OPTIONS、ONE_VALUE_ARG和MULTI_VALUE_ARGS。这些变量用于配置cmake_parse_arguments()函数的行为。

然后,使用cmake_parse_arguments()函数进行参数解析。该函数接受多个参数,包括:

第一个参数ARG是用于保存解析结果的变量名。
第二个参数 O P T I O N S 指定了可选参数的名称。第三个参数 {OPTIONS}指定了可选参数的名称。 第三个参数 OPTIONS指定了可选参数的名称。第三个参数{ONE_VALUE_ARG}指定了单值参数的名称。
第四个参数 M U L T I V A L U E A R G S 指定了多值参数的名称。最后一个参数 {MULTI_VALUE_ARGS}指定了多值参数的名称。 最后一个参数 MULTIVALUEARGS指定了多值参数的名称。最后一个参数{ARGS}是传递给宏的参数列表。
通过调用cmake_parse_arguments()函数,输入的参数列表将按照指定的规则进行解析,并将解析结果保存到ARG变量中。这样,在宏被调用之后,可以通过访问ARG变量来获取解析后的参数值。

当调用宏_parse_arguments时,可以传递一个参数列表,并按照预定义的规则进行解析。下面是一个示例调用:

_parse_arguments(MY_ARGS
  "OPTION1;OPTION2"
  "SINGLE_ARG"
  SRCS source1.cpp source2.cpp
)

当调用宏_parse_arguments时,可以传递一个参数列表,并按照预定义的规则进行解析。下面是一个示例调用:
cmake
Copy code
_parse_arguments(MY_ARGS
“OPTION1;OPTION2”
“SINGLE_ARG”
SRCS source1.cpp source2.cpp
)
在这个示例中,OPTION1和OPTION2被定义为可选参数,SINGLE_ARG被定义为单值参数,SRCS被定义为多值参数。参数列表中的参数将按照这些规则进行解析。
解析后的结果将保存在名为MY_ARGS的变量中。可以通过访问MY_ARGS来获取解析后的参数值。例如:

message("OPTION1: ${MY_ARGS_OPTION1}")
message("SINGLE_ARG: ${MY_ARGS_SINGLE_ARG}")
message("SRCS: ${MY_ARGS_SRCS}")

这将打印出解析后的参数值。注意,解析后的参数值的名称是根据传递给宏的参数名称自动生成的,前缀为宏的名称(即MY_ARGS)加上下划线。

macro(_common_compile_stuff VISIBILITY)
  set(TARGET_COMPILE_FLAGS "${TARGET_COMPILE_FLAGS} ${GOOG_CXX_FLAGS}")

  set_target_properties(${NAME} PROPERTIES
    COMPILE_FLAGS ${TARGET_COMPILE_FLAGS})

  target_include_directories(${NAME} PUBLIC ${PROJECT_NAME})
  target_link_libraries(${NAME} PUBLIC ${PROJECT_NAME})
endmacro(_common_compile_stuff)

这是一个名为 _common_compile_stuff 的宏,它接受一个参数 VISIBILITY。

在宏的定义中,首先将变量 TARGET_COMPILE_FLAGS 设置为 ${TARGET_COMPILE_FLAGS} ${GOOG_CXX_FLAGS},将 GOOG_CXX_FLAGS 添加到已有的编译标志中。这个变量用于存储目标的编译标志。

接下来,通过 set_target_properties 函数设置目标的属性。具体来说,它将目标 ${NAME} 的 COMPILE_FLAGS 属性设置为 ${TARGET_COMPILE_FLAGS},这将应用先前设置的编译标志。

然后,使用 target_include_directories 函数将目标 ${NAME} 的公共包含目录设置为 ${PROJECT_NAME}。这将使得 ${PROJECT_NAME} 中的头文件可以在目标中访问。

最后,使用 target_link_libraries 函数将目标 ${NAME} 链接到 ${PROJECT_NAME}。这将确保目标可以使用 ${PROJECT_NAME} 中定义的库。

总结起来,这个宏主要用于设置目标的编译标志、包含目录和链接库,以便在构建过程中正确地编译和链接目标。

function(google_test NAME ARG_SRC)
  add_executable(${NAME} ${ARG_SRC})
  _common_compile_stuff("PRIVATE")

  # Make sure that gmock always includes the correct gtest/gtest.h.
  target_include_directories("${NAME}" SYSTEM PRIVATE
    "${GMOCK_INCLUDE_DIRS}")
  target_link_libraries("${NAME}" PUBLIC ${GMOCK_LIBRARIES})

  add_test(${NAME} ${NAME})
endfunction()

这是一个名为 google_test 的函数,它接受两个参数 NAME 和 ARG_SRC。

在函数的定义中,首先使用 add_executable 函数创建一个可执行目标 ${NAME},并将其源文件设置为 ${ARG_SRC}。这将生成一个可以运行的可执行文件。

接下来,调用了之前定义的 _common_compile_stuff 宏,并将参数 “PRIVATE” 传递给它。这将应用通用的编译设置,包括编译标志、包含目录和链接库。

然后,使用 target_include_directories 函数将 ${NAME} 目标的私有包含目录设置为 ${GMOCK_INCLUDE_DIRS}。这将确保在编译时可以正确包含 ${GMOCK_INCLUDE_DIRS} 中的头文件。

接着,使用 target_link_libraries 函数将 ${NAME} 目标链接到 ${GMOCK_LIBRARIES}。这将确保在链接时可以使用 ${GMOCK_LIBRARIES} 中定义的库。

最后,使用 add_test 函数将测试 ${NAME} 添加到测试套件中。这将使得在运行测试时可以执行 ${NAME} 可执行文件。

综上所述,这个函数用于创建一个测试的可执行目标,设置相关的编译和链接选项,并将测试添加到测试套件中以便运行。

function(google_test NAME ARG_SRC)
  add_executable(${NAME} ${ARG_SRC})
  _common_compile_stuff("PRIVATE")

  # Make sure that gmock always includes the correct gtest/gtest.h.
  target_include_directories("${NAME}" SYSTEM PRIVATE
    "${GMOCK_INCLUDE_DIRS}")
  target_link_libraries("${NAME}" PUBLIC ${GMOCK_LIBRARIES})

  add_test(${NAME} ${NAME})
endfunction()

这段代码定义了一个名为 google_test 的 CMake 函数,用于简化创建和配置 Google Test 测试的过程。下面是对代码的解释:

function(google_test NAME ARG_SRC):这行代码声明了一个名为 google_test 的函数,它接受两个参数:NAME 和 ARG_SRC。NAME 是一个字符串,用于标识测试的名称或标识符,ARG_SRC 是一个参数,用于指定测试源文件的路径。

add_executable(${NAME} ${ARG_SRC}):这行代码创建一个可执行文件,并将名称设置为 NAME 参数的值,源文件为 ARG_SRC 参数指定的路径。这样就创建了一个与测试名称相对应的可执行文件。

_common_compile_stuff(“PRIVATE”):这行代码调用一个名为 _common_compile_stuff 的辅助宏(或函数),并将 “PRIVATE” 作为参数传递给它。该辅助宏或函数负责设置一些通用的编译配置,例如编译标志、包含目录和链接库。

target_include_directories(“ N A M E " S Y S T E M P R I V A T E " {NAME}" SYSTEM PRIVATE " NAME"SYSTEMPRIVATE"{GMOCK_INCLUDE_DIRS}”):这行代码将 ${NAME} 所表示的目标(即测试可执行文件)的包含目录设置为 ${GMOCK_INCLUDE_DIRS},并将其作为系统目录(SYSTEM)添加。这样可以确保 gmock 始终包含正确的 gtest/gtest.h 头文件。

target_link_libraries(“${NAME}” PUBLIC ${GMOCK_LIBRARIES}):这行代码将 ${NAME} 所表示的目标(即测试可执行文件)与 ${GMOCK_LIBRARIES} 中指定的库进行链接。这样可以确保测试可执行文件可以使用 gmock 提供的功能。

add_test(${NAME} N A M E ) :这行代码使用 a d d t e s t 函数将测试添加到 C T e s t 测试套件中。 {NAME}):这行代码使用 add_test 函数将测试添加到 CTest 测试套件中。 NAME):这行代码使用addtest函数将测试添加到CTest测试套件中。{NAME} 参数用于指定测试的名称,${NAME} 参数用于指定要运行的测试可执行文件。

通过调用 google_test 函数并传递适当的参数,你可以创建和配置 Google Test 测试,并将其添加到测试套件中以进行执行。

function(google_binary NAME)
  _parse_arguments("${ARGN}")

  add_executable(${NAME} ${ARG_SRCS})

  _common_compile_stuff("PRIVATE")

  install(TARGETS "${NAME}" RUNTIME DESTINATION bin)
endfunction()

function(google_binary NAME):定义了一个名为 google_binary 的 CMake 函数,它接受一个参数 NAME,用于指定生成的可执行文件的名称。

_parse_arguments(“${ARGN}”):调用了之前解释过的 _parse_arguments 宏,用于解析函数的参数列表。这个宏将参数列表解析为不同的变量,以便在后续的代码中使用。

add_executable(${NAME} A R G S R C S ) :使用 a d d e x e c u t a b l e 命令创建一个可执行文件。 {ARG_SRCS}):使用 add_executable 命令创建一个可执行文件。 ARGSRCS):使用addexecutable命令创建一个可执行文件。{NAME} 是函数的参数,用于指定可执行文件的名称。${ARG_SRCS} 是通过解析参数列表得到的变量,它包含了可执行文件所需的源代码文件。

_common_compile_stuff(“PRIVATE”):调用了之前解释过的 _common_compile_stuff 宏,用于设置编译选项和链接库。

install(TARGETS " N A M E " R U N T I M E D E S T I N A T I O N b i n ) :使用 i n s t a l l 命令将生成的可执行文件安装到指定目录。 {NAME}" RUNTIME DESTINATION bin):使用 install 命令将生成的可执行文件安装到指定目录。 NAME"RUNTIMEDESTINATIONbin):使用install命令将生成的可执行文件安装到指定目录。{NAME} 是函数的参数,用于指定要安装的目标。RUNTIME DESTINATION bin 指定了可执行文件在安装时应放置的目标位置。

通过调用 google_binary 函数并传递相应的参数,你可以生成一个可执行文件,并将其安装到指定目录中。这样,你可以在构建过程中创建和安装可执行文件,并在安装后的目录中找到生成的二进制文件。

function(google_add_flag VAR_NAME FLAG)
  if (${VAR_NAME})
    set(${VAR_NAME} "${${VAR_NAME}} ${FLAG}" PARENT_SCOPE)
  else()
    set(${VAR_NAME} "${FLAG}" PARENT_SCOPE)
  endif()
endfunction()

这段代码定义了一个 CMake 函数 google_add_flag,它用于添加标志(flags)到一个变量中。

参数 VAR_NAME:表示要添加标志的变量的名称。
参数 FLAG:表示要添加的标志。
函数的功能是将指定的标志 FLAG 添加到变量 VAR_NAME 中。如果变量 VAR_NAME 已经有值,则将 FLAG 追加到现有值的末尾,否则直接将 FLAG 赋给变量 VAR_NAME。

下面是代码的解释:

首先,函数通过 ${VAR_NAME} 语法检查变量 VAR_NAME 是否已经被设置。
如果变量 VAR_NAME 已经被设置(即不为空),则使用 KaTeX parse error: Expected '}', got 'EOF' at end of input: {{VAR_NAME}} 语法获取变量 VAR_NAME 的当前值,并将 FLAG 追加到该值的末尾。最终结果再次赋值给变量 VAR_NAME。
如果变量 VAR_NAME 未设置(即为空),则直接将 FLAG 赋值给变量 VAR_NAME。
使用 PARENT_SCOPE 关键字将变量的作用域扩展到父级作用域,以便在函数外部也能访问到变量的更新值。

这个函数的目的是方便地添加标志到指定的变量中,可以用于构建过程中的参数配置,例如编译选项、链接选项等。

macro(google_initialize_cartographer_project)
  if(CARTOGRAPHER_CMAKE_DIR)
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
        ${CARTOGRAPHER_CMAKE_DIR}/modules)
  else()
    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
        ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
  endif()

这段代码定义了一个名为 google_initialize_cartographer_project 的宏。它用于初始化 Cartographer 项目的配置。

首先,宏检查变量 CARTOGRAPHER_CMAKE_DIR 是否已定义。如果已定义(非空),则将 ${CARTOGRAPHER_CMAKE_DIR}/modules 添加到 CMAKE_MODULE_PATH 变量的末尾。这个变量用于指定 CMake 模块的搜索路径,以便在构建过程中使用。

如果 CARTOGRAPHER_CMAKE_DIR 未定义或为空,宏将将 C M A K E C U R R E N T S O U R C E D I R / c m a k e / m o d u l e s 添加到 C M A K E M O D U L E P A T H 变量的末尾。 {CMAKE_CURRENT_SOURCE_DIR}/cmake/modules 添加到 CMAKE_MODULE_PATH 变量的末尾。 CMAKECURRENTSOURCEDIR/cmake/modules添加到CMAKEMODULEPATH变量的末尾。{CMAKE_CURRENT_SOURCE_DIR} 是当前源代码目录的路径,cmake/modules 是相对于源代码目录的子目录。

通过修改 CMAKE_MODULE_PATH 变量,宏确保 CMake 在构建项目期间能够正确找到所需的自定义模块文件,以便在构建过程中使用它们。这对于项目的配置和依赖项管理非常重要。

  if(WIN32)
    # TODO turn on equivalent warnings on Windows
  else()
    set(GOOG_CXX_FLAGS "-pthread -fPIC ${GOOG_CXX_FLAGS}")

    if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 6.1)
      google_add_flag(GOOG_CXX_FLAGS "-std=c++11")
    endif()

这段代码是一个条件语句,用于根据不同的操作系统平台设置编译器标志。

在Windows平台上,代码中的注释指出需要在Windows上启用相应的警告。这意味着该部分代码目前没有针对Windows平台做任何特定的编译器标志设置。

在非Windows平台上,代码设置了变量 GOOG_CXX_FLAGS。它将 -pthread 和 -fPIC 标志添加到现有的 GOOG_CXX_FLAGS 变量中。这些标志用于指示编译器在编译过程中使用线程库(-pthread)以及生成位置无关代码(-fPIC)。

接下来的条件语句检查正在使用的 C++ 编译器是否为 GNU 编译器,并且版本是否小于 6.1。如果是,它调用宏 google_add_flag,将 -std=c++11 标志追加到 GOOG_CXX_FLAGS 变量中。这个标志指示编译器使用 C++11 标准进行编译。

总的来说,这段代码用于设置编译器标志,以确保在非Windows平台上使用正确的标志和选项来编译代码。

    google_add_flag(GOOG_CXX_FLAGS "-Wall")
    google_add_flag(GOOG_CXX_FLAGS "-Wpedantic")

    # Turn some warnings into errors.
    google_add_flag(GOOG_CXX_FLAGS "-Werror=format-security")
    google_add_flag(GOOG_CXX_FLAGS "-Werror=missing-braces")
    google_add_flag(GOOG_CXX_FLAGS "-Werror=reorder")
    google_add_flag(GOOG_CXX_FLAGS "-Werror=return-type")
    google_add_flag(GOOG_CXX_FLAGS "-Werror=switch")
    google_add_flag(GOOG_CXX_FLAGS "-Werror=uninitialized")

这段代码用于向变量 GOOG_CXX_FLAGS 添加一系列编译器标志。

首先,通过调用 google_add_flag 宏,将 -Wall 标志添加到 GOOG_CXX_FLAGS 变量中。-Wall 标志启用编译器的所有警告。

接下来,通过多次调用 google_add_flag 宏,将其他警告标志添加到 GOOG_CXX_FLAGS 变量中。这些警告标志包括:

-Wpedantic:启用严格的符合标准的警告。
-Werror=format-security:将格式化字符串安全问题警告视为错误。
-Werror=missing-braces:将缺少大括号警告视为错误。
-Werror=reorder:将成员变量初始化列表顺序警告视为错误。
-Werror=return-type:将缺少返回值类型警告视为错误。
-Werror=switch:将缺少 switch 语句中的枚举值警告视为错误。
-Werror=uninitialized:将未初始化变量警告视为错误。
通过将这些警告标志添加到 GOOG_CXX_FLAGS 变量中,并将其设置为 GOOG_CXX_FLAGS 的新值,可以确保在编译过程中启用这些警告,并将它们视为错误,从而提高代码质量和可靠性。


    if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
      google_add_flag(GOOG_CXX_FLAGS "-Wthread-safety")
    endif()

这段代码用于在使用 Clang 或 AppleClang 编译器时,向 GOOG_CXX_FLAGS 变量添加 -Wthread-safety 标志。

通过条件判断,检查变量 CMAKE_CXX_COMPILER_ID 是否匹配 “Clang” 或 “AppleClang”。如果匹配成功,就调用 google_add_flag 宏,将 -Wthread-safety 标志添加到 GOOG_CXX_FLAGS 变量中。

-Wthread-safety 标志是 Clang 编译器的一个警告选项,用于检查多线程代码的线程安全性。通过启用此标志,编译器将检查代码中的潜在线程安全问题,并给出相应的警告信息。这有助于提高多线程代码的质量和可靠性。

    if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
      set(CMAKE_BUILD_TYPE Release)
    endif()

这段代码用于检查构建类型(CMAKE_BUILD_TYPE)是否已设置或为空。如果构建类型未设置或为空,它将设置构建类型为 Release。

首先,NOT CMAKE_BUILD_TYPE 检查构建类型是否未设置,即是否为空。如果构建类型未设置,条件为真。

接下来,CMAKE_BUILD_TYPE STREQUAL “” 检查构建类型是否为空字符串。如果构建类型为空,条件为真。

如果上述两个条件之一为真,表示构建类型未设置或为空,那么 set(CMAKE_BUILD_TYPE Release) 将构建类型设置为 Release。

总而言之,这段代码的目的是确保构建类型被设置为 Release,除非已经明确设置了其他构建类型。这样可以确保在构建过程中使用适当的优化和处理设置。

    if(CMAKE_BUILD_TYPE STREQUAL "Release")
      google_add_flag(GOOG_CXX_FLAGS "-O3 -DNDEBUG")
    elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
      google_add_flag(GOOG_CXX_FLAGS "-O3 -g -DNDEBUG")
    elseif(CMAKE_BUILD_TYPE STREQUAL "Debug")
      if(FORCE_DEBUG_BUILD)
        message(WARNING "Building in Debug mode, expect very slow performance.")
        google_add_flag(GOOG_CXX_FLAGS "-g")
      else()
        message(FATAL_ERROR
          "Compiling in Debug mode is not supported and can cause severely degraded performance. "
          "You should change the build type to Release. If you want to build in Debug mode anyway, "
          "call CMake with -DFORCE_DEBUG_BUILD=True"
        )
      endif()

这段代码根据不同的构建类型(CMAKE_BUILD_TYPE)设置不同的编译标志(GOOG_CXX_FLAGS)。

如果构建类型是 Release,则会将编译标志设置为 -O3(优化级别为最高)和 -DNDEBUG(禁用断言和调试信息)。
如果构建类型是 RelWithDebInfo,则会将编译标志设置为 -O3(优化级别为最高)、-g(生成调试信息)和 -DNDEBUG。
如果构建类型是 Debug,则会根据 FORCE_DEBUG_BUILD 变量的值进行判断。
如果 FORCE_DEBUG_BUILD 为真,则会给出警告信息,表示正在以调试模式构建,性能会非常低下,并将编译标志设置为 -g(生成调试信息)。
如果 FORCE_DEBUG_BUILD 为假,则会给出致命错误信息,建议将构建类型更改为 Release,因为在调试模式下编译可能导致严重的性能下降。
这段代码的目的是根据不同的构建类型为项目设置不同的编译标志,以优化和调整编译过程。它提供了不同构建类型下的编译选项,并根据需要给出警告或错误信息,以确保以最佳的方式构建项目。

    elseif(CMAKE_BUILD_TYPE STREQUAL "None")
      message(WARNING "Building with CMAKE_BUILD_TYPE None, "
          "please make sure you have set CFLAGS and CXXFLAGS according to your needs.")
    else()
      message(FATAL_ERROR "Unknown CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
    endif()

    message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

这段代码处理了构建类型为 None 的情况,并输出构建类型的信息。

如果构建类型是 None,则会给出警告信息,表示正在使用 None 构建类型,同时提醒用户确保根据自己的需求设置了 CFLAGS 和 CXXFLAGS 环境变量。这种情况下,编译选项可能没有被明确设置,需要用户自行配置。
如果构建类型不是上述提到的已知类型,那么会给出致命错误信息,指出未知的构建类型 ${CMAKE_BUILD_TYPE}。
这段代码的目的是处理构建类型的不同情况,如果构建类型不在预定义的类型范围内,则给出错误信息。同时,它也输出当前构建类型的信息,以便用户可以了解正在使用的构建类型。

    # Add a hook that reruns CMake when source files are added or removed.
    set(LIST_FILES_CMD "find ${PROJECT_SOURCE_DIR}/ -not -iwholename '*.git*' | sort | sed 's/^/#/'")
    set(FILES_LIST_PATH "${PROJECT_BINARY_DIR}/AllFiles.cmake")
    set(DETECT_CHANGES_CMD "bash" "-c" "${LIST_FILES_CMD} | diff -N -q ${FILES_LIST_PATH} - || ${LIST_FILES_CMD} > ${FILES_LIST_PATH}")
    add_custom_target(${PROJECT_NAME}_detect_changes ALL
      COMMAND ${DETECT_CHANGES_CMD}
      VERBATIM
    )
    if(NOT EXISTS ${FILES_LIST_PATH})
      execute_process(COMMAND ${DETECT_CHANGES_CMD})
    endif()
    include(${FILES_LIST_PATH})
  endif()
endmacro()

macro(google_enable_testing)
  enable_testing()
  find_package(GMock REQUIRED)
endmacro()

这段代码用于添加一个自定义目标(Custom Target),该目标可以在源文件添加或删除时重新运行 CMake。

具体实现如下:

LIST_FILES_CMD 变量定义了一个命令,用于列出项目源代码目录下(${PROJECT_SOURCE_DIR})除了 .git 目录之外的所有文件,并对结果进行排序,并在每行的开头添加 # 字符。
FILES_LIST_PATH 变量定义了一个文件路径,用于存储列出的文件列表。
DETECT_CHANGES_CMD 变量定义了一个命令,用于执行以下操作:
首先,通过 ${LIST_FILES_CMD} 命令获取当前源文件列表,并将结果与 ${FILES_LIST_PATH} 文件中的内容进行比较。
如果两者不同(即源文件发生了变化),则将新的文件列表存储到 ${FILES_LIST_PATH} 文件中。
add_custom_target 函数创建一个自定义目标,命名为 ${PROJECT_NAME}_detect_changes。
COMMAND 指定要执行的命令,即 ${DETECT_CHANGES_CMD}。
VERBATIM 参数用于确保命令参数中的转义字符得到正确处理。
通过添加这个自定义目标,当源文件发生变化时,即可运行 ${DETECT_CHANGES_CMD} 命令来更新 ${FILES_LIST_PATH} 文件。这样,可以在构建系统中使用 ${FILES_LIST_PATH} 文件的变化来触发重新运行 CMake,以确保项目的构建配置与源文件的变化保持同步。

首先,使用 NOT EXISTS 条件判断 ${FILES_LIST_PATH} 文件是否存在。
如果 ${FILES_LIST_PATH} 文件不存在,则执行 execute_process 命令,运行 ${DETECT_CHANGES_CMD},即重新生成文件列表并存储到 ${FILES_LIST_PATH} 文件中。
接下来,使用 include 命令加载 F I L E S L I S T P A T H 文件。这将导入文件列表中的所有文件作为 C M a k e 脚本的一部分,从而将源文件的变化反映在 C M a k e 构建过程中。通过这些步骤,可以确保在构建过程中, {FILES_LIST_PATH} 文件。这将导入文件列表中的所有文件作为 CMake 脚本的一部分,从而将源文件的变化反映在 CMake 构建过程中。 通过这些步骤,可以确保在构建过程中, FILESLISTPATH文件。这将导入文件列表中的所有文件作为CMake脚本的一部分,从而将源文件的变化反映在CMake构建过程中。通过这些步骤,可以确保在构建过程中,{FILES_LIST_PATH} 文件中列出的源文件列表是最新的,并能够及时应用于构建系统。

这段代码定义了一个名为 google_enable_testing 的宏,用于启用测试并查找 GMock 库。
enable_testing() 是 CMake 提供的命令,用于启用测试支持。它会自动创建一个名为 test 的构建目标,以及与测试相关的其他设置。
find_package(GMock REQUIRED) 用于查找 GMock 库,并将其引入到构建系统中。这要求在系统中安装了 GMock 库,并配置了正确的路径或环境变量,以便 CMake 可以找到库的位置。
通过调用 google_enable_testing 宏,可以启用测试支持,并确保 GMock 库已被正确地集成到项目中,以便进行单元测试等相关操作。

附录:
STREQUAL 是 CMake 中的一个字符串比较运算符,用于比较两个字符串是否相等。

在条件语句中,STREQUAL 可以用来检查两个字符串是否完全相等。如果两个字符串相等,条件表达式将返回 true,否则返回 false。

在给定的代码段中,CMAKE_BUILD_TYPE STREQUAL “” 表示检查变量 CMAKE_BUILD_TYPE 的值是否与空字符串相等。如果 CMAKE_BUILD_TYPE 的值是空字符串或未定义,那么条件表达式为真,进入条件语句的代码块。在这种情况下,通过 set(CMAKE_BUILD_TYPE Release) 将 CMAKE_BUILD_TYPE 设置为 Release,确保构建类型至少是 Release。这样可以避免构建类型未设置的问题,并为项目提供默认的构建类型。

简而言之,这段代码的作用是检查并设置默认的构建类型,如果构建类型未定义或为空,则将其设置为 Release。
Release 是 CMake 中的一个构建类型选项之一。构建类型用于指定在构建项目时所应用的编译和链接选项。
Release 构建类型通常用于生成最终发布版本的代码,它启用了优化和最小化的调试信息,以提高执行效率和减小可执行文件的大小。在 Release 模式下编译的代码通常用于正式发布给最终用户。
其他常见的构建类型包括 Debug(用于开发和调试,启用详细的调试信息和禁用优化)和 RelWithDebInfo(用于发布版本,同时包含调试信息以便进行故障排除)。
通过设置适当的构建类型,可以根据不同的需求优化构建过程,例如在开发和测试阶段进行快速编译和调试,或者在发布阶段进行优化和性能提升。

AppleClang 是苹果公司为 macOS 和 iOS 开发的一种编译器。它基于Clang,是Clang编译器的一个变种,经过了苹果的自定义和优化。AppleClang提供了与标准Clang相似的功能,同时还支持与苹果平台相关的扩展和特性。它是苹果开发工具链中的默认编译器,用于编译和构建 macOS 和 iOS 应用程序。

“将 FLAG 追加到现有值的末尾” 意味着将变量 VAR_NAME 的当前值与新的标志 FLAG 进行合并,使 FLAG 成为变量值的一部分,并放置在原始值的末尾。
具体而言,如果变量 VAR_NAME 的当前值是 “value1”,并且要添加的标志 FLAG 是 “value2”,那么将使用空格或其他分隔符将它们连接起来,形成一个新的值 “value1 value2”。新值中的空格或分隔符用于将原始值和新添加的标志分隔开。
这样做的目的是在不覆盖原始值的情况下,将新的标志添加到变量中,以便更灵活地构建变量的内容。例如,可以使用这种方法将多个编译选项或链接选项逐步添加到变量中,而不需要手动编写完整的选项字符串。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值