用于lib和可执行文件的c++ CMake项目结构

标签 c++ cmake build clion directory-structure

关闭。这个问题需要更多 focused .它目前不接受答案。












想改进这个问题?更新问题,使其仅关注一个问题 editing this post .

1年前关闭。




Improve this question




我有一个关于如何构建 c++ 项目并使用 CMake(在 CLion 内部)构建它的问题。我对 c++(我两周前才开始学习该语言)和 CMake(我从未配置过 CMake 文件)非常陌生。不过,我确实对其他编程语言及其生态系统(如 Java、JavaScript、Php 和 .NET)有大量经验——也许与这些生态系统进行类比会有所帮助?
我们正在为学校项目构建自己的(小型 2d)游戏和游戏引擎。游戏引擎应该可以自己交付,游戏应该建立在我们自己的引擎上。引擎将有自己的依赖项(使用 SDL2 构建,这是一个要求)。
我想引擎将成为一个(静态)库,而实际游戏将编译为依赖于引擎库的可执行文件。
为了简化项目管理,我们希望将引擎和游戏代码托管在同一个 git 存储库中。
鉴于我们可能想要放置 math模块进入我们的引擎(可能不是这种情况,但出于这个问题的目的)我想象一个文件夹结构如下:

our-project/
├── README.md
├── engine
│   ├── src
│   │   ├── math.cpp
│   │   └── math.h
│   └── test
│       └── ...
└── game
    ├── src
    │   └── main.cpp
    └── test
        └── ...
然后引擎将包含以下代码:
// in math.h
namespace engine::math {
    int add(int a, int b);
}

// in math.cpp
#include "math.h"

namespace engine::math {
    int add(int a, int b) {
        return a + b;
    }
}
假设我们想从我们的游戏中使用这个引擎代码,我想象下面的代码:
// in game/main.cpp
#include <iostream>
#include "engine/math.h"

using namespace engine;

int main() {
    std::cout << math::add(10, 1) << std::endl;
}
问题
  • 如何设置 CMake 以便我既可以单独构建引擎(静态库),又可以构建依赖于同一引擎的游戏(可执行文件)?
  • 我应该如何管理引擎头文件?如何使它们可以访问游戏代码?我应该为头文件使用不同的结构吗?
  • 这个文件夹结构是否易于管理?我应该考虑不同的方法吗?
  • 最佳答案

  • 您声明单独的 CMake 目标,即在 engine/src/CMakeLists.txt :
    add_library(engine
        math.cpp)
    
    而在 game/src/CMakeLists.txt , 你有
    add_executable(my-game
       main.cpp)
    
    target_link_libraries(my-game
        PRIVATE
        engine)
    
    当使用例如make ,您可以通过以下方式单独构建目标
    make engine # build only the engine, not the executable
    make my-game # build engine if necessary, then build executable
    
    单独的测试目标也很有意义。
  • CMake 中的包含标志按如下方式传播。
    target_include_directories(engine
       INTERFACE
       ${CMAKE_CURRENT_SOURCE_DIR})
    
    上述设置将包含目录传播到链接到引擎的所有目标。这很简单,但有一个缺点:您无法区分公共(public) header 和实现细节。作为替代方案,您可以有一个目录 engine/src/public/engine包含游戏应使用的所有公共(public) header :
    target_include_directories(engine
       INTERFACE
       ${CMAKE_CURRENT_SOURCE_DIR}/public)
    
    target_include_directories(engine
       PRIVATE
       ${CMAKE_CURRENT_SOURCE_DIR}/public/engine)
    
    这样,game 中的客户端代码使用 #include "engine/math.h" , 而在 engine ,您可以选择 #include "math.h" .我喜欢这样的设置,因为它很容易看出什么是库的接口(interface)以及它的实现是什么。但这也是一个品味问题。
  • 又自以为是。但我认为这是一个很好的目录结构。坚持下去。
  • 关于用于lib和可执行文件的c++ CMake项目结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63916507/

    相关文章:

    c++ - std::unordered_map<Foo, Bar> 测试特定的 Foo 键是否存在

    C++ 双下标重载 : cannot convert from 'type' to 'type &'

    c++ - CMake:将库链接到 KDE4 库时 undefined reference

    php - 尝试为 Windows 编译 phpredis

    c++ - 非立方区域的 Morton 曲线是 2 的幂

    c++ - 来自 Python 的 SWIG C++ 类型的数组分配

    cmake - 无论任何依赖项如何在构建时始终运行命令?

    include - 在 cmake 命令行上指定包含目录

    xcode - 如何在 xcode 持续集成中自动删除旧构建的文件?

    c# - 构建软件补丁的好习惯是什么?