Как правильно добавить каталоги include с CMake

около года назад я спрашивал о зависимости заголовков в CMake.

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

быстрый поиск в учебнике CMake указал только на include_directories который, похоже, не делает то, что я хочу...

Как правильно сигнализировать CMake, что определенный каталог содержит заголовки, которые должны быть включены, и что эти заголовки должны отслеживаться сгенерированным Makefile?

4 ответов


необходимо сделать две вещи.

Сначала добавьте каталог, который будет включен:

target_include_directories(test PRIVATE ${YOUR_DIRECTORY})

в случае, если вы застряли с очень старой версией CMake (2.8.10 или старше) без поддержки target_include_directories, вы также можете использовать наследие include_directories вместо:

include_directories(${YOUR_DIRECTORY})

затем вы также должны добавить заголовочные файлы в список исходных файлов для текущей цели, например:

set(SOURCES file.cpp file2.cpp ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_executable(test ${SOURCES})

таким образом, файлы заголовков будут отображаться как зависимости в Makefile, а также, например, в созданном проекте Visual Studio, Если вы его создаете.

как использовать эти заголовочные файлы для нескольких целей:

set(HEADER_FILES ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)

add_library(mylib libsrc.cpp ${HEADER_FILES})
target_include_directories(mylib PRIVATE ${YOUR_DIRECTORY})
add_executable(myexec execfile.cpp ${HEADER_FILES})
target_include_directories(myexec PRIVATE ${YOUR_DIRECTORY})

во-первых, вы используете include_directories() чтобы сказать CMake добавить каталог как -I в командной строке компиляции. Во-вторых, вы перечисляете заголовки в своем add_executable() или add_library() звонок.

в качестве примера, если источники вашего проекта находятся в src, и вам нужны заголовки из include, вы могли бы сделать это вот так:

include_directories(include)

add_executable(MyExec
  src/main.c
  src/other_source.c
  include/header1.h
  include/header2.h
)

CMake больше похож на язык скриптов, если сравнивать его с другими способами создания Makefile (например, make или qmake). Это не очень круто, как Python, но все же.

нет такой вещи, как "правильно " если смотреть в различных проектах с открытым исходным кодом, как люди включают каталоги. Но есть два способа сделать это.

  1. нефть include_directories добавит каталог к текущему проекту и всем другим потомкам проекты, которые вы добавите через серию add_subdirectory команды. Иногда люди говорят, что такой подход является наследием.

  2. более элегантный способ-с target_include_directories. Это позволяет добавить каталог для конкретного проекта / цели без (возможно) ненужного наследования или столкновения различных каталогов include. Также позволяют выполнить даже тонкую настройку и добавить для этого один из следующих маркеров команда.

частная - использовать только для указанной цели

общественные - используйте его для указанной цели и для целей, которые связаны с этим проектом

интерфейс -- используйте его только для целей, которые связаны с текущим проектом

PS:

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

  2. аналогичный ответ с другими парами команд target_compile_definitions/add_definitions, target_compile_options/CMAKE_C_FLAGS


у меня была та же проблема.

мой каталог проекта был такой:

    --project
    ---Classes
    ----Application
    -----.h and .c files
    ----OtherFolders
    --main.cpp

и что я использовал для включения файлов во все эти папки:

    file(GLOB source_files
            "*.h"
            "*.cpp"
            "Classes/*/*.cpp"
            "Classes/*/*.h"
    )

    add_executable(Server ${source_files})

и это сработало.