Импорт из дочернего каталога без указания относительного пути с помощью CMake

#c #cmake #build

#c #cmake #сборка

Вопрос:

Учитывая такую структуру проекта:

 project/
    src/
        CMakeLists.txt
        foo.h
        main.cpp
        util/
            CMakeLists.txt
            bar.h 
  

Внутри bar.h возможно ли иметь инструкцию include как #include "foo.h" ? Я видел несколько возможных способов сделать это с помощью конфигураций «предварительно скомпилированных заголовков» в Visual Studio, но не используя CMake напрямую.

Комментарии:

1. Предполагая, что у вас есть project/src каталог среди включенных каталогов , тогда #include "foo.h" это сработает. В CMake включаемые каталоги указываются с помощью команды include_directories .

2. Также https://cmake.org/cmake/help/v3.9/command/target_include_directories.html может быть использован.

3. Это не имеет ничего общего с предварительно скомпилированными заголовками.

4. Что не так с #include "../foo.h" ? И почему util доступ осуществляется к его родительскому каталогу? Звучит как плохой дизайн.

5. @WilliamBright Дело в том, что наличие CMakeLists.txt для каждого каталога в вашем дереве исходных текстов это неправильный способ сделать это.

Ответ №1:

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

  1. В файле src/CMakeLists.txt создайте дополнительный целевой интерфейс с именем, например, src_interface
     add_library( src_interface INTERFACE )
      
  2. Добавьте в него свой включаемый каталог:
     target_include_directories( src_interface INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} )
      
  3. Это необходимо сделать перед добавлением util в качестве подкаталога
     add_subdirectory( util )
      
  4. В src/util/CMakeLists.txt добавьте ссылку на интерфейс:
     target_link_libraries( util_target PRIVATE src_interface )
      

Подробнее об ИНТЕРФЕЙСНЫХ библиотеках в CMake: https://cmake.org/cmake/help/latest/command/add_library.html#interface-libraries

Комментарии:

1. Хорошо, я только что протестировал его, и он работает хорошо. Конечно, вам нужно правильно интегрировать его с остальной частью вашего CMakeLists.txt содержимое. Одной из проблем может быть смешивание команд целевой области с командами файловой области. Другой проблемой может быть команда target_link_libraries, где вам нужно ввести имя вашей фактической целевой утилиты. Просто опубликуйте свои полные сценарии сборки, если вам нужна дополнительная помощь.