关于Makefile

第一本参考书大家看一点就晓得,作者使用的是他发的工具链.
里面有cc1,make,…
为了脱离不透明工具链(过时),决定使用gcc,但是实践中出现一些莫名其妙的问题在此记录:

背景

一模一样的程序,一模一样的Makefile文件,命令完全相同

问题1

TARGET_IMG  = release/MonkeyOS.img
make     = ../z_tools/make.exe # 注意:这个千万不要改
run:
	$(make) $(TARGET_IMG)

生成的镜像,完全没问题

但是如果改成
make $(TARGET_IMG)就会出错,而且很要命

这里自然而然想到,手动写make release/MonkeyOS.img会怎么样.
得到的结果仍是:vmware报错,fatal…

问题2

各模块都可以直接gcc -c -m32 -std=c99,众所周知它等效于:

cc1 -m32 -std=c99 -o .s
as --32 .s -o .o

一条命令的那个用来编译主程序,就报错,后者就正常

build/%.kernel.o: kernel/%.c include/kernel/%.h Makefile
	@$(cc) $< -o $@
	@echo $@

build/MonkeyOS.kernel.o: kernel/MonkeyOS.c include/kernel/MonkeyOS.h Makefile # 注意:千万不要换成gcc -c,后果自负
	where cc1
	@cc1 $< -m32 -std=c99 -o build/MonkeyOS.kernel.s -I include/ -Os
	@echo 
	@as --32 build/MonkeyOS.kernel.s -o $@

其中,cc = gcc -m32 -Os -I include/ -c -std=c99

稍有头绪但是仍不清晰

为什么Makefile会有如此奇怪的怪圈?难道是mingw版本高了有bug?不大可能,那么会不会是环境的问题?试试看
把z_tools/里的make.exe放到mingw/的bin/,在此之前把原有make.exe改成make_.exe 结果:仍报错
这说明不是make的问题,问题在于make调用了哪个cc1
gcc的问题肯定没有,因为在系统环境变量下,只能是mingw的那个gcc
前文有提到,主程序必须cc1+as,as跟gcc一样,问题就在于cc1!

猜测

使用z_tools/make.exe的时候,内部调用z_tools/cc1.exe

验证

把z_tools/cc1.exe改成z_tools/cc1_.exe
结果:不正常了.

为什么这样做?

小细节注意到:使用系统make的时候调用cc1底下会有几行统计信息,解析时间,编译时间,等等
但是z_tools/的cc1,却只输出程序文件中的函数名,这说明两个环境下的Makefile调用的是不同的cc1

结论

由此得出结论:make.exe自动优先搜索它所在目录下的程序(这不废话,这好像windows下的吧)
可以做个小实验:把作者提供的cc1换到mingw下,然后直接make估计就能成(我不敢因为怕那个cc1不如mingw的())

Makefile 是一种简单的文本文件,它用来描述程序的构建过程,也就是编译、链接等步骤。编写 Makefile 的目的是为了自动化软件开发流程,提高效率并保证一致性。下面是创建一个基础 Makefile 的步骤及一些关键元素: 1. **顶部注释**:可以包含项目信息、作者和版本等。 ```makefile # Project Name Makefile ``` 2. **变量定义**:声明常量如源文件、目标文件和编译器等。 ```makefile CC = gcc SOURCES = source1.c source2.c OBJECTS = source1.o source2.o EXECUTABLE = program ``` 3. **规则**(Rules):这部分定义了如何从源文件生成目标文件或最终可执行文件。 ```makefile %.o: %.c $(CC) -c $< -o $@ all: $(EXECUTABLE) ``` - `%` 代表任意字符串,`.` 表示匹配规则的剩余部分。 - `$(SOURCES:.c=.o)` 是替换语法,将 `.c` 替换为 `.o` 来生成目标文件名列表。 4. **目标规则**(Target Rules):这里定义 "all" 目标,即默认动作。 ```makefile $(EXECUTABLE): $(OBJECTS) $(CC) $(OBJECTS) -o $@ ``` 5. **清理规则**(Clean Rule):如果需要,你可以定义一个 "clean" 或者 "distclean" 目标来删除中间产物。 ```makefile .PHONY: clean clean: rm -f $(OBJECTS) $(EXECUTABLE) ``` 6. **保存 Makefile**:最后将文件保存为 `Makefile`。 以上是一个基本的 Makefile 示例。实际应用中,可能会根据项目需求增加更多的规则、变量和条件判断。要执行 Makefile,只需在项目目录下输入 `make`(或其他指定的 make 命令)即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dtsroy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值