IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> CmakeList使用(结合Qt实例) -> 正文阅读

[C++知识库]CmakeList使用(结合Qt实例)

CmakeList使用

序言:参考文章1 参考文章2 参考文章3

cmake 是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。

一个c++程序编译需要包含:源文件、引用库以及相关头文件、第三方库以及相关路径,cmakelist.txt文件主要任务就是对这些文件进行查找、链接。

一、常用变量

1、预定义变量

PROJECT_SOURCE_DIR:工程的根目录
PROJECT_BINARY_DIR:运行 cmake 命令的目录,通常是 ${PROJECT_SOURCE_DIR}/build
PROJECT_NAME:返回通过 project 命令定义的项目名称
CMAKE_CURRENT_SOURCE_DIR:当前处理的 CMakeLists.txt 所在的路径
CMAKE_CURRENT_BINARY_DIR:target 编译目录
CMAKE_CURRENT_LIST_DIR:CMakeLists.txt 的完整路径
CMAKE_CURRENT_LIST_LINE:当前所在的行
CMAKE_MODULE_PATH:定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块
EXECUTABLE_OUTPUT_PATH:重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH:重新定义目标链接库文件的存放位置

2、环境变量

1、使用环境变量

 $ENV{Name}

2、写入环境变量

 set(ENV{Name} value) # 这里没有“$”符号
3、系统信息

CMAKE_MAJOR_VERSION:cmake 主版本号,比如 3.4.1 中的 3
-CMAKE_MINOR_VERSION:cmake 次版本号,比如 3.4.1 中的 4
CMAKE_PATCH_VERSION:cmake 补丁等级,比如 3.4.1 中的 1
-CMAKE_SYSTEM:系统名称,比如 Linux--2.6.22
-CMAKE_SYSTEM_NAME:不包含版本的系统名,比如 Linux
-
CMAKE_SYSTEM_VERSION:系统版本,比如 2.6.22
-
CMAKE_SYSTEM_PROCESSOR
:处理器名称,比如 i686
UNIX:在所有的类 UNIX 平台下该值为 TRUE,包括 OS X 和 cygwin
WIN32:在所有的 win32 平台下该值为 TRUE,包括 cygwin

4、主要开关选项

BUILD_SHARED_LIBS:这个开关用来控制默认的库编译方式,如果不进行设置,使用 add_library 又没有指定库类型的情况下,默认编译生成的库都是静态库。如果 set(BUILD_SHARED_LIBS ON) 后,默认生成的为动态库
CMAKE_C_FLAGS:设置 C 编译选项,也可以通过指令 add_definitions() 添加
CMAKE_CXX_FLAGS:设置 C++ 编译选项,也可以通过指令 add_definitions() 添加

二、常用命令(使用示例进行说明)

1、指定 cmake 的最小版本
#这行命令是可选的,我们可以不写这句话,但在有些情况下,
#如果 CMakeLists.txt 文件中使用了一些高版本 cmake 特有的一些命令的时候,就需要加上这样一行,提醒用户升级到该版本之后再执行 cmake。
cmake_minimum_required(VERSION 3.1)

2、设置项目名称
#这个命令不是强制性的,但最好都加上。它会引入两个变量 demo_BINARY_DIR 和 demo_SOURCE_DIR,
#同时,cmake 自动定义了两个等价的变量 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR。
project(DEMO)

#-------------------------------------- 编译器设置 --------------------------------------#
3、set命令
语法: SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]]) 
指令功能: 用来显式的定义变量 
例子: SET (SRC_LST main.c other.c) 
说明: 用变量代替值,例子中定义SRC_LST代替后面的字符串

#set命令可以看成定义变量,可以将长路径用变量代替,并且可进行拼接
#3.1 set 直接设置变量的值
set(SRC_LIST main.cpp test.cpp)
add_executable(demo ${SRC_LIST})

#3.2 set 追加设置变量的值
set(SRC_LIST main.cpp)
set(SRC_LIST ${SRC_LIST} test.cpp)
add_executable(demo ${SRC_LIST})

#3.3 list 追加或者删除变量的值
set(SRC_LIST main.cpp)
list(APPEND SRC_LIST test.cpp)
list(REMOVE_ITEM SRC_LIST main.cpp)
add_executable(demo ${SRC_LIST})

#以下是程序中对编译器进行设置
set(CMAKE_BUILD_TYPE  Debug) #设置编译类型为debug
set(CMAKE_CXX_STANDARD 11) #设置C++版本为C11
set(CMAKE_INCLUDE_CURRENT_DIR ON) #设置当前包含的头文件开启

