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:没有这样的文件或目录)?
感谢您的时间和帮助。
答案 0 :(得分:6)
1)编写多平台CMakeLists.txt文件的指导原则(它将独立于os和项目文件的位置工作),这最好能让我轻松地从一个操作系统配置另一个操作系统?
嗯,我当然不是专家,但我可以与基于cmake的跨平台项目分享我10个月的经验。
马上我认为你真的应该使用源代码构建。这意味着您不要在代码所在的同一目录中运行cmake;相反,你创建一个新的文件夹,例如engine/build
并从那里运行cmake ../main
。这样你就不会使用cmake的东西破坏你的源文件,例如CMakeCache.txt等。甚至有一些宏可以用来禁止你的用户进行源内构建。
我还发现创建一组宏文件以帮助为不同平台设置编译器选项很有用。在工作中我们有ADD_GCC_FLAG
或ADD_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,所以我可以提供详细的比较。
但是,以下是我喜欢这个工具的原因: