在实际开发中,项目往往具有复杂的结构,包含多个子目录和源文件,这时候就需要进行 CMake 的多层级文件编译。下面详细介绍实现步骤及示例。
1. 项目结构规划
假设我们有一个简单的项目结构如下:
project_root/
├── CMakeLists.txt # 根目录的 CMakeLists.txt 文件
├── src/
│ ├── CMakeLists.txt # src 目录的 CMakeLists.txt 文件
│ ├── main.cpp # 主源文件
│ └── utils/
│ ├── CMakeLists.txt # utils 目录的 CMakeLists.txt 文件
│ ├── utils.cpp # 工具函数源文件
│ └── utils.h # 工具函数头文件
2. 编写各级 CMakeLists.txt 文件
根目录 project_root/CMakeLists.txt
此文件负责设置项目的基本信息,并包含子目录的 CMakeLists.txt
文件。
# 设置 CMake 最低版本要求
cmake_minimum_required(VERSION 3.10)
# 设置项目名称
project(MyProject)
# 添加子目录
add_subdirectory(src)
src/CMakeLists.txt
该文件负责处理 src
目录下的源文件,链接子目录生成的库,并生成可执行文件。
# 添加 utils 子目录
add_subdirectory(utils)
# 添加可执行文件
add_executable(MyExecutable main.cpp)
# 链接 utils 库
target_link_libraries(MyExecutable PRIVATE UtilsLibrary)
src/utils/CMakeLists.txt
此文件用于生成 utils
目录下的源文件对应的库。
# 添加库
add_library(UtilsLibrary utils.cpp)
# 为库添加包含目录
target_include_directories(UtilsLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
3. 编写源文件
src/main.cpp
#include <iostream>
#include "utils.h"
int main() {
// 调用 utils 中的函数
printMessage();
return 0;
}
src/utils/utils.h
#ifndef UTILS_H
#define UTILS_H
#include <iostream>
// 声明函数
void printMessage();
#endif // UTILS_H
src/utils/utils.cpp
#include "utils.h"
// 定义函数
void printMessage() {
std::cout << "Hello from utils!" << std::endl;
}
4. 编译项目
按照以下步骤进行编译:
- 在项目根目录下创建一个
build
目录,用于存放编译生成的文件。
mkdir build
cd build
- 运行 CMake 生成 Makefile。
cmake ..
- 使用
make
命令进行编译。
make
5. 运行可执行文件
编译完成后,在 build
目录下会生成可执行文件 MyExecutable
,运行该文件:
./MyExecutable
总结
通过上述步骤,你可以实现 CMake 的多层级文件编译。核心要点是合理规划项目结构,编写各级 CMakeLists.txt
文件,使用 add_subdirectory
包含子目录,使用 add_library
生成库,使用 add_executable
生成可执行文件,并使用 target_link_libraries
链接库。