Makefile入门到放弃

1、Makefile HelloWorld

Makefile 是一个常用的构建工具,用于编译源代码、链接文件以及执行其他构建任务。

  1. 创建Makefile
vim Makefile
================================
main:main.o test1.o test2.o
	gcc -o main main.o test1.o test2.o
main.o:main.c
	gcc -c main.c
test1.o:test1.c
	gcc -c test1.c
test2.o:test2.c
	gcc -c test2.c
 
clean:
	rm *.o
	rm main
  1. 执行Makefile
make

2、Makefile的规则

目标依赖的关系执行的命令 三部分结构如下:

targets:prerequisites
【TAB】command

相关说明如下:

targets:规则的目标,是必须要有的,可以是 Object File(一般称它为中间文件),也可以是可执行文件,还可以是一个标签;
prerequisites:是我们的依赖文件,要生成 targets 需要的文件或者是目标。可以是多个,用空格隔开,也可以是没有;
commandmake 需要执行的命令(任意的 shell 命令)。可以有多条命令,每一条命令占一行;
如果 command 太长, 可以用 \ 作为换行符。

注意:我们的目标和依赖文件之间要使用冒号分隔开,命令的开始一定要使用 Tab 键,不能使用空格键。

简单的概括一下Makefile 中的内容,它主要包含有五个部分,分别是:

2.1 Makefile的显式规则与通配符

显式规则说明了,如何生成一个或多的的目标文件。这是由 Makefile 的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。

  • *:表示任意一个或多个字符。
  • ?:表示任意一个字符。
  • [...][abcd] 表示 a,b,c,d中任意一个字符。
                   [^abcd]表示除 a,b,c,d 以外的字符。
                   [0-9] 表示 0~9中任意一个数字。
  • ~:表示用户的 home 目录。

2.2 Makefile的隐晦规则

由于我们的 make 命名有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写 Makefile,这是由 make 命令所支持的。

2.3 Makefile的变量

在 Makefile 中我们要定义一系列的变量,变量一般都是字符串,这个有点像 C 语言中的宏,当 Makefile 被执行时,其中的变量都会被扩展到相应的引用位置上。

2.3.1 Makefile自动变量(Special Variables)

自动变量是由Makefile系统自动提供的,主要用于规则的依赖和命令行中的引用。它们不需要在Makefile中显式定义,而是根据构建的上下文自动填充。常见的自动变量包括:

$@:目标文件的完整名称。在规则的命令行中,$@会被替换为目标文件的名字。
$<:第一个依赖文件的名称。在多依赖项中,$<仅指第一个依赖项。
$^:所有依赖文件的名称,以空格分隔。如果规则中有多个依赖文件,$^将包含所有这些依赖文件的名称。
$*:不包含扩展名的目标文件名的部分,通常用于模式规则中。
$+:与$^类似,但是$+会重复每个依赖文件的名称,即使它们在依赖列表中出现多次。
$?:所有比目标文件时间戳新的依赖文件的名称,以空格分隔。这在确定哪些文件需要重新编译时非常有用。

all: prog
	$(CC) $(CFLAGS) -o $@ $^

2.3.2 Makefile预定义变量(Predefined Variables)

预定义变量是Makefile系统自带的,用于描述构建环境和配置信息。这些变量可以被覆盖或重新定义,以适应不同的构建需求。常见的预定义变量包括:

MAKE:用于递归调用make命令的变量。
MAKEFLAGS:控制make行为的标志。
VPATH:虚拟路径,用于指定源文件所在的位置。
CC:编译器名称。
CFLAGS:编译器的附加选项。

CC:=gcc
CFLAGS:=-Wall -g

all:
	$(CC) $(CFLAGS) -o prog prog.c

2.3.3 Makefile用户自定义变量

用户自定义变量是Makefile中最常见的变量类型,它们由用户在Makefile中定义,用于存储任意的字符串或路径。这些变量可以用于指定源文件、头文件、库文件的路径,或者传递给编译器的参数等。

