Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.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

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
将cmake项目与Qt5链接时部署icu库_Qt_Cmake_Qt5_Icu - Fatal编程技术网

将cmake项目与Qt5链接时部署icu库

将cmake项目与Qt5链接时部署icu库,qt,cmake,qt5,icu,Qt,Cmake,Qt5,Icu,我有以下CMakeLists.txt用于创建一个小应用程序: cmake_minimum_required (VERSION 3.5.0) project (sampleapp) # Setting project flags set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib) set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)

我有以下
CMakeLists.txt
用于创建一个小应用程序:

cmake_minimum_required (VERSION 3.5.0)

project (sampleapp)

# Setting project flags
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin)
set (CMAKE_INCLUDE_CURRENT_DIR ON)
set (CMAKE_AUTOMOC ON)

# Finding needed packages
find_package (Qt5Widgets REQUIRED)
find_package (Qt5Core REQUIRED)
find_package (Qt5Gui REQUIRED)

# Setting project files
include_directories (${CMAKE_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE PROJECT_SRC *.cpp)

# Creating project
add_executable(${PROJECT_NAME} ${PROJECT_SRC})

# Linking dependencies
target_link_libraries (${PROJECT_NAME} somelibrary Qt5::Widgets Qt5::Gui Qt5::Core)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:${PROJECT_NAME}>)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:${PROJECT_NAME}>)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:${PROJECT_NAME}>)
cmake_最低要求(3.5.0版)
项目(sampleapp)
#设置项目标志
集合(CMAKE_存档_输出_目录${CMAKE_二进制_目录}/build/lib)
集合(CMAKE_库_输出_目录${CMAKE_二进制_目录}/build/lib)
集合(CMAKE_运行时_输出_目录${CMAKE_二进制_目录}/build/bin)
设置(CMAKE\U INCLUDE\U CURRENT\U DIR ON)
设置(CMAKE_自动监控开启)
#查找所需的包
查找_包(需要Qt5Widgets)
查找包(需要QT5核心)
查找_包(需要Qt5Gui)
#设置项目文件
包括目录(${CMAKE\u SOURCE\u DIR}/src${CMAKE\u CURRENT\u SOURCE\u DIR})
文件(全局递归项目\u SRC*.cpp)
#创建项目
添加可执行文件(${PROJECT\u NAME}${PROJECT\u SRC})
#链接依赖项
目标链接库(${PROJECT\u NAME}somelibrary Qt5::Widgets Qt5::Gui Qt5::Core)
添加自定义命令(目标${PROJECT\u NAME}POST\u BUILD命令${CMAKE\u command}-E copy\u如果不同$$)
添加自定义命令(目标${PROJECT\u NAME}POST\u BUILD命令${CMAKE\u command}-E copy\u如果不同$$)
添加自定义命令(目标${PROJECT\u NAME}POST\u BUILD命令${CMAKE\u command}-E copy\u如果不同$$)
当我运行它并构建应用程序时,Qt DLL被复制到目标文件夹中。我特别抄袭:

  • Qt5Core.dll
  • Qt5Gui.dll
  • Qt5Widgets.dll
当我运行应用程序时,它不会启动,因为Qt所需的ICU库没有被复制。启动应用程序时,Windows告诉我缺少以下库:

  • icuin53.dll
  • icuuc53.dll
如果我从Qt insallation文件夹中手动复制这些库,它会工作(好的,我有一个关于“平台插件windows”丢失的错误,但这是另一个故事)


是否有一种方法可以以标准方式复制icu库,比如我用于复制库的构建后命令?或者,如果可能的话,以透明的方式复制它们的最佳方式是什么(CMake可以知道什么是Qt的依赖项,并在需要Qt的地方复制它们)?

您可以使用Qt提供的用于在Windows上部署的工具
windeployqt安装所有Qt依赖项,而不是手动复制每个dll

您可以首先将
windeployqt
声明为导入的可执行文件:

find_package(Qt5
    # ...
)

if(Qt5_FOUND AND WIN32 AND TARGET Qt5::qmake AND NOT TARGET Qt5::windeployqt)
    get_target_property(_qt5_qmake_location
        Qt5::qmake IMPORTED_LOCATION
    )

    execute_process(
        COMMAND "${_qt5_qmake_location}" -query QT_INSTALL_PREFIX
        RESULT_VARIABLE return_code
        OUTPUT_VARIABLE qt5_install_prefix
        OUTPUT_STRIP_TRAILING_WHITESPACE
    )

    set(imported_location "${qt5_install_prefix}/bin/windeployqt.exe")

    if(EXISTS ${imported_location})
        add_executable(Qt5::windeployqt IMPORTED)

        set_target_properties(Qt5::windeployqt PROPERTIES
            IMPORTED_LOCATION ${imported_location}
        )
    endif()
endif()
现在可以按如下方式使用导入的可执行文件:

add_executable(foo
    # ...
)

if(TARGET Qt5::windeployqt)
    add_custom_command(TARGET foo
        POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/windeployqt"
        COMMAND set PATH=%PATH%$<SEMICOLON>${qt5_install_prefix}/bin
        COMMAND Qt5::windeployqt --dir "${CMAKE_CURRENT_BINARY_DIR}/windeployqt" "$<TARGET_FILE:foo>"
    )

    install(
        DIRECTORY
        "${CMAKE_CURRENT_BINARY_DIR}/windeployqt/"
        DESTINATION ${FOO_INSTALL_RUNTIME_DESTINATION}
    )
endif()
add_可执行文件(foo
# ...
)
if(目标Qt5::windeployqt)
添加自定义命令(目标foo
后期构建
COMMAND${CMAKE_COMMAND}-E remove_目录“${CMAKE_CURRENT_BINARY_DIR}/windeployqt”
命令集路径=%PATH%$${qt5\u install\u prefix}/bin
命令Qt5::windeployqt--dir“${CMAKE_CURRENT_BINARY_dir}/windeployqt”“$”
)
安装(
目录
“${CMAKE\u CURRENT\u BINARY\u DIR}/windeployqt/”
目标${FOO\u INSTALL\u RUNTIME\u DESTINATION}
)
endif()

CMake可以知道什么是Qt的依赖项,并在需要Qt的地方复制它们
-CMake本身没有复制所有Depdent库的功能。那么什么是最好的CMake方法来复制这些库和Qt库呢?据我所知,CMake认为将3d party库复制到包含可执行文件的目录中是一种糟糕的设计。从开发人员的角度来看,3d party库应该广泛安装在系统中,这样就可以从任何可执行文件加载它们。虽然我知道你的问题是真实的,但我不知道该怎么做。太好了!谢谢,这是我需要的工具。。。我只需要创建一个cmake函数来处理所有这些,并将其放在一个单独的文件中,这样我就可以在我所有的项目中使用它而不会膨胀。再次感谢。你不能用
$
替换
$/$
吗?后者是到达目标的完整路径,这也是您试图用前者构建的。我错了吗?@skypjack看起来你是对的。我编辑了我的答案。Thx:)