Как получить включаемые каталоги от цели для использования в add_custom_target? - PullRequest
1 голос
/ 08 ноября 2019

Я моделирую зависимости с помощью target_link_libraries, как это сделано в этом сообщении в блоге.

target_link_libraries(Foo
    LibraryA
    LibraryB
)

Это прекрасно работает, но по разным причинам мне нужно использовать add_custom_target для предварительной обработки файла с помощью специальной команды. Проблема в том, что эта пользовательская цель зависит от включений LibraryA и LibraryB. Я действительно надеялся сделать следующее, например, как target_link_libraries работает (см. Бит LibraryA и LibraryB):

add_custom_target(Bar ALL
    COMMAND ${CMAKE_C_COMPILER} thing.cpp LibraryA LibraryB /P
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Path/Here
    COMMENT "Preprocessing to a file"
    VERBATIM
)

Однако это не работает. LibraryA и LibraryB вставляются, как они появляются. Даже если бы это сработало, я думаю, что я бы получил больше, чем включает, так как я думаю, что цели включают в себя и библиотеку. Может быть, это не очень хороший подход.

Итак, что я могу сделать здесь? Как я могу извлечь каталоги включения из каждой цели для использования в пользовательской команде? Я обнаружил, что если я find_package(Foo REQUIRED) получаю доступ к Foo_DIR, но это указывает на каталог сборки, а не на исходный каталог, где находятся включения.

1 Ответ

1 голос
/ 08 ноября 2019

Вы можете извлечь каталоги включения из каждой цели, используя get_target_property(). Свойство цели INCLUDE_DIRECTORIES содержит каталоги включения для этой цели. Поскольку у вас есть две цели, LibraryA и LibraryB, мы должны вызвать ее дважды. Затем мы можем объединить список включаемых каталогов, используя foreach(). Если вы используете их в качестве включаемых каталогов в команде компилятора (например, MSVC), вы можете добавить /I параметр компилятора также к каждому каталогу в цикле:

# Get the include directories for the target.
get_target_property(LIBA_INCLUDES LibraryA INCLUDE_DIRECTORIES)
get_target_property(LIBB_INCLUDES LibraryB INCLUDE_DIRECTORIES)

# Construct the compiler string for the include directories.
foreach(dir ${LIBA_INCLUDES} ${LIBB_INCLUDES})
    string(APPEND INCLUDE_COMPILER_STRING "/I${dir} ")
endforeach()

Затем вы можете вызвать пользовательскую целевую команду, используя созданную переменную INCLUDE_COMPILER_STRING:

add_custom_target(Bar ALL
    COMMAND ${CMAKE_C_COMPILER} thing.cpp ${INCLUDE_COMPILER_STRING} /P
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Path/Here
    COMMENT "Preprocessing to a file"
    VERBATIM
)

Если вы хотите что-то более краткое, вы можете использовать пример выражения генератора здесь , который получает каталоги include для целей и расширяет их в рамках вашей собственной целевой команды. Нечто подобное может работать также:

add_custom_target(Bar ALL
    COMMAND ${CMAKE_C_COMPILER} thing.cpp 
        "/I$<JOIN:$<TARGET_PROPERTY:LibraryA,INCLUDE_DIRECTORIES>,;/I>"
        "/I$<JOIN:$<TARGET_PROPERTY:LibraryB,INCLUDE_DIRECTORIES>,;/I>"
        /P
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/Path/Here
    COMMENT "Preprocessing to a file"
    VERBATIM
    COMMAND_EXPAND_LISTS
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...