Cmake学习

cmake大致

image.png

cmake_minimum_required(VERSION 3.0)project(test)
#通过set自定义变量,通过${}取出
#set(SRC add.cpp main.cpp muti.cpp sub.cpp)
#cmake搜索文件 宏定义PROJECT_SOURCE_DIR
aux_source_directory(${PROJECT_SOURCE_DIR} SRC)
#file(GLOB/GLOB_RECURSE 变量名 要搜索的文件路径和文件类型)
#GLOB: 将指定目录下搜索到的满足条件的所有文件名生成一个列表,并将其存储到变量中。
#GLOB_RECURSE:递归搜索指定目录,将搜索到的满足条件的文件名生成一个列表,并将其存储到变量中。#指定最后生成程序输出的路径
set(EXECUTABLE_OUTPUT_PATH ./bin)
#指定c++使用的标准
set(CAMKE_CXX_STANDARD 11)
#生成可执行程序exe
add_executable(app ${SRC})
#指定头文件路径
cmake_minimum_required(VERSION 3.0)project(test)
#通过set自定义变量,通过${}取出
#aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
#指定最后生成程序输出的路径
set(EXECUTABLE_OUTPUT_PATH ./bin)
#引入头文件
include_directories(${PROJECT_SOURCE_DIR}/include)
#指定c++使用的标准
set(CAMKE_CXX_STANDARD 11)
add_executable(app ${SRC})

通过Cmake制作库文件

制作静态库

cmake_minimum_required(VERSION 3.0)
project(CALC)
include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
add_library(calc STATIC ${SRC_LIST})
#add_library(库名称 STATIC 源文件1 [源文件2] ...) 

动态库dll是有可执行权限的

制作动态库

include_directories(${PROJECT_SOURCE_DIR}/include) #包含头文件
set(LIBRARY_OUTPUT_PATH ../lib)
add_library(calc SHARED ${SRC})

链接静态库

如果要新建一个项目使用库文件,需要将原来的头文件和库文件一同拷贝过来

#使用静态链接库
cmake_minimum_required(VERSION 3.0)project(test)
#通过set自定义变量,通过${}取出
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
include_directories(${PROJECT_SOURCE_DIR}/include)
#链接静态库
link_libraries(calc)
#指定静态库的位置
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
add_executable(app ${SRC})

当我们在使用静态库的时候,在生成可执行文件exe的时候相应的静态库文件会打包到exe那个文件夹里面

链接动态库

