1. Makefile版本1(基础版)

一、Makefile初识

执行 make 命令时,它会去当前目录下查找名为Makefile的文件,并根
据它的指示去执行操作,生成第一个目标

二、第一个Makefile(效率很低)

同一目录下存在 main.csub.csub.h 这三个文件。
make 将 main.csub.c 这两个源代码文件编译成一个名为 test 的可执行文件

# 编译并链接main.c和sub.c生成可执行文件test
test : main.c sub.c sub.h
    gcc -o test main.c sub.c

  1. main.c:这是主程序的源代码文件。
  2. sub.c:这是辅助函数的源代码文件。
  3. sub.h:这是辅助函数的头文件。

指令 gcc -o test main.c sub.c 使用 GCC 编译器来将 main.csub.c 这两个源代码文件编译成一个名为 test 的可执行文件。 -o 选项用于指定输出的可执行文件名。

编译完成后,你可以运行 ./test 命令来执行生成的可执行文件 test。请确保在同一目录下存在 main.csub.csub.h 这三个文件,不然编译过程会出错。

三、第二个Makefile(效率高、规则太多、不支持自动检测头文件)

test : main.o sub.o  # 定义test目标,依赖于main.o和sub.o两个目标文件
    gcc -o test main.o sub.o  # 使用gcc编译器将main.o和sub.o目标文件链接为可执行文件test

main.o : main.c  # 定义main.o目标,依赖于main.c源文件
    gcc -c -o main.o main.c  # 使用gcc编译器将main.c源文件编译为main.o目标文件

sub.o : sub.c  # 定义sub.o目标,依赖于sub.c源文件
    gcc -c -o sub.o sub.c  # 使用gcc编译器将sub.c源文件编译为sub.o目标文件

clean:  # 定义clean目标,用于清理生成的目标文件和可执行文件
    rm *.o test -f  # 删除所有的目标文件和可执行文件,-f选项表示强制删除而不提示

  1. test : main.o sub.otest目标依赖于main.osub.o文件。如果它们有任何更新,将会重新构建test可执行文件。
  2. gcc -o test main.o sub.o:该规则描述了如何构建test目标。它使用gcc编译器将main.osub.o链接为一个可执行文件test
  3. main.o : main.cmain.o目标依赖于main.c文件。如果main.c有任何更新,将会重新构建main.o
  4. gcc -c -o main.o main.c:该规则描述了如何构建main.o目标。它使用gcc编译器将main.c编译为一个目标文件main.o
  5. sub.o : sub.csub.o目标依赖于sub.c文件。如果sub.c有任何更新,将会重新构建sub.o
  6. gcc -c -o sub.o sub.c:该规则描述了如何构建sub.o目标。它使用gcc编译器将sub.c编译为一个目标文件sub.o
  7. clean: rm *.o test -fclean目标用于删除生成的目标文件和可执行文件。rm命令用于删除文件,*.o表示匹配所有以.o结尾的文件,test表示删除名为test的文件,-f选项用于强制删除而不提示。

四、第三个Makefile(效率高、不支持头文件检测)

test : main.o sub.o  # 定义test目标,依赖于main.o和sub.o两个目标文件
    gcc -o test main.o sub.o  # 使用gcc编译器将main.o和sub.o目标文件链接为可执行文件test

%.o : %.c  # 定义模式规则,表示以.o结尾的目标文件依赖于同名的.c文件
    gcc -c -o $@ $<  # 使用gcc编译器将.c文件编译为.o目标文件

clean:  # 定义clean目标,用于清理生成的目标文件和可执行文件
    rm *.o test -f  # 删除所有的目标文件和可执行文件,-f选项表示强制删除而不提示

这段代码是一个使用变量和模式规则的Makefile脚本。它定义了以下几个规则:

  1. test: main.o sub.otest目标依赖于main.osub.o文件。如果它们有任何更新,将会重新构建test可执行文件。
  2. gcc -o test main.o sub.o:该规则描述了如何构建test目标。它使用gcc编译器将main.osub.o链接为一个可执行文件test
  3. %.o : %.c:这个模式规则表示任何以.o结尾的目标都依赖于同名的.c文件。如果.c文件有任何更新,将会重新构建对应的.o目标文件。
  4. gcc -c -o $@ $<:该规则描述了如何构建.o目标文件。$@表示当前目标的文件名,$<表示当前目标的第一个依赖文件。使用gcc编译器将.c文件编译为.o目标文件。
  5. clean: rm *.o test -fclean目标用于删除生成的目标文件和可执行文件。rm命令用于删除文件,*.o表示匹配所有以.o结尾的文件,test表示删除名为test的文件,-f选项用于强制删除而不提示。

与之前相比,这段代码使用了模式规则来简化目标与依赖的定义。通过使用%.o : %.c规则,可以在不同的.o文件之间共享相同的规则,并自动匹配对应的.c文件进行编译。这样可以减少代码的重复以及添加新的源文件时的维护工作。

五、第四个Makefile(效率高、精简,但是要手动添加头文件匹配规则)

test : main.o sub.o  # test目标依赖于main.o和sub.o目标文件
    gcc -o test main.o sub.o  # 使用gcc编译器将main.o和sub.o目标文件链接为可执行文件test

