преобразовать фрагмент кода в функцию - не работает - PullRequest
1 голос
/ 11 октября 2019

У меня есть проект с исполняемым файлом и несколькими плагинами, каждый из которых имеет 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}
    )

1 Ответ

2 голосов
/ 11 октября 2019

Ваша переменная RESOURCE_FOLDERS содержит два значения .

Когда они передаются в функцию, они интерпретируются как два аргумента функции (RESOURCE_FOLDERS иOUTPUT_DIR).

Путь 1 . Вы можете передать «многозначную» переменную в кавычках :

copy_common_files("${RESOURCE_FOLDERS}" ${OUTPUT_DIR} copiedFiles)

Обратите внимание, что цитирование работает только для именованных аргументов.

В противном случае, таким образомидеально подходит и используется, например, при реализации команды cmake_parse_arguments .

Way 2 . Расположите многозначный аргумент в end в сигнатуре функции после именованных аргументов:

function(copy_common_files OUTPUT_DIR copiedFiles)

Эта функция может быть вызвана как

copy_common_files(${OUTPUT_DIR} copiedFiles ${RESOURCE_FOLDERS})

Внутри функции вы можете ссылаться на список остальных аргументов как ${ARGN}:

foreach(folder ${ARGN})

Этот способ используется во многих не внутренних командах CMake.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...