make命令和makefile文件的结合提供了一个在项目管理领域十分强大的工具,它不只常被用于控制源代码的编译,并且还用于手册页的编写以及将应用程序安装到目标目录。app
makefile文件由一组依赖关系和规则构成,每一个依赖关系由一个目标和一组该目标所依赖的源文件组成,而规则描述了如何经过这些依赖文件建立目标,通常来讲,目标是一个单独的可执行文件。工具
make程序自己有许多选项,其中最经常使用的三个选项以下所示:优化
(1)-k:让make命令在发现错误时仍然继续执行spa
(2)-n:让make命令输出将要执行的操做步骤,而不真正执行这些操做命令行
(3)-f <filename>:告诉male命令将哪一个文件做为makefile文件调试
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
依赖关系定义了最终应用程序里的每一个文件和源文件之间的关系code
若是想一次建立多个文件,能够利用伪目标allblog
all: myapp myapp.1
建议约定:在本身的makefile文件中将第一个目标定为all,而后再列出其它重属目标项目管理
makefile文件中一个很是奇怪而又使人遗憾的语法现象:空格和制表符是有区别的,规则所在的行必须以制表符开头,用空格是不行的,若是makefile文件中的某行以空格结尾,也可能致使make命令执行失败。io
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
$(MACRONAME)或${MACRONAME}或$MACRONAME
若要定义一个值为空的宏,能够MACRONAME =
宏一般都是在makefile中定义的,但也能够在调用make命令时在命令行上给出宏定义,例如male CC=c89.命令行上的宏定义将覆盖makefile中的宏定义。
all: myapp #which compier CC = gcc #where are include files kept INCLUDE = #options for development CFLAGS = -g -Wall -ansi #options for release #CFLAGS = -0 -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
"-g" 是 gcc 的选项, "-o"也是 gcc 的选项。前者指示加入调试信息,后者指示对代码进行优化。
gcc 的-Wall 选项能够打印出编译时全部的错误或者警告信息
$? 当前目标所依赖的文件列表中比当前目标文件还要新的文件
$@ 当前的目标的名字
$< 当前规则的第一个依赖文件
$^ 当前规则的全部依赖文件,以逗号分隔
$* 不包括后缀名的当前依赖文件的名字
- 告诉make命令忽略全部的错误
@ 告诉make在执行命令前不要将该命令显示在标准输出上@echo
$(@D) 目标文件的目录名部分
$(@F) 目标文件的文件名部分
all: myapp #which compier 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 = -0 -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 && \ chmod og-w $(INSTDIR)/myapp;\ else \ echo "Sorry,$(INSTDIR) does not exist";\ fi
clean:删除不须要的目标文件,因为clean:的后面是空的,所以该目标总被认为是过期,因此在执行make命令时,若是指定目标clean,则目标所对应的规则将总被执行
install:将编译成功的应用程序安装到另外一个目录下
-rm:rm命令以减号开头是让make命令忽略rm命令的执行结果
能够经过make -p来打印make的全部内置规则,好比:
OUTPUT_OPTION=-o ¥@ COMPILE.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c %.o: %.c $(CONPILE.c) $(OUTPUT_OPTION) $<