Makefile基础语法 看这一篇就够了

news2025/1/11 5:46:14

在这里插入图片描述

Makefile 基础语法

Makefile 是一种用于自动化构建过程的脚本文件,它通过定义目标文件和依赖关系来告诉 make 工具如何构建项目。Makefile 的语法和结构可以非常灵活,适用于各种复杂的构建场景。本教程将详细介绍 Makefile 的基本概念、语法以及如何编写高效的 Makefile 文件。

Makefile 意义:

  • 自动化构建:
    Makefile 可以自动构建项目,减少手动编译和链接的时间消耗。
    通过简单的 make 命令,就可以自动处理项目的编译和链接过程。
  • 依赖管理:
    Makefile 能够追踪文件之间的依赖关系,只对那些真正需要更新的文件进行编译。
    当源文件发生变化时,Makefile 可以确保只重新编译受影响的部分,而不是整个项目。
  • 提高效率:
    自动化构建过程减少了人为错误的机会,同时也节省了大量的时间。
    开发者可以专注于编写代码而不是编译过程。
  • 可配置性和可扩展性:

Makefile 可以轻松地配置不同的构建选项,如编译器标志、调试信息等。
可以很容易地添加新的目标或规则来适应项目的增长和发展。

1. Makefile 基础

1.1 规则格式

Makefile 文件中的每一条规则都由三个部分组成:

  1. 目标(target): 目标文件或要完成的任务。
  2. 依赖(dependencies): 完成目标所需的文件或其他目标。
  3. 命令(commands): 用于生成目标的一系列 shell 命令。

1.2 示例

target: dependencies
    command1
    command2

1.3 默认目标

Makefile 中的第一个目标会被当作默认目标。如果没有显式指定目标,make 会构建第一个列出的目标。

1.4 变量

Makefile 支持变量定义,可以简化重复的文本。它们用于存储和管理数据,比如文件名、目录路径、编译器选项等。

CC = gcc # 定义编译器
CFLAGS = -Wall -g # 定义编译选项
OBJS = foo.o bar.o baz.o # 定义目标依赖

1.5 自动变量

自动变量 $@, $<, $^, $+ 等用于引用目标或依赖。

  1. $@
    • 含义:表示规则的目标文件名。当 Makefile 正在执行某个规则时,$@ 就会被替换为目标文件的名称。
    • 用途
      • 构建命令:在构建命令中使用 $@ 来指定输出文件
      • 依赖检查:在依赖检查时 $@ 用来标识当前规则的目标文件
  2. $^
    • 含义:在 Makefile 中,自动变量 $^ 代表的是规则中所有依赖文件的集合。它包含了所有依赖文件的名称,但去除了重复的依赖文件。这与 $+ 不同,后者保留所有依赖文件,即使有重复也会列出多次
    • 用途
      • 构建命令:在构建命令中使用 $^ 来引用所有依赖文件
      • 依赖检查:在依赖检查时 $^ 用来标识所有依赖文件
  3. $<
  • 含义:在 Makefile 中,自动变量 < 代表的是规则中第一个依赖文件的名称。当 M a k e f i l e 正在执行某个规则时, < 代表的是规则中第一个依赖文件的名称。当 Makefile 正在执行某个规则时, <代表的是规则中第一个依赖文件的名称。当Makefile正在执行某个规则时,< 就会被替换为第一个依赖文件的名称。
    • 用途
      • 构建命令:在构建命令中使用 $< 来引用第一个依赖文件
      • 依赖检查:在依赖检查时 $< 用来标识第一个依赖文件
        示例
    CC = gcc
    CFLAGS = -Wall -g
    all: hello
    
    hello: main.o util.o
         $(CC) $(CFLAGS) -o $@ $^
    
    %.o: %.c
         $(CC) $(CFLAGS) -c -o $@ $<
    
    clean:
         rm -f *.o hello
    