#设置opencv路径
set(OpenCV_DIR /usr/local/lib/cmake/opencv4)
set(OpenCV_INCLUDE_DIRS /usr/local/include/opencv4)

#-------------------------------------- 搜索软件包 --------------------------------------#
4、find_package
#使用背景:当编译一个需要使用第三方库的软件时,我们需要知道:

		去哪儿找头文件 .h												对比GCC的 -I 参数     			——INCLUDE_DIRECTORIES——
		去哪儿找库文件 (.so/.dll/.lib/.dylib/…)	对比GCC的 -L 参数			   ——LINK_DIRECTORIES——
		需要链接的库文件的名字									对比GCC的 -l 参数				——LINK_LIBRARIES——

#比如说,我们需要一个第三方库 curl,那么我们的 CMakeLists.txt 需要指定头文件目录,和库文件,类似:
include_directiories(/usr/include/curl)
target_link_libraries(myprogram path/curl.so)

#如果借助于cmake提供的finder会怎么样呢?使用cmake的Modules目录下的FindCURL.cmake,相应的CMakeList.txt 文件:
find_package(CURL REQUIRED)  #REQUIRED参数,没找到的话cmake执行失败
include_directories(${CURL_INCLUDE_DIR})
target_link_libraries(curltest ${CURL_LIBRARY})

#具体实例如下:
# Find the QtWidgets library
find_package(Qt5 COMPONENTS Widgets REQUIRED)
find_package(OpenCV  REQUIRED)
find_package(CUDA REQUIRED)

#追加  LIBRARIES  路径
list(APPEND LIBRARIES ${CUDA_LIBRARIES})
list(APPEND LIBRARIES ${CUDA_CUBLAS_LIBRARIES})

5、message
#打印信息,可以进行路径验证,方便查错
message(STATUS "CUDA library status:")
message(STATUS "version: ${CUDA_VERSION}")
message(STATUS "*****libraries: ${CUDA_LIBRARIES}")
message(STATUS "\n include path*****: ${CUDA_INCLUDE_DIRS}")
message(STATUS "\n OpenCV  include path*****: ${OpenCV_INCLUDE_DIRS}")
message(STATUS "*****CUDACUBLAS libraries: ${CUDA_CUBLAS_LIBRARIES}")

#-------------------------------------- 包含头文件 --------------------------------------#
#CMake支持大写、小写、混合大小写的命令
#引用第三方库需要  
#1、在哪找头文件  include_directories
#2、在哪找库文件  link_directories
#3、库文件名称	  target_link_libraries

6、include_directories
#添加第三方库包含的目录(即找头文件)
include_directories(${Caffe_INCLUDE_DIRS})  #设置包含caffe组件头文件的路径

7、link_directories
# 添加需要链接的库文件目录(即找 .so库文件)
link_directories(${Caffe_LIB_DIRS})

 #添加常见包含路径
include_directories(include
                                        ${Qt5Widgets_INCLUDE_DIRS}
                                        ${OpenCV_INCLUDE_DIRS}
                                        ${CUDA_INCLUDE_DIRS}
                                        ${EIGEN3_INCLUDE_DIR}
                                        ${FFmpeg_include_path}
										)
include_directories(${CMAKE_CURRENT_BINARY_DIR}) #target 编译目录

#-------------------------------------- -添加项目- --------------------------------------#
#添加所有的源文件
SET(DEMO_SOURCES  main.cpp xxx.cpp) #.cpp
SET(DEMO_HEADERS   xxx.h) #.h
SET(DEMO_FORMS  Display.ui) #.ui
SET(DEMO_QRC_FILE Resource.qrc) #.qrc
qt5_add_resources(QRC ${DEMO_QRC_FILE})

#调用预编译器moc,需要使用 QT5_WRAP_CPP宏
QT5_WRAP_CPP(DEMO_HEADERS_MOC ${DEMO_HEADERS})

#使用uic处理.ui文件
QT5_WRAP_UI(DEMO_FORMS_HEADERS ${DEMO_FORMS})

8、 指定编译包含的源文件
#8.1 明确指定包含哪些源文件
add_library(demo demo.cpp test.cpp util.cpp)

#8.2 搜索所有的 cpp 文件
aux_source_directory(. SRC_LIST) # 搜索当前目录下的所有.cpp文件
add_library(demo ${SRC_LIST})

