跳转到内容
新建笔记

CMake 语言

(1)if

if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
find_program(CMAKE_CXX_COMPILER NAMES $ENV{CXX} g++)
endif()

(2)file

用法类型描述代码示例
GLOB查找与指定模式匹配的文件路径。file(GLOB FILES_PATTERN "*.c")
GLOB_RECURSE递归地查找与指定模式匹配的文件路径。file(GLOB_RECURSE FILES_PATTERN "src/*.cpp")
STRINGS读取文件的每一行到列表中。file(STRINGS "file.txt" FILE_CONTENT)
READ读取文件的全部内容到一个字符串变量。file(READ "file.txt" FILE_CONTENT)
WRITE将内容写入到文件中。file(WRITE "file.txt" "Some content.")
APPEND将内容追加到现有文件的末尾。file(APPEND "file.txt" "More content.")
TOUCH创建一个空文件或更新现有文件的时间戳。file(TOUCH "file.txt")
TOUCH_NOCREATE更新现有文件的时间戳,但不创建文件。file(TOUCH_NOCREATE "file.txt")
REMOVE删除文件或目录。file(REMOVE "file.txt")
REMOVE_RECURSE递归删除文件或目录。file(REMOVE_RECURSE "dir")
RENAME重命名文件或目录。file(RENAME "oldname.txt" "newname.txt")
MAKE_DIRECTORY创建一个目录。file(MAKE_DIRECTORY "dir")
RELATIVE_PATH获取相对于另一路径的相对路径。file(RELATIVE_PATH REL_PATH "dir1" "dir2")
TO_CMAKE_PATH转换路径为CMake可接受的路径格式。file(TO_CMAKE_PATH "path/to/file" CMAKE_PATH)
TO_NATIVE_PATH转换路径为系统原生路径格式。file(TO_NATIVE_PATH "path/to/file" NATIVE_PATH)
PATH_EXISTS检查文件或目录是否存在。file(PATH_EXISTS "path/to/file" EXISTS)
IS_DIRECTORY检查给定路径是否为目录。file(IS_DIRECTORY "dir" IS_DIR)
IS_SYMLINK检查给定路径是否为符号链接。file(IS_SYMLINK "symlink" IS_SYMLINK)
IS_ABSOLUTE_PATH检查给定路径是否为绝对路径。file(IS_ABSOLUTE_PATH "/path/to/dir" IS_ABSOLUTE)
GET_FILENAME_COMPONENT获取文件的特定组件,如目录、名称、扩展名。file(GET_FILENAME_COMPONENT NAME "[path/to/file]" NAME)

(3)获得package的全部变量名

get_cmake_property(OPENCV_VARIABLES VARIABLES)
foreach(VAR ${OPENCV_VARIABLES})
if(VAR MATCHES "OpenCV")
message(STATUS "OpenCV related variable: ${VAR}=${${VAR}}")
endif()
endforeach()

(4)从环境变量获取路径

$ENV{CUDA_TOOLKIT_ROOT_DIR}

(5)list用法

list(APPEND listname item1 [item2 [...]]) #将项添加到列表的末尾。
list(FIND listname item var) #在列表中查找项,如果找到,将其索引存储在变量中,如果未找到,将-1存储在变量中。
list(INSERT listname index item1 [item2 [...]]) #在列表的指定索引处插入项。
list(REMOVE_ITEM listname item1 [item2 [...]]) #从列表中删除项。
list(REMOVE_AT listname index1 [index2 [...]]) #从列表中删除指定索引的项。
list(GET listname index1 [index2 [...]] var) #获取列表中指定索引的项,并将其存储在变量中。
list(LENGTH listname var) #获取列表的长度,并将其存储在变量中。

(6)编译选型