解释
- 规则 hello 的目标文件是 hello,依赖项是 main.o 和 util.o。
- 在构建 hello 时, @ 就会被替换为 h e l l o , @ 就会被替换为 hello, @就会被替换为hello,^ 就会被替换为 main.o util.o
- 在构建 .o 文件时, @ 会被替换为 . o 文件名,例如 m a i n . o 或 u t i l . o 。 − 在构建 . o 文件时 , @ 会被替换为 .o 文件名,例如 main.o 或 util.o。 - 在构建 .o 文件时, @会被替换为.o文件名,例如main.outil.o在构建.o文件时,^ 不会被使用,因为每个 .o 文件只有一个依赖文件。
- 在构建 .o 文件时,$< 会被替换为 .c 文件名,例如 main.c 或 util.c。

  1. $%
    • 含义:自动变量 $% 代表的是规则中目标成员的名称,通常用于处理归档成员(archive member)的情况,即库文件中的成员文件。这个变量在处理静态库(例如 .a 文件)时非常有用。
    • 用途
      • 构建命令:在构建命令中使用 $% 来引用归档库中的成员文件
      • 依赖检查:在依赖检查时 $% 用来标识归档库中的成员文件
    • 示例
      AR = ar
      ARFLAGS = rcs
      LIB = libfoo.a
      
      all: $(LIB)
      
      $(LIB): foo.o bar.o
        $(AR) $(ARFLAGS) $@ $^
      
      %.o: %.c
           $(CC) $(CFLAGS) -c -o $@ $<
      
      clean:
           rm -f *.o $(LIB)
      
    • 解释
      • 规则 $(LIB) 的目标文件是 libfoo.a,依赖项是foo.o bar.o
      • 在构建 $(LIB) 时,$% 就会被替换为库中的成员文件名,例如 foo.o bar.o
      • 在构建 .o 文件时,$% 不会被使用,因为每个 .o 文件只有一个依赖文件
  2. $?
    • 含义:自动变量 $? 代表的是所有比目标文件更新的依赖文件的集合。它包含了所有比目标文件更新的依赖文件的名称,并且这些文件之间是以空格分隔的。
    • 用途
      • 构建命令:在构建命令中使用 $? 来引用所有比目标文件更新的依赖文件。
      • 依赖检查:在依赖检查时 $? 用来标识所有比目标文件更新的依赖文件。
    • 示例
      CC = gcc
      CFLAGS = -Wall -g
      
      all: myapp
      
      myapp: main.o util.o
           $(CC) $(CFLAGS) -o $@ $?
      
      %.o: %.c
           $(CC) $(CFLAGS) -c -o $@ $<
      
      clean:
           rm -f *.o myapp
      
    • 解释
    • 当首次运行 make 时,所有 .c 文件都会比 myapp 新,因此 $? 包含 main.o util.o
    • $(CC) $(CFLAGS) -o $@ $? 会链接 main.o util.o生成 myapp
    • 如果之后修改了 main.c 文件,但 util.c 未修改,则 $? 只包含 main.o,因此只有 main.o 会被重新编译,然后与 util.o 一起链接生成 myapp
    • 如果 util.c 也被修改了,那么 $? 将包含 main.o util.o,这两个文件都将被重新编译,然后链接生成 myapp

1.6 通配符

在 Makefile 中,通配符被用来匹配文件名的一部分或全部,以便于构建规则的定义更加灵活。这里有几个常用的通配符及其用途:

  • %:在模式规则中用于匹配单个文件名的部分。它通常用于目标或依赖项的模板中。
    • 示例
    %.o: %.c
        gcc -c $< -o $@
    
    • 解释:这条规则会匹配所有.c文件,并将它们编译成相应的 .o 文件。当你运行 make foo.o,make 将会尝试找到匹配 foo.o: foo.c 的规则。
  • *:匹配任意数量的字符(包括零字符)。
    • 示例
    objects = $(wildcard *.o)
    all: $(objects)
    
    • 解释:这里 $(wildcard *.o) 会扩展为当前目录下所有的.o文件。
  • ?:匹配单个字符。

1.7 条件执行

Makefile 中,条件执行允许您根据变量的值来控制某些规则或命令的执行。这可以通过几个条件指令来实现,主要包括 ifeq, ifneq, ifdef, 和 ifndef

1. ifeq 和 ifnq
  • ifeq 用于测试两个表达式的值是否相等,如果相等则执行 then 后面的语句块,否则跳过。
  • ifneq 则相反,如果两个表达式的值不相等,则执行 then 后面的语句块。
2. 基本语法
ifeq (value1, value2)
    # TEXT-IF-TRUE
else
    # TEXT-IF-FALSE
