Need help setting up a basic multi-platform project with cmake support

tl; dr questions are below.

I am a developer trying something new - my last poison is C ++. Since I spend half my time on my Linux laptop and the other half on a Windows XP PC, I tried to find a way to create a basic, barebone project using good C ++ practices (well, I don’t know them from experience, I just read about them). Right now my project almost works when using cmake . && make cmake . && make on Linux (it works when the header and source files are in the same folder, it fails when I separate them to include / src folders). I use muw nuwen distribution on windows (and I know that the toolchain works, it compiles projects from Eclipse without any problems).

My project directory is as follows:

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

The contents of the files are very simple (I can remove include security elements, etc.).

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) - main:

 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) - inside the include directory

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

CMakeLists.txt (3) - inside the src directory

 include_directories (../include) 

And this is until I got it - with some changes (for example, moving App.cc to the include directory) the whole thing compiles and works fine on Linux, but I can not get the mingw generator to work in Win XP, I manually set CMAKE_MAKE_PROGRAM to CMakeCache.txt file to point to the correct make.exe (I know that this should be defined as a system variable, but since I work on many different computers, I do not want to leave garbage after me).

My questions:

1) what are the guidelines for writing a multi-platform CMakeLists.txt file (which will work regardless of os and the location of the project files), which will preferably allow me to easily reconfigure my project from one another

2) how can I fix the error without finding the header file (make gives: (...) \ engine \ main \ src \ main.cc: 2: 17: fatal error: App.h: there is no such file or directory)?

Thanks for your time and help.

+4
source share
2 answers

1) what are the guidelines for writing a multi-platform CMakeLists.txt file (which will work regardless of os and the location of the project files), which will preferably allow me to easily reconfigure my project from one another

Well, I'm certainly not an expert, but I can share my 10-month experience with a cross-platform cmake-based project.

From the very beginning, I think that you really should use from source builds . This means that you are not running cmake in the same directory where your code is located; instead, you create a new folder, for example. engine/build and release cmake ../main . This way you are not dropping the source files with cmake materials like CMakeCache.txt etc. There are even some macros that you can use to prevent your users from assembling in the source.

It’s also useful for me to create a set of macro files to help set compiler options for different platforms. Here we have macros, such as ADD_GCC_FLAG or ADD_MSVC_FLAG , which check the current compiler and add flags accordingly.

I find it good practice to have one .cmake file that concentrates all your project configurations in one place. At work, all of our CMakeLists.txt starts with include( ../cmake/configs.cmake ) . Various parameters are set in this file, such as standard include directories, default compiler flags, etc.

To fix the problem with the included directories, I suggest that you use absolute rather than relative paths in your source files. Define a standard include directory, for example engine/main/include and always #include files relative to this path. In your example, if you want to include engine/main/include/somefolder/header.h , you should write #include <somefolder/header.h> (using <> instead of quotes so that the C ++ preprocessor skips the current directory when searching for a file )


2) how can I fix the error without finding the header file (make gives: (...) \ engine \ main \ src \ main.cc: 2: 17: fatal error: App.h: there is no such file or directory)?

There are several problems with your cmake layout, but the reason you got this error is because you need to call include_directories in CMakeLists.txt (1) .

In addition, your other CMakeLists.txt files also have problems. In CMakeLists.txt (2) add_library arguments are incorrect; it should be ../src/App.cc , otherwise you just add an empty library. And you do not need this set_target_properties either, at least if you got the add_library arguments. You also need an include_directory call in the same CMakeLists.txt that adds the library; putting it in (3) does nothing.

In fact, you do not need the CMakeLists.txt file in the include directory, since there is nothing to build there. It is better to place the add_library call in CMakeLists.txt (3) , immediately after the call to include_directories .

Hope this resolves some of your doubts.

+6
source

This is probably not the answer you are expecting, but since you have not indicated whether you want alternative solutions, I still suggest:

For multi-platform projects, I would recommend SConstruct , which is a really great and flexible tool. I do not know CMake very well, so I can give a detailed comparison.

However, this is why I love this tool:

  • This is Python. That way you can do almost anything you want with regard to customization and / or special needs.
  • This is very easy to learn, and simple projects require only a few lines of code.
  • It depends entirely on Python, so it is often already installed on Linux, and on Windows it takes 5 minutes to download and install.
  • It has very good automatic dependency tree creation and parallel compilation support.
0
source

All Articles