Postgresql源码(140)理解PG的编译流程(make、Makefile、Makefile.global.in)
PG16
PG中使用的makefile看起来代码比较多,但是实际逻辑比较简单,这里做一些抽象总结。
总结
- Makefile.global.in的
$(recurse)
宏自动生成了target,可以方便的进入内存目录进行编译。
all: all-common-recurse
all-common-recurse: submake-generated-headersMAKE -C common allall: all-backend-recurse
all-backend-recurse: submake-generated-headersMAKE -C backend allinstall: install-common-recurse
install-common-recurse: submake-generated-headersMAKE -C common installinstall: install-backend-recurse
install-backend-recurse: submake-generated-headersMAKE -C backend installcheck: check-common-recurse
check-common-recurse: submake-generated-headers temp-installMAKE -C common checkcheck: check-backend-recurse
check-backend-recurse: submake-generated-headers temp-installMAKE -C backend check
- Makefile.global.in同时定义了对.o合.bc文件的生成规则:
%.o : %.c@if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi$(COMPILE.c) -o $@ $< -MMD -MP -MF $(DEPDIR)/$(*F).Po%.o : %.cpp@if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi$(COMPILE.cc) -o $@ $< -MMD -MP -MF $(DEPDIR)/$(*F).Po%.bc : %.c$(COMPILE.c.bc) -o $@ $<%.bc : %.cpp$(COMPILE.cxx.bc) -o $@ $<
- 在最内层目录的Makefile定义了OBJS例如:
OBJS=aset.o mcxt.o ...
,然后调用common.mk文件,对OBJS中的每一个元素进行隐式编译,common.mk:
简化版内层Makefile:
OBJS = aset.o mcxt.o# 没有OBJS生成规则,make隐式生成.o文件,调用上面定义的%.o : %.c规则
objfiles.txt: $(OBJS)# echo or touch objfiles
- 如果打开了llvm,简化版内层Makefile:
OBJS = aset.o mcxt.o# 没有aset.bc mcxt.bc生成规则,make隐式生成.bc文件,调用上面定义的%.bc : %.c规则。
objfiles.txt: $(patsubst %.o,%.bc, $(OBJS)) ## objfiles.txt: aset.bc mcxt.bc
# 没有OBJS生成规则,make隐式生成.o文件,调用上面定义的%.o : %.c规则
$(patsubst %.o,%.bc, $(OBJS)): $(OBJS) ## aset.bc mcxt.bc: aset.o mcxt.o
1 执行make后发生了什么?
简单工程中的makefile中可以看到很多target,依赖关系一般也比较直接,例如下面例子中:
OrcV2CBindingsAddObjectFile 依赖 OrcV2CBindingsAddObjectFile.o 依赖 OrcV2CBindingsAddObjectFile.c
all: __BUILD_DIR \$(BUILD_DIR)/OrcV2CBindingsAddObjectFile \$(BUILD_DIR)/OrcV2CBindingsBasicUsage.PHONY: __BUILD_DIR$(BUILD_DIR)/OrcV2CBindingsAddObjectFile: $(BUILD_DIR)/OrcV2CBindingsAddObjectFile.o${CXX} $< ${CXXFLAGS} ${LLVM_LD_FLAGS} -o $@
$(BUILD_DIR)/OrcV2CBindingsAddObjectFile.o: OrcV2CBindingsAddObjectFile.c${CC} -c $< ${CFLAGS} ${LLVM_CC_FLAGS} -o $@
但打开PG根目录下的Makefile:
subdir = src
top_builddir = ..
include Makefile.globalSUBDIRS = \common \port \timezone \backend \backend/utils/mb/conversion_procs \backend/snowball \include \interfaces \backend/replication/libpqwalreceiver \backend/replication/pgoutput \fe_utils \bin \pl \makefiles \test/regress \test/isolation \test/perlifeq ($(with_llvm), yes)
SUBDIRS += backend/jit/llvm
endif# There are too many interdependencies between the subdirectories, so
# don't attempt parallel make here.
.NOTPARALLEL:$(recurse)...
...
- 看不到target信息,代码的可读性比较差,因为所有target都是生成的。优点是target动态生成,代码量少,比较灵活。
- 所有的细节都封装在
$(recurse)
中,具体在Makefile.global.in中定义。
2 Makefile.global.in
截取关键代码:
standard_targets = all install installdirs uninstall distprep clean distclean maintainer-clean coverage check checkprep installcheck init-po update-po
# these targets should recurse even into subdirectories not being built:
standard_always_targets = distprep clean distclean maintainer-clean.PHONY: $(standard_targets) install-strip html man installcheck-parallel update-unicode# make `all' the default target
all:##########################################################################
#
# Programs and flags# CompilersCPP = @CPP@
CPPFLAGS = @CPPFLAGS@
PG_SYSROOT = @PG_SYSROOT@override CPPFLAGS := $(ICU_CFLAGS) $(CPPFLAGS)ifdef PGXS
override CPPFLAGS := -I$(includedir_server) -I$(includedir_internal) $(CPPFLAGS)
else # not PGXS
override CPPFLAGS := -I$(top_srcdir)/src/include $(CPPFLAGS)
ifdef VPATH
override CPPFLAGS := -I$(top_builddir)/src/include $(CPPFLAGS)
endif
endif # not PGXSCC = @CC@
GCC = @GCC@
SUN_STUDIO_CC = @SUN_STUDIO_CC@
CXX = @CXX@
CFLAGS = @CFLAGS@
CFLAGS_SL = @CFLAGS_SL@
# *_MODULE are for flags applied to extension libraries
CFLAGS_SL_MODULE = @CFLAGS_SL_MODULE@
CXXFLAGS_SL_MODULE = @CXXFLAGS_SL_MODULE@
CFLAGS_UNROLL_LOOPS = @CFLAGS_UNROLL_LOOPS@
CFLAGS_VECTORIZE = @CFLAGS_VECTORIZE@
CFLAGS_CRC = @CFLAGS_CRC@
PERMIT_DECLARATION_AFTER_STATEMENT = @PERMIT_DECLARATION_AFTER_STATEMENT@
CXXFLAGS = @CXXFLAGS@LLVM_CPPFLAGS = @LLVM_CPPFLAGS@
LLVM_CFLAGS = @LLVM_CFLAGS@
LLVM_CXXFLAGS = @LLVM_CXXFLAGS@# Kind-of compilersBISON = @BISON@
BISONFLAGS = @BISONFLAGS@ $(YFLAGS)
FLEX = @FLEX@
FLEXFLAGS = @FLEXFLAGS@ $(LFLAGS)
DTRACE = @DTRACE@
DTRACEFLAGS = @DTRACEFLAGS@
ZIC = @ZIC@# LinkingAR = @AR@
AROPT = crs
LIBS = @LIBS@
LDAP_LIBS_FE = @LDAP_LIBS_FE@
LDAP_LIBS_BE = @LDAP_LIBS_BE@
UUID_LIBS = @UUID_LIBS@
LLVM_LIBS=@LLVM_LIBS@# Tree-wide build supportall install check installcheck: submake-generated-headers.PHONY: submake-generated-headerssubmake-generated-headers:
ifndef NO_GENERATED_HEADERS
ifeq ($(MAKELEVEL),0)$(MAKE) -C $(top_builddir)/src/backend generated-headers
endif
endif##########################################################################
#
# Recursive make supportdefine _create_recursive_target
.PHONY: $(1)-$(2)-recurse
$(1): $(1)-$(2)-recurse
$(1)-$(2)-recurse: $(if $(filter all install check installcheck, $(3)), submake-generated-headers) $(if $(filter check, $(3)), temp-install)$$(MAKE) -C $(2) $(3)
endefrecurse = $(foreach target,$(if $1,$1,$(standard_targets)),$(foreach subdir,$(if $2,$2,$(SUBDIRS)),$(eval $(call
在最后面我们看到了recurse的定义:
recurse = $(foreach target,$(if $1,$1,$(standard_targets)),$(foreach subdir,$(if $2,$2,$(SUBDIRS)),$(eval $(call _create_recursive_target,$(target),$(subdir),$(if $3,$3,$(target))))))
这里调用了_create_recursive_target函数来生成所有目录的target。
PG的例子太复杂,这里抽象出来一个最小用例来继续分析。
3 $(recurse)最小DEMO
Makefile
subdir = src
top_builddir = ..
include Makefile.globalSUBDIRS = \common \port \timezone \backend$(recurse)
Makefile.global
standard_targets = all install check
.PHONY: $(standard_targets)all:###############################
all install check installcheck: submake-generated-headers.PHONY: submake-generated-headerssubmake-generated-headers:
ifndef NO_GENERATED_HEADERS
ifeq ($(MAKELEVEL),0)$(info ------------GENERATEHEADERS------------)
endif
endif###############################
define _create_recursive_target
.PHONY: $(1)-$(2)-recurse
$(1): $(1)-$(2)-recurse
$(1)-$(2)-recurse: $(if $(filter all install check installcheck, $(3)), submake-generated-headers) $(if $(filter check, $(3)), temp-install)$(info ------------GENERATE TATGETS------------)$(info $$1: $1, $$2: $2, $$3: $3)$(info $(1): $(1)-$(2)-recurse)$(info $(1)-$(2)-recurse: $(if $(filter all install check installcheck, $(3)), submake-generated-headers) $(if $(filter check, $(3)), temp-install))$(info MAKE -C $(2) $(3))$$(MAKE) -C $(2) $(3)
endefrecurse = $(foreach target,$(if $1,$1,$(standard_targets)),$(foreach subdir,$(if $2,$2,$(SUBDIRS)),$(eval $(call _create_recursive_target,$(target),$(subdir),$(if $3,$3,$(target))))))# recurse = \
# $(foreach target,$(if $1,$1,$(standard_targets)),\
# $(foreach subdir,$(if $2,$2,$(SUBDIRS)),\
# $(eval $(call _create_recursive_target,$(target),$(subdir),$(if $3,$3,$(target))))\
# )\
# )
执行结果:
4 $(recurse)最小DEMO结果分析
recurse = $(foreach target,$(if $1,$1,$(standard_targets)),$(foreach subdir,$(if $2,$2,$(SUBDIRS)),$(eval $(call _create_recursive_target,$(target),$(subdir),$(if $3,$3,$(target))))))
展开后
recurse = \$(foreach target,$(if $1,$1,$(standard_targets)),\$(foreach subdir,$(if $2,$2,$(SUBDIRS)),\$(eval $(call _create_recursive_target,$(target),$(subdir),$(if $3,$3,$(target))))\)\)
- 外层循环遍历
standard_targets = all install check
,也就是PG定义的所有make指令,需要为每个指令定义target。 - 内层循环遍历
SUBDIRS = common backend
,这个是Makefile中定义的,也就是谁include Makefile.global,谁负责定义好SUBDIRS。表示当前目录下,哪些子目录需要进行编译。
调用_create_recursive_target函数,为makefile动态定义target:
define _create_recursive_target
.PHONY: $(1)-$(2)-recurse
$(1): $(1)-$(2)-recurse
$(1)-$(2)-recurse: $(if $(filter all install check installcheck, $(3)), submake-generated-headers) $(if $(filter check, $(3)), temp-install)$$(MAKE) -C $(2) $(3)
endef
函数执行后,生成一系列target,两个小细节:
- 如果target是all install check installcheck集中情况,需要增加submake-generated-headers依赖,这个是生成头文件的,PG的一些头文件是编译时生成出来的。
- 如果target是check,需要增加temp-install依赖,temp-install是负责regress测试的target。
all: all-common-recurse
all-common-recurse: submake-generated-headersMAKE -C common allall: all-backend-recurse
all-backend-recurse: submake-generated-headersMAKE -C backend allinstall: install-common-recurse
install-common-recurse: submake-generated-headersMAKE -C common installinstall: install-backend-recurse
install-backend-recurse: submake-generated-headersMAKE -C backend installcheck: check-common-recurse
check-common-recurse: submake-generated-headers temp-installMAKE -C common checkcheck: check-backend-recurse
check-backend-recurse: submake-generated-headers temp-installMAKE -C backend check
5 继续完善demo
- 前面提到的demo只构造了target,并没有真正编译.c文件。
- 继续增加了.c文件编译到.o的部分。
$ tree
.
├── common
│ ├── aset.c
│ └── Makefile
├── common.mk
├── Makefile
└── Makefile.global1 directory, 5 files
common/Makefile
subdir = src/backend/utils/mmgr
top_builddir = ../../../..
include ../Makefile.globalOBJS = \aset.oinclude ../common.mk
common.mk
subsysfilename = objfiles.txtifneq ($(subdir), src/backend)
all: $(subsysfilename)
endifobjfiles.txt: $(OBJS)$(if $(filter-out $(OBJS),$?),( $(if $(SUBDIROBJS),cat $(SUBDIROBJS); )echo $(addprefix $(subdir)/,$(OBJS)) ) >$@,touch $@)
Makefile
subdir = src
top_builddir = ..
include Makefile.globalSUBDIRS = \common \backend$(recurse)
Makefile.global
standard_targets = all install check
.PHONY: $(standard_targets)all:###############################
all install check installcheck: submake-generated-headers.PHONY: submake-generated-headerssubmake-generated-headers:
ifndef NO_GENERATED_HEADERS
ifeq ($(MAKELEVEL),0)$(info ------------GENERATEHEADERS------------)
endif
endif###############################
define _create_recursive_target
.PHONY: $(1)-$(2)-recurse
$(1): $(1)-$(2)-recurse
$(1)-$(2)-recurse: $(if $(filter all install check installcheck, $(3)), submake-generated-headers) $(if $(filter check, $(3)), temp-install)$(info ------------GENERATE TATGETS------------)$(info $$1: $1, $$2: $2, $$3: $3)$(info $(1): $(1)-$(2)-recurse)$(info $(1)-$(2)-recurse: $(if $(filter all install check installcheck, $(3)), submake-generated-headers) $(if $(filter check, $(3)), temp-install))$(info MAKE -C $(2) $(3))$$(MAKE) -C $(2) $(3)
endefrecurse = $(foreach target,$(if $1,$1,$(standard_targets)),$(foreach subdir,$(if $2,$2,$(SUBDIRS)),$(eval $(call _create_recursive_target,$(target),$(subdir),$(if $3,$3,$(target))))))# recurse = \
# $(foreach target,$(if $1,$1,$(standard_targets)),\
# $(foreach subdir,$(if $2,$2,$(SUBDIRS)),\
# $(eval $(call _create_recursive_target,$(target),$(subdir),$(if $3,$3,$(target))))\
# )\
# )
这里主要需要关注的就是common.mk。每个源码目录中都有一些文件需要编译,所以都需要配一个Makefile,这些Makefile中相同的逻辑抽取到了common.mk中。
objfiles.txt: $(OBJS)......
注意这里OBJS = aset.o,这里makefile构造objfiles.txt依赖aset.o,而aset.o触发了Makefile的隐式规则,会自动从aset.c编译为aset.o。
除了规则外,具体的编译方法也可以在Makefile中定义,例如PG的makefile.global.in中定义了对.o文件的处理方法。
%.o : %.c@if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi$(COMPILE.c) -o $@ $< -MMD -MP -MF $(DEPDIR)/$(*F).Po%.o : %.cpp@if test ! -d $(DEPDIR); then mkdir -p $(DEPDIR); fi$(COMPILE.cc) -o $@ $< -MMD -MP -MF $(DEPDIR)/$(*F).Po
llvm支持:common.mk中还有一段,如果打开了llvm后,objfiles.txt会同时依赖.o和.bc文件。
ifeq ($(with_llvm), yes)
objfiles.txt: $(patsubst %.o,%.bc, $(OBJS))
$(patsubst %.o,%.bc, $(OBJS)): $(OBJS)
endif
在makefile.global.in中也定义了对.bc文件的处理方法:
%.bc : %.c$(COMPILE.c.bc) -o $@ $<%.bc : %.cpp$(COMPILE.cxx.bc) -o $@ $<
相关文章:

Postgresql源码(140)理解PG的编译流程(make、Makefile、Makefile.global.in)
PG16 PG中使用的makefile看起来代码比较多,但是实际逻辑比较简单,这里做一些抽象总结。 总结 Makefile.global.in的$(recurse)宏自动生成了target,可以方便的进入内存目录进行编译。 all: all-common-recurse all-common-recurse: submak…...

logback日志自定义占位符
前言 在大型系统运维中,很大程度上是需要依赖日志的。在java大型web工程中,一般都会使用slf4jlogback这一个组合来实现日志的管理。 logback中很多现成的占位符可以可以直接使用,比如线程号【%t】、时间【%d】、日志等级【%p】,…...

Vue平台开发三——项目管理页面
前言 对于多个项目的使用,可能需要进行项目切换管理,所以这里创建一个项目管理页面,登录成功后跳转这个页面,进行选择项目,再进入Home页面展示对应项目的内容。 一、实现效果图预览 二、页面内容 功能1、项目列表展…...

用于牙科的多任务视频增强
Multi-task Video Enhancement for Dental Interventions 2022 miccai Abstract 微型照相机牢牢地固定在牙科手机上,这样牙医就可以持续地监测保守牙科手术的进展情况。但视频辅助牙科干预中的视频增强减轻了低光、噪音、模糊和相机握手等降低视觉舒适度的问题。…...

【Node.js]
一、概述 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境 ,使用了一个事件驱动、非阻塞式I/O模型, 让JavaScript 运行在服务端的开发平台,它让JavaScript成为与PHP、Python、Perl、Ruby等服务端语言平起平坐的脚本语言。 官网地…...

【Elasticsearch】腾讯云安装Elasticsearch
Elasticsearch 认识Elasticsearch安装Elasticsearch安装Kibana安装IK分词器分词器的作用是什么?IK分词器有几种模式?IK分词器如何拓展词条?如何停用词条? 认识Elasticsearch Elasticsearch的官方网站如下 Elasticsearch官网 Ela…...

【网络协议】ACL(访问控制列表)第一部分
概述 网络安全在网络中的重要性不言而喻。本文(即第一部分)将介绍ACL的基本概念以及标准ACL的配置。第二部分将重点讨论扩展ACL、其他相关概念以及ACL的故障排除。 文章目录 概述ACL定义数据包过滤ACLACL配置指导原则配置ACL的三条规则ACL功能ACL工作原…...

2025.1.20——一、[RCTF2015]EasySQL1 二次注入|报错注入|代码审计
题目来源:buuctf [RCTF2015]EasySQL1 目录 一、打开靶机,整理信息 二、解题思路 step 1:初步思路为二次注入,在页面进行操作 step 2:尝试二次注入 step 3:已知双引号类型的字符型注入,构造…...
Spring Boot 整合 Knife4j:打造更优雅的 API 文档
在现代 Web 应用开发中,API 文档的重要性不言而喻。清晰、准确、易用的 API 文档不仅可以方便开发者理解和使用 API,还能提高团队协作效率。Knife4j 是一个基于 Swagger 的增强型 API 文档工具,它可以为 Spring Boot 项目生成美观、易于交互的…...

Kafka 源码分析(一) 日志段
首先我们的 kafka 的消息本身是存储在日志段中的, 对应的源码是下面这段代码: class LogSegment private[log] (val log: FileRecords,val lazyOffsetIndex: LazyIndex[OffsetIndex],val lazyTimeIndex: LazyIndex[TimeIndex],val txnIndex: TransactionIndex,val baseOffset:…...

javaEE初阶————多线程初阶(2)
今天给大家带来第二期啦,保证给大家讲懂嗷; 1,线程状态 NEW安排了工作还未开始行动RUNNABLE可工作的,或者即将工作,正在工作BLOCKED排队等待WAITING排队等待其他事TIMED_WAITING排队等待其他事TERMINATED工作完成了 …...
Redis学习笔记1【数据类型和常用命令】
Redis学习笔记 基础语法 1.数据类型 String: 最基本的类型,可以存储任何数据,例如文本或数字。示例值为 hello world。Hash: 用于存储键值对,适合存储对象或结构体。示例值为 {"name": "Jack", "age": 21}。…...

JavaWeb项目——查询角色列表到页面中——转发模式
一、知识点 1、req.getRequestDispatch与resp.sendRedirect跳转方式的比较 一、实现原理 1、req.getRequestDispatcher: 属于服务器端跳转,在服务器内部将请求转发给另一个资源(如另一个 Servlet 或 JSP 页面)。调用 getReques…...
feign调用跳过HTTPS的SSL证书校验配置详解
一、问题抛出 如果不配置跳过SSL证书校验,当Feign客户端尝试连接到一个使用自签名证书的服务器时,可能会抛出类似以下的异常: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building faile…...

今天也是记录小程序进展的一天(破晓时8)
嗨嗨嗨朋友们,今天又来记录一下小程序的进展啦!真是太激动了,项目又迈出了重要的一步,231啦!感觉每一步的努力都在积累,功能逐渐完善,离最终上线的目标越来越近了。大家一直支持着这个项目&…...
SQL-leetcode—1084. 销售分析 III
1084. 销售分析 III 表: Product --------------------- | Column Name | Type | --------------------- | product_id | int | | product_name | varchar | | unit_price | int | --------------------- product_id 是该表的主键(具有唯一值的列&…...

Linux C\C++编程-文件位置指针与读写文件数据块
【图书推荐】《Linux C与C一线开发实践(第2版)》_linux c与c一线开发实践pdf-CSDN博客 《Linux C与C一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 Linu…...

Flask简介与安装以及实现一个糕点店的简单流程
目录 1. Flask简介 1.1 Flask的核心特点 1.2 Flask的基本结构 1.3 Flask的常见用法 1.3.1 创建Flask应用 1.3.2 路由和视图函数 1.3.3 动态URL参数 1.3.4 使用模板 1.4 Flask的优点 1.5 总结 2. Flask 环境创建 2.1 创建虚拟环境 2.2 激活虚拟环境 1.3 安装Flask…...

【自动化测试】—— Appium使用保姆教程
目录 一. 连接手机 1. 授权 2. 调试 3. 获取参数 二. 启动APP 1. 启动Appium服务 2. 启动Appium Inspector 3. 配置Appium Inspector 三. 功能说明 1. 主菜单功能 2. 快照视图菜单 3. 元素视图菜单 四. 常见问题 1. appPackage有多个设备时 一. 连接手机 1. 授权 首先将手机的开…...

西门子【Library of General Functions (LGF) for SIMATIC S7-1200 / S7-1500】
文章目录 概要整体架构流程技术名词解释技术细节小结 概要 通用函数库 (LGF) 扩展了 TIA Portal 中用于 PLC 编程的 STEP 7 指令(数学函数、时间、计数器 等)。该库可以不受限制地使用,并包含 FIFO 、搜索功能、矩阵计算、 astro 计…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...