endif
3. 示例
ifeq ($(DEBUG), 1)
    CFLAGS += -g
else
    CFLAGS += -O2
endif
4. ifdef 和 ifndef
  • ifdef 用于检查变量是否已经被定义,如果已定义则执行 then 后面的语句块。
  • ifndef 则检查变量是否未被定义,如果没有定义则执行 then 后面的语句块。
5. 基本语法
ifdef variable
    # TEXT-IF-DEFINED
else
    # TEXT-IF-NOT-DEFINED
endif
6. 示例
ifdef DEBUG
    CFLAGS += -DDEBUG
endif

1.8 函数

在 Makefile 中,函数是用来处理变量值的工具,可以让构建过程更加灵活和动态。以下是一些常用的 Makefile 函数及其用途:

字符串处理函数
  • subst:
    • 功能:字符串替换函数
    • 语法$(subst FROM,TO,TEXT)
    • 示例
      STR := hello world
      NEW_STR := $(subst l,X,$(STR))
      
    • 解释:STR 变量被设置为 “hello world”,然后使用 subst 函数将其中的字母 l 替换为 X,因此,最终 NEW_STR 的值将是 “heXXo worXd”,并将结果赋值给 NEW_STR 变量。
  • patsubst:
    • 功能:模式字符串替换函数
    • 语法$(patsubst PATTERN,REPLACEMENT,TEXT)
      • PATTERN %.c,表示匹配任何以 .c 结尾的文件。
      • REPLACEMENT %.o,表示将匹配到的 .c 替换成 .o
      • TEXT FILES 变量,包含了一组 .c 文件。
    • 示例
      FILES := foo.c bar.c baz.c
      OBJECTS := $(patsubst %.c,%.o,$(FILES))
      
    • 解释patsubst 函数会遍历 FILES 变量中的每个元素,如果元素匹配 PATTERN(即以 .c 结尾),则用 REPLACEMENT 替换该元素。因此,OBJECTS 变量的值将会是:foo.o bar.o baz.o
  • wildcard:
    • 功能:扩展通配符,返回匹配的文件列表。
    • 语法$(wildcard PATTERN)
    • 示例
      SOURCES := $(wildcard *.c)
      
    • 解释:返回当前目录下所有.c文件
  • notdir:
    • 功能:从文件路径中移除目录部分,只保留文件名。
    • 语法$(notdir FILE)
    • 示例
      FILE := /path/to/file.txt
      NAME := $(notdir $(FILE))
      
    • 解释:当 notdir 函数执行时,它会从给定的路径中移除目录部分,只保留文件名。因此,最终 NAME 的值将是 “file.txt”。
  • dir:
    • 功能:返回文件路径的目录部分
    • 语法:$(dir FILE)
    • 示例
      FILE := /path/to/file.txt
      DIR := $(dir $(FILE))
      
    • 解释dir 函数执行时,它会从给定的路径中移除文件名部分,只保留目录路径。因此,最终 DIR 的值将是 “/path/to/”。
  • addsuffix:
    • 功能:给列表中的每个元素添加后缀
    • 语法$(addsuffix SUFFIX,LIST)
    • 示例
      SUFFIX := .o
      LIST := foo bar baz
      OBJECTS := $(addsuffix $(SUFFIX),$(LIST))
      
    • 解释:在这里,SUFFIX 是要添加到列表每个元素末尾的后缀,LIST 是要处理的列表。addsuffix 函数执行时,它会将 SUFFIX 的值 “.o” 添加到 LIST 中每个元素的末尾。因此,最终 OBJECTS 的值将是:foo.o bar.o baz.o
  • addprefix:
    • 功能:给列表中的每个元素添加前缀。
    • 语法$(addprefix PREFIX,LIST)
    • 示例
      PREFIX := obj/
      LIST := foo.o bar.o baz.o
      OBJECTS := $(addprefix $(PREFIX),$(LIST))
      
    • 解释:在这里,PREFIX 是要添加到列表每个元素的前缀,LIST 是要处理的列表。addprefix 函数执行时,它会将 prefix 的值 “obj/” 添加到 LIST 中每个元素的末尾。因此,最终 OBJECTS 的值将是:obj/foo obj/bar obj/baz
  • filter:
    • 功能:从列表中选择匹配的元素。
    • 语法$(filter PATTERN,...)
    • 示例
      FILES := foo.c bar.c foo.h bar.h
      CS := $(filter %.c,$(FILES))
      
    • 解释:当 filter 函数执行时,它会从 FILES 变量中筛选出所有匹配模式 %.c 的元素。因此,最终 CS 的值将是:foo.c bar.c
  • filter-out:
    • 功能:从列表中排除匹配的元素。
    • 语法$(filter-out PATTERN,...)
    • 示例
      FILES := foo.c bar.c foo.h bar.h
      NON_CS := $(filter-out %.c,$(FILES))
      
    • 解释:当 filter-out 函数执行时,它会从 FILES 变量中筛选出所有匹配模式不是 %.c 的元素。因此,最终 NON_CS 的值将是:foo.h bar.h
