CMake объявляет зависимость функции от ExternalProject_Add

TLDR:

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

контекст:

У меня есть модуль cmake SomeModule.cmake который должен добавить flatbuffers как внешний проект из своего репозитория и построить его. Сборка создаст исполняемый файл компилятора flatbuffers, который я собираюсь использовать в some/directory/CMakeLists.txt файл для генерации заголовочных файлов c ++ из схемы flatbuffers. Так что в том же модуле CMake, который я использую ExternalProject_AddЯ объявил функцию CMake, которая генерирует заголовочные файлы из заданного набора файлов схемы и где-то в some/directory/CMakeLists.txt Я называю эту функцию.

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

Хватит говорить. Вот соответствующие части кода:

SomeModule.cmake:

include(ExternalProject)

set(flatbuffers_CMAKE_ARGS
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}""-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}""-DFLATBUFFERS_BUILD_TESTS=OFF""-DFLATBUFFERS_BUILD_FLATC=ON""-DFLATBUFFERS_BUILD_FLATHASH=OFF""-DCMAKE_INSTALL_PREFIX=${OTS_DEPENDENCIES}")

ExternalProject_Add(
flatbuffers
GIT_REPOSITORY  "https://github.com/google/flatbuffers.git"GIT_TAG         "v1.9.0"SOURCE_DIR      "${OTS_DEPDENDENCIES_DIR}/flatbuffers"BINARY_DIR      "${OTS_DEPDENDENCIES_DIR}/flatbuffers"CMAKE_ARGS      "${flatbuffers_CMAKE_ARGS}"INSTALL_COMMAND "")

ExternalProject_Get_Property(flatbuffers SOURCE_DIR)
ExternalProject_Get_Property(flatbuffers BINARY_DIR)
set(flatbuffers_SOURCE_DIR ${SOURCE_DIR})
set(flatbuffers_BINARY_DIR ${BINARY_DIR})
set(flatbuffers_INCLUDE_DIR ${flatbuffers_SOURCE_DIR}/include)
set(flatbuffers_FLATC_EXECUTABLE ${flatbuffers_BINARY_DIR}/flatc)
# please assume that the variables above are all set to appropriate values

function(FlatbuffersGenerateCpp SCHEMA_FILES GENERATED_DIR GENERATED_CXX)
foreach(SCHEMA_FILE ${SCHEMA_FILES})
get_filename_component(NAME ${SCHEMA_FILE} NAME_WE)
set(GENERATED_HEADER_FILE_PATH ${GENERATED_DIR}/${NAME}_generated.h)
message(STATUS "attempting to generate: ${GENERATED_HEADER_FILE_PATH}")
add_custom_command(
DEPENDS ${flatbuffers_FLATC_EXECUTABLE}
OUTPUT ${GENERATED_HEADER_FILE_PATH}
COMMAND ${flatbuffers_FLATC_EXECUTABLE} -o ${GENERATED_DIR} -c ${SCHEMA_FILE}
COMMENT "generating flatbuffers c++ header file: ${GENERATED_HEADER_FILE_PATH}")
list(APPEND GENERATED_FILES ${GENERATED_HEADER_FILE_PATH})
endforeach()
message(STATUS "generated c++ header files: ${GENERATED_FILES}")
set(${GENERATED_CXX} ${GENERATED_FILES} PARENT_SCOPE)
endfunction()

А также some/directory/CMakeLists.txt:

# cmake module path is properly set so the following works:
include(SomeModule)

set(flatbuffers_GENERATED_INCLUDES_DIR
${CMAKE_BINARY_DIR}/generated/config/flatbuffers
)

FlatbuffersGenerateCpp(
"${flatbuffers_SCHEMAS}""${flatbuffers_GENERATED_INCLUDES_DIR}"flatbuffers_GENERATED_CXX
)

add_library(
my_framework
SHARED
${THE_PUBLIC_HEADER_FILES}
${THE_IMPL_SOURCE_FILES}
${THE_IMPL_HEADER_FILES}
${flatbuffers_GENERATED_CXX}
)

add_dependencies(my_framework flatbuffers ${flatbuffers_GENERATED_CXX})

target_include_directories(my_framework PRIVATE ${flatbuffers_INCLUDE_DIR})
target_include_directories(my_framework PRIVATE ${CMAKE_SOURCE_DIR})
target_include_directories(my_framework PRIVATE ${CMAKE_BINARY_DIR}/generated)
set_source_files_properties(${flatbuffers_GENERATED_CXX} PROPERTIES GENERATED TRUE)

1

Решение

Я начал изменять свой код на основе комментариев, опубликованных Цыварев:

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

Хотя я верил, что предложенное им решение будет работать, мне было немного не по себе и я думал, что должно быть более элегантное решение. Я проконсультировался с коллегой и нашел лучшее решение, которое так же просто, как следующий diff (который удаляет ${flatbuffers_GENERATED_CXX}).

- add_dependencies(my_framework flatbuffers ${flatbuffers_GENERATED_CXX})
+ add_dependencies(my_framework flatbuffers)

мы рассмотрели, что проблема с данным кодом заключается в том, что, как есть, CMake читает add_dependencies(my_framework flatbuffers ${flatbuffers_GENERATED_CXX}) и понимает, что ему нужно ${flatbuffers_GENERATED_CXX} как цель для строительства my_framework так что продолжается с запуском функции. Но у него нет возможности понять, что функция зависит от внешнего проекта. Теперь, если мы удалим явное объявление зависимости ${flatbuffers_GENERATED_CXX}CMake откладывает запуск функции после разрешения других зависимостей (целевой объект flatbuffers), которые эффективно загрузят и соберут внешний проект до запуска проекта.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]