Правильный способ структурировать мой проект c++ с помощью cmake?

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

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

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

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

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

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

когда я запускаю make, библиотека компилируется отлично, но когда проект.cpp компилируется, он жалуется, что не может найти codepart1.ГЭС (входит в lib.ГЭС, включенная в проект.СРР.)

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

4 ответов


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

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


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

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

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

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


глядя на свой пост, вы, похоже, не добавляете "codepart1folder" в includes anywhere. Как вы в том числе codepart1.hpp as:

#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 строить && сборка CD && CMake, например .. & и сделать' в корневой папке проекта.

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

у меня есть некоторые из моих РЕПО:https://github.com/dcbishop/ Если вы хотите посмотреть на CMakeLists.txt-файл.

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

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


вы, вероятно, отсутствует

include_directories(${PROJECT_SOURCE_DIR}/libfolder/codepart1folder)

в таком случае вы можете захотеть set( CMAKE_INCLUDE_CURRENT_DIR on) чтобы добавить все папки в переменную include directory path.

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

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

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

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

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