其他函数
  • sort:
    • 功能:对列表排序。
    • 语法$(sort LIST)
    • 示例
      FILES := foo.c bar.c baz.c extra.c
      SORTED_FILES := $(sort $(FILES))
      
    • 解释:sort 函数会对 FILES 变量中的元素进行排序,SORTED_FILES量将包含按字母顺序排序后的文件名列表,结果为:bar.c baz.c extra.c foo.c
  • strip:
    • 功能:删除变量值中的空白字符。
    • 语法$(strip TEXT)
    • 示例
      TEXT := hello world
      STRIPPED := $(strip $(TEXT))
      
    • 解释:当 strip 函数执行时,它会去除 TEXT 变量值中的前导和尾随空白字符。由于 “hello world” 本身没有前导或尾随空白字符,因此最终 STRIPPED 的值仍然是 “hello world”。
  • call:
    • 功能:调用宏或函数。
    • 语法$(call macro-name, arguments...)
    • 示例
      define MY_MACRO
          @echo "Hello, $(1)"
      endef
      
      $(call MY_MACRO,World)
      
    • 解释:这段代码定义了一个宏 MY_MACRO,它接受一个参数(这里用 $(1) 表示),并打印一条包含该参数的消息。

当 call 函数执行时,它会调用 MY_MACRO 宏,并将 “World” 作为参数传递。因此,最终会打印出:Hello, World

  • foreach :
    • 功能:用于迭代变量名。
    • 语法$(foreach var, list, command)
      • var: 用于迭代的变量名。
      • list: 需要迭代的列表。
      • command: 对每个元素执行的命令。
    • 示例
      SOURCES := foo.c bar.c baz.c
      OBJECTS :=
      
      define foreach
          $(eval $(1) := $(foreach $(2),$(3),$(4)))
      endef
      
      $(call foreach, OBJECTS, %.c, %.o, $(SOURCES))
      
      all:
          @echo "Sources: $(SOURCES)"
          @echo "Objects: $(OBJECTS)"
      
    • 输出
      Sources: foo.c bar.c baz.c
      Objects: foo.o bar.o baz.o
      
    • 解释:这表明 foreach 函数成功地将每个 .c 文件名转换成了对应的 .o 文件名。
    • 注意事项
      • foreach 函数不是内置的 Makefile 函数,而是通过宏定义来实现的。
      • 在实际使用中,您可能需要根据具体需求调整 foreach 函数中的命令。

1.10 清理规则

在 Makefile 中,清理规则(clean rule)是一种常见的做法,用于删除中间文件和编译产物,以便重新编译项目或保持工作目录的整洁。

基本语法
.PHONY: clean
clean:
    rm -f *.o my_program
详解
  • .PHONY 标记:
    • clean 目标通常标记为 .PHONY,这意味着即使没有与之对应的目标文件存在,make 也会执行这个目标。这是因为清理规则通常不需要与任何具体的文件关联,而是要删除一系列文件。通常clean放在makefile文件末尾。
  • 清理命令:
    • rm -f 命令用于删除文件。-f 选项表示强制删除,即使文件不存在也不会产生错误。
    • *.o 表示删除所有 .o 文件。
    • my_program 表示删除名为 my_program 的可执行文件。
示例
SOURCES := foo.c bar.c baz.c
OBJECTS := $(addsuffix .o, $(basename $(SOURCES)))

all: my_program

my_program: $(OBJECTS)
    gcc -o $@ $(OBJECTS)