SOURCES:=prog.c util.c
HEADERS:=prog.h util.h
LIBS:=-lm

all: prog
prog: $(SOURCES)
	$(CC) $(CFLAGS) -o prog $(SOURCES) $(HEADERS) $(LIBS)

2.3.4 Makefile使用变量

Makefile 中,变量的引用通常通过$符号加上变量名来实现。在规则的命令行中,变量会被其对应的值替换。如果变量名后面跟有括号 () ,则表示使用函数调用的方式引用变量,例如$(subst a,b,$(VARIABLE)),这将替换VARIABLE中的所有a字符为b

2.4 Makefile的文件包含

其包括了三个部分,一个是在一个 Makefile 中引用另一个 Makefile,就像 C 语言中的 include 一样;另一个是指根据某些情况指定 Makefile 中的有效部分,就像 C 语言中的预编译 #if 一样;还有就是定义一个多行的命令。

2.5 Makefile的注释

Makefile 中只有行注释,和 UNIX 的 Shell 脚本一样,其注释是用 # 字符,如果你要在你的 Makefile 中使用 # 字符,可以用反斜框进行转义,如: \#

3、Makefile小试牛刀

# 指定目标文件和依赖关系
target: dependency1 dependency2
    command1
    command2

# 定义目标 target 的依赖关系和命令

dependency1:
    command3

dependency2:
    command4

在上面的示例中,我们定义了一个名为 target 的目标,它依赖于 dependency1 和 dependency2。当执行 make 命令时,Makefile 将根据依赖关系执行相应的命令。

  • target: dependency1 dependency2 - 这行指令定义了目标 target 和其依赖关系。
  • command1command2 - 这两行指令是目标 target 的命令。它们将会在目标被构建时执行。
  • dependency1:dependency2: - 这两行指令定义了目标 target 的两个依赖项。

使用 Makefile 时,你可以在命令行中运行 make 命令来执行构建。例如,在上述示例中,运行 make target 将会执行相关的命令,构建目标 target。

你可以根据自己的实际需求添加更多目标、依赖项和命令。Makefile 还支持变量、条件语句、循环等高级功能,以满足更复杂的构建需求。

AAAAAAA

vim test1.c
==============================
#include<stdio.h>

int main(void) {
	test2_func1();
	return 0;
}
vim test2.c
==============================
#include<stdio.h>

void test2_func1(void) {
	printf("你好 世界,我是test2.c 中的test2_func1 函数;函数名=%s;line=%d !\n", __FUNCTION__,__LINE__);
}
gcc -v
gcc -o test test1.c test2.c
gcc -o test test1.c test2.c -v
==============================
1、编译:由编译器将 .c源代码编译成 .s汇编代码
	    预处理:编译预处理主要是处理4种情况
			① 宏定义 替换
			② \#include文件包含 展开
			③ 条件编译
			④ 特殊符号

2、汇编:由汇编器将 .s源代码转换成 .o目标代码

3、链接:由链接器将代码在执行过程中用到的目标文件和库文件链接成一个可执行程序。

Makefile 的规则

目标文件: 依赖文件1 依赖文件2 依赖文件3 依赖文件4 依赖文件5 依赖文件n
[TAB键]需要执行的命令(如何将依赖文件编译成目标文件)

第一个Makefile

test:test1.c test2.c
	gcc -o test test1.c test2.c

第二个Makefile

test:test1.o test2.o
	gcc -o test test1.o test2.o

test1.o:test1.c
	gcc -c -o test1.o test1.c

test2.o:test2.c
	gcc -c -o test2.o test2.c

如果依赖文件的时间比目标文件新,那么就执行相应的编译命令。

总结:
1、规则是Makefile的核心,规则如下
目标文件:依赖文件(可以是多个文件)
[TAB]需要执行的命令
2、规则执行的原理
当“目标文件不存在” 或 “某个依赖文件比目标文件新”,则执行命令。

3、根据第一个目标文件递归执行依赖文件相关命令,最后执行第一个目标文件的命令。

https://www.cnblogs.com/chien/p/17328638.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值