makefile文件编写

1.make命令调用格式:

make [-f makefile文件名][选项][宏定义][目标]

2.常用选项有:

-Idirname 指定被包含的makefile所在目录

-w 如果make在执行时改变目录,打印当前目录名

-d 打印调试信息

-k 用该选项,即使make程序遇到错误也会继续向下运行

3.makefile文件主要包含了6部分内容

1、显式规则:用于描述系统中模块之间的相互依赖关系,以及产生目标文件所要执行的命令(规则)。

编写规则通用形式:

target : dependency [depenency [...] ]

    command

    command

    [...]

注:command前是tab键,而非空格

使用这些命令来根据依赖模块产生目标,这里的command既可以是gcc/g++编译命令,也可以是shell命令或是其他可执行文件。

main : main.o f1.o f2.o

    gcc -o main main.o f1.o f2.o

main.o : main.c def1.h

    gcc -c main.c

f1.o : f1.c def1.h def2.h

    gcc -c f1.c

f2.o : f2.c def2.h def3.h

    gcc -c f2.c

2、隐式规则:又称预定义规则。隐式规则简化了makefile的编写和维护。(make命令带-p选项),

比如:后缀规则,可以指定:.SUFFIXES: .o .cpp

.cpp.o:

    $(CPP) –c $<

3、模式规则提供的一种扩展make隐式规则的方法,规则与普通规则一样,主要是目标必定含有%号,

比如:%.o : %.c

$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@

4、变量定义(自动变量/预定义变量/自定义变量)

5、文件指示(include, make -I, #if include)。

6、特殊字符:注释# 转义/ 通配符* 宿主目录~ 模式字符“%”

“*.c”代表了当前工作目录下所有的以“.c”结尾的文件

“%”意思是匹配一个或者多个字符,例如,“%.h”表示所有以“.h”结尾的文件

4.变量(或者说宏)

1、定义方法: VARNAME=some_text [...]

如: OBJS := howdy.o helper.o

2、变量引用:$(VARNAME)或 ${VARNAME)

3、变量扩展:VARNAME += $(VARNAME) some_textn..

注:在使用变量时要注意库的连接左右问题

建议使用:VARNAME := some_textn $(VARNAME)

4、作用:用代表某些多处使用而又可能发生变化的内容,节省重复修改的工作,避免遗漏。一般用来代表一些文件名或选项。

5、自动变量

$@ 规则的目标所对应的文件名

$< 规则中的第一个相关文件名

$^ 规则中所有相关文件的列表,以空格为分隔符

$? 规则中日期新于目标的所有相关文件的列表

$(@D) 目标文件的目录部分

$(@F) 目标文件的文件名部分

$* 这个变量表示目标模式中“%”及其之前的部分。

6、预定义变量

CC C编译程序,默认值=cc

CFLAGS 传给C编译器的标志

CPP C++编译程序,默认值=cpp

CPPFLAGS

LDFLAGS 传给链接程序(ld)的标志,默认值=

AR 归档维护程序,默认值=ar

ARFLAGS 默认值=rv

AS 汇编程序,默认值=as

ASFLAGS

5.makefile实例

1、通过g++的MM选项显示各文件间依赖关系

gcc -MM main.c f1.c f2.c

main.o: main.c def1.h

f1.o: f1.c def1.h def2.h

f2.o: f2.c def2.h def3.h

2、多目标

$(OBJ_DIR)%.o:$(SRC_DIR)%.cpp

    @echo "Compiling $< ==> $@..."

    $(CXX) $(INC) $(C_FLAGS) -c $< -o $@

3、静态模式

objects = foo.o bar.o

all: $(objects)

%.o: %.c

    $(gcc) -c $(CFLAGS) $< -o $@

4、大项目makefile的处理

Ø给源文件分类,并存放在不同的目录中,给各个目录定义变量。

Ø按层定义makefile.pub文件,该文件主要定义一些变量(如INC, SRC)、函数、本层会生成的lib文件。

Ø子层文件include上层及相关makefile.pub文件。并根据情况对变量进行扩展。

Ø生成库文件提供给下一级makefile进行链接。

Ø嵌套调用make

subsystem:

    cd subdir && $(MAKE)

subsystem:

    $(MAKE) –C subdir

Ø在makefile文件中定义VPATH = src:../headers

Ø使用环境变量

5、程序包(函数的定义)

•定义程序包:

define run-yacc

    yacc $(firstword $^)

    mv y.tab.c $@

endef

•程序包的使用

%.c : %.y

    $(run-yacc)

6、函数使用

$(<function> <arguments>)

或是:

i := ${<function> <arguments>}

示例:

INC = $(patsubst %,-I%,$(ALLINC))

make支持的函数有:

$(subst <from>,<to>,<text>)

$(patsubst <pattern>,<replacement>,<text>)

$(filter <pattern...>,<text>) .....

7、分支语法

< conditional-directive>

    < text-if-true>

endif

以及:

< conditional-directive>

    <text-if-true>

else

    <text-if-false>

endif

注:conditional-directive可以是:ifeq(), ifneq(), ifdef, ifndef

分支语法示例:

libs_for_gcc = -lgnu

normal_libs =

foo: $(objects)

ifeq ($(CC),gcc)

    $(CC) -o foo $(objects) $(libs_for_gcc)

else

    $(CC) -o foo $(objects) $(normal_libs)

endif

注:上面示例的这个规则中,目标foo可以根据变量$(CC)的值选取不同的函数库来编译程序

8.make的妙用

•同步文件至远端服务器:

cmdscp:

scp -P3600 exe user_00@172.25.32.162:/usr/local/..

原文地址:https://www.cnblogs.com/lidan/p/2239515.html