Make进阶使用

由于课程需要,进一步学习了一下make的使用,在之前的基础上添加一些高级知识, 同时提供一个makefile的模版共以后使用。

Make的内部规则

目标 依赖 规则
x.o x.c cc -c x.c
x.o x.s as -o x.s
x.o x.y yacc x.y
cc -c y.tab.c
rm y.tab.c
mv y.tab.o x.o
x.o x.l lex x.l
cc -c lex.yy.c
rm -f lex.yy.c
mv les.yy.o x.o
x.c x.y yacc x.y
mv y.tab.c x.c
x.c x.l lex x.l
mv les.yy.c x.c
x.a x.c cc -c x.c
ar rv x.a x.c
rm -f x.o

利用上述规则可以简写makefile。

main: main.o libylmath.a ylmathp.o
    cc -o main -L . -l ylmath main.o ylmathp.o

libylmath.a: libylmath.a(ylmath.o)

ylmathp.o: ylmathp.h

Make的内部宏

内部宏 含义
$< 使目标过时的依赖文件(即已更新的文件)
$* 不带后缀的依赖文件(常用写法$*.c)
$@ 目标文件名,用于显式说明行
$? 类似$< 用于显式说明行
$% 用于处理库文件的依赖文件

这些宏大多用于修改上述隐含规则或创建自己的隐含规则。

实用技巧

使用一个例子展示如下

# 使用宏定义增加可移植性
INSTDIR= bin
CFLAGS= -O -g
LDFLAGS=
CC= cc
# 文件声明
HEADERS= ylmath.h ylmathp.h
SOURCE= main.c ylmathp.c
OBJECT= $(SOURCE: .c=.o)
# 库声明
LIBSRC= ylmath.c
LIBOBJ= ylmath.o
LIBDIR= lib

# 覆盖默认的.c.o规则,添加-O(优化) -g(调试)
.c.o:
    $(CC) $(CFLAGS) -c $*.c

# 连接得到可执行文件
demo: $(OBJECT) libylmath.a
    $(CC) -o $@ $(OBJECT) -L$(LIBDIR) -lylmath

all: demo install

# 声明头文件,使用.c.o规则生成
$(OBJECT): $(HEADERS)

# 使用.c.a规则生成库并移到lib文件夹
# -开头的命令忽略运行错误和命令返回码,继续执行
libylmath.a: libylmath.a($(LIBOBJ))
    -mv $(LIBDIR)/libylmath.a libylmath.a.old
    -mv libylmath.a $(LIBDIR)/libylmath.a

# 更新bin文件夹
install: demo libylmath.a
    -mv $(INSTDIR)/demo demo.old
    -mv demo $(INSTDIR)/demo

# 删除
clean:
    -rm *.old demo $(LIBDIR)/libylmath.a

# 记录更新信息
# @开头的命令在运行时不显示
print: $(SOURCE) $(OBJECT)
    @ echo printing modified files
    @ echo $? > $@
Lei Yang
Lei Yang
PhD candidate

My research interests include visual speech recognition and semantics segmentation.