Unix系统编程(工具篇) - Makefile

1.Makefile的作用

  • 1 项目代码管理编译

  • 2 节省编译项目时间

在不使用Makefile编译的时候不免都要在终端下输入:

gcc -o app a.c b.c c.c d.c

诸如此类的命令,反复的输入这类命令很浪费时间,然而有了Makefile之后复杂的命令就变成了make一个命令了。同时合适的Makefile会根据源码是否修改来决定是否重新编译源文件。

  • 3 一次编写终生受益
    写得好的Makefile通用性一般都很好,也就说说,在A项目中使用的Makefile稍作修改就能在B项目中使用了。

2. Makefile的基本规则

2.1 Makefile的基本形式

Makefile的形式可表示成:

目标:依赖(条件)
[Tab键]命令

Makefile的执行有两个阶段,第一个阶段是分析各个目标和条件的依赖关系,第二阶段就根据依赖关系自底向上执行命令。举例来看一个Makefile:

app:add.o sub.o dive.o mul.o main.o
    gcc add.o sub.o dive.o mul.o main.o -o app

add.o:add.c
    gcc -c add.c
sub.o:sub.c
    gcc -c sub.c
dive.o:dive.c
    gcc -c dive.c
mul.o:mul.c
    gcc -c mul.c
main.o:main.c
    gcc -c main.c

上面的Makefile文件中,app是一个目标,后面的.o文件都是依赖,这个Makefile的执行过程就是首先分析到app有5个依赖,那么就去指向这5个依赖,这5个依赖在他们的段内又是一个目标,在重复这个过程。最终自底向上的完成Makefile的执行过程。

2.2 Makefile执行目标

Makefile默认执行第一个出现的目标,也可以通过指定目标来让Makefile来执行非第一个出现的目标。最常见的一个就是make clean。项目在生成的过程中会产生很多中间中间文件,有时候并不需要这些文件,所以在Makefile的编写的时候一般都会写一个clean目标,用于删除中间文件。

app:add.o sub.o dive.o mul.o main.o
    gcc add.o sub.o dive.o mul.o main.o -o app

add.o:add.c
    gcc -c add.c
sub.o:sub.c
    gcc -c sub.c
dive.o:dive.c
    gcc -c dive.c
mul.o:mul.c
    gcc -c mul.c
main.o:main.c
    gcc -c main.c

clean:
    -rm -f *.o
    -rm -f app

3. 编写通用性好的Makefile

3.1 使用变量CC

在不同的平台下编译器异能不同,这里通过变量可以解决这个问题,同样是上述的Makefile,如果现在我想用g++来编译它,那么是不是需要把全部的gcc改写成g++呢?

CC=g++ 
app:add.o sub.o dive.o mul.o main.o
    $(CC) add.o sub.o dive.o mul.o main.o -o app

add.o:add.c
    $(CC) -c add.c
sub.o:sub.c
    $(CC)-c sub.c
dive.o:dive.c
    $(CC)-c dive.c
mul.o:mul.c
    $(CC)-c mul.c
main.o:main.c
    $(CC)-c main.c

clean:
    -rm -f *.o
    -rm -f app

3.2 隐含规则和模式规则

在makefile中
$@ 表示目标,
$^ 表示所有依赖,
$< 表示依赖中的第一个
$(wildcard *.c) 查找符合条件的文件名
$(patsubst %.c,%.o,$(src)) 模式查找替换
根据这些规则Makefile再次修改成如下样貌:

src = $(wildcard *.c)
obj = $(patsubst %.c,%.o,$(src))
target = app

$(target):$(obj)
    gcc $^ -o $@

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

clean:
    -rm -f *.o
    -rm -f app

3.3 隐含规则和模式规则

CPPFLAGS
CFLAGS
LDFLAGS
.PHONY 伪目标声明

CPPFLAGS= -Iinclude
CFLAGS= -g -Wall
LDFLAGS= 
CC=gcc

src = $(wildcard *.c)
obj = $(patsubst %.c,%.o,$(src))
target = app

$(target):$(obj)
    $(CC) $^ $(LDFLAGS) -o $@

%.o:%.c
    $(CC) -c $< $(CFLAGS) $(CPPFLAGS) -o $@

.PHONY:clean

#彻底清除生生过程文件
clean:
    -rm -f *.o
    -rm -f app

#彻底清除生生过程文件和生成配置文件
distclean:
    rm /usr/bin/app
install:
    cp app  /usr/bin
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

空空的司马

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

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

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

打赏作者

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

抵扣说明:

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

余额充值