target_link_libraries(<target> <PRIVATE|PUBLIC|INTERFACE> <item>... [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)

target:指定要加载动态库的文件的名字
动态库具有链接的能力,假如说动态库a链接b再链接c,但是传递是由前提条件的,必须是public
该文件可能是一个源文件
该文件可能是一个动态库文件
该文件可能是一个可执行文件
PRIVATE|PUBLIC|INTERFACE:动态库的访问权限,默认为PUBLIC

如果各个动态库之间没有依赖关系,无需做任何设置,三者没有没有区别,一般无需指定,使用默认的 PUBLIC 即可。

动态库的链接具有传递性,如果动态库 A 链接了动态库B、C,动态库D链接了动态库A,此时动态库D相当于也链接了动态库B、C,并可以使用动态库B、C中定义的方法。

target_link_libraries(A B C)
target_link_libraries(D A)
  • PUBLIC:在public后面的库会被Link到前面的target中,并且里面的符号也会被导出,提供给第三方使用。
  • PRIVATE:在private后面的库仅被link到前面的target中,并且终结掉,第三方不能感知你调了啥库
  • INTERFACE:在interface后面引入的库不会被链接到前面的target中,只会导出符号。

使用动态链接库

#使用动态链接库
cmake_minimum_required(VERSION 3.0)
project(test)FILE(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)include_directories(${PROJECT_SOURCE_DIR}/include)
# 指定动态库存放的位置
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
add_executable(app ${SRC})
# 使用动态链接库
target_link_libraries(app calc)

动态库的链接和静态库是完全不同的:

静态库会在生成可执行程序的链接阶段被打包到可执行程序中,所以可执行程序启动,静态库就被加载到内存中了。
动态库在生成可执行程序的链接阶段不会被打包到可执行程序中,当可执行程序被启动并且调用了动态库中的函数的时候,动态库才会被加载到内存
因此,在cmake中指定要链接的动态库的时候,应该将命令写到生成了可执行文件之后:

cmake_minimum_required(VERSION 3.0)
project(TEST)
file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
# 添加并指定最终生成的可执行程序名
add_executable(app ${SRC_LIST})
# 指定可执行程序要链接的动态库名字
target_link_libraries(app pthread)

在target_link_libraries(app pthread)中:

app: 对应的是最终生成的可执行程序的名字
pthread:这是可执行程序要加载的动态库,这个库是系统提供的线程库,全名为libpthread.so,在指定的时候一般会掐头(lib)去尾(.so)。
假设在测试文件main.cpp中既使用了自己制作的动态库libcalc.so又使用了系统提供的线程库,此时CMakeLists.txt文件可以这样写:

cmake_minimum_required(VERSION 3.0)
project(TEST)
file(GLOB SRC_LIST ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
include_directories(${PROJECT_SOURCE_DIR}/include)
add_executable(app ${SRC_LIST})
target_link_libraries(app pthread calc)

cmake日志

#使用动态链接库
cmake_minimum_required(VERSION 3.0)
project(test)FILE(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)include_directories(${PROJECT_SOURCE_DIR}/include)
# 日志
message("first logs")
# 指定动态库存放的位置
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
message(STATUS "second logs")
add_executable(app ${SRC})
# 使用动态链接库
target_link_libraries(app calc)
message(FATAL_ERROR "third fatal error")
message(STATUS "fourth logs")

image.png

#使用动态链接库
cmake_minimum_required(VERSION 3.0)
project(test)FILE(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)include_directories(${PROJECT_SOURCE_DIR}/include)
# 日志
message("first logs")
# 指定动态库存放的位置
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
message(STATUS "second logs")
add_executable(app ${SRC})
# 使用动态链接库
target_link_libraries(app calc)
#打印变量值
message("var is :"${SRC})
message(FATAL_ERROR "third fatal error")
message(STATUS "fourth logs")

image.png

字符串操作

cmake_minimum_required(VERSION 3.5)
project(test)
set(value1 "value1")
set(value2 "value2")
message(${value1})
#字符串拼接
set(value3 ${value1} "+" ${value2})
message("value3:" ${value3})#使用list追加字符串
list(APPEND value3 " zhui jia zi fu chuan")
message(${value3})

#移除src中main.cpp的名字
cmake_minimum_required(VERSION 3.5)
project(test)
#获取src目录下所有源文件的绝对路径
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
message("======================")
message(${SRC})
list(REMOVE_ITEM SRC ${PROJECT_SOURCE_DIR}/src/main.cpp)
message("删除之后的字符串")
message(${SRC})

=====================
D:/C++workspace/c++程序/cmake_str/src/add.cppD:/C++workspace/c++程序/cmake_str/src/main.cppD:/C++workspace/c++程序/cmake_str/src/muti.cppD:/C++workspace/c++程序/cmake_str/src/sub.cpp
删除之后的字符串
D:/C++workspace/c++程序/cmake_str/src/add.cppD:/C++workspace/c++程序/cmake_str/src/muti.cppD:/C++workspace/c++程序/cmake_str/src/sub.cpp

list的其他命令:
获取list长度

list(LENGTH <list> <output variable>)
  • LENGTH:子命令LENGTH用于读取列表长度
  • :当前操作的列表
  • :新创建的变量,用于存储列表的长度。

读取列表中指定索引的的元素,可以指定多个索引:

list(GET <list> <element index> [<element index> ...] <output variable>)
  • :当前操作的列表
  • :列表元素的索引
    • 从0开始编号,索引0的元素为列表中的第一个元素;
    • 索引也可以是负数,-1表示列表的最后一个元素,-2表示列表倒数第二个元素,以此类推
    • 当索引(不管是正还是负)超过列表的长度,运行会报错
  • :新创建的变量,存储指定索引元素的返回结果,也是一个列表。

将列表中的元素用连接符(字符串)连接起来组成一个字符串

list (JOIN <list> <glue> <output variable>)
  • :当前操作的列表
  • :指定的连接符(字符串)
  • :新创建的变量,存储返回的字符串

查找列表是否存在指定的元素,若果未找到,返回-1

list(FIND <list> <value> <output variable>)
  • :当前操作的列表
  • :需要再列表中搜索的元素
  • :新创建的变量

等等。。。

cmake中自定义宏

#include <stdio.h>
#define NUMBER  3int main()
{int a = 10;//cmake中没有添加debug相关配置所以在debug模式下运行,并不会运行ifdef debug里面的打印内容#ifdef DEBUGprintf("我是一个程序猿, 我不会爬树...\n");#endiffor(int i=0; i<NUMBER; ++i){printf("hello, GCC!!!\n");}return 0;
}

image.png

cmake_minimum_required(VERSION 3.5)
project(Test)
file(GLOB SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
add_definitions(-DDEBUG)
add_executable(app ${SRC})

image.png

嵌套的cmake

文件夹目录
image.png
根目录下的cmakelist

cmake_minimum_required(VERSION 3.5)
project(test)
#定义变量
#静态库生成路径
set(LIBPATH ${PROJECT_SOURCE_DIR}/lib)
#可执行程序存放地址
set(EXECPATH ${PROJECT_SOURCE_DIR}/bin)
#头文件路径
set(HEADPATH ${PROJECT_SOURCE_DIR}/include)
#库文件的名字
set(CALCLIB calc)
set(SORTLIB sort)
#可执行程序的名字
set(APPNAME1 app1)
set(APPNAME2 app2)#给当前节点添加子目录
add_subdirectory(calc)
add_subdirectory(sort)
add_subdirectory(test1)
add_subdirectory(test2)

calc文件夹下的cmakelist 子节点中的变量无法在父节点中用,父节点的变量可以在子节点用

cmake_minimum_required(VERSION 3.5)
project(calc)
#搜索当前路径下的所有cpp文件 搜索源文件
aux_source_directory(./ SRC)
# 搜索头文件 include文件夹下 父节点已经定义了include文件夹路径变量HEADPATH
include_directories(${HEADPATH})
#指定静态库生成的路径
set(LIBRARY_OUTPUT_PATH ${LIBPATH})
#把源文件变成静态库
add_library(${CALCLIB} STATIC ${SRC})

sort目录下的文件cmakelist

cmake_minimum_required(VERSION 3.5)
project(sort)
#搜索当前路径下的所有cpp文件 搜索源文件
aux_source_directory(./ SRC)
# 搜索头文件 include文件夹下 父节点已经定义了include文件夹路径变量HEADPATH
include_directories(${HEADPATH})
#指定静态库生成的路径
set(LIBRARY_OUTPUT_PATH ${LIBPATH})
#把源文件变成静态库
add_library(${SORTLIB} STATIC ${SRC})

test1目录下的cmakelist执行calc的主程序

cmake_minimum_required(VERSION 3.5)
project(test1)aux_source_directory(./ SRC)include_directories(${HEADPATH})
link_directories(${LIBPATH})
link_libraries(${CALCLIB})
#生成可执行文件的目录
set(EXECUTABLE_OTPUT_PATH ${EXECPATH})
add_executable(${APPNAME1} ${SRC})

在静态库中链接静态库

主要做的是在排序的静态库sort.lib中引用calc.lib需要做以下修改
冒泡排序cpp中调用calc静态库的链接 删掉test2

#include<iostream>
#include "sort.h"
#include "calc.h"using namespace std;void bubble_sort(int mylist[],int listsize){int number1 = add(mylist[0],mylist[1]);cout<<"在选择排序中调用calc的加法操作"<<number1<<endl;for(int i=0;i<listsize;i++){for(int j=i;j<listsize;j++){if(mylist[i]<mylist[j]){int temp = mylist[i];mylist[i]=mylist[j];mylist[j]=temp;}}}}

calc目录下的cmakelist保持不变
sort目录下的cmakelist

cmake_minimum_required(VERSION 3.5)
project(sort)
#搜索当前路径下的所有cpp文件 搜索源文件
aux_source_directory(./ SRC)
# 搜索头文件 include文件夹下 父节点已经定义了include文件夹路径变量HEADPATH
include_directories(${HEADPATH})
#指定静态库生成的路径
set(LIBRARY_OUTPUT_PATH ${LIBPATH})
# 指定自定义静态库的存放路径
link_directories(${LIBPATH})
# 链接calc静态库
link_libraries(${CALCLIB})
#把源文件变成静态库
add_library(${SORTLIB} STATIC ${SRC})

test/main.cpp下的cmakelist

cmake_minimum_required(VERSION 3.5)
project(test2)aux_source_directory(./ SRC)include_directories(${HEADPATH})
link_directories(${LIBPATH})
link_libraries(${SORTLIB})
#生成可执行文件的目录
set(EXECUTABLE_OTPUT_PATH ${EXECPATH})
add_executable(${APPNAME2} ${SRC})

sort.lib已经引用的calc.lib所以,test下就不需要再引用calc.lib了
image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/150768.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

静态文件鉴权

​ 静态文件鉴权的解决方案 背景介绍 XX业务系统作为BXX业务系统的孪生姐妹系统&#xff0c;是对BXX受理业务的强力补充系统&#xff0c;他允许操作员拿着IPAD&#xff0c;和客户约定地点上门受理业务。 因一些业务的受理&#xff0c;按照最新的业务规章制度&#xff0c;需…

常用 API 异常

常用 API & 异常 对之前那篇 API 文章的补充学习 1.API 1.1 API概述【理解】 什么是API ​ API (Application Programming Interface) &#xff1a;应用程序编程接口 java中的API ​ 指的就是 JDK 中提供的各种功能的 Java类&#xff0c;这些类将底层的实现封装了起来&am…

OpenCV快速入门:窗口交互

文章目录 前言一、鼠标操作1.1 鼠标操作简介1.2 鼠标事件类型&#xff08;event类型&#xff09;1.3 鼠标事件标志&#xff08;flags&#xff09;1.4 代码示例1.4.1 获取鼠标坐标位置1.4.2 监听鼠标滚轮事件1.4.3 在图像中显示鼠标坐标 二、键盘操作2.1 代码示例2.2 waitKey的等…

ssm家长乐山美食网站系统

1.需求分析\n将进行家乡乐山美食网站的需求分析。需求分析是系统开发过程中的一项重要工作&#xff0c;它是对用户需求进行深入研究和分析&#xff0c;明确系统的功能、性能、界面等方面的需求&#xff0c;为后续的设计和开发提供依据。\n首先&#xff0c;需要明确该网站的主要…

制作Go程序的Docker容器(以及容器和主机的网络问题)

今天突然遇到需要将 Go 程序制作成 Docker 的需求&#xff0c;所以进行了一些研究。方法很简单&#xff0c;但是官方文档和教程有些需要注意的地方&#xff0c;所以写本文进行记录。 源程序 首先介绍一下示例程序&#xff0c;示例程序是一个 HTTP 服务器&#xff0c;会显示si…

【GUI】-- 11 贪吃蛇小游戏之绘制静态的小蛇

GUI编程 04 贪吃蛇小游戏 4.2 第二步&#xff1a;绘制静态的小蛇 现在绘制静态的小蛇(即小蛇初始位置)&#xff0c;并且完善游戏默认初始状态。这一步还在GamePanel类中实现。 首先&#xff0c;定义了小蛇的数据结构&#xff0c; //定义蛇的数据结构int length; //小蛇总长…

yolo系列模型训练数据集全流程制作方法(附数据增强代码)

yolo系列的模型在目标检测领域里面受众非常广&#xff0c;也十分流行&#xff0c;但是在使用yolo进行目标检测训练的时候&#xff0c;往往要将VOC格式的数据集转化为yolo专属的数据集&#xff0c;而yolo的训练数据集制作方法呢&#xff0c;最常见的也是有两种&#xff0c;下面我…

开源与闭源:大模型发展的双重走向

目录 前言开源和闭源的优劣势比较开源的优势闭源的优势 开源和闭源对大模型技术发展的影响对技术发展的影响对数据共享的影响对业务拓展的影响 开源与闭源的商业模式比较开源的商业模式闭源的商业模式 处在大模型洪流中&#xff0c;向何处去&#xff1f;结语 前言 随着人工智能…

中国智能音箱市场销量下降,百度稳居第一 /中国即评出10个大模型创新案例 |魔法半周报

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件&#x1f525;&#xff0c;更新AIGC的最新动态&#xff0c;生成相应的魔法简报&#xff0c;节省阅读时间&#x1f47b; 中国智能音箱市场销量下降&#xff0c;百度稳居第一 中国即将评选出10个最具代表性的大模型创新案例…

【Typroa使用】Typroa+PicGo-Core(command line)+gitee免费图片上传配置

TyproaPicGo-Core(command line)gitee免费图片上传配置 本文是在win10系统下配置typroapicGo-Core(command line)gitee图片上传的教程。需要的环境和工具有&#xff1a; gitee账号&#xff0c;新建仓库及token令牌&#xff1b;已经安装了的typroa&#xff0c;需要0.9.98版本以上…

2023最全的性能测试种类介绍,这6个种类特别重要!

系统的性能是一个很大的概念&#xff0c;覆盖面非常广泛&#xff0c;包括执行效率、资源占用、系统稳定性、安全性、兼容性、可靠性、可扩展性等&#xff0c;性能测试就是描述测试对象与性能相关的特征并对其进行评价而实施的一类测试。 性能测试是一个统称&#xff0c;它其实包…

大数据Doris(二十五):Stream Load数据导入演示和其他导入案例

文章目录 数据导入演示和其他导入案例 一、数据导入演示

【Web】Ctfshow SSRF刷题记录1

核心代码解读 <?php $url$_POST[url]; $chcurl_init($url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $resultcurl_exec($ch); curl_close($ch); ?> curl_init()&#xff1a;初始curl会话 curl_setopt()&#xff1a;会…

水质测定仪的优势特点有哪些?

水质测定仪&#xff1a;水环境保护的得力助手 随着人们环保意识的不断提高&#xff0c;水质问题逐渐引起了大家的关注。为了保护水环境&#xff0c;必须加强对污水排放的监测&#xff0c;而水质测定仪在这个过程中扮演着重要的角色。 水质测定仪是一种专业的仪表&#xff0c;主…

旋极携手西班牙SoC-e公司,为中国客户提供高效可靠TSN通讯解决方案

2023年2月&#xff0c;旋极信息与西班牙SoC-e公司正式签订战略合作协议&#xff0c;成为其在中国区重要合作伙伴。 SoC-e是一家世界领先的基于FPGA技术的以太网通讯解决方案供应商&#xff0c;是一系列IP核开发领域的先锋&#xff0c;为关键任务实施网络化、同步性和安全性提供…

如何使用贝锐花生壳内网穿透远程访问JupyterNotebook?

在数据科学领域&#xff0c;Jupyter Notebook 已成为处理数据的必备工具。 其用途包括数据清理和探索、可视化、机器学习和大数据分析。Jupyter Notebook的安装非常简单&#xff0c;如果你是小白&#xff0c;那么建议你通过安装Anaconda来解决Jupyter Notebook的安装问题&#…

【23真题】超难985!做完感觉没学过!

本套试卷难度分析&#xff1a;22年西北工业大学827考研真题&#xff0c;我也发布过&#xff0c;若有需要&#xff0c;戳这里自取&#xff01;本套试题内容有难度&#xff0c;题目考察全为大题&#xff0c;题目不多&#xff01;但是题目都很新颖&#xff0c;状态方程的题目考察较…

CMSIS-RTOS在stm32使用

目录&#xff1a; 一、安装和配置CMSIS_RTOS.1.打开KEIL工程&#xff0c;点击MANAGE RUN-TIME Environment图标。2.勾选CMSIS CORE和RTX.3.配置RTOS 时钟频率、任务栈大小和数量&#xff0c; 软件定时器. 二、CMSIS_RTOS内核启动和创建线程。1.包含头文件。2.内核初始化和启动。…

【开源】基于JAVA的快递管理系统

项目编号&#xff1a; S 007 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S007&#xff0c;文末获取源码。} 项目编号&#xff1a;S007&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快…