Как я могу создать проект C ++ с несколькими взаимозависимыми подкаталогами? - PullRequest
64 голосов
/ 03 августа 2011

У меня есть проект на C ++, в котором я использовал каталоги как организационный элемент - способ, которым можно использовать пакеты в Java или каталоги в PHP.Каталоги не предназначены для того, чтобы быть самодостаточными элементами, а скорее просто способом организации всего проекта и предотвращения попадания меня в источники.Как я могу создать свои файлы CMakeLists.txt, чтобы справиться с этим?Создание библиотек каталогов здесь, кажется, не подходит, так как они все взаимозависимы и не предназначены для такого использования.

В качестве связанной проблемы, большинство примеров, которые я видел, касались нескольких подкаталогов в CMake.(и таких не очень много) игнорировали или закрывали глаза на проблему установки include_directories, с которой у меня были проблемы.Если не считать объединения моих исходных файлов, чтобы определить, какой файл зависит от того, от какого и в каком каталоге, есть ли в любом случае просто установить все каталоги под /src/ как потенциальные каталоги включения и позволить CMake решить, какие из них на самом деле зависят?

Вот пример структуры:

--src
  --top1
    --mid1
      --bot1
        --src1.cpp
        --hdr1.h
      --bot2
        --src2.cpp
        --hdr2.h
    --mid2
      --bot3
        --src3.cpp
        --src4.cpp
        --hdr3.h
  --top2
    --mid3
      --src5.cpp
      --hdr4.h

И так далее, и тому подобное.Как я могу структурировать мои CMakeLists.txt файлы для обработки такого рода структуры?

Ответы [ 2 ]

57 голосов
/ 03 августа 2011

Поскольку структура каталогов в вашем проекте просто предназначена для организации ваших файлов, один из подходов заключается в том, чтобы иметь CMakeLists.txt, который автоматически находит все исходные файлы в каталоге src, а также добавляет все каталоги как включающие каталоги, заголовочный файл в них. Следующий файл CMake может служить отправной точкой:

cmake_minimum_required(VERSION 3.0)

project (Foo)

file(GLOB_RECURSE Foo_SOURCES "src/*.cpp")
file(GLOB_RECURSE Foo_HEADERS "src/*.h")

set (Foo_INCLUDE_DIRS "")
foreach (_headerFile ${Foo_HEADERS})
    get_filename_component(_dir ${_headerFile} PATH)
    list (APPEND Foo_INCLUDE_DIRS ${_dir})
endforeach()
list(REMOVE_DUPLICATES Foo_INCLUDE_DIRS)

add_executable (FooExe ${Foo_SOURCES})
target_include_directories(FooExe PRIVATE ${Foo_INCLUDE_DIRS})

Две команды file(GLOB_RECURSE ... определяют набор исходных и заголовочных файлов. Цикл foreach вычисляет набор включаемых каталогов из списка всех заголовочных файлов.

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

2 голосов
/ 03 августа 2011

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

Похоже, что CMake позволяет вам получить список включаемых каталогов: http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories

Так что-то вроде:

include_directories("src/top1/mid1/bot1" "src/top1/mid1/bot2/" ... )

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

Подобно тому, как вы должны быть в состоянии перечислить все ваши исходные файлы в команде add_executable :

add_executable(name "src/top1/mid1/bot1/src1.cpp" "src/top1/id1/bot2/src2.cpp" ...)

Так что это был бы наивный способ заставить все построить. Каждый исходный файл будет скомпилирован и будет искать заголовки во всех этих каталогах, а затем объектные файлы будут связаны вместе. Подумайте, есть ли какой-нибудь способ упростить это так, что вам не нужно так много включаемых папок, возможно, есть только несколько общих заголовочных файлов, на которые должны ссылаться все исходные файлы. Если что-то становится более сложным, вы можете встроить подчиненные иерархии в библиотеки и т. Д. Также рассмотрите возможность разделения исходных файлов и заголовков (например, в src и include).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...