Make脚本的基础

Makefile中的变量,就像是C/C++语言中的宏一样,代表文本字符串,在Makefile中执行的时候会自动原样地展开在所使用的地方。

其与C/C++的宏所不同的是可以在Makefile中改变其值。在Makefile中,变量可以使用在目标、依赖目标、命令或是Makefile的其它部分中。

变量的命名可以包含字符、数字、下划线(可以是数字开头),但不应该含有“:”、“#”、“=”或是空白字符(空格、回车等)

变量名对大小写敏感,传统的变量名是全大写的命名方式。

变量的定义格式

变量名 赋值符号 变量的值

赋值符号有三种:

直接将后面的字符串赋给变量

:= 后面跟变量,将它的内容赋给变量

+= 变量原来的值+空格+后面的字符串=>新的变量值

例如

CC = arm-linux-gcc

Echo  $CC

常用的为 =   +=

 

变量的引用

变量引用的三种格式:

 $(变量名)

 ${变量名}

 当变量名为单个字符时,可以省略括号

make处理变量时会扫描一遍整个Makefile,确定所有变量的值,因此变量的使用可以在定义之后,而且使用的是最后一次赋予的值

例:

objects = program.o foo.o utils.o
    program : $(objects)
        gcc -o program $(objects)

 

变量的定义可以出现在三个地方

makefile中定义

make命令行中定义

使用shell环境中的定义

优先级:

make命令行中定义 makefile中定义 使用shell环境中的定义 预定义的变量 

spacer.gif 

Makefile中的CC= xxxxxx就会失效而执行  make后面的语句

 

make有许多预定义的变量,这些变量具有特殊的含义,可在规则中直接使用。¥

 

 

1.$*不包含扩展名的目标文件名称

  Main.o  可以写成$*

2.$+所有的依赖文件,空格分开,并以出现的先后为序,可能包含重复的依赖文件

3.$<第一个依赖文件的名称

4.$?所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚

5.$@目标的完整名称

6.$`所有的依赖文件,以空格分开,不包含重复的依赖文件

7.$%如果目标是归档成员,则该变量表示目标的归档成员名称,例如,如果目标文件为

 Mytarget.sop_w_picpath.o)。则$@mytarget.so。而$%p_w_picpath.o

 

 

1.条件表达式的语法为:

 conditional-directive    

     text-if-true
endif

其中conditional-directive表示条件关键字,如“ifeq”。Makefile所支持的关键字有四个

ifeq 

ifneq 

ifdef 

ifndef    

 

2.for k in $(DIRS) ; do …… 

k依次取变量DIRS中的每一个值,执行do后面的语句 

例:

SUBDIRS=temp1 temp2

 for i in $(SUBDIRS);

         Do

         make-C $$i||exit $?;

         done

 

3.wildcard函数(通配符函数),其形式是:

         $(wildcard _pattern)

  通过该函数可得到当前工作目录中满足_pattern

  式的文件或目录名列表。如:

         SRCS:=$(wildcard *.c)

   subst函数,格式为:$(subst <from>, <to>, <text>)

   该函数把字符串<text>中的<from>字符串替换为<to>。函数返回被替换后的字符串。

spacer.gif

 

patsubst函数,格式为:

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

  查找<text>中的单词(单词以“空格”、“Tab”、“回车”分隔)是否符合模式<pattern>,若匹配的话,则以<replacement>模式替换,<pattern>可以包含通配符”%”,表示任意长度的字符串。若<replacement>中也包含“%”,则其所代表的的即为<pattern>中的那个“%”所代表的的字符串。如:

         OBJS:=$(patsubst %.c, %.o, x.c.c bar.c)

  函数返回结果为:x.c.o bar.o

: SRCS:=$(wildcard *.c)

   OBJS:=$(patsubst %.c,%.o,$(SRCS))

       ……

   hello: $(OBJS)

     $(CC)  -o  $@  $(OBJS)

spacer.gif 

 

 

spacer.gif 

 

模式规则(pattern rules)。这种规则更加通用,因为可以利用模式规则定义更加复杂的依赖性规则。模式规则看起来非常类似于正则规则,但在目标名称的前面多了一个 号,同时可用来定义目标和依赖文件之间的关系,例如下面的模式规则定义了如何将任意一个 X.c 文件转换为 X.o 文件

%.o:%.c

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

spacer.gif 

makefile中,目标分为两类:实目标和伪目标 

实目标--真正要生成、以文件形式放在磁盘上的目标。

例:

main.o:mai.c

$(CC) $(CCFLAGS) -c -o $@ $<

伪目标--不要求make生成实际的文件,而是使make程序执行一些与创建和维护目标文件没有直接联系的辅助性操作,如打印信息、删除文件。

例:

clean:
    rm *.o

为了避免和文件重名的这种情况,可以使用一个特殊的标记“.PHONY”来显示地指明一个目标是“伪目标”

.PHONY: clean
clean:
    rm *.o temp

外一个使用假想目标的例子是使用make的递归调用进行连接的情况:此时,makefile文件常常包含列举一系列需要创建的子目录变量。例:

 subdirs: 
     for dir in $(SUBDIRS); do \ 
     $(MAKE) -C $$dir; \ 
     done 

伪目标也可以有依赖,例 :

.PHONY : all 

   all : prog1 prog2 prog3 
prog1 : prog1.o utils.o 
cc -o prog1 prog1.o utils.o 
prog2 : prog2.o 
cc -o prog2 prog2.o 
……

缺省情况下,当make寻找makefile文件时,它试图搜寻具有如下的名字的文件,按顺序:‘GNUmakefile’、‘makefile’和‘Makefile’。

 

 如果您使用非标准名字makefile文件,您可以使用‘-f’或‘--file’参数指定您的makefile文件。参数‘-f name’或‘--file=name’能够告诉make读名字为‘name’的文件作为makefile文件

makefile后,就可以调用make命令生成和维护目标文件。命令格式为:

  Make [option] [macrodef] [target]

- Option指定make工作的行为

- Macrodef给出执行makefile时的宏值

- Targetmakefile中的目标之一

GNUmake工作时的执行步骤

- 读入所有的Makefile 

- 读入被include的其它Makefile 

- 初始化文件中的变量 

- 推导隐晦规则,并分析所有规则 

- 为所有的目标文件创建依赖关系链 

- 根据依赖关系,决定哪些目标要重新生成 

- 执行生成命令

 

 

第一步:编辑源文件

#vi  hello.c

第二步:建立makefile

#vi makefile

第三步:编辑makefile

 

(同一目录下有多个.C文件,这些.C文件最后链接成可执行程序hello)

BIN=hello

SRCS:=$(wildcard *.c)

OBJS:=$(patsubst %.c,%.o,$(SRCS))

 

CC=gcc

 

all:$(BIN)

 

$(BIN):$(OBJS)

(CC)  -o  $(EXECPROGRAM)  $(OBJS)

 

%.o:%.c

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

clean

rm  rf  *.o  $(BIN)

Linux下的图形开发工具

 

Eclipse

Code blocks

 

Linux下的应用程序调试工具

Gdb

printf