cmake配置自动调用qt的windeployqt并根据find_package设置的components拷贝动态库

在cmake中直接配置windeploy.exe拷贝qt的动态库,可能会遇到有些模块在find_package配置了,而当前模块并没有使用的问题。那么用windeploy.exe拷贝的时候,会遗漏需要的qt库。

解决方法:

# qt_helper.cmake

# 根据find_package拷贝所需要的qt库(目标文件未依赖的)

# 根据组件名获取库文件的目标
function(get_qt_library_target component_name target_var)
    if (TARGET Qt5::${component_name})
        set(${target_var} Qt5::${component_name} PARENT_SCOPE)
    elseif (TARGET Qt6::${component_name})
        set(${target_var} Qt6::${component_name} PARENT_SCOPE)
    else()
        message(FATAL_ERROR "Unknown Qt component: ${component_name}")
    endif()
endfunction()

# 项目使用
function(deployqt_qt_runtime arg_target)
    get_target_property(qt_qmake_executable Qt5::qmake IMPORTED_LOCATION)
    get_filename_component(qt_bin_directory "${qt_qmake_executable}" DIRECTORY)

    find_program(qt_deployqt_executable NAMES windeployqt macdeployqt HINTS "${qt_bin_directory}")

    if (NOT EXISTS "${qt_deployqt_executable}")
        message("can not find the deployqt tools")
        return()
    endif ()

    # 获取组件参数列表
    # ${ARGN}是一个内置变量,表示传递给函数或宏的所有未命名参数
    set(qt_components ${ARGN})

    if (WIN32)
        add_custom_command(TARGET ${arg_target} POST_BUILD COMMAND
            "${qt_deployqt_executable}"
            --libdir "$<TARGET_FILE_DIR:${arg_target}>"
            --plugindir "$<TARGET_FILE_DIR:${arg_target}>"
            --no-translations
            --no-compiler-runtime
            --no-system-d3d-compiler
            --no-opengl-sw
            --no-angle
            --no-webkit2
            $<$<CONFIG:Debug>:--pdb>
            "$<TARGET_FILE:${arg_target}>"
        )

        # 根据find_package后面的component拷贝需要的动态库(防止遗漏)
        foreach (component IN LISTS qt_components)
            get_qt_library_target(${component} qt_component_target)
            add_custom_command(TARGET ${arg_target} POST_BUILD COMMAND
                ${CMAKE_COMMAND} -E copy_if_different
                "$<TARGET_FILE:${qt_component_target}>"
                "$<TARGET_FILE_DIR:${arg_target}>"
                )
        endforeach()
    endif ()
endfunction()

使用:

  1. 项目根目录的CMakeLists.txt:
cmake_minimum_required(VERSION 3.21)

project(XXXX)
set(CMAKE_CXX_STANDARD 17)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

set(Qt5_DIR /opt/homebrew/Cellar/qt@5/5.15.8_2/lib/cmake/Qt5)

if(MSVC)
    add_compile_options("/utf-8")
    add_definitions(-DUNICODE -D_UNICODE)
    add_compile_options(/MP)
endif ()

set(qt_required_components Core Widgets Gui OpenGL Svg Xml Sql Network Charts)
find_package(Qt5 COMPONENTS ${qt_required_components} LinguistTools REQUIRED)
# 添加自己创建的cmake函数
include(qt_helper.cmake)
  1. 子模块(需要add_library或者add_execute的地方):
add_library(${PROJECT_NAME} SHARED
        XXXX.h
        )
target_link_libraries(${PROJECT_NAME}
        Qt5::Core Qt5::Widgets Qt5::Network
        )        
# 直接在文件最后加上这行就行
deployqt_qt_runtime(${PROJECT_NAME} ${qt_required_components})

cmake ${ARGN}内置函数说明:

在CMake中,${ARGN}是一个内置变量,表示传递给函数或宏的所有未命名参数。这些参数以列表的形式存储在变量中,可以用于循环、字符串操作等。要使用 ${ARGN} 处理传递给函数的参数,请参考以下示例:

function(example_function)
    # 获取未命名参数
    set(extra_args ${ARGN})

    # 使用未命名参数
    foreach(arg IN LISTS extra_args)
        message("Argument: ${arg}")
    endforeach()
endfunction()

# 调用 example_function
example_function(arg1 arg2 arg3)

在这个示例中,example_function() 函数使用 ${ARGN} 变量获取所有传递给它的未命名参数。然后,它遍历这些参数并打印出它们。在这种情况下,输出将是:

Argument: arg1
Argument: arg2
Argument: arg3

您可以在自己的CMake函数中使用类似的方法处理 ${ARGN} 中的参数。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个关于使用 CMake 生成可供其他 CMake 文件 `find_package()` 的库文件的问题。下面是一个简单的步骤: 1. 编写 CMakeLists.txt 文件,定义要生成的库文件。 ```cmake # 定义要生成的库文件名称和源文件 add_library(mylib mylib.cpp) # 定义头文件路径 target_include_directories(mylib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) # 导出库文件的头文件和库文件 include(GNUInstallDirs) install(TARGETS mylib EXPORT mylib-config LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(EXPORT mylib-config NAMESPACE mylib:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/mylib FILE mylib-config.cmake) ``` 2. 在 CMakeLists.txt 文件中设置库文件的属性。 ```cmake # 设置库文件属性 set_target_properties(mylib PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION 1 PUBLIC_HEADER include/mylib.h ) ``` 3. 生成配置文件 ```cmake # 生成配置文件 include(CMakePackageConfigHelpers) write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/mylib-config-version.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) configure_package_config_file( "${CMAKE_CURRENT_LIST_DIR}/mylib-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/mylib-config.cmake" INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mylib" ) # 安装配置文件 install( FILES "${CMAKE_CURRENT_BINARY_DIR}/mylib-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/mylib-config-version.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mylib" ) ``` 4. 在其他 CMakeLists.txt 文件中使用生成的库文件。 ```cmake # 查找库文件 find_package(mylib REQUIRED) # 添加库文件路径 link_directories(${mylib_LIBRARY_DIRS}) # 添加库文件 add_executable(myapp main.cpp) target_link_libraries(myapp ${mylib_LIBRARIES}) ``` 以上就是一个简单的使用 CMake 生成可供其他 CMake 文件 `find_package()` 的库文件的步骤。希望能够帮到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值