将依赖项添加到自定义目标

时间:2012-08-11 14:15:45

标签: cmake

我需要一种方法来向自定义目标添加其他依赖项。我有一个宏,它将资源文件添加到特定项目,使用如下:

ADD_RESOURCES( ${TARGET} some/path pattern1 pattern2 )
ADD_RESOURCES( ${TARGET} another/path pattern1 )

我创建了一个名为${TARGET}_ASSETS的目标,并希望将所有这些资源的生成附加到一个目标。 add_dependencies但是只接受其他目标。因此,如果我通过add_custom_command生成文件,我就不能将其用作依赖项。

解决方法可能是为每次调用ADD_RESOURCES创建一个新的自定义taget,然后将其附加到ASSETS目标。但是,每个目标都需要一个唯一的名称,而这些名称无法从ADD_RESOURCES的参数中生成此唯一名称。

2 个答案:

答案 0 :(得分:1)

一种解决方法是推迟生成${target}_ASSETS个自定义目标,直到通过调用ADD_RESOURCES设置所有依赖关系。

ADD_RESOURCES必须将依赖项记录在全局变量中,而不是立即将依赖项添加到自定义目标中,该变量的名称取决于目标:

macro (ADD_RESOURCES _targetName)
    set (_dependencies ${ARGN})
    ...
    # record depencies in a target dependency variable
    if (DEFINED ${_targetName}_Dependencies)
        list (APPEND ${_targetName}_Dependencies ${_dependencies})
    else()
        set (${_targetName}_Dependencies ${_dependencies})
    endif()
endmacro()

然后添加另一个辅助宏,它通过反射确定所有已定义的目标依赖变量,并为每个目标设置自定义目标:

macro (SETUP_ASSETS_TARGETS)
    get_cmake_property(_vars VARIABLES)
    foreach (_var ${_vars})
        if (_var MATCHES "(.+)_Dependencies")
            set (_targetName ${CMAKE_MATCH_1})
            set (_targetDependencies ${${_var}})
            message("${_targetName} depends on ${_targetDependencies}")
            add_custom_target(${_targetName}_ASSETS DEPENDS ${_targetDependencies})
        endif()
    endforeach()
endmacro()

CMakeLists.txt通过调用ADD_RESOURCES添加所有必要的依赖项,然后调用SETUP_ASSETS_TARGETS宏以定义所有自定义目标。

ADD_RESOURCES( target1 some/path pattern1 pattern2 )
ADD_RESOURCES( target1 another/path pattern1 )
ADD_RESOURCES( target2 foo/bar pattern1 )
...
...
SETUP_ASSETS_TARGETS()

答案 1 :(得分:1)

我知道这是一个迟到的答案,但我将我的解决方案发布给搜索此问题的每个人:

function(target_resources THIS)

    if (NOT TARGET ${THIS}_res)
        # this is just a pseudo command which can be appended later
        add_custom_command(OUTPUT ${THIS}_dep COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR})

        # add a dependency with a target, as a command itself can not be a dependency
        add_custom_target(${THIS}_res DEPENDS ${THIS}_dep)
        add_dependencies(${THIS} ${THIS}_res)
    endif ()

    get_target_property(RUNTIME_OUTPUT_DIRECTORY ${THIS} RUNTIME_OUTPUT_DIRECTORY)

    foreach (RES_FILE IN LISTS ARGN)

        if (IS_ABSOLUTE ${RES_FILE})
            file(RELATIVE_PATH PATH ${CMAKE_CURRENT_SOURCE_DIR} ${RES_FILE})
        endif ()

        # append the resource command with our resource
        add_custom_command(OUTPUT ${THIS}_dep
                COMMAND ${CMAKE_COMMAND} -E copy
                ${CMAKE_CURRENT_SOURCE_DIR}/${RES_FILE}
                ${RUNTIME_OUTPUT_DIRECTORY}/${RES_FILE}
                APPEND)

    endforeach ()

endfunction()

这个解决方案的好处是不依赖于全局变量,也不需要调用设置宏。