【小沐学C++】C++ 基于CMake构建工程项目(Windows、Linux)
文章目录
- 1、简介
- 2、下载cmake
- 3、安装cmake
- 4、测试cmake
- 4.1 单个源文件
- 4.2 同一目录下多个源文件
- 4.3 不同目录下多个源文件
- 4.4 标准组织结构
- 4.5 动态库和静态库的编译
- 4.6 对库进行链接
- 4.7 添加编译选项
- 4.8 添加控制选项
- 5、构建最小项目
- 5.1 新建代码文件
- 5.2 新建CMakeLists.txt
- 5.3 构建项目
- 5.4 编译项目
- 5.5 运行项目
- 5.6 修改相关文件
- 结语
1、简介
官网地址:
https://cmake.org
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。只是 CMake 的组态档取名为 CMakeLists.txt。
2、下载cmake
(1)官网下载地址一
https://cmake.org/download/
(2)官网下载地址二
https://cmake.org/files/
(3)GitHub下载地址:
https://github.com/Kitware/CMake/releases
ubuntu系统下只需要如下一句命令即可:
# ubuntu
sudo apt install cmake
CMake 提供了多种版本,包括但不限于 “RC 版本”(Release Candidate)和“稳定版本”(Latest Release)。切换到系统存放源代码的目录,再用 curl 命令通过该链接将 CMake 的二进制分发压缩包下载下来:
cd /usr/local/srccurl -LO https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz# or
yum install -y wget
wget -c https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz
# wget -c https://cmake.org/files/v3.26/cmake-3.26.0-rc1-linux-x86_64.tar.gz
3、安装cmake
CMake 二进制分发压缩包下载完毕后,运行以下两条命令将压缩包解压缩,并将得到的文件夹移动到系统的本地程序目录,同时将文件夹重命名为 cmake(即 /usr/local/cmake):
tar -xvf cmake-3.26.0-rc1-linux-x86_64.tar.gz
# tar zxvf cmake-3.22.2-linux-x86_64.tar.gz
mv cmake-3.26.0-rc1-linux-x86_64 /usr/local/cmake
查看安装后的路径:
ls /usr/local/cmake
如果你是第一次按照本文步骤安装 CMake,为方便之后运行 CMake 的相关命令,请运行以下两条命令将 CMake 的可执行文件目录添加到系统环境变量 PATH 中:
echo 'export PATH="/usr/local/cmake/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
查看~/.bashrc:
vi ~/.bashrc
#在最后添加export PATH=/usr/local/cmake/bin:$PATH
查看cmake的版本:
cmake --verison
4、测试cmake
4.1 单个源文件
main.c:
#include <stdio.h>int main(void)
{printf("Hello World\n");return 0;
}
然后在main.c相同目录下编写CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (demo)
add_executable(main main.c)
执行命令:
cmake .
再来看看目录下的文件,成功生成了Makefile,还有一些cmake运行时自动生成的文件:
查看Makefile:
vi Makefile
输入make命令进行编译:
make
ls
./main
#make clean
4.2 同一目录下多个源文件
安装tree命令,方便查看文件夹的层级关系:
ubuntu:sudo apt-get install tree
centos:yum -y install tree
tree ./
修改CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)project (demo)
add_executable(main main.c anotherTest.c)
执行命令:
cmake .
ls
make
./main
如果在同一目录下有多个源文件。cmake提供了一个命令可以把指定目录下所有的源文件存储在一个变量中,这个命令就是 aux_source_directory(dir var)。第一个参数dir是指定目录,第二个参数var是用于存放源文件列表的变量。
修改CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)project (demo)
aux_source_directory(. SRC_LIST)
add_executable(main ${SRC_LIST})
使用aux_source_directory把当前目录下的源文件存列表存放到变量SRC_LIST里,然后在add_executable里调用SRC_LIST(注意调用变量时的写法)。
aux_source_directory()也存在弊端,它会把指定目录下的所有源文件都加进来,可能会加入一些我们不需要的文件,此时我们可以使用set命令去新建变量来存放需要的源文件,如下:
cmake_minimum_required (VERSION 2.8)project (demo)
set( SRC_LIST./main.c./anotherTest.c)add_executable(main ${SRC_LIST})
4.3 不同目录下多个源文件
修改CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (demo)include_directories (test1 test2)aux_source_directory (test1 SRC_LIST)
aux_source_directory (test2 SRC_LIST1)add_executable (main main.c ${SRC_LIST} ${SRC_LIST1})
4.4 标准组织结构
一般会把源文件放到src目录下,把头文件放入到include文件下,生成的对象文件放入到build目录下,最终输出的elf文件会放到bin目录下,这样整个结构更加清晰。
修改CMakeLists.txt:
cmake_minimum_required (VERSION 2.8)
project (demo)add_subdirectory (src)
这里指定src目录下存放了源文件,当执行cmake时,就会进入src目录下去找src目录下的CMakeLists.txt,所以在src目录下也建立一个CMakeLists.txt:
添加CMakeLists.txt:
aux_source_directory (. SRC_LIST)
include_directories (../include)
add_executable (main ${SRC_LIST})
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
这里又出现一个新的命令set,是用于定义变量的,EXECUTABLE_OUT_PATH和PROJECT_SOURCE_DIR是CMake自带的预定义变量,其意义如下,
EXECUTABLE_OUTPUT_PATH :目标二进制可执行文件的存放位置
PROJECT_SOURCE_DIR:工程的根目录
新建build文件夹,然后进入:
mkdir build
cd build
cmake ..
make
ls
../bin/main
也可以只使用一个CMakeLists.txt,把最外层的CMakeLists.txt内容改成如下:
cmake_minimum_required (VERSION 2.8)
project (demo)set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
aux_source_directory (src SRC_LIST)
include_directories (include)
add_executable (main ${SRC_LIST})
4.5 动态库和静态库的编译
有时需要编译出动态库和静态库,然后等着让其它程序去使用。测试工程文件夹如下:
- Windows示例如下:
CMakeLists.txt内容如下:
cmake_minimum_required (VERSION 2.8)project (myrand)# find *.cpp *.c
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/getRandomAPI.cpp)# find *.h
include_directories (${PROJECT_SOURCE_DIR}/include)########################################
# create lib and dll
add_library (myrand_shared SHARED ${SRC_LIST})
add_library (myrand_static STATIC ${SRC_LIST})set_target_properties (myrand_shared PROPERTIES OUTPUT_NAME "myrand")
set_target_properties (myrand_static PROPERTIES OUTPUT_NAME "myrand_s")set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)########################################
# create exe
add_compile_options(-std=c++11 -Wall)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_executable (myrand_test ${SRC_LIST})
命令解释如下:
(1)add_library: 生成动态库或静态库(第1个参数指定库的名字;第2个参数决定是动态还是静态,如果没有就默认静态;第3个参数指定生成库的源文件)
(2)set_target_properties: 设置最终生成的库的名称,还有其它功能,如设置库的版本号等等
(3)LIBRARY_OUTPUT_PATH: 库文件的默认输出路径,这里设置为工程目录下的lib目录
在build目录下运行cmake,并把生成的库文件(.dll、.lib)存放到lib文件夹下,exe放到bin文件夹里。执行命令如下:
cd C:\Users\tomcat\Desktop\test_cmake
mkdir build
cd build
cmake ..
打开build文件夹如下:
通过命令行编译myrand.sln,如下。
# release x64(默认)
cd C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE
.\devenv.com C:\Users\tomcat\Desktop\test_cmake\build\myrand.sln /Build# or debug x64
.\devenv.com F:\00Projects\test.sln /Build "Debug|64"# or debug win32
.\devenv.com F:\00Projects\test.sln /Build "Debug|Win32"
运行结果如下:
运行结果文件夹如下:
4.6 对库进行链接
在src目录下添加一个main.cpp,调用上面一节生成的库文件。
cmake_minimum_required (VERSION 2.8)
project (myrand_test)set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.cpp)# find *.h
include_directories (${PROJECT_SOURCE_DIR}/include)find_library(TEST_LIB NAMES myrand HINTS ${PROJECT_SOURCE_DIR}/lib/debug)add_executable (test ${SRC_LIST})
target_link_libraries (test ${TEST_LIB})
执行命令:
cmake ..
4.7 添加编译选项
添加一些编译选项,如-Wall,-std=c++11等,就可以使用add_compile_options来进行操作。
cmake_minimum_required (VERSION 2.8)
project (test)set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
add_compile_options(-std=c++11 -Wall)
add_executable(test main.cpp)
4.8 添加控制选项
有时只编译一些指定的源码,可以使用cmake的option命令:
1、本来要生成多个bin或库文件,现在只想生成部分指定的bin或库文件
2、对于同一个bin文件,只想编译其中部分代码(使用宏来控制)
CMakeLists.txt内容如下:
cmake_minimum_required(VERSION 3.0)
project(test)set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
set (SRC_LIST ${PROJECT_SOURCE_DIR}/src/main.cpp)
set (SRC_LIST2 ${PROJECT_SOURCE_DIR}/src/main2.cpp)option(USE_TEST_1 "use test 1" OFF)
option(USE_TEST_2 "use test 2" OFF)
option(USE_TEST_3 "use test 3" OFF)if (USE_TEST_1)add_definitions(-DTEST_1)
endif()if (USE_TEST_2)add_definitions(-DTEST_2)
endif()if (USE_TEST_3)add_definitions(-DTEST_3)
endif()add_executable(main ${SRC_LIST})if (USE_PROJECT2)add_executable(main2 ${SRC_LIST2})
else()message(STATUS "No project main2")
endif()
main.cpp:
#include <windows.h>
#include <iostream>int main()
{
#ifdef TEST_1printf("getRandom_1\n");
#endif#ifdef TEST_2printf("getRandom_2\n");
#endif#ifdef TEST_3printf("getRandom_3\n");
#endifsystem("pause");return 0;
}
cmake .. -DTEST_3=ON -DTEST_2=OFF -DUSE_PROJECT2=OFF
cmake .. -DTEST_3=ON && make
5、构建最小项目
5.1 新建代码文件
编辑代码文件:tutorial.cpp
- tutorial.cpp
// tutorial.cpp#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>int main(int argc, char* argv[])
{if (argc < 2) {std::cout << "Usage: " << argv[0] << " number" << std::endl;return 1;}// convert input to doubleconst double inputValue = atof(argv[1]);// calculate square rootconst double outputValue = sqrt(inputValue);std::cout << "(爱看书的小沐)The square root of " << inputValue<< " is " << outputValue<< std::endl;return 0;
}
5.2 新建CMakeLists.txt
在同一个文件夹内新建文件:CMakeLists.txt。
- CMakeLists.txt
cmake_minimum_required(VERSION 3.15)# set the project name
project(Tutorial)# add the executable
add_executable(Tutorial tutorial.cpp)
cmake_minimum_required:指定使用 CMake 的最低版本号,
project:指定项目名称,
add_executable:用来生成可执行文件,需要指定生成可执行文件的名称和相关源文件。
现在开始构建、编译和运行上面代码示例。
5.3 构建项目
在当前项目工作文件夹,创建一个构建目录 build,接下来,进入 build 目录并运行 CMake 来配置项目,并生成构建系统。
mkdir build
cd build
cmake ..
- 命令执行情况:
- 生成文件和文件夹如下:
5.4 编译项目
然后调用该构建系统来实际编译/链接项目:
cmake --build .
- 生成文件和文件夹如下:
5.5 运行项目
.\debug\Tutorial.exe 3.14
运行结果如下:
5.6 修改相关文件
编辑代码文件:CMakeLists.txt
- CMakeLists.txt
cmake_minimum_required(VERSION 3.15)## set the project name
# project(Tutorial)
project(Tutorial VERSION 1.2.3)string(TIMESTAMP COMPILE_TIME %Y%m%d-%H%M%S)
configure_file(TutorialConfig.h.in TutorialConfig.h)# set(SRC_LIST a.cpp b.cpp c.cpp)
SET(SRC_LIST tutorial.cpp)## add the executable
# add_executable(Tutorial tutorial.cpp)
# add_executable(${PROJECT_NAME} tutorial.cpp)
# add_executable(${PROJECT_NAME} a.cpp b.cpp c.cpp)
add_executable(${PROJECT_NAME} ${SRC_LIST})target_include_directories(${PROJECT_NAME} PUBLIC${PROJECT_BINARY_DIR} )
新建文件:TutorialConfig.h.in
- TutorialConfig.h.in
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define Tutorial_VERSION_PATCH @PROJECT_VERSION_PATCH@#define TIMESTAMP @COMPILE_TIME@
编辑代码文件:tutorial.cpp
- tutorial.cpp
// tutorial.cpp#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
#include "TutorialConfig.h"int main(int argc, char* argv[])
{if (argc < 2) {std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."<< Tutorial_VERSION_MINOR << std::endl;std::cout << "Usage: " << argv[0] << " number" << std::endl;return 1;}// convert input to doubleconst double inputValue = atof(argv[1]);// calculate square rootconst double outputValue = sqrt(inputValue);std::cout << "(爱看书的小沐)The square root of " << inputValue<< " is " << outputValue<< std::endl;return 0;
}
执行如下命令:
cmake --build .
.\debug\Tutorial.exe
生成文件:TutorialConfig.h
TutorialConfig.h:
结语
如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;
╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地
//(ㄒoㄒ)//,就在评论处留言,作者继续改进;
o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;
(✿◡‿◡)
感谢各位大佬童鞋们的支持!
( ´ ▽´ )ノ ( ´ ▽´)っ!!!
相关文章:

【小沐学C++】C++ 基于CMake构建工程项目(Windows、Linux)
文章目录 1、简介2、下载cmake3、安装cmake4、测试cmake4.1 单个源文件4.2 同一目录下多个源文件4.3 不同目录下多个源文件4.4 标准组织结构4.5 动态库和静态库的编译4.6 对库进行链接4.7 添加编译选项4.8 添加控制选项 5、构建最小项目5.1 新建代码文件5.2 新建CMakeLists.txt…...

计算机视觉与图形学-神经渲染专题-ConsistentNeRF
摘要 Neural Radiance Fields (NeRF) 已通过密集视图图像展示了卓越的 3D 重建能力。然而,在稀疏视图设置下,其性能显着恶化。我们观察到,在这种情况下,学习不同视图之间像素的 3D 一致性对于提高重建质量至关重要。在本文中&…...

初级算法-其他
文章目录 位1的个数题意:解:代码: 汉明距离题意:解:代码: 颠倒二进制位题意:解:代码: 杨辉三角题意:解:代码: 有效的括号题意…...

Containerd的两种安装方式
1. 轻量级容器管理工具 Containerd 2. Containerd的两种安装方式 3. Containerd容器镜像管理 4. Containerd数据持久化和网络管理 操作系统环境为centos7u6 1. YUM方式安装 1.1 获取YUM源 获取阿里云YUM源 # wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun…...

Android学习之路(1) 文本设置
Android学习之路(1) 文本 一、设置文本内容 设置文本内容的两种方式: 一种是在XML文件中通过属性android:text设置文本代码如下 <TextViewandroid:id"id/tv_hello"android:layout_width"wrap_content"android:layout_height"wrap_c…...

Docker相关命令与入门
1. Docker 命令 # centos 7 systemctl start docker # 启动服务 systemctl stop docker systemctl restart docker # 重启服务 systemctl status docker systemctl enable docker # 开机自启动1.1 镜像相关的命令 # 查看镜像 docker images docker images -q # 查看…...

如何配置一个永久固定的公网TCP地址来SSH远程树莓派?
文章目录 如何配置一个永久固定的公网TCP地址来SSH远程树莓派?前置条件命令行使用举例:修改cpolar配置文件 1. Linux(centos8)安装redis数据库2. 配置redis数据库3. 内网穿透3.1 安装cpolar内网穿透3.2 创建隧道映射本地端口 4. 配置固定TCP端口地址4.1 …...

Kubernetes架构和工作流程
目录 一、kubernetes简介 1.k8s的由来 2.为什么用 k8s ? 3.k8s主要功能 二、k8s集群架构与组件 1.Master 组件 1.1Kube-apiserver 1.2Kube-controller-manager 1.3Kube-scheduler 2.Node组件 2.1Kubelet 2.2Kube-Proxy 2.3docker 或 rocket 3.配置存储中…...

C语言赋值号的运算顺序
从右到左。 int & f(int & a) { printf("参数 %d\n", a); return a; } int main(void) {int a 9;int b 3;f(a) f(b);// 运行到此处,a 3,b 3return 0; } 输出...

fishing之第四篇使用案例一模拟登陆口
文章目录 一、访问钓鱼平台二、Sending Profiles(发件人邮箱配置)三、User&Groups(接收人邮件列表)四、Landing Pags(钓鱼页面配置)五、Email Templates(邮件内容配置)六、Campa…...

CS 144 Lab Six -- building an IP router
CS 144 Lab Six -- building an IP router 引言路由器的实现测试 对应课程视频: 【计算机网络】 斯坦福大学CS144课程 Lab Six 对应的PDF: Lab Checkpoint 5: building an IP router 引言 在本实验中,你将在现有的NetworkInterface基础上实现一个IP路由器…...

edge://settings/defaultbrowser default ie
Microsoft Edge 中的 Internet Explorer 模式 有些网站专为与 Internet Explorer 一起使用,它们具有 Microsoft Edge 等新式浏览器不支持的功能。 如果你需要查看其中的某个网站,可使用 Microsoft Edge 中的 Internet Explorer 模式。 大多数网站在新…...

Centos7安装jdk8教程——rpm安装
1. rpm文件下载 下载链接 Java SE 8 Archive Downloads (JDK 8u211 and later) 2.上传到服务器指定路径下并安装 切换到上传目录,然后执行以下命令 rpm -ivh jdk-8u221-linux-x64.rpm3. 设置环境变量并重载配置 # 设置环境变量 vim /etc/profile# 文件末尾添加…...

Node.js-path模块操作路径的基本使用
path模块提供了操作路径的功能,以下为常用的API。 path.resolve():拼接规范的绝对路径 const path require("path"); // 目录的绝对路径 // __dirname: D:\node\path const pathStr path.resolve(__dirname, "index.html"); // 拼…...

油猴脚本:验证码识别辅助器
脚本信息 描述:当鼠标放在验证码图片上时,显示弹窗并提供识别选项 实现逻辑 定义了一个isRectangle函数,用于判断图片是否符合验证码的特征。判断条件是:图片的宽高比大于1.5,宽度大于等于80且高度大于等于30&#…...

【力扣】24. 两两交换链表中的节点 <栈>
【力扣】24. 两两交换链表中的节点 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 输入:hea…...

C#中控件的invoke方法
https://www.exyb.cn/news/show-280348.html 在用.NET Framework框架的WinForm构建GUI程序界面时,如果要在控件的事件响应函数中改变控件的状态,例如:某个按钮上的文本原先叫“打开”,单击之后按钮上的文本显示“关闭”࿰…...

x光下危险物品/违禁物品目标识别的模型训练与推理代码
前言 1.安检在公共场合的重要性不言而喻,保障群众人身安全是其首要任务。在各种场合,安检都是不可或缺的环节。x光安检机作为安检的重要工具,尽管其具有人工监控判断成像的特性,但是其局限性也十分明显。 为了解决这一局限性为出…...

基于Matlab实现图像融合技术(附上多个仿真源码+数据)
图像融合技术是一种将多幅图像融合为一幅图像的方法,使得这幅融合图像包含原始图像的所有信息。近年来,图像融合技术已经广泛应用于图像分割、变换和裁剪等领域。本文将介绍如何使用Matlab实现图像融合技术。 实现步骤 首先,我们需要了解图…...

国家级与省级开发区设立超长时间段数据(1970-2022年)
在基于因果推断方法的政策评估备受经济学研究欢迎的今天,将一个重要政策作为外生冲击进行计量建模这一做法,是很多顶刊论文的“宠儿”,大家整理分享的国家级与省级开发区设立超长时间段数据正是其中的代表。 我国各级人民ZF均将开发区设立作为…...
数据结构 10-排序4 统计工龄 桶排序/计数排序(C语言)
给定公司名员工的工龄,要求按工龄增序输出每个工龄段有多少员工。 输入格式: 输入首先给出正整数(≤),即员工总人数;随后给出个整数,即每个员工的工龄,范围在[0, 50]。 输出格式: 按工龄的递…...

SpringBoot复习:(16)TomcatStarter
直接在idea里运行SpringBoot程序时,内嵌的tomcat容器会调用TomcatStarter这个类的onStartup方法。TomcatStarter继承自ServletContainerInitializer 其onStartup方法会调用ServletContextInitializer(不是ServletContainerInitializer)的onStartup方法.…...

RISCV 5 RISC-V调用规则
RISCV 5 RISC-V调用规则 1 Register Convention1.1 Integer Register Convention1.2 Floating-point Register Convention 2. Procedure Calling Convention2.1 Integer Calling Convention2.2 Hardware Floating-point Calling Convention2.3 ILP32E Calling Convention2.4 Na…...

Spring Boot如何整合mybatis
文章目录 1. 相关配置和代码2. 整合原理2.1 springboot自动配置2.2 MybatisAutoConfiguration2.3 debug过程2.3.1 AutoConfiguredMapperScannerRegistrar2.3.2 MapperScannerConfigurer2.3.4 创建MapperFactoryBean2.3.5 创建MybatisAutoConfiguration2.3.6 创建sqlSessionFact…...

TypeScript中 interface 和 type 的区别
区别1 使用 interface 和 type 都是表示给定数据结构的常用方法。定义的方式略有不同。type 定义的时候有 “” 符号 interface User {name: string,age: number } type User {name: string,age: number }区别2 interface 可以多次声明同一接口。它们将合并在一起形成一个接…...

题解 | #B.Distance# 2023牛客暑期多校6
B.Distance 贪心(?) 题目大意 对于两个大小相同的多重集 A , B \mathbb{A},\mathbb{B} A,B ,可以选择其中任一元素 x x x 执行操作 x x 1 xx1 xx1 任意次数,最少的使得 A , B \mathbb{A},\mathbb{B} A,B 相同的操作次数记为 C ( A , B ) C(\m…...

【flink】开启savepoint
先启动一个任务 flink run -c com.yang.flink.CDCJob test-cdc.jar开启savepoint 命令: flink savepoint JobID 文件地址 flink savepoint e929a11d79bdc5e6f140f2cfb92e1335 file:///workspace/flinkSavepoints/backend这样就开启好了 操作中的错误 详细信…...

【C++】开源:事件驱动网络库libevent配置使用
😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍事件驱动库libevent配置使用。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下…...

业务测试——历史数据
业务测试历史数据的必要性 1.保留上一版本的呈现效果以及数据正确性 2.做发版前后数据、样式一致性校验 3.后端处理历史数据,覆盖各类场景,保证客户的现有数据不会被影响,造成线上事务 4.为测试过程的覆盖度以及产品迭代的质量保驾护航 如何…...

【Linux】计算机网络套接字编写
文章目录 前言TCP协议和UDP协议网络字节序socket接口sockaddr结构1.创建套接字 cs2.绑定端口号 s3.监听socket s4.接受请求 s5.建立连接 c 地址转换函数字符串转in_addrin_addr转字符串 recvfrom和sendto 前言 上篇文章我们学习了计算机网络分层,了解了网络通信的本…...