%.o : %.c  # 模式规则,表示以.o结尾的目标文件依赖于同名的.c文件
    gcc -c -o $@ $<  # 使用gcc编译器将.c文件编译为.o目标文件

sub.o : sub.h  # sub.o目标文件依赖于sub.h头文件

clean:  # clean目标,用于删除生成的目标文件和可执行文件
    rm *.o test -f  # 删除所有的目标文件和test可执行文件

这段代码是一个使用变量和模式规则的Makefile脚本,与之前相比进行了一些修改。它定义了以下几个规则:

  1. test: main.o sub.otest目标依赖于main.osub.o文件。如果它们有任何更新,将会重新构建test可执行文件。
  2. gcc -o test main.o sub.o:该规则描述了如何构建test目标。它使用gcc编译器将main.osub.o链接为一个可执行文件test
  3. %.o : %.c:这个模式规则表示任何以.o结尾的目标都依赖于同名的.c文件。如果.c文件有任何更新,将会重新构建对应的.o目标文件。
  4. gcc -c -o $@ $<:该规则描述了如何构建.o目标文件。$@表示当前目标的文件名,$<表示当前目标的第一个依赖文件。使用gcc编译器将.c文件编译为.o目标文件。
  5. sub.o : sub.hsub.o目标依赖于sub.h头文件。如果头文件有任何更新,将会重新构建sub.o目标文件。
  6. clean: rm *.o test -fclean目标用于删除生成的目标文件和可执行文件。rm命令用于删除文件,*.o表示匹配所有以.o结尾的文件,test表示删除名为test的文件,-f选项用于强制删除而不提示。

通过添加sub.o : sub.h规则,当头文件sub.h有任何更新时,会重新构建sub.o目标文件。

同样,运行make命令将会自动根据依赖关系构建所需的目标文件,make clean命令则会删除生成的目标文件和可执行文件。

六、第五个Makefile(高效、精简,自动检测头文件)

以下是对代码的注释:

objs := main.o sub.o  # 定义目标文件列表

test : $(objs)  # test目标依赖于objs列表中的目标文件
    gcc -o test $^  # 使用gcc编译器将目标文件链接为可执行文件test

# 判断是否存在依赖文件
# .main.o.d .sub.o.d
dep_files := $(foreach f, $(objs), .$(f).d)
dep_files := $(wildcard $(dep_files))

# 包含依赖文件
ifneq ($(dep_files),)
include $(dep_files)
endif

%.o : %.c  # 模式规则,表示以.o结尾的目标文件依赖于同名的.c文件
    gcc -Wp,-MD,.$@.d -c -o $@ $<  # 使用gcc编译器将.c文件编译为.o目标文件,并生成依赖文件

clean:  # clean目标,用于删除生成的目标文件和可执行文件
    rm *.o test -f  # 删除所有的目标文件和test可执行文件

distclean:  # distclean目标,更彻底地清理,包括删除依赖文件
    rm $(dep_files) *.o test -f  # 删除依赖文件、所有目标文件和test可执行文件

这段代码是一个使用变量和模式规则的Makefile脚本,相对于之前的版本进行了一些修改。它定义了以下几个规则:

  1. objs := main.o sub.o:定义了一个变量objs,包含需要构建的目标文件列表。
  2. test : $(objs)test目标依赖于objs列表中的目标文件。如果它们有任何更新,将会重新构建test可执行文件。
  3. gcc -o test $^:该规则描述了如何构建test目标。$^表示所有依赖文件的列表。使用gcc编译器将依赖的目标文件链接为一个可执行文件test
  4. dep_files := $(foreach f, $(objs), .$(f).d):定义了一个变量dep_files,用于存储生成的依赖文件列表。每个目标文件都对应一个以.d结尾的依赖文件。
  5. dep_files := $(wildcard $(dep_files)):使用wildcard函数扩展dep_files变量,将其中的通配符表示的依赖文件替换为实际的文件名。
  6. ifneq ($(dep_files),):条件判断,检查是否存在依赖文件。如果存在依赖文件,则执行下面的操作。
  7. include $(dep_files):将依赖文件包含进来,确保Makefile能够感知到依赖关系。
  8. %.o : %.c:这个模式规则表示任何以.o结尾的目标都依赖于同名的.c文件。如果.c文件有任何更新,将会重新构建对应的.o目标文件。同时,-Wp,-MD,.$@.d选项用于生成带有依赖关系的.d文件。
  9. clean: rm *.o test -fclean目标用于删除生成的目标文件和可执行文件。rm命令用于删除文件,*.o表示匹配所有以.o结尾的文件,test表示删除名为test的文件,-f选项用于强制删除而不提示。
  10. distclean: rm $(dep_files) *.o test -fdistclean目标用于执行更彻底的清理,不仅删除生成的目标文件和可执行文件,还会删除依赖文件。$(dep_files)表示需要删除的依赖文件列表。

通过添加依赖文件的处理,可以更准确地跟踪源文件的更新并重新构建相关的目标文件。运行make命令将会自动根据依赖关系构建所需的目标文件,make clean命令将会删除生成的目标文件和可执行文件,make distclean命令则会更彻底地清理,并删除依赖文件。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

MrWang.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值