C语言Makefile笔记总结

Makefile 工程管理器, 顾名思义,是指管理较多的文件
Make工程管理器也就是个"自动编译管理器",这里的"自动"是指能够根据文件时间戳自动发现更新过的文件
而减少编译的工作量,同时,它通过读入Makefile文件的内容来执行大量的编译工作
Make将只编译改动的代码文件,而不用完全编译.
如果.c文件特别多第一次编译时间会特别长,在做项目时有时我们只改动某些文件,如果再重新编译工程会耗费时间,make
可以只编译我们改动的文件和有变化的文件

Makefile基本结构
Makefile是Make读入的唯一配置文件
由make工具创建的目标体(target),通常是目标文件或可执行文件
要创建的目标体所依赖的文件(dependency_file)
创建每个目标体时需要运行的命令(command)
注意:命令行前面必须是一个"TAB键",否则编译错误为:*** missing separator. Stop

Makefile格式
目标 生成这个目标所依赖文件
target: dependency_files
缩进 命令
command
例子
hello.o: hello.c hello.h
gcc -c hello.c -o hello.o
Makefile变量
一个复杂一些的例子
sunq:kang.o yu1.o
gcc kang.o yu1.o -o sunq
kang.o:kang.c kang.h
gcc -Wall -O -g -c kang.c -o kang.o
yu1.o:yu1.c
gcc -Wall -O -g -c yu1.c -o yu1.o
注释:-Wall:表示允许发出gcc所有有用的报警信息.
-c:只是编译不链接 ,生成目标文件".o"
-o file:表示把输出文件输出到file里
关于更多的用man工具 -O是优化 -g利用gdb进行调试
-c和-o都是gcc编译器的可选参数。-c表示只编译(compile)源文件但不链接,会把.c或.cc的c源程序编译成目标文件,
一般是.o文件。-o用于指定输出(out)文件名。不用-o的话,一般会在当前文件夹下生成默认的a.out文件作为可执行程序。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Makefile只编译更新过的文件 , 减少编译的工作量, 用了make后会在你的目录当中生成非常多的中间文件,一些目标文件…一些库等等, 有时候我们需要对工程做一个清理,往往是我们需要通过make一些的相关命令来清理,而不是通过rm命令一个一个的去删除,

创建和使用变量
创建变量的目的:
用来代替一个文本字符串:
1.系列文件的名字
2.传递给编译器的参数
3.需要运行的程序
4.需要查找源代码的目录
5.你需要输出信息的目录
6.你想做的其他事情
这个大型的工程涉及到的.c非常的多每一个.c都会生成一个同名的.o那么.o文件会非常的多,几百个.o文件敲一遍链接命令再敲一遍又几百个,这个敲.o文件的过程中很容易出现错误,所以我们往往会搞一些变量使出错率降低,可读性增强. 有点像宏起替换的作用
变量定义的两种方式
递归展开方式VAR=var
简单方式 VAR: =var
变量使用 $ (VAR)
用” $ ”则用”$$”来表示
类似于编程语言中的宏
例子:
OBJS=kang.o yu1.o
CC=gcc
CFLAGS=-Wall -O -g
Sunq: $(OBJS)
$(CC) $(OBJS) -o sunq
Kang.o :kang.c kang.h
$(CC) $(CFLAGS) -c kang.c -o kang.o
yu1.o:yu1.o yu1.h
$(CC) $(CFLAGS) -c yu1.c -o yu1.o

递归展开方式VAR=var
例子:变量值是在后面找的
Foo= $(bar)
bar= $(ugh)
ugh=Huh?
$(Foo)的值为?
echo $(foo)来进行查看
优点:
它可以向后引用变量
缺点:
不能对该变量进行任何扩展,例如:
CFLAGS= $(CFLAGS) -0
会造成死循环

简单方式 VAR:=var
m:=mm
x:= $(m)
y:= $(x)bar
x:=later
echo $(x) $(y)
看看打印的是什么信息
在这里插入图片描述
用这种方式定义的变量,会在变量的定义点,按照被引用的变量的当前值进行展开
这种定义变量的方式更适合在大的编程项目中使用,因为它更像我们一般的编程语言

用?=定义变量
Dir:=/foor/bar
FOO?=bar 意思是,如果这个FOO没有定义过,那它就是bar
FOO是?
含义是,如果FOO没有被定义过,那么变量FOO的值就是”bar”,如果FOO先前被定义过,那么这条语句将什么也不做,其等价于:
Ifeq( $ (origin FOO),undefined)
FOO=bar
endif
为变量添加值
你可以通过+=为已定义的变量添加新的值
Main=hello.o hello-1.o
Main+=hello-2.o 相当于 Main=hello.o hello-1.o hello-2.o
预定义变量
-AR 库文件维护程序的名称,默认值为ar . AS汇编程序的名称,默认值为as
-CC C编译器的名称,默认值为cc. CPP C预编译器的名称,默认值为$(CC) -E
-CXX c++编译器的名称,默认值为g++
-FC FORTRAN编译器的名称,默认值为f77
-RM 文件删除程序的名称,默认值为rm -f
例子:
Hello:main.c main.h
$(CC) -o hello main.c
Clean:
$(RM) hello

预定义变量

  • ARFLAGS 库文件维护程序的选项 , 无默认值
  • ASFLAGS 汇编程序的选项, 无默认值
  • CFLAGS C编译器的选项 , 无默认值
  • CPPFLAGS C预编译的选项 , 无默认值
  • CXXFLAGS C++编译器的选项 , 无默认值
  • FFLAGS FORTRAN编译器的选项 , 无默认值
    自动变量
  • $* 不包含扩展名的目标文件名称
  • $+ 所有的依赖文件, 以空格分开,并以出现的先后顺序,可能包含重复的依赖文件 - $< 第一个依赖文件的名称
  • $? 所有时间戳比目标文件晚的依赖文件, 并以空格分开
  • $@ 目标文件的完整名称
  • $^ 所有不重复的目标依赖文件, 以空格分开
  • $% 如果目标是归档成员,则该变量表示目标的归档成员名称

为目标:
如果目录文件中有跟我们命令相同名称的文件,那么我们执行命令的时候就会失效, 说文件是最新的不需要执行命令
例如:
.PHONY:clean
clean:
rm *.o test
在这里插入图片描述
环境变量
Make在启动时会自动读取系统当前已经定义了的环境变量,并且会创建与之具有相同名称和数值的变量
如果用户在Makefile 中定义了相同名称的变量,那么用户自定义变量将会覆盖同名的环境变量

Make使用
直接运行 make
选项
-C dir读入指定目录下的Makefile
-f file读入当前目录下的file文件作为Makefile
-i 忽略所有的命令执行错误
-I dir指定被包含的Makefile所在目录
-n 只打印要执行的命令, 但不执行这些命令
-p 显示make变量数据库和隐含规则
-s 在执行命令时不显示命令
-w 如果make在执行过程中改变目录,打印当前目录名
在这里插入图片描述

隐含规则
隐含规则1: 编译C程序的隐含规则 (默认的时候就加一个 -c 并没有加其他内容)
“.o”的目标的依赖目标会自动推导为”.c” , 并且其生成命令是
“$(CC) -c $(CPPFLAGS) $(CFLAGS)”
会根据.c文件自动推导出.o
会根据.o文件自动推导出.c
如果没有 CPPFLAGS 和CFLAGS那么默认就是-c
默认只有-c如果有特殊的选项可以为CFLAGS赋值

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值