#8.3 自定义搜索规则
file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_library(demo ${SRC_LIST})
# 或者
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
# 或者
file(GLOB_RECURSE SRC_LIST "*.cpp") #递归搜索
FILE(GLOB SRC_PROTOCOL RELATIVE "protocol" "*.cpp") # 相对protocol目录下搜索
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
# 或者
aux_source_directory(. SRC_LIST)
aux_source_directory(protocol SRC_PROTOCOL_LIST)
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

#具体实例如下:
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR})#工程的根目录
file(GLOB_RECURSE HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h*)#当前处理的 CMakeLists.txt 所在的路径/include

9、find_library
#查找到指定的预编译库,并将它的路径存储在变量中
#默认的搜索路径为 cmake 包含的系统库,因此如果是 NDK 的公共库只需要指定库的 name 即可
find_library(streamhk NAMES libstreamhk.so REQUIRED)
find_library(rqueue NAMES librqueue.so REQUIRED)
message(STATUS "streamhk:" ${streamhk})
message(STATUS "rqueue:" ${rqueue})

#-------------------------------------- -添加所有的源文件- --------------------------------------#
SET(DEMO_SOURCES  main.cpp xxx.cpp) #.cpp
SET(DEMO_HEADERS   xxx.h) #.h
SET(DEMO_FORMS  Display.ui) #.ui
SET(DEMO_QRC_FILE Resource.qrc) #.qrc

qt5_add_resources(QRC ${DEMO_QRC_FILE}
QT5_WRAP_CPP(DEMO_HEADERS_MOC ${DEMO_HEADERS})
QT5_WRAP_UI(DEMO_FORMS_HEADERS ${DEMO_FORMS})

#-------------------------------------- -生成可以执行的文件- --------------------------------------#
add_executable(DEMO
                                ${DEMO_SOURCES}
                                ${DEMO_HEADERS_MOC}
                                ${DEMO_FORMS_HEADERS}
                                ${HEADER_FILES}
                                ${QRC}
								)

#===================================================#                             
 #TARGET_LINK_LIBRARIES (设置要链接的库文件的名称)
#语法:TARGET_LINK_LIBRARIES(targetlibrary1 <debug | optimized> library2 ..)

比如(以下写法(包括备注中的)都可以): 
TARGET_LINK_LIBRARIES(myProject hello),连接libhello.so库
TARGET_LINK_LIBRARIES(myProject libhello.a)
TARGET_LINK_LIBRARIES(myProject libhello.so)

再如:
TARGET_LINK_LIBRARIES(myProject libeng.so)  #这些库名写法都可以。
TARGET_LINK_LIBRARIES(myProject eng)
TARGET_LINK_LIBRARIES(myProject -leng)
#===================================================#

#-------------------------------------- -链接第三方库- --------------------------------------#
target_link_libraries(DEMO
                                        ${Qt5Widgets_LIBRARIES}
                                        ${streamhk}
                                        ${rqueue}
                                        /usr/lib/x86_64-linux-gnu/libgflags.so
                                        /usr/lib/x86_64-linux-gnu/libglog.so
                                        ${OpenCV_LIBRARIES}
                                        ${caffe}
                                        ${nvcuvid}
                                        /usr/local/cuda-10.0/lib64/libcudart.so
                                        /usr/local/cuda-10.0/lib64/stubs/libcuda.so
                                        -lpthread
                                        libavformat.so
                                        libavcodec.so
                                        libswscale.so
                                        libavutil.so
                                        )
#-------------------------------------- -生成可执行文件(二进制文件)- --------------------------------------#             
install(TARGETS DEMO RUNTIME DESTINATION ${CMAKE_SOURCE_DIR})
                  
#===================================================#
#INSTALL 命令用于定义安装规则,安装内容包括可执行文件,静态库,动态库以及文件,目录,脚本等
#命令格式:
INSTALL(TARGETS target...
                 [ [ARCHIVE|LIBRARY|RUNTIME]
                 [DESTINATION <dir>]
                 ] [...])
命令解释:
TARGETS 后面跟的可能是二进制,动态库,静态库中的某一种或者全是
目标类型也相对的有三种: ARCHIVE特指静态库,LIBRARY特指动态库,RUNTIME特质可执行目标二进制
DESTINATION 定义安装路径,如果以" /" 开头,则说明指定的是绝对路径,此时的CMAKE_INSTALL_PREFIX就无效了
#===================================================#

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-18 09:54:07  更:2021-09-18 09:59:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 12:47:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计