• [Cmake Qt]找不到文件ui_xx.h的问题?有关Qt工程的问题,看这篇文章就行了。


    前言

    最近在开发一个组件,但是这个东西是以dll的形式发布的界面库,所以在开发的时候就需要上层调用。

    在这里插入图片描述
    如果你是很懂CMake的话,ui_xx.h的文件目录在

    $

    然后除了有关这个ui_xx.h,还有一些别的可以简单聊聊的

    一、父子工程组织,或者说依赖关系

    在使用CMake进行开发的时候,一般可以有一个上下级的关系,或者一般情况下上下级工程会摆在同一个文件夹下,对于我这个项目来说,View_Equalizer是Demo_View_Equalizer的依赖

    在CMake中,如果工程之间有依赖,一般代表了几件事:

    1. 子工程一定是要先于父工程编译的
    2. 父工程需要引用到子工程的所有头文件
    3. 父工程需要链接到子工程

    那我们一步步拆解地来看

    1.要求子工程优先于父工程编译

    可以直接在父工程中添加

    add_subdirectory(./View_Equalizer)

    的方式来添加子工程,这样的话View_Equalizer就会优先于当前工程进行编译了

    2. 要求父工程能引用到子工程的全部头文件

    这是因为,如果父工程如果不能引用到子工程的所有头文件的话,很有可能会出现无法编译的情况,即子工程引用了头文件,但是父工程则无法直接引用到所有的头文件,这样父工程的编译就会报错。

    为了解决这个问题,我们需要在子工程中添加target_include_directories,以在作为子工程的时候向上传递包含列表

    示例如下:

    target_include_directories(View_Equalizer PUBLIC 
    ${CMAKE_CURRENT_SOURCE_DIR}/math 
    ${CMAKE_CURRENT_SOURCE_DIR}/QCustomPlot 
    ${CMAKE_CURRENT_SOURCE_DIR}/includes 
    ${CMAKE_CURRENT_SOURCE_DIR}/Views 
    ${CMAKE_CURRENT_SOURCE_DIR}/View_Items 
    ${CMAKE_CURRENT_BINARY_DIR})
    

    需要注意的是,这里target_include_directories传递的是路径,而不是具体的文件,如果传递具体文件的话,上层仍然是找不到的,这里需要注意。

    注:关于之前提到的找不到文件ui_xx.h的问题,这个其实就是没有写

    target_include_directories(View_Equalizer PUBLIC ${CMAKE_CURRENT_BINARY_DIR})

    所有的ui_xx.h文件都会存放在${CMAKE_CURRENT_BINARY_DIR}下,所以将这个目录传递给上层,就不会出现找不到 ui_xx.h的情况了。

    3.父工程需要链接子工程

    这个很好理解了,在父工程的CMakeLists.txt中添上这么一句话就行了

    target_link_libraries(Demo_View_Equalizer PRIVATE View_Equalizer)
    

    二、有关ui、qrc等qt特有的文件

    首先,当你在使用CMake编写Qt的时候,这三个属性是必不可少的

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

    如果你想要添加ui或者qrc文件,同样的,需要将ui文件添加到add_library的名下,我这里是通过列表的形式插入所有需要的文件

    set(HEADER_FILES  
        ./includes/DataClass.h  
        ./includes/View_Equalizer_global.h
        ./includes/math_functions.h
        ./includes/Center.h
        ./Views/view_equalizer.h
        ./View_Items/ViewItem_ControlPoint.h
        ./View_Items/PointWidget.h
    )  
    
    set(SOURCE_FILES 
    ./src/DataClass.cpp
    ./src/Center.cpp
    ./QCustomPlot/qcustomplot.cpp
    ./Views/view_equalizer.cpp
    ./View_Items/ViewItem_ControlPoint.cpp
    ./View_Items/PointWidget.cpp
    )
    
    set(UI_FILES
    ./View_Items/PointWidget.ui
    )
    
    add_library(View_Equalizer SHARED ${HEADER_FILES} ${SOURCE_FILES} ${UI_FILES} ${QRC_SOURCES})
    
    

    当然了,既然是qt的库,对于ui文件和qrc文件,则需要加入以下两个命令:

    qt5_add_resources(QRC_SOURCES ${RESOURCE_FILES})
    qt5_wrap_ui(${UI_FILES}) 
    

    子模块完整的CMakeLists.txt放在下面:

    cmake_minimum_required(VERSION 3.5)
    
    project(View_Equalizer LANGUAGES CXX)
    
    #(CMAKE_INCLUDE_CURRENT_DIR ON)
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    find_package(Qt5 COMPONENTS Widgets PrintSupport REQUIRED)
    
    include_directories(${CMAKE_CURRENT_SOURCE_DIR}/includes)
    set(RESOURCE_FILES  
        ./Resource/Resource.qrc
    )  
    qt5_add_resources(QRC_SOURCES ${RESOURCE_FILES})
    
    set(HEADER_FILES  
        ./includes/DataClass.h  
        ./includes/View_Equalizer_global.h
        ./includes/math_functions.h
        ./includes/Center.h
        ./Views/view_equalizer.h
        ./View_Items/ViewItem_ControlPoint.h
        ./View_Items/PointWidget.h
    )  
    
    set(SOURCE_FILES 
    ./src/DataClass.cpp
    ./src/Center.cpp
    ./QCustomPlot/qcustomplot.cpp
    ./Views/view_equalizer.cpp
    ./View_Items/ViewItem_ControlPoint.cpp
    ./View_Items/PointWidget.cpp
    )
    
    set(UI_FILES
    ./View_Items/PointWidget.ui
    )
    # 假设生成的头文件被放置在当前构建目录下的对应子目录中  
     qt5_wrap_ui(${UI_FILES}) 
    
    add_library(View_Equalizer SHARED ${HEADER_FILES} ${SOURCE_FILES} ${UI_FILES} ${QRC_SOURCES})
    
    target_include_directories(View_Equalizer PUBLIC 
    ${CMAKE_CURRENT_SOURCE_DIR}/math 
    ${CMAKE_CURRENT_SOURCE_DIR}/QCustomPlot 
    ${CMAKE_CURRENT_SOURCE_DIR}/includes 
    ${CMAKE_CURRENT_SOURCE_DIR}/Views 
    ${CMAKE_CURRENT_SOURCE_DIR}/View_Items 
    ${CMAKE_CURRENT_BINARY_DIR})
    target_link_libraries(View_Equalizer PRIVATE Qt5::Widgets Qt5::PrintSupport)
    
    target_compile_definitions(View_Equalizer PRIVATE VIEW_EQUALIZER_LIBRARY)
    
    

    三、关于编译后,组织编译后的内容

    我这里是写了一下编译后的事件,可以参考一下

    cmake_minimum_required(VERSION 3.5)
    
    project(Demo_View_Equalizer LANGUAGES CXX)
    add_subdirectory(./View_Equalizer)
    add_subdirectory(./QtHid)
    set(CMAKE_INCLUDE_CURRENT_DIR ON)
    
    set(CMAKE_AUTOUIC ON)
    set(CMAKE_AUTOMOC ON)
    set(CMAKE_AUTORCC ON)
    
    set(CMAKE_CXX_STANDARD 11)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    
    # QtCreator supports the following variables for Android, which are identical to qmake Android variables.
    # Check http://doc.qt.io/qt-5/deployment-android.html for more information.
    # They need to be set before the find_package(Qt5 ...) call.
    
    #if(ANDROID)
    #    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    #    if (ANDROID_ABI STREQUAL "armeabi-v7a")
    #        set(ANDROID_EXTRA_LIBS
    #            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so
    #            ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so)
    #    endif()
    #endif()
    
    find_package(Qt5 COMPONENTS Widgets REQUIRED)
    if(ANDROID)
      add_library(Demo_View_Equalizer SHARED
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
      )
    else()
      add_executable(Demo_View_Equalizer
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
      )
    endif()
    
    target_link_libraries(Demo_View_Equalizer PRIVATE Qt5::Widgets)
    target_link_libraries(Demo_View_Equalizer PRIVATE View_Equalizer)
    
    # 假设View_Equalizer模块的可执行文件或库在构建后将位于对应的Debug或Release目录下  
    # 并且想在Demo_View_Equalizer模块构建完成后将其复制到对应的Demo_View_Equalizer的Debug或Release目录  
      
    # 获取当前构建类型,默认为Debug,如果未设置CMAKE_BUILD_TYPE  
    if(NOT DEFINED CMAKE_BUILD_TYPE)  
      set(CMAKE_BUILD_TYPE Debug)  
    endif()  
    
    
    # 根据构建类型设置A模块的输出目录路径  
    set(A_OUTPUT_DIR "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}")  
      
    # 假设View_Equalizer模块的输出文件名(需要根据实际情况替换)  
    set(B_OUTPUT_NAME "View_Equalizer.dll") # 假设的输出文件名  
      
    # 设置View_Equalizer模块的输出文件路径  
    set(B_OUTPUT_FILE "${CMAKE_BINARY_DIR}/View_Equalizer/${CMAKE_BUILD_TYPE}/${B_OUTPUT_NAME}")  
      
    # 目标文件在Demo_View_Equalizer模块的输出目录下的路径  
    set(B_OUTPUT_DESTINATION "${A_OUTPUT_DIR}/${B_OUTPUT_NAME}")  
    
    message(STATUS "B_OUTPUT_FILE : ${B_OUTPUT_FILE}")
    message(STATUS "B_OUTPUT_DESTINATION : ${B_OUTPUT_DESTINATION}")
    message(STATUS "command : ${CMAKE_COMMAND} -E copy ${B_OUTPUT_FILE} ${B_OUTPUT_DESTINATION}")
    # 添加一个自定义目标,以确保复制操作被执行  
    add_custom_target(AllBuild ALL  
        DEPENDS ${B_OUTPUT_DESTINATION}  
    )
    # 添加一个自定义命令来执行复制操作  
    add_custom_command(  
        OUTPUT ${B_OUTPUT_DESTINATION}  
        COMMAND ${CMAKE_COMMAND} -E copy ${B_OUTPUT_FILE} ${B_OUTPUT_DESTINATION}  
        DEPENDS ${B_OUTPUT_FILE}  
        COMMENT "Copying View_Equalizer output to Demo_View_Equalizer/${CMAKE_BUILD_TYPE} directory"  
        VERBATIM  
    )  
    # 确保我们的自定义目标在Demo_View_Equalizer之后构建  
    add_dependencies(AllBuild Demo_View_Equalizer)
    
  • 相关阅读:
    可编程 USB 转串口适配器开发板 DS1302 时钟芯片参数读取与修改
    渗透测试之——信息收集思路
    JavaScript-修炼之路第六层
    内网渗透-隧道代理转发
    zsh: command not found: adb问题分析
    基于FPGA的图像高斯滤波实现,包括tb测试文件和MATLAB辅助验证
    同样是测试员,为什么有的人薪资15K,有的人薪资20-30W,学会谈薪真的很重要
    python --- 变量、函数、类的命名规范
    用Python订正数据
    WIN10系统禁止自动更新设置(二)
  • 原文地址:https://www.cnblogs.com/Leventure/p/18180739