在Qt中用cmake实现类似pri文件的功能

文章目录

在假如我们是使用qmake来构建我们的项目的话,可以把子项目的代码用pri文件给组织起来,然后再在主项目中的pro文件中将其include进来。这样就可以将子项目的代码包含进来一起编译,这个对于分工合作还是挺有帮助的。cmake也能实现类似的功能,下面来介绍一下。

1.qmake构建

比如我现在主项目为untitled4.pro,子项目为comm.pri.

其内容为

可以在左侧的文件树状图看到,已经将子项目的文件包含进来了,并且将子项目的东西都收纳在子项目下,清晰明了。

2.cmake实现

cmake这边主要是通过FetchContent模块来实现的。先来看看效果

要达到这个效果,必须要在我们的子项目中创建两个文件:

CMakeLists.txt、comm.cmake(这个comm是我的子项目的命名,实际命名请根据自己的项目来命名)

具体实现过程为:

2.1.子项目CMakeLists.txt的编写

子项目要作为一个库项目来编写,其CMakeLists.txt的内容如下

bash 复制代码
cmake_minimum_required(VERSION 3.16)
project(comm VERSION 1.0.0 LANGUAGES CXX)

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

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt5 REQUIRED COMPONENTS Core)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core)

# 1. 创建一个库目标
add_library(${PROJECT_NAME})

# 添加Qt模块的包含目录和链接库
target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Core)


# 2. 添加头文件路径
#    让使用者能找到头文件
target_include_directories(${PROJECT_NAME}
    PUBLIC
    # ${CMAKE_CURRENT_SOURCE_DIR}
    # 构建时,使用源代码树的路径
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)

# 3. 添加源文件(头文件和源文件都加进来)
target_sources(${PROJECT_NAME}
    PRIVATE
    fakeconnector.h
    fakeconnector.cpp
    baseconnector.h
    baseconnector.cpp
)

# 4. (可选) 设置任何需要的编译特性或链接库
# target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_11)
# target_link_libraries(${PROJECT_NAME} PUBLIC some::other::lib)

2.2.子项目comm.cmake的编写

关键是这个文件,这个文件是用来给主项目中的CMakeLists.txt来引入的。其中的第一句的作用是为了实现无论将这个子项目放在哪个路径下都不会出现路径依赖的问题。下面出现的comm也是我子项目的名字,实际名字请根据自己的项目来决定。

这里有个地方要特别注意。无论你原来的工程名叫啥,FetchContent都会调用string(TOLOWER ${contentName} contentNameLower)将你的工程名小写后再使用。如下图FetchContent的源码所示:

也就是说,经过处理后,所有与FetchContent的相关的变量中包含你的工程名的,你的工程名都要用小写,比如我下面的${comm_SOURCE_DIR} ${comm_BINARY_DIR}这两个变量。否则会报错

bash 复制代码
# 获取当前 CMake 脚本所在目录
get_filename_component(COMM_DIR "${CMAKE_CURRENT_LIST_DIR}" ABSOLUTE)

include(FetchContent)

FetchContent_Declare(
    comm 
    SOURCE_DIR ${COMM_DIR}
)

FetchContent_GetProperties(comm)
if(NOT comm_POPULATED)
    FetchContent_MakeAvailable(comm)
    # FetchContent_Populate(comm)
    # add_subdirectory(${comm_SOURCE_DIR} ${comm_BINARY_DIR})
endif()

2.3.主项目CMakeLists.txt中引入子项目

直接用include() + 你的子项目的cmake文件的相对或者绝对路径即可。

2.4.在子项目中引入第三方库

需要修改一下CMakeLists.txt文件,比如现在我们需要引入opencv库,那么需要以下代码添加到CMakeLists.txt中。关键点在于那几个PUBLIC。用PRIVATE还是PUBLIC得自行判断。

bash 复制代码
# 手动设置OpenCV路径(根据你的实际安装路径修改)
set(OPENCV_ROOT "D:/Qt/opencv4.4.0")  # 修改为你的OpenCV安装根目录
set(OPENCV_INCLUDE_DIRS "${OPENCV_ROOT}/include;${OPENCV_ROOT}/include/opencv2")
set(OPENCV_LIB_DIR "${OPENCV_ROOT}/x64/vc15/lib")

# 添加头文件目录
target_include_directories(${PROJECT_NAME} PUBLIC ${OPENCV_INCLUDE_DIRS})

# 添加库目录
target_link_directories(${PROJECT_NAME} PUBLIC ${OPENCV_LIB_DIR})

# 根据具体的编译模式,自动选择不同的库文件
target_link_libraries(${PROJECT_NAME} PRIVATE
    $<$<CONFIG:Debug>:opencv_world440d>
    $<$<CONFIG:Release>:opencv_world440>
    # $<$<NOT:$<CONFIG:Debug>>:opencv_world440>  # 所有非Debug配置使用Release库
    $<$<CONFIG:RelWithDebInfo>:opencv_world440>  # 明确指定Profile配置使用Release库
)

参考:
【cmake以源码的方式引入第三方项目】

相关推荐
充值内卷12 分钟前
C++单文件迷宫游戏:TauriCPP 开发全记录
开发语言·c++·游戏
Antruly13 分钟前
C++ Web 开发选型漫谈:从 Drogon 到 libuvcpp + uvp,八个项目的定位、兼容性与务实排名
开发语言·前端·c++
EnCi Zheng17 分钟前
AI Agent工具调用防护层怎么写-一份能直接跑的Python四层拦截实现
大数据·开发语言·python
香蕉大香蕉(06敬畏市场)28 分钟前
高频八股 · Java 并发编程(10):异步、ThreadLocal 与虚拟线程(收官)
java·开发语言·网络·jvm·python·ai·实习
念何架构之路31 分钟前
Go reflect包值操作 Value 的读写、可设置性与 interface 布局
开发语言·后端·golang
云中飞鸿38 分钟前
.Net和C#有什么关系?(从C++视角观察)
开发语言·c#·.net
another heaven40 分钟前
【C/C++ C++ 新特性中的那些内存优化的特性】
c语言·开发语言·c++
Wang's Blog42 分钟前
Java 项目实战: 交友项目 - 查询推荐动态
java·开发语言·交友
jaysee-sjc1 小时前
【苍穹外卖】Day10:定时任务与 WebSocket 实时提醒实战
java·开发语言·javascript·数据库·vue.js·websocket·网络协议
ysu_03141 小时前
【C++ 进阶之路】(二)从内联函数到类与对象:深挖内存对齐、this 指针与三大默认成员函数
开发语言·数据结构·c++·笔记·面向对象·this