Правильный способ структурировать мой c ++ проект с помощью cmake? - PullRequest
9 голосов
/ 14 декабря 2011

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

Я создал библиотеку, состоящую из нескольких файлов,следующим образом:

-libfolder
  -codepart1folder
    -CMakeLists.txt
    -codepart1.cpp
    -codepart1.hpp
  -codepart2folder
  -codepart3folder
  -lib.cpp
  -lib.hpp
  -CMakeLists.txt

Я написал файл CMakeLists для компиляции библиотеки (после некоторых экспериментов), и я могу сгенерировать файл lib.a.Теперь я хотел бы включить этот код в виде библиотеки в другие проекты и получить к нему доступ через интерфейс в lib.hpp.Каков наилучший способ сделать это, с точки зрения структуры каталогов, и что мне нужно поместить в CMakeLists.txt в моем корневом проекте?

В настоящее время я пытался добавить -libfolder в качестве подпапки к моейтекущий проект и добавьте команды:

include_directories(${PROJECT_SOURCE_DIR}/libfolder)
link_directories(${PROJECT_BINARY_DIR}/libfolder)
add_subdirectory(libfolder)
target_link_libraries(project lib)

Когда я запускаю make, библиотека компилируется нормально, но когда компилируется project.cpp, она жалуется, что не может найти codepart1.hpp (который включен в lib.hpp, включен из project.cpp).

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

Ответы [ 4 ]

5 голосов
/ 14 декабря 2011

Простой способ импортировать один проект CMake в другой с помощью команды find_package .Объявление пакета выполняется с помощью команды export .Преимущество использования find_package состоит в том, что он устраняет необходимость в жестком кодировании путей к файлам пакета.

Что касается отсутствующего hpp-файла, вы не включили codepart1folder, поэтому он не находится на пути включения.

2 голосов
/ 14 декабря 2011

Хорошо, поэтому после консультации с моим коллегой, который является гуру CMake, кажется, что CMake не поддерживает то, что я пытаюсь сделать, оставив один с 3 вариантами:

  1. Добавьте все зависимости в родительские проекты CMakeLists.txt - не очень чистый, но он заставит работать.Вам придется делать это для каждого проекта, в который вы добавляете код, и возвращаться и исправлять ошибки, если ваша библиотека изменится.

  2. очистите заголовки вашей библиотеки.Это делается с помощью некоторых хакерских программ.Идея состоит в том, чтобы заранее объявить каждый класс и использовать только указатели или boost :: shared_ptr, а затем включить зависимости только в файл cpp.Таким образом, вы можете создать файл cpp, используя весь материал findpackage, и вы получите возможность использовать библиотеку, включив только заголовок и ссылку на библиотеку.

  3. Lookв сборку систем.Наличие переносимого кода и быстрой компиляции кода со сложными зависимостями - не решенная проблема!Из моих расследований оказалось довольно сложно.В итоге я принял систему сборки моего коллеги, которую он сам создал в cmake, используя вещи, которые он взял из Google.

1 голос
/ 14 декабря 2011

Глядя на свое сообщение, вы, кажется, нигде не добавляете 'codepart1folder' во включаемые элементы.Как вы включаете codepart1.hpp как:

#include <codepart1.hpp>
#include "codepart1folder/codepart1.hpp"

Я не думаю, что существует стандартный приемлемый способ структурирования проектов cmake.Я посмотрел на кучу репозиториев cmake, и они, как правило, имеют различия.Лично я делаю следующее:

-project
    CMakeLists.txt
    -build
    -cmake
         OptionalCmakeModule.cmake
    -src
        -Main
            Main.cpp
            Main.hpp
        -DataStructs
            SomeTree.hpp
            SomeObject.hpp
        -Debug
            Debug.hpp
        -UI
            Window.hpp
            Window.cpp

По сути, это создает дамп всего исходного кода в 1 каталог, а затем вы выполняете сборку вне исходного кода с помощью: ' mkdir build && cd build && cmake .. &&сделайте 'в корневой папке проектов.

Если у вас есть отдельные библиотеки libs как часть вашего проекта, то вам может потребоваться отдельный каталог libs с другой подпапкой для вашей конкретной библиотеки.

У меня есть несколько моих репозиториев: https://github.com/dcbishop/, если вы хотите посмотреть файлы CMakeLists.txt.

Основные проблемы со структурой моего проекта заключаются в том, что я использую FILE_GLOB, который, по-видимому, 'неправильный способ действий (если вы добавляете файлы после запуска ' cmake .. ', тогда они не будут обнаружены, если вы выполните ' make ').Я не понял, каков «правильный» способ сделать это (из того, что я вижу, это сохранение отдельного списка файлов), я также использую только 1 файл CMakeLists.txt.

Некоторые проекты такжевыберите разделить свои файлы cpp и hpp на отдельные каталоги.Таким образом, у вас будут папки include и src (по крайней мере, для hpp-файлов, которые предназначены для внешнего использования).Я думаю, что это будет в основном для проектов, которые в основном крупные библиотеки.Также значительно упростит установку файлов заголовков.

0 голосов
/ 14 декабря 2011

Вы, вероятно, пропали без вести

include_directories(${PROJECT_SOURCE_DIR}/libfolder/codepart1folder)

В таком случае вам может потребоваться set( CMAKE_INCLUDE_CURRENT_DIR on), чтобы добавить все папки в переменную пути включаемого каталога.

Проверьте вывод команды cmake в командной строке, установлены ли правильные папки для включения или нет. Кроме того, вы всегда можете использовать message() в качестве «отладки печати» для переменных cmake. Однако в случае включаемых каталогов вам необходимо прочитать свойство directory, чтобы увидеть, что на самом деле находится в включаемых каталогах.

get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
message("inc_dirs = ${inc_dirs}")

Надеюсь, это поможет вам понять, чего не хватает.

Редактировать

Я только что увидел ваш комментарий о добавлении codepart1folder в libfolder. Он доступен только в пути include_directory библиотеки и не распространяется в корневую папку. Поскольку include codepart1.hpp присутствует в lib.hpp, вам необходимо, чтобы он также был доступен в пути проекта, в противном случае вы получите пропущенные ошибки объявления при сборке проекта.

...