如何使用add_custom_command使用生成器表达式复制dll?

时间:2016-05-02 12:01:03

标签: cmake

我必须在编译时在我的解决方案中复制dll,所以我使用add_custom_command,如下所示:

function(dll_dependencies TEST_CASE )
foreach(depencency ${ARGN})        
    add_custom_command(TARGET ${TEST_CASE} POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy
        $<DLL_FILE_NAME:${depencency}>)
endforeach()
endfunction()

在cmakelist.txt中我将上述函数称为:

dll_dependencies(performance QT5::Core QT5::FileSystem)

但我收到的错误是:

Error evaluating generator expression:
$<DLL_FILE_NAME:QT5::Core>

Error evaluating generator expression:
$<DLL_FILE_NAME:QT5::FileSystem>

所以,我不知道它无法到达安装qt相关内容的位置,或者我在add_custom_command生成器表达式中出错? 我希望函数是如此通用,以至于我想在解决方案中获得的任何dll都会在编译期间放在目标中。

1 个答案:

答案 0 :(得分:4)

您无法以通用的方式管理所有依赖项,因为它不是一般问题,而且我认为它甚至不是一个好的尝试的想法。

以Qt为例(这是你问题中提到的唯一依赖项)。在Windows上,复制Qt dll依赖项的正确方法是运行windeployqt.exe。您需要做的不仅仅是复制dll以使Qt应用程序运行,目录结构/依赖项必须在二进制目录中完全镜像 windeployqt为你完成所有这些。以任何其他方式管理Qt dll依赖项是错误想法。没有理由打击工具或重新发明轮子。

这是我运行windeployqt的自定义构建步骤:

# Windows specific build steps
if(WIN32)
    # Run winddeployqt if it can be found
    find_program(WINDEPLOYQT_EXECUTABLE NAMES windeployqt HINTS ${QTDIR} ENV QTDIR PATH_SUFFIXES bin)
    add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
    COMMAND ${WINDEPLOYQT_EXECUTABLE} $<TARGET_FILE:${TARGET_NAME}>)
endif()

找到它,然后将其作为构建后步骤运行。简单。

它假设:

  • 您的Qt根路径在QTDIR cmake或环境变量中设置。
  • 您的可执行目标名称存储在变量TARGET_NAME

更通用(对于windows,cmake&lt; 3.5):

对于非qt dll(在这种情况下是qwt),我有一个这样的步骤:

# on windows, to copy, we need to replace the pesky forward slashes with back slashes
STRING(REGEX REPLACE "/" "\\\\" copySource \"${QWT_DIR}/lib/*.dll\")
STRING(REGEX REPLACE "/" "\\\\" copyDest \"${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>\")

# Copy
ADD_CUSTOM_COMMAND( TARGET ${TARGET_NAME}
    POST_BUILD
    COMMAND COMMAND copy ${copySource} ${copyDest}
    COMMENT "Copying Qwt dll's...\n"
)

通常这样可行,但它也可能会复制大量垃圾。请注意,您仍然需要知道在哪里找到Dll(在${QWT_DIR}中指定)。环境变量可能是你的朋友,

如果您愿意,也可以使用${CMAKE_COMMAND} -E copy,或者将其转换为接受dll lib位置的函数。

更一般地说(cmake&gt; = 3.5):

@Florian为跨平台共享库复制步骤提出了一些非常有用的建议。使用file(TO_NATIVE_PATH)替换正则表达式,使用cmake变量替换带有cmake变量的正则值,使用cmake命令行副本替换copy命令,可以得到:

file(TO_NATIVE_PATH "${QWT_DIR}/lib/*.${CMAKE_SHARED_LIBRARY_SUFFIX}" copy_source)
set(copy_dest "$<TARGET_FILE_DIR:${TARGET_NAME}>")

# perform copy
ADD_CUSTOM_COMMAND(TARGET ${TARGET_NAME}
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy ${copySource} ${copyDest}
)

如评论中所述,在cmake -E副本中使用通配符(*)在版本3.5之前无效。对于旧版本,可以使用包含特定于平台的复制命令的变量。