假如一个Makefile需要管理的是很多个源文件构成的工程,还一个一个地列出依赖关系,库文件和源文件,估计都要吐血了,所以就需要宏了
Makefile文件中的宏用来设置编译选项,在开发阶段一般不会进行优化,而是将debug信息给添加进去;而release的时候,却正好反过来,不包含任何调试debug信息,符号表之类的,而是让可执行程序性能优化得越快越好
Linux下编译器gcc,其它类UNIX系统中,编译器可能不同,如果将Makefile移植之后,想要work不得不修改很多地方,这样看来定义一个宏会十分方便;或者可以在调用make命令的时候给出宏定义作为参数,比如make CC=XXX,这时候就会覆盖Makefile文件当中的宏定义,但注意的是等号两边不要有空格,否则必须make “CC = XXX”
上篇中的例子,可以重新写一个Makefile1:
$ cat Makefile1 all: lihui #compiler CC = gcc #include files INCLUDE = . #development options CFLAGS = -g -O0 -Wall #release options #CFLAGS = -O2 -Wall lihui: main.o 1.o 2.o $(CC) -o lihui main.o 1.o 2.o main.o: a.h main.c $(CC) -I$(INCLUDE) $(CFLAGS) -c main.c 1.o: a.h b.h 1.c $(CC) -I$(INCLUDE) $(CFLAGS) -c 1.c 2.o: b.h c.h 2.c $(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
这里定义了宏定义$(CC),$(CFLAGS)和$(INCLUDE),与#define的用法类似,如此假如你需要修改编译选项只需要修改一个地方就行了,下面就直接执行Makefile1这个文件:
$ make -f Makefile1 gcc -I. -g -O0 -Wall -c main.c main.c: 在函数‘main’中: main.c:5:5: 警告:隐式声明函数‘fun1’ [-Wimplicit-function-declaration] fun1("From function 1!"); ^ main.c:6:5: 警告:隐式声明函数‘fun2’ [-Wimplicit-function-declaration] fun2("From function 2!"); ^ gcc -I. -g -O0 -Wall -c 1.c gcc -I. -g -O0 -Wall -c 2.c gcc -o lihui main.o 1.o 2.o
这里用了比较严厉的检查宏Wall,报了两个警告,可见main.c里直接调用两个函数的问题,只需要添加两行extern即可:
$ cat main.c #include <stdio.h> #include "a.h" extern int fun1(char *); extern int fun2(char *); int main(){ fun1("From function 1!"); fun2("From function 2!"); return 0; }
再执行一次
$ make -f Makefile1 gcc -I. -g -O0 -Wall -c main.c gcc -I. -g -O0 -Wall -c 1.c gcc -I. -g -O0 -Wall -c 2.c gcc -o lihui main.o 1.o 2.o $ ./lihui.exe From function 1! From function 2!