Требуется помощь при настройке базового мультиплатформенного проекта с поддержкой cmake - PullRequest
4 голосов
/ 03 ноября 2010

tl; dr вопросы внизу.

Я разработчик, пытающийся что-то новое - мой последний яд - c ++.Поскольку я трачу половину своего времени на свой ноутбук с Linux и другую половину на ПК с Win XP, я попытался найти способ создания базового проекта barebone, используя хорошие практики c ++ (ну, я не знаю их по опыту,Я просто прочитал о них).Прямо сейчас мой проект почти работает при использовании cmake . && make в linux (он работает, когда заголовочные и исходные файлы находятся в одной папке, происходит сбой, когда я разделяю их для включения папок / src).Я использую ньювенский дистрибутив mingw для Windows (и я знаю, что инструментарий работает, он без проблем компилирует проекты из 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.Я вручную настроил CMAKE_MAKE_PROGRAM в файле CMakeCache.txt, чтобы он указывал на правильный make.exe (я знаю, что это должно быть определено как системная переменная, но так как я работаю на многих разных компьютерах, я не хочу оставлять ненужную информацию послемне).

Мои вопросы:

1) каковы рекомендации по написанию мультиплатформенного файла CMakeLists.txt (который будет работать независимо от операционной системы и расположения файлов проекта), что предпочтительно позволитмне легко сменить конфигурацию моего проекта с одного компьютера на другой?

2) как мне исправить ошибку, связанную с отсутствием файла заголовка (make дает: (...) \ engine \ main \ src \main.cc:2:17: фатальная ошибка: App.h: нет такого файла или каталога)?

Спасибо за ваше время и помощь.

Ответы [ 2 ]

6 голосов
/ 03 ноября 2010

1) каковы рекомендации по написанию мультиплатформенного файла CMakeLists.txt (который будет работать независимо от операционной системы и расположения файлов проекта), что предпочтительно позволит мне легко переключить конфигурацию моего проекта из одной операционной системыдругой?

Ну, я, конечно, не эксперт, но я могу поделиться своим 10-месячным опытом с кроссплатформенным проектом на основе cmake.

Сразуbat Я думаю, вам действительно следует использовать из исходных сборок .Это означает, что вы не запускаете cmake в той же директории, где находится ваш код;вместо этого вы создаете новую папку, например, engine/build и запускаете cmake ../main оттуда.Таким образом, вы не забиваете свои исходные файлы с помощью cmake, например, CMakeCache.txt и т. Д. Есть даже некоторые макросы, которые вы можете использовать, чтобы запретить пользователям делать сборки в исходном коде.

Я также нахожуполезно для создания набора макрофайлов, чтобы помочь установить параметры компилятора для разных платформ.Здесь, на работе, у нас есть макросы, такие как ADD_GCC_FLAG или ADD_MSVC_FLAG, которые проверяют текущий компилятор и соответственно добавляют флаги.

Я думаю, что хорошей практикой будет иметь один файл .cmake, который концентрирует весь ваш проект.Конфигурации в одном месте.На работе все наши CMakeLists.txt начинаются с include( ../cmake/configs.cmake ).В этом файле задаются всевозможные параметры, такие как стандартные каталоги включения, флаги компилятора по умолчанию и т. Д.

Чтобы решить вашу проблему с каталогами включения, я предлагаю вам использовать абсолютные, а не относительные пути в исходных файлах.Определите стандартный каталог include, например, 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_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.

Надеюсь, это рассеет некоторые ваши сомнения.

0 голосов
/ 03 ноября 2010

Вероятно, это не тот ответ, который вы ожидаете, но, поскольку вы не указали, хотите ли вы альтернативные решения, я все равно предложу:

Для мультиплатформенных проектов я бы порекомендовал SConstruct, который действительно отличный и гибкий инструмент. Я не очень хорошо знаю CMake, поэтому могу дать подробное сравнение.

Однако вот почему я люблю этот инструмент:

  • Это Питон. Таким образом, вы можете сделать практически все, что захотите, в отношении настройки и / или особых потребностей
  • Это действительно легко изучить, а для простых проектов требуется всего несколько строк кода, чтобы начать работу.
  • Это зависит исключительно от Python, поэтому в Linux он очень часто уже установлен, а в Windows загрузка и установка занимает 5 минут.
  • Имеет очень хорошую автоматическую генерацию дерева зависимостей и поддержку параллельной компиляции.
...