您的位置:首页 > 其它

make命令和makefile文件

2017-11-29 17:39 288 查看

多个源文件带来的问题

比如三个头文件a.h b.h c.h;三个C源文件main.c 2.c 3.c;

/* main.c */
#include "a.h"
...

/* 2.c */
#include "a.h"
#include "b.h"
...

/* 3.c */
#include "b.h"
#include "c.h"


如果只修改了头文件c.h,则源文件main.c和2.c无需重新编译,因为他们不依赖于这个头文件,而源文件3.c需要重新编译。

make工具可以解决上述这些问题,它会在必要时重新编译所有受改动影响的源文件。

makefile文件

makefile一般都会和项目的其他源文件放在同意目录下。可以有多个makefile文件

make命令的选项和参数

-k:让make命令在发现错误时仍然继续执行

-n:让make命令输出将要执行的操作步骤,而不真正执行这些操作

-f (filename):告诉make命令将哪个文件作为makefile文件

makefile语法

makefile文件由一组依赖关系和规则构成。每个依赖关系由一个目标(即将要创建的文件)和一组该目标所依赖的源文件组成。

依赖关系

先写目标的名称,然后紧跟一个冒号,接着是空格或制表符tab,最后是空格或制表符tab隔开的文件列表

myapp: main.o 2.o 3.o
main.o: main.c a.h
2.o: 2.c a.h b.h
3.o: 3.c b.h c.h


规则

让make命令确定需要重建2.o时,它具体应该使用哪条命令需要用规则

规则前一定要用tab

myapp: main.o 2.o 3.o
gcc -o myapp main.o 2.o 3.o

main.o: main.c a.h
gcc -c main.c

2.o: 2.c a.h b.h
gcc -c 2.c

3.o: 3.c b.h c.h
gcc -c 3.c


注释

makefile文件中的注释以#开头,一直延续到这一行的结束

对于包含非常多源文件的大型项目来说,它们就显得过于庞大并缺乏弹性。因此makefile文件允许使用宏以一种更通用的格式来书写它们。

通过语句MACRONAME=value在makefile文件中定义宏,引用宏的方法是使用(MACRONAME)或{MACRONAME}。

makefile文件中的宏常被用于设置编译器的选项。

all: myapp

# Which compiler
CC = gcc

# Where are include files kept
INCLUDE = .

# Options for development
CFLAGS = -g -Wall -ansi

# Options for release
# CFLAGS = -O -Wall -ansi

myapp: main.o 2.o 3.o
$(CC) -o myapp main.o 2.o 3.o

main.o: main.c a.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c main.c

2.o: 2.c a.h b.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c

3.o: 3.c b.h c.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c


make命令内置了一些特殊的宏定义

$?:当前目标所依赖的文件列表中比当前目标文件还要新的文件

$@:当前目标的名字

$<:当前依赖文件的名字

$*:不包括后缀名的当前依赖文件的名字

多个目标

通常制作不止一个目标文件或者将多组命令集中到一个位置来执行是很有用的。

all: myapp

# Which compiler
CC = gcc

# Where to install
INSTDIR = /usr/local/bin

# Where are include files kept
INCLUDE = .

# Options for development
CFLAGS = -g -Wall -ansi

# Options for release
# CFLAGS = -O -Wall -ansi

myapp: main.o 2.o 3.o
$(CC) -o myapp main.o 2.o 3.o

main.o: main.c a.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c main.c

2.o: 2.c a.h b.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c

3.o: 3.c b.h c.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c

clean:
-rm main.o 2.o 3.o

install: myapp
@if [-d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else \
echo "Sorry, $(INSTDIR) does not exist";\
fi


内置规则

make命令中有大量的内置规则,它们可以极大地简化makefile文件的内容,尤其在拥有许多源文件时更是如此。可以用make -p让make打印其所有内置规则。

用make管理函数库

对于大型项目,一种比较方便的做法是用函数库来管理多个编译产品。函数库实际上就是文件。make命令用一个特殊的语法来处理函数库,这使得函数库的管理工作变得容易。

用于管理函数库的语法是lib(file.o)它的含义是目标文件file.o是存储在函数库lib.a中的。

all: myapp

# Which compiler
CC = gcc

# Where to install
INSTDIR = /usr/local/bin

# Where are include files kept
INCLUDE = .

# Options for development
CFLAGS = -g -Wall -ansi

# Options for release
# CFLAGS = -O -Wall -ansi

# Local Libraries
MYLIB = mylib.a

myapp: main.o $(MYLIB)
$(CC) -o myapp main.o $(MYLIB)

$(MYLIB): $(MYLIB)(2.o) $(MYLIB)(3.o)
main.o: main.c a.h
2.o: 2.c a.h b.h
3.o: 3.c b.h c.h

clean:
-rm main.o 2.o 3.o $(MYLIB)

install: myapp
@if [-d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else \
echo "Sorry, $(INSTDIR) does not exist";\
fi
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: