如何使用add_custom_command使用生成器表达式复制dll? [英] How to use add_custom_command to copy dlls using generator expressions?

查看:275
本文介绍了如何使用add_custom_command使用生成器表达式复制dll?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to copy dll's in my solution at the compile time , so i am using add_custom_command for that as follows:

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中,我将上述函数称为:

and in the cmakelist.txt i am calling the above function as:

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都在编译期间放置在目标内部。

So, i am not getting wether its not able to reach to the location of where qt related stuff is installed or am i doing mistake in the add_custom_command generator expression? I want the function to be so generic that whatever dll i want to get in the solution is placed inside the target during compilation.

推荐答案

您将无法以通用的方式管理所有依赖项,因为这不是通用的问题,我认为尝试使用它甚至不是一个好主意。

You're not going to be able to manage all dependencies in a generic way, because it's not a generic problem, and I'll contend that it's not even a good idea to try.

以Qt为例(这是问题中提到的唯一依赖项)。在Windows上,复制Qt dll依赖项的正确方法是运行 windeployqt.exe 。您要做的不只是复制dll来运行Qt应用程序,还需要在二进制目录中精确地镜像 的目录结构/依赖项。 windeployqt 为您完成所有这些工作。以其他任何方式管理Qt dll依赖项都是 Bad Idea

Take Qt for example (which are the only dependencies mentioned in your question). On windows, the right way to copy Qt dll dependencies is to run windeployqt.exe. You need to do more than just copy dll's to get Qt apps to run, there are directory structures/dependencies that have to be mirrored exactly in your binary directory. windeployqt does all that for you. Managing the Qt dll dependencies any other way is a Bad Idea. There is no reason to fight the tool or reinvent the wheel.

这是我自定义构建步骤,用于运行 windeployqt

Here's my custom build step for running 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()

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

It finds it, then runs it as a post-build step. Simple.

它假定:


  • 您的Qt根路径在 QTDIR cmake或环境变量。

  • 您的可执行目标名称存储在变量 TARGET_NAME
  • $中b $ b
  • Your Qt root path is set in the QTDIR cmake or environment variable.
  • your executable target name is stored in the variable TARGET_NAME

对于非qt dll(在本例中为qwt),我有这样一个步骤:

For non-qt dll's (in this case qwt), I have a step like this:

# 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"
)

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

Usually that works, but it also probably copies a lot of garbage. Notice, you still need to know where to find the Dll's (specified in ${QWT_DIR}). Environment variables could be your friend,

如果您愿意,也可以使用 $ {CMAKE_COMMAND} -E复制或将其打开

You can probably also use ${CMAKE_COMMAND} -E copy if you like, or turn it into a function that takes in the dll lib location.

@Florian提供了一些帮助有关使共享库复制步骤跨平台的建议。使用 file(TO_NATIVE_PATH)替换正则表达式,使用cmake变量的后缀以及使用cmake命令替换 copy 命令-行复制,您将得到:

@Florian made some very helpful suggestions for making the shared-library copy step cross-platform. Replacing the regexs with file(TO_NATIVE_PATH), the suffixes with cmake variables, and the copy command with the cmake command-line copy, you get:

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

在注释中,直到3.5版之前,在cmake -E复制中使用通配符(*)无效。对于较旧的版本,可以使用包含特定于平台的复制命令的变量。

As mentioned in the comments, using wildcard(*) in cmake -E copy was not working until version 3.5. For older versions, a variable containing the platform-specific copy command could be used.

这篇关于如何使用add_custom_command使用生成器表达式复制dll?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