Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将cmake代码段转换为函数-不工作_C++_Cmake - Fatal编程技术网

C++ 将cmake代码段转换为函数-不工作

C++ 将cmake代码段转换为函数-不工作,c++,cmake,C++,Cmake,我有一个带有可执行文件和几个插件的项目,每个插件都有QML和其他文件(例如图像、svg)。为此创建CMake构建需要在适当的位置安装运行时所需的插件及其相关文件。文件的类型和相对位置使得每个模块都需要重复,因此我将重复的CMake代码移动到一个.CMake文件中,该文件包含在每个插件的CMakeLists.txt中。当它只是.cmake文件中的基本代码时,它工作得非常好。我最近想把它转换成一个函数,但一直没能让它工作。我想我遗漏了一些关于在生成过程中调用函数的基本信息。转换为函数后,文件的复制不

我有一个带有可执行文件和几个插件的项目,每个插件都有QML和其他文件(例如图像、svg)。为此创建CMake构建需要在适当的位置安装运行时所需的插件及其相关文件。文件的类型和相对位置使得每个模块都需要重复,因此我将重复的CMake代码移动到一个.CMake文件中,该文件包含在每个插件的CMakeLists.txt中。当它只是.cmake文件中的基本代码时,它工作得非常好。我最近想把它转换成一个函数,但一直没能让它工作。我想我遗漏了一些关于在生成过程中调用函数的基本信息。转换为函数后,文件的复制不起作用,从函数调用返回后${copiedFiles}为空

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}
    )
下面是.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的一个示例,其工作方式只是include语句,而不包括函数调用

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}
    )

您的
RESOURCE\u文件夹
变量包含两个值

将它们传递给函数时,它们被解释为函数的两个参数(
RESOURCE\u FOLDERS
OUTPUT\u DIR

方式1。您可以传递“多值”变量引号

copy_common_files("${RESOURCE_FOLDERS}" ${OUTPUT_DIR} copiedFiles)
请注意,引用仅适用于命名参数

否则,这种方法是完全有效的,例如在执行命令时使用

方式2。将多值参数排列到函数签名
中的结尾,在命名参数之后:

function(copy_common_files OUTPUT_DIR copiedFiles)
该函数可以称为

copy_common_files(${OUTPUT_DIR} copiedFiles ${RESOURCE_FOLDERS})
在函数内部,您可以将rest参数列表称为
${ARGN}

foreach(folder ${ARGN})

这种方法在许多非内部CMake命令中使用。

函数
copy_common_files
创建许多
add_custom_命令
,每个生成的源文件一个,并设置输出参数
copiedFiles
以包含该源文件的列表。功能的哪一部分没有工作?您可以使用通常的
message()
call检查输出参数的值。是的,问得好。最终文件没有被复制,我现在可以看到${copiedFiles}在从函数调用返回后是空的。我只是注意到我的输入变量是一个列表,它在函数中的第一个值之后被截断。出于好奇,在这种情况下宏是更好的选择吗?不,宏无法解决多值参数的问题。此外,宏在解释
ARGN
方面有一些特定的功能,因此我发现无论何时只要两者都适用,函数都比宏更好。但是,当需要不惜任何代价避免嵌套范围时,宏是一个不错的选择。