【如何写CMake】一个解决方案,多个工程

文章目录


一个解决方案,多个工程,即多个exe/dll/lib等

代码

多加几个ADD_EXECUTABLE即可

#1.cmake verson,指定cmake版本
cmake_minimum_required(VERSION 3.2)

#2.project name,指定项目的名称,一般和项目的文件夹名称对应
PROJECT(chapter2)

#3.head file path,头文件目录
INCLUDE_DIRECTORIES(
include
)

#4.source directory,源文件目录
AUX_SOURCE_DIRECTORY(src DIR_SRCS)

#5.set environment variable,设置环境变量,编译用到的源文件全部都要放到这里,否则编译能够通过,但是执行的时候会出现各种问题,比如"symbol lookup error xxxxx , undefined symbol"
SET(TEST_MATH
${DIR_SRCS}
2.01.nullptr.cpp
)

#6.add executable file,添加要编译的可执行文件
ADD_EXECUTABLE(nullptr 2.01.nullptr.cpp)
ADD_EXECUTABLE(constexpr 2.02.constexpr.cpp)

#7.add link library,添加可执行文件所需要的库,比如我们用到了libm.so(命名规则:lib+name+.so),就添加该库的名称
#TARGET_LINK_LIBRARIES(${PROJECT_NAME} m)

参考

[1]Cmake之CMakeLists.txt
[2]Cmake知识----编写CMakeLists.txt文件编译C/C++程序