cmake_minimum_required (VERSION 3.28)
target_compile_options(my_target PRIVATE -std=c++17 -O3)
set(CMAKE_C_COMPILER gcc) # 位置重要不然不成功
set(CMAKE_CXX_COMPILER g++)
# C的解决办法
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fexec-charset=GBK")
# C++ 的解决办法
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fexec-charset=GBK")
# 设置项目输出目录
set(PROJECT_OUTPUT_DIR ${PROJECT_BINARY_DIR}/${CMAKE_SYSTEM_PROCESSOR})
# 设置项目包含目录
set(PROJECT_INCLUDE_DIR ${PROJECT_OUTPUT_DIR}/include)
# 创建包含目录
file(MAKE_DIRECTORY ${PROJECT_INCLUDE_DIR})
# 创建bin目录用于存放可执行文件
file(MAKE_DIRECTORY ${PROJECT_OUTPUT_DIR}/bin)
# 设置可执行文件、库文件和归档文件的输出目录
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_OUTPUT_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_OUTPUT_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_OUTPUT_DIR}/archive)

# 定义目标路径为当前源代码目录
set(COMPILE_COMMANDS_OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
# 添加自定义命令和目标以复制 compile_commands.json 文件
add_custom_command(
OUTPUT "${COMPILE_COMMANDS_OUTPUT_DIR}/compile_commands.json"
# 如果目标文件与源文件不同,则复制文件
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_BINARY_DIR}/compile_commands.json"
"${COMPILE_COMMANDS_OUTPUT_DIR}/compile_commands.json"
# 定义依赖关系,确保在执行该命令前生成源文件
DEPENDS "${CMAKE_BINARY_DIR}/compile_commands.json"
COMMENT "Copying compile_commands.json to output directory"
)
# 定义一个名为 copy_compile_commands 的自定义目标
# 该目标在所有构建(ALL)时都会被执行,并依赖于上述自定义命令生成的文件
add_custom_target(copy_compile_commands ALL DEPENDS "${COMPILE_COMMANDS_OUTPUT_DIR}/compile_commands.json")

注释和解释

  1. 定义目标路径:

    set(COMPILE_COMMANDS_OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}")

    这行代码将 COMPILE_COMMANDS_OUTPUT_DIR 变量设置为当前源代码目录的路径,即 CMakeLists.txt 文件所在的目录。

  2. 添加自定义命令:

    add_custom_command(
    OUTPUT "${COMPILE_COMMANDS_OUTPUT_DIR}/compile_commands.json"
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
    "${CMAKE_BINARY_DIR}/compile_commands.json"
    "${COMPILE_COMMANDS_OUTPUT_DIR}/compile_commands.json"
    DEPENDS "${CMAKE_BINARY_DIR}/compile_commands.json"
    COMMENT "Copying compile_commands.json to output directory"
    )
    • add_custom_command 添加了一个自定义命令,用于将 compile_commands.json 文件从构建目录 (${CMAKE_BINARY_DIR}) 复制到源代码目录 (${COMPILE_COMMANDS_OUTPUT_DIR})。
    • COMMAND ${CMAKE_COMMAND} -E copy_if_different 指定了实际执行的命令:如果目标文件与源文件不同,则进行复制。
    • DEPENDS "${CMAKE_BINARY_DIR}/compile_commands.json" 指定了该命令的依赖文件,即 compile_commands.json 文件必须存在。
    • COMMENT 提供了一个注释,在执行命令时会显示这段文本。
  3. 添加自定义目标:

    add_custom_target(copy_compile_commands ALL DEPENDS "${COMPILE_COMMANDS_OUTPUT_DIR}/compile_commands.json")
    • add_custom_target 定义了一个名为 copy_compile_commands 的自定义目标。
    • ALL 表示该目标在每次构建时都会被执行。
    • DEPENDS 指定了该目标依赖的文件,即自定义命令生成的 compile_commands.json 文件。

实现过程

  1. 定义路径: 首先定义了目标路径 COMPILE_COMMANDS_OUTPUT_DIR。
  2. 添加自定义命令: 通过 add_custom_command 添加了一个自定义命令,用于将 compile_commands.json 文件从构建目录复制到源代码目录。
  3. 添加自定义目标: 通过 add_custom_target 添加了一个自定义目标,该目标在每次构建时都会执行,并依赖于自定义命令生成的文件。