add_subdirectory是 CMake 中的一个命令,用于向当前项目添加一个子目录。它的语法如下:
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
其中:
source_dir
是要添加的子目录的路径。binary_dir
是可选的二进制目录路径,用于指定子目录的构建输出目录。如果未指定,将使用默认的构建输出目录。EXCLUDE_FROM_ALL
是可选的参数,用于指定是否将子目录排除在构建过程之外。如果指定了该参数,子目录将不会在构建时被构建。使用 add_subdirectory
命令后,CMake 会在指定的 source_dir
中查找 CMakeLists.txt 文件,并执行该文件中的命令。这样,您可以将子目录作为独立的项目进行构建,并与主项目进行协作。
通常,在子目录的 CMakeLists.txt 文件中,您可以定义和配置子目录的构建过程、生成库或可执行文件,并使用 target_link_libraries
命令将子目录的目标与主项目的目标进行链接。
假设您的项目结构如下:
project/
├── CMakeLists.txt
├── main.cpp
└── subdirectory/
├── CMakeLists.txt
├── lib/
│ ├── CMakeLists.txt
│ ├── lib.cpp
│ └── lib.h
└── tests/
├── CMakeLists.txt
└── test.cpp
在主项目的 CMakeLists.txt 文件中,您可以使用 add_subdirectory
命令将子目录添加到主项目中:
cmake_minimum_required(VERSION 3.12)
project(MyProject)
# 主项目的构建配置
# 添加子目录
add_subdirectory(subdirectory)
# 主项目的目标和链接等配置
在子目录的 CMakeLists.txt 文件中,您可以定义子目录的构建过程和目标:
# 子目录的 CMakeLists.txt
# 子目录的构建配置
# 生成库或可执行文件
add_library(mylib lib/lib.cpp lib/lib.h)
# 子目录的目标和链接等配置
通过 add_subdirectory
命令,子目录中的 CMakeLists.txt 文件将被执行,子目录的构建过程和目标将与主项目一起构建和链接。
请注意,add_subdirectory
命令应该在主项目的 CMakeLists.txt 文件中使用,并且应该在主项目的目标和链接配置之前。这样可以确保子目录的目标在主项目的构建过程中可用。
可以通过在
add_subdirectory
命令中提供可选的binary_dir
参数来指定子目录的二进制目录。这样可以将子目录的构建输出与主项目的构建输出分开,使项目结构更清晰。例如:
add_subdirectory(subdirectory bin)
这将在主项目的构建目录下创建一个名为 bin
的子目录,用于存放子目录的构建输出。
如果您希望在构建主项目时排除某个子目录,可以使用
EXCLUDE_FROM_ALL
参数。这在某些情况下很有用,比如只构建主项目的特定部分或避免构建测试目录。例如:
add_subdirectory(tests EXCLUDE_FROM_ALL)
这将排除名为 tests
的子目录,使其不会在构建主项目时被构建。
在主项目中,您可以为子目录的目标创建一个别名,以便在主项目中更方便地引用子目录的目标。这在链接库或设置依赖关系时很有用。例如:
add_subdirectory(subdirectory)
add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE subdirectory::mylib)
这里,subdirectory::mylib
是对子目录中名为 mylib
的目标的别名,可以直接在主项目中使用。
使用
add_subdirectory
命令可以将变量传递给子目录的 CMakeLists.txt 文件。您可以在主项目的 CMakeLists.txt 文件中定义变量,并在子目录的 CMakeLists.txt 文件中使用。例如:
set(MY_VARIABLE "Hello, World!")
add_subdirectory(subdirectory)
在子目录的 CMakeLists.txt 文件中,可以访问和使用 MY_VARIABLE
变量。
在使用
add_subdirectory
命令之前,可以使用if(EXISTS ...)
检查子目录是否存在。这可以避免在子目录不存在时引发错误。例如:
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/subdirectory")
add_subdirectory(subdirectory)
else()
message(FATAL_ERROR "Subdirectory 'subdirectory' does not exist.")
endif()
这将在子目录存在时添加子目录,否则会发出错误消息并停止构建。