设置基本的多平台cmake启用项目时需要帮助

时间:2010-11-03 07:19:19

标签: c++ header makefile cmake project-structure

tl; dr问题在底部。

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

我的项目目录如下所示:

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

    |- CMakLists.txt (1)

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

App.h:

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

App.cc:

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

App::App() {
}

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

main.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) - 在include目录中

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

CMakeLists.txt(3) - 在src目录中

include_directories (../include)

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

我的问题是:

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

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

感谢您的时间和帮助。

2 个答案:

答案 0 :(得分:6)

  

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

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

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

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

我认为最好有一个.cmake文件,将所有项目配置集中在一个地方。在工作中,我们所有CMakeLists.txt都以include( ../cmake/configs.cmake )开头。此文件设置各种选项,例如标准包含目录,默认编译器标志等。

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


  

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

您的cmake布局存在许多问题,但您收到该错误的原因是因为您还需要在include_directories中调用CMakeLists.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

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

答案 1 :(得分:0)

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

对于多平台项目,我建议SConstruct这是一个非常灵活的工具。我不太清楚CMake,所以我可以提供详细的比较。

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

  • 这是Python。因此,您几乎可以做任何有关定制和/或特殊需求的事情
  • 这很容易学习,对于简单的项目,只需几行代码即可开始。
  • 它完全取决于Python,所以在Linux上经常安装,在Windows上下载和安装需要5分钟。
  • 它具有非常好的自动依赖关系树生成和并行编译支持。