5

tl;博士问题在底部。

我是一名尝试新事物的开发人员——我最后的毒药是 C++。由于我一半时间花在我的 linux 笔记本电脑上,另一半时间花在 Win XP PC 上,我试图找到一种方法来创建基本的准系统项目,使用良好的 c++ 实践(嗯,我不从经验中了解它们,我刚读到他们)。现在我的项目cmake . && make在 linux 上使用时几乎可以工作(当头文件和源文件在同一个文件夹中时它可以工作,当我将它们分开到 include / src 文件夹时会失败)。我在 Windows 上使用 nuwen 的 mingw 发行版(而且我知道工具链正在工作,它从 Eclipse 中编译项目没有任何问题)。

我的项目目录如下所示:

engine 
    |
    |- main
         |
         |- include
                 |
                 |- App.h  
                 |- CMakeLists.txt (2)
         |- src
             |
             |- main.cc
             |- App.cc
             |- CMakeLists.txt (3)

    |- CMakLists.txt (1)

文件的内容非常简单(为了清楚起见,我将删除包含保护等)

应用程序.h:

class App {
   public:
      App();
      int onExecute();
};

应用程序.cc:

#include <iostream>
#include "App.h"

App::App() {
}

int App::onExecute() {
   std::cout << "inside app.." << '\n';
   return 0;
}

主.cc:

#include <iostream>
#include "App.h"

using namespace std;

int main(int argc, char* argv[]) {
  App a;

  a.onExecute();
  std::cout << "inside main.." << '\n';
}

CMakeLists.txt (1) - 主要的:

cmake_minimum_required (VERSION 2.6)
set (CMAKE_CXX_COMPILER "g++")

project (gameengine)

add_definitions ( "-Wall -ansi -pedantic")

add_subdirectory (${CMAKE_SOURCE_DIR}/main/include)
add_subdirectory (${CMAKE_SOURCE_DIR}/main/src)

add_executable (engine ${CMAKE_SOURCE_DIR}/main/src/main.cc)
target_link_libraries (engine Application)

CMakeLists.txt (2) - 在包含目录中

add_library (Application App)
set_target_properties (Application PROPERTIES LINKER_LANGUAGE CXX)

CMakeLists.txt (3) - src 目录内

include_directories (../include)

这就是我所得到的 - 通过一些更改(即将 App.cc 移动到包含目录),整个东西在 linux 上编译并运行良好 - 但我无法让 mingw 生成器在 Win XP 上工作。我手动调整文件 CMakeCache.txt 中的 CMAKE_MAKE_PROGRAM 以指向正确的 make.exe(我知道这应该定义为系统变量,但由于我在许多不同的 PC 上工作,我不想在之后留下垃圾我)。

我的问题是:

1) 编写多平台 CMakeLists.txt 文件的准则是什么(它将独立于操作系统和项目文件的位置工作),这最好能让我轻松地从一个操作系统切换我的项目配置?

2)如何解决找不到头文件的错误(make给出:(...)\engine\main\src\main.cc:2:17:致命错误:App.h:没有这样的文件或目录) ?

感谢您的时间和帮助。

4

2 回答 2

7

1) 编写多平台 CMakeLists.txt 文件的准则是什么(它将独立于操作系统和项目文件的位置工作),这最好能让我轻松地从一个操作系统切换我的项目配置?

好吧,我当然不是专家,但我可以分享我 10 个月的跨平台基于 cmake 项目的经验。

马上我认为你真的应该使用out of source builds。这意味着您不会在代码所在的同一目录中运行 cmake;相反,您创建一个新文件夹,例如engine/buildcmake ../main从那里运行。这样你就不会用 cmake 的东西破坏你的源文件,比如 CMakeCache.txt 等。甚至有一些宏可以用来禁止你的用户进行源内构建。

我还发现创建一组宏文件以帮助为不同平台设置编译器选项很有用。在工作中,我们有诸如ADD_GCC_FLAGor之类的宏,ADD_MSVC_FLAG它们检查当前编译器并相应地添加标志。

我认为拥有一个.cmake将所有项目配置集中在一个位置的文件是一种很好的做法。在工作中我们都CMakeLists.txtinclude( ../cmake/configs.cmake ). 此文件设置各种选项,例如标准包含目录、默认编译器标志等。

为了缓解包含目录的问题,我建议您在源文件中使用绝对路径而不是相对路径。例如,定义一个标准的包含目录,engine/main/include并且总是#include相对于该路径的文件。在您的示例中,如果您想包含engine/main/include/somefolder/header.h,您将编写#include <somefolder/header.h>(使用<>而不是引号告诉 C++ 预处理器在查找文件时跳过当前目录)。


2)如何解决找不到头文件的错误(make给出:(...)\engine\main\src\main.cc:2:17:致命错误:App.h:没有这样的文件或目录) ?

您的 cmake 布局存在许多问题,但您收到该错误的原因是您也需要调用include_directoriesCMakeLists.txt (1)

除此之外,您的其他CMakeLists.txt文件也有问题。在CMakeLists.txt (2)中, 的论点add_library是错误的;它应该是../src/App.cc,否则你只是添加一个空库。而且您也不需要,set_target_properties至少如果您的add_library论点正确,则不需要。您还需要在添加库的include_directory同一调用中调用;CMakeLists.txt把它放进去(3)并没有真正做任何事情。

实际上,您不需要目录CMakeLists.txt中的include文件,因为那里没有什么可以构建的。最好在add_library打电话CMakeLists.txt (3)之后立即拨打电话include_directories

我希望这能消除你的一些疑虑。

于 2010-11-03T11:45:19.990 回答
0

这可能不是您期望的答案,但由于您没有说明您是否想要替代解决方案,我还是会建议:

对于多平台项目,我会推荐SConstruct这确实是一个伟大而灵活的工具。我不太了解 CMake,所以我真的可以提供详细的比较。

但是,以下是我喜欢这个工具的原因:

  • 是蟒蛇。因此,您几乎可以针对定制和/或特殊需求做任何您想做的事情
  • 它真的很容易学习,对于简单的项目,只需要几行代码就可以开始。
  • 它完全依赖于 Python,因此在 Linux 上它通常已经安装,而在 Windows 上下载和安装需要 5 分钟。
  • 它具有非常好的自动依赖树生成和并行编译支持。
于 2010-11-03T08:16:19.703 回答