%.o: %.c
    gcc -c $< -o $@

.PHONY: clean
clean:
    rm -f $(OBJECTS) my_program
解释
1. 定义源文件和目标文件:
SOURCES := foo.c bar.c baz.c
OBJECTS := $(addsuffix .o, $(basename $(SOURCES)))
2. 定义 all 目标:
all: my_program

运行 make 时,默认会执行 all 目标,这里指向 my_program。

3. 定义 my_program 目标
my_program: $(OBJECTS)
    gcc -o $@ $(OBJECTS)

这个目标定义了如何从目标文件列表 OBJECTS 创建可执行文件 my_program。

4. 定义 .o 文件的规则:
%.o: %.c
    gcc -c $< -o $@

这个规则定义了如何从 .c 文件创建对应的 .o 文件。

5. 定义清理规则:
.PHONY: clean
clean:
    rm -f $(OBJECTS) my_program

这个清理规则定义了如何删除所有的 .o 文件和可执行文件 my_program。

运行示例
$ make
gcc -c foo.c -o foo.o
gcc -c bar.c -o bar.o
gcc -c baz.c -o baz.o
gcc -o my_program foo.o bar.o baz.o
$ ls
foo.c  foo.o  bar.c  bar.o  baz.c  baz.o  my_program  Makefile
$ make clean
rm -f foo.o bar.o baz.o my_program
$ ls
foo.c  bar.c  baz.c  Makefile

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

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

相关文章

python3 pyside6图形库学习笔记及实践(五)

目录 前言选项卡(QTabWidget)创建选项卡常用属性和方法常用信号 堆叠页面(QStackedWidget)创建堆叠容器切换页面过渡动画 前言 本系列文章为b站PySide6教程以及官方文档的学习笔记 原视频传送门&#xff1a;【已完结】PySide6百炼成真&#xff0c;带你系统性入门Qt 官方文档…

Linux云计算 |【第二阶段】CLUSTER-DAY3

主要内容&#xff1a; Ceph概述、部署Ceph集群、Ceph块存储 一、分布式存储基础 分布式系统&#xff08;Distributed File System&#xff09;是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。文件系统管理的物理存储资源不一定直接连接在本…

ClickHouse:单机安装

目录 一、ClickHouse介绍 二、安装ClickHouse 2.1安装要求 2.2单机安装 2.3修改配置文件(可选) 2.4升级软件 三、使用ClickHouse 3.1连接ClickHouse 3.2 执行SQL 一、ClickHouse介绍 ClickHouse是由Yandex开源的一个高性能、面向列的SQL数据库管理系统&#xff08;DBM…

【踩坑】pytorch中的索引与copy_结合不会复制数据及其解决方案

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 背景知识 实验验证 结论分析 错误案例 处理方法 注意事项 附加说明 基本索引返回视图 高级索引返回副本 赋值操作都是原地操作 以下内容…

SS9283403 sqlite3交叉编译并部署到SS928(六)

1.Sqlite3下载 连接&#xff1a;SQLite Download Page 2.解压 tar zxvf sqlite-autoconf-3460000.tar.gz 3.配置并编译 进入解压目录&#xff0c;打开命令行&#xff0c;输入如下命令 ./configure CCaarch64-mix210-linux-gcc --hostarm-linux --prefix/home/mc/work/sqlite…

002发那科ROBOGUIDE仿真导入模型

打开已经创建好的工程&#xff0c;找到“机器” 右键&#xff0c;添加机器->CAD文件(F) 找到本地的3D模型&#xff0c;然后点击&#xff0c;打开 设置模型位置[0,0,0,0,0,0] 然后就导入进来啦

对比速览 | Alluxio 企业版 v.s. 社区版

当前诸多企业面临着日益增长的数据量和复杂的数据管理挑战。特别是在模型训练的过程中&#xff0c;诸如GPU短缺、GPU利用率不高等问题已经成为许多企业在技术实施中面临的挑战。同时&#xff0c;大数据分析中跨云数据访问速度慢、成本高等问题也给企业带来了痛点。为了应对这些…

redolog和binlog的两阶段提交和区别

