Makefile文件编写,简易实用版本

Makefile文件编写

写在前面:本文只是作者在学习过程中的一些记录,多数为自己的理解,如果和您意见不一致,建议以您的为主,谢谢。
本文参考B站UP主《韦东山》相关课程,详情见右侧链接:点我直达韦东山老师课程
感谢韦东山老师提供的课程供大家学习和参考。

什么是Makefile

Makefile是一个用于组织和自动化编译和链接项目的文本文件。
在编写 Makefile 时,可以定义一系列规则,来说明哪些源文件需要先编译,哪些需要后编译,哪些需要重新编译等。Makefile 类似于一个 Shell 脚本,可以执行操作系统命令。Makefile 结合使用 GNU Make 这个工具,可以自动地根据源代码文件是否更新来编译项目,减少重复工作,提高编程效率。

组成内容

有五个组成部分:

  1. 显示规则:生成一个或多个目标文件的方法和步骤。
  2. 隐式规则:make工具具有自动推导的功能,所以在编写makefile文件时可以利用该规则,简写makefile。
  3. 变量的定义:支持变量定义,变量一般都是字符串。
  4. 文件指示:可以在一个makefile文件中引用另一个makefile;根据某些情况指定makefile中的有效部分,类似C语言中的编译宏#if;可以定义一个多行命令。
  5. 注释:‘#’用来注释。

文件包含:include <filename>

规则

格式:

目标文件:依赖文件
(有一个Tab)    命令
例子:
test:a.o b.o
    gcc -o test a.o b.o
a.o:a.c
    gcc -c a.o a.c
b.o:b.c
    gcc -c b.o b.c

语法

通配符%.o,全部后缀名为.o的文件
优化一下上面的例子:

test:a.o b.o
    gcc -o test a.o b.o
%.o:%.c
    gcc -c -o $@ $<

上面例子中:$@为目标文件,即为a.ob.o$<为第一个依赖文件,此处为对应的.c文件;$^为所有依赖文件。
所以上面的例子可以进一步优化为:

test:a.o b.o
    gcc -o test $^
%.o:%.c
    gcc -c -o $@ $<

假想目标
通过关键字.PHONY声明的为假想目标

test:a.o b.o
    gcc -o test $^
%.o:%.c
    gcc -c -o $@ $<
clean:
    rm *.o test
.PHONY:clean

假想目标:不代表实际存在的文件名,通常用于调用一系列命令而不用担心有同名文件存在。比如目录中存在与clean目标同名的文件或目录,当执行make clean时可能会提示没有对应的规则去生成目标。就出现了不能够删除文件的情况,所以将clean定义为假想目标,则在执行时就直接进行清理了。

变量
变量可以分为两类:即时变量和延时变量
即时变量:在变量定义时就确定好了值。A := 123
延时变量:若变量是第一次定义,才有效;若之前已经定义,则本语句无效。
例子:

A := $(C)
B = $(C)
C = abc
D = ask
D ?= jeffrey

all:
    @echo A=$(A)
    @echo B=$(B)
    @echo C=$(C)
    @echo D=$(D)

输出:
A=
B=abc
C=abc
D=ask

函数

  1. foreach函数
    使用:$(foreach var,list,text)
    功能:对list中每一个变量var执行text操作
    例子:

    A = a b c
    B = $(foreach f,$(A),$(f).o)
    
    all:
        @echo B=$(B)
    输出:
        B=a.o b.o c.o
  2. filter函数
    使用:$(filter pattern...,text)
    功能:在text中取出符合pattern格式的值

  3. filter-out函数
    使用:$(filter-out pattern...,text)
    功能:在text中取出不符合pattern格式的值
    例子

    A = a b c d/
    B = $(filter %/, $(A))
    C = $(filter-out %/, $(A))
    
    all:
        @echo B=$(B)
        @echo C=$(C)
    
    输出:
        B=d/
        C=a b c
  4. wildcard函数
    使用:$(wildcard pattern)
    功能:用于获取符合特定模式(pattern)的文件名列表。
    例子:

    //假设当前目录中有文件:a.c b.c a.h b.h Makefile
    
    files = $(wildcard *.c)
    all:
        @echo files=$(files)
    输出:
    files=a.c b.c
    
    files1 = a.c b.c c.c d.c
    files2 = $(wildcard $(files1))
    all:
        @echo files2=$(files2)
    输出:
        files2=a.c b.c
        类似与筛选出在files1中真实在当前目录下存在的文件
  5. patsubst函数
    使用:$(patsubst pattern, replacement, $(var))
    功能:将$(var)中满足pattern格式的值替换为replacement
    例子:

    files = a.c b.c c.c
    file1 = $(patsubst %.c,%.o,$(files))
    all:
        @echo file1=$(file1)
    输出:
        file1=a.o b.o c.o

完整例子讲解

# 指定编译器
CC = gcc

# 指定头文件目录
INCLUDE = -I ./

# 指定源文件
SRCS = main.c func1.c func2.c

#指定编译选项
CFLAGS = -g -O0

# 指定目标文件
OBJS = $(SRCS:.c=.o)

# 链接库
LDFLAGS = -lpthread

# 链接库路径
LDPATH = -L ./

# 自己的库
LDFLAGS += -lmylib

# 指定最终执行文件
TARGET = myprogram

# 编译规则
$(TARGET): $(OBJS)
    $(CC) -o $@ $(OBJS) $(CFLAGS) $(LDPATH) $(LDFLAGS) $(INCLUDE)

# 对每一个.c文件生成对应的.o文件
.c.o:
    $(CC) -o $@ -c $<

# 清理规则
clean:
    rm -f $(TARGET) $(OBJS)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
error: Content is protected !!内容保护!!