У меня есть проект с исполняемым файлом и несколькими плагинами, каждый из которых имеет QML и другие файлы (например, изображения, SVG). Создание сборки CMake для этого включает установку плагинов и связанных с ними файлов, необходимых во время выполнения, в соответствующем месте. Типы файлов и их относительное расположение делают это повторяющимся элементом для каждого модуля, поэтому я переместил повторяющийся код CMake в один файл .cmake, который включен в CMakeLists.txt каждого плагина. Это прекрасно работает, когда это просто основной код в файле .cmake. Недавно я подумал, что смогу преобразовать это в функцию, и не смог заставить ее работать. Я думаю, что мне не хватает чего-то фундаментального в том, когда функция вызывается в процессе генерации. После преобразования в функцию копирование файлов не работает, и $ {copiedFiles} после возврата из вызова функции пуст.
Вот файл .cmake, с работающим кодом, закомментированным внизу. Реализация функции этого кода находится наверху.
# This convenience snippet expects ${RESOURCE_FOLDERS} and ${OUTPUT_DIR} to
# set.
#
function(copy_common_files RESOURCE_FOLDERS OUTPUT_DIR copiedFiles)
foreach(folder ${RESOURCE_FOLDERS})
file(GLOB QML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/*.qml)
file(GLOB SVG_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/*.svg)
file(GLOB QMLDIR_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/qmldir)
file(GLOB APPCFG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/appconfig.json)
file(GLOB TRANSLATION_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/*.ts)
file(GLOB QRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/*.qrc)
set(FILES_TO_COPY
${QML_FILES} ${SVG_FILES} ${QM_FILES} ${QMLDIR_FILE} ${QRC_FILES}
${APPCFG_FILE} ${TRANSLATION_FILES}
)
foreach(file ${FILES_TO_COPY})
get_filename_component(nam ${file} NAME)
add_custom_command(OUTPUT ${OUTPUT_DIR}/${folder}/${nam}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${file} ${OUTPUT_DIR}/${folder}
DEPENDS ${file}
COMMENT "Copying ${file}"
VERBATIM
)
list(APPEND outputList ${OUTPUT_DIR}/${folder}/${nam})
set(${copiedFiles} ${outputList} PARENT_SCOPE)
endforeach()
endforeach()
endfunction()
#foreach(folder ${RESOURCE_FOLDERS})
# file(GLOB QML_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/*.qml)
# file(GLOB SVG_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/*.svg)
# file(GLOB QMLDIR_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/qmldir)
# file(GLOB APPCFG_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/appconfig.json)
# file(GLOB TRANSLATION_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/*.ts)
# file(GLOB QRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${folder}/*.qrc)
# set(FILES_TO_COPY
# ${QML_FILES} ${SVG_FILES} ${QM_FILES} ${QMLDIR_FILE} ${QRC_FILES}
# ${APPCFG_FILE} ${TRANSLATION_FILES}
# )
# foreach(file ${FILES_TO_COPY})
# get_filename_component(nam ${file} NAME)
# add_custom_command(OUTPUT ${OUTPUT_DIR}/${folder}/${nam}
# COMMAND ${CMAKE_COMMAND} -E copy_if_different ${file} ${OUTPUT_DIR}/${folder}
# DEPENDS ${file}
# COMMENT "Copying ${file}"
# VERBATIM
# )
# list(APPEND copiedFiles ${OUTPUT_DIR}/${folder}/${nam})
# endforeach()
#endforeach()
Пример плагина CMakeLists.txt, который вызывает это, здесь, с рабочим способом, являющимся просто оператором включения, не включая вызов функции.
find_package(Qt5 COMPONENTS Core REQUIRED)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC OFF) # Set this to ON if you want resources compiled in
set(OUTPUT_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/AEPPApps/ImportFiles)
set(RESOURCE_FOLDERS
.
images
)
include(copy_common_files) # only this when not using 'function'
copy_common_files(${RESOURCE_FOLDERS} ${OUTPUT_DIR} copiedFiles)
# Adding ${copiedFiles} as a dependency below forces the conditional copy
# to get considered:
# https://stackoverflow.com/questions/33938239/cmake-does-not-copy-file-in-custom-command
add_library(ImportFiles SHARED ${copiedFiles})
target_compile_definitions(ImportFiles
PRIVATE
IMPORTFILESPLUGIN_LIBRARY
NOMINMAX
)
target_include_directories(ImportFiles
PRIVATE
.
)
# Enable below when you want to compile resources for apps, then remove the copying above
#
#qt5_add_resources(ImportFiles_RESOURCES
# ImportFiles.qrc
# )
target_sources(ImportFiles
PRIVATE
Redacted.cpp
)
target_link_libraries(ImportFiles
PUBLIC
REDACTED-lib
PRIVATE
Qt5::Core
)
set_target_properties(ImportFiles PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${OUTPUT_DIR}
)