<think>我们正在讨论的是在同一个解决方案(Solution)中,多个工程(Project)之间如何引用头文件的问题。根据引用[1]和引用[3],我们可以总结出以下步骤: ### 步骤1:设置工程依赖关系 - 在解决方案资源管理器中,右击需要引用其他工程工程(例如工程A),选择“属性”。 - 在“通用属性”->“引用”中,点击“添加新引用”,然后勾选需要引用的工程(例如工程B)。这样设置后,工程A就会依赖于工程B,编译时先编译工程B。 ### 步骤2:添加头文件包含路径 - 在工程A的属性页中,转到“配置属性”->“C/C++”->“常规”。 - 在“附加包含目录”中添加工程B的头文件所在目录。这样,工程A中的代码就可以通过`#include`指令包含工程B的头文件了。 ### 步骤3:设置被引用工程的输出类型(如果需要) 根据引用[1]和引用[3],如果工程B需要被工程A引用,那么工程B的输出类型需要设置为静态库(.lib)或动态链接库(.dll)。这是因为可执行文件(.exe)不能直接作为库被链接。 - 在工程B的属性页中,转到“配置属性”->“常规”。 - 将“配置类型”改为“静态库(.lib)”或“动态链接库(.dll)”。 ### 步骤4:在代码中引用头文件 在工程A的源文件中,使用`#include`包含工程B的头文件。注意,由于已经添加了附加包含目录,所以可以直接使用头文件的相对路径或绝对路径。例如: ```cpp #include "../ProjectB/header.h" ``` ### 步骤5:处理库链接(如果工程B生成了库) - 如果工程B生成了静态库(.lib)或动态链接库(.dll),那么工程A需要链接这个库。 - 方法1:在工程A的属性页中,转到“配置属性”->“链接器”->“输入”,在“附加依赖项”中添加工程B生成的库文件(例如ProjectB.lib)。 - 方法2:在工程A的源代码中使用`#pragma comment`指令(仅适用于MSVC): ```cpp #pragma comment(lib, "ProjectB.lib") ``` - 同时,在工程A的属性页中,转到“配置属性”->“链接器”->“常规”,在“附加库目录”中添加工程B生成的库文件所在的目录(通常是工程B的输出目录,如$(SolutionDir)Debug或$(SolutionDir)Release)。 ### 注意事项: 1. **跨平台兼容性**:`#pragma comment`是MSVC特有的,如果代码需要跨平台,建议使用在项目设置中添加库依赖的方式。 2. **路径设置**:在设置附加包含目录和附加库目录时,可以使用相对路径或宏(如$(SolutionDir))来保证路径的正确性。 3. **依赖顺序**:设置引用后,编译顺序会自动调整,先编译被引用的工程(如工程B),再编译引用方(工程A)。 4. **动态链接库**:如果工程B生成的是动态链接库(.dll),那么除了链接.lib文件(导入库)外,还需要确保运行时.dll文件在可执行文件的搜索路径中(例如,将.dll放在工程A的输出目录中)。 ### 示例场景: 假设解决方案中有两个工程: - `MathLibrary`:生成静态库(.lib),包含头文件`MathFunctions.h`和源文件`MathFunctions.cpp`。 - `MyApp`:可执行程序(.exe),需要使用`MathLibrary`中的函数。 **步骤:** 1. 将`MathLibrary`的配置类型设置为“静态库(.lib)”。 2. 在`MyApp`中添加对`MathLibrary`的引用(通过“添加引用”)。 3. 在`MyApp`的附加包含目录中添加`MathLibrary`的头文件路径(例如`$(SolutionDir)MathLibrary`)。 4. 在`MyApp`的源代码中包含头文件:`#include "MathFunctions.h"`。 5. 编译运行。 ### 相关问题: 1. 如何在同一个解决方案中实现动态链接库(DLL)的创建和使用? 2. 在跨平台开发中,如何处理不同工程之间的依赖关系? 3. 如何避免在包含头文件时出现路径错误? 4. 在多个工程共享头文件时,如何防止头文件重复包含? 以上步骤和注意事项应该能帮助你在同一个解决方案的不同工程之间成功引用头文件。</think>### 在 C++ 解决方案中跨工程引用头文件的完整指南 #### 核心步骤(以 Visual Studio 为例) 1. **设置被引用工程属性** ```cpp // 在工程B的头文件中声明导出符号 // MathUtils.h (工程B) #ifdef MATHUTILS_EXPORTS #define MATH_API __declspec(dllexport) #else #define MATH_API __declspec(dllimport) #endif MATH_API double calculateSquare(double x); ``` - 配置类型改为 **"动态库(.dll)"** 或 **"静态库(.lib)"** - 在属性页 → C/C++ → 预处理器 → 预处理器定义 添加 `MATHUTILS_EXPORTS`[^3] 2. **配置引用工程** - **添加工程引用**:右击工程A → 添加 → 引用 → 勾选工程B - **包含头文件路径**: ```cpp // 工程A属性 → C/C++ → 常规 → 附加包含目录 $(SolutionDir)ProjectB\Include // 添加工程B的头文件目录 ``` - **链接库配置**: ```cpp // 方法1:代码中直接声明(仅MSVC) #pragma comment(lib, "ProjectB.lib") // 方法2:工程属性配置 // 链接器 → 常规 → 附加库目录: $(SolutionDir)ProjectB\$(Configuration) // 链接器 → 输入 → 附加依赖项: ProjectB.lib ``` 3. **代码中使用** ```cpp // 工程A的源文件 #include "MathUtils.h" // 直接包含工程B的头文件 int main() { double result = calculateSquare(5.0); // 使用工程B的函数 std::cout << "Result: " << result; // 输出: 25.0 return 0; } ``` #### 关键配置图解 ```mermaid graph TD A[工程A - 可执行文件] -->|依赖| B[工程B - 库项目] B --> C[头文件目录\nProjectB/Include] B --> D[库文件输出\nProjectB/Debug/ProjectB.lib] A -->|附加包含目录| C A -->|附加库目录| D ``` #### 注意事项 1. **生成顺序问题** - 右击解决方案 → 项目依赖项 → 设置工程A依赖工程B - 确保编译顺序:先编译库工程(B),再编译主工程(A) 2. **路径使用宏变量** ```cpp // 推荐使用解决方案目录宏 $(SolutionDir)ProjectB/Include // 绝对路径替代 ``` 3. **跨平台兼容方案** ```cpp #ifdef _WIN32 # pragma comment(lib, "ProjectB.lib") #else # // Linux/Mac 使用编译参数: -lProjectB -L/path/to/lib #endif ``` 4. **头文件保护** ```cpp // ProjectB/Include/utils.h #ifndef PROJECTB_UTILS_H #define PROJECTB_UTILS_H // 头文件内容 #endif ``` #### 常见问题解决 - **LNK2019未解析符号错误**:检查`__declspec(dllexport)`声明和库路径 - **C1083无法打开头文件**:验证附加包含目录路径是否正确 - **运行时缺少DLL**:将工程B生成的.dll复制到工程A的输出目录 > 通过文件共享传递数据是次优方案[^2],推荐使用进程间通信(IPC)或内存映射文件等专业方法 --- ### 相关问题 1. 如何在不同解决方案的项目之间共享代码? 2. CMake 中如何配置工程的头文件依赖? 3. 动态库(DLL)和静态库(LIB)在工程引用中有何区别? 4. Linux 下如何实现类似`#pragma comment`的功能? 5. 如何设计跨平台的头文件导出宏? [^1]: 工程调用dll中的类 [^2]: C++ VS2010 一个解决方案多个项目间的数据调用 [^3]: 同一解决方案下项目调用动态链接库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值