redolog和binlog区别 redo log 是 InnoDB 引擎特有的&#xff1b;binlog 是 MySQL 的 Server 层实现的&#xff0c;所有引擎都可以使用。redo log 是物理日志&#xff0c;记录的是“在某个数据页上做了什么修改”&#xff1b;binlog 是逻辑日志&#xff0c;记录的是这个语句的…

Shell编程 --函数语法与重定向

文章目录 Shell编程shell函数语法函数参数 Shell 输入/输出重定向输出重定向输入重定向重定向深入讲解/dev/null 文件 总结 Shell编程 Shell是一种程序设计语言。作为命令语言&#xff0c;它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令&…

Postman入门:环境变量和全局变量

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、发送请求 二、设置并引用环境变量 比如&#xff1a;我建的这个生产环境 使用环境有两个方式&#xff0c;一个是点击每个环境后面的对勾&#xff1b;另一种方式…

【Linux操作系统】进程的基本概念(PCB对象)详解

目录 一、进程的基本概念二、进程的描述组织&#xff08;PCB对象&#xff09;1.PCB的基本概念2.为什么要有PCB对象&#xff08;操作系统对进程的组织管理&#xff09;3.PCB对象的内部属性&#xff08;tast_struct结构体&#xff09; 三、查看进程1.ps指令2.top指令3.通过 /proc…

【LeetCode 1991 找到数组的中间位置 / LeetCode 724 寻找数组的中心下标】中间索引问题

1991 题目描述 暴力解法1&#xff1a; 思路&#xff1a; 遍历下标&#xff0c;求出左边和和右边和比较两边是否相等相等直接返回值没有符合的返回 -1 class Solution {public int findMiddleIndex(int[] nums) {int lennums.length;//初始化一个变量 midIndex 为 -1&#xff…

前端性能优化-script标签中的async与defer

前言 当浏览器解析 DOM 时候&#xff0c;遇到 script 标签时&#xff0c;会暂停 DOM 的解析&#xff0c;先加载并执行 script 中的代码&#xff0c;然后再继续 DOM 的解析。 比如 <script>window.env {version: "production",}; </script>上面的代码…

KVM——虚拟机添加设备与挂载磁盘

目录 一. 图形化方式添加设备 1. 添加磁盘 2. 添加网卡 二. 命令行形式添加设备 方式一&#xff1a; 方式二&#xff1a; 磁盘格式raw和qcow2 raw格式 qcow2格式 如何选择 挂载磁盘 一. 图形化方式添加设备 1. 添加磁盘 2. 添加网卡 先关机 给宿主机添加一块网…

华南理工大学-大学物理实验 迈克尔逊干涉仪

迈克尔逊干涉仪的调整与使用 引言 迈克尔逊( Albert Abrham Michelson, 1852-1931) , 著名的实验物理学家,近现代干涉仪的开山鼻祖。他设计了至今仍在广泛应用的迈克尔逊干涉仪。该仪器设计非常巧妙,测量极其精密,是近代许多干涉仪的基础。迈克尔逊当时设计该仪器的目的之…

HCIA复习 | HCIP基础

目录 Days01&#xff08;24.8.1&#xff09; IPv4 Header OSI七层模型 TCP、UDP数据结构 TCP/IP模型 OSI模型与TCP/IP模型区别 ARP Days02&#xff08;24.8.2&#xff09; 交换机 封装和解封装 IPv6 Header 路由 RIP Days01&#xff08;24.8.1&#xff09; IPv4 …

【面试题】【简历版】完整版

一、Java 基础 java 面向对象特性 封装&#xff08;Encapsulation&#xff09;&#xff1a; public class Student {// 将name和age封装起来private String name;private int age;// 提供方法设置和获取这些属性public void setName(String name){this.name name;}public Str…

JavaEE: 查看线程信息

示例用代码 public class Main {static class MyThread extends Thread {Overridepublic void run() {while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}public st…

基于Java+SpringBoot+Vue的网上超市的设计与实现

基于JavaSpringBootVue的网上超市的设计与实现 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f34…

canal监听mysql增量数据发布到rabbitmq

canal工作原理 canal 依靠mysql主从备份的原理&#xff0c;模拟 MySQL slave 的交互协议&#xff0c;伪装自己为 MySQL slave &#xff0c;向 MySQL master 发送dump 协议MySQL master 收到 dump 请求&#xff0c;开始推送 binary log 给 slave (即 canal )canal 解析 binary …