Chinaunix首页 | 论坛 | 博客
  • 博客访问: 44616
  • 博文数量: 9
  • 博客积分: 465
  • 博客等级: 下士
  • 技术积分: 120
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-11 15:07
文章分类

全部博文(9)

文章存档

2011年(2)

2010年(7)

我的朋友
最近访客

分类: LINUX

2010-08-31 10:36:34

                                    Makefile的简化
一般常用的方法:
一.变量
二.隐含规则
三.Makefile的引用
四.Makefile的函数

一.变量
例子:
CC = gcc
引用变量前需要添加$: 如$(CC)
 
Makefile 变量定义
(1).Makefile变量定义跟Shell变量定义刚好相反!
 Shell  变量定义时, =  两边不能有空格.
 Makefile 变量定义, =  两边一定要有空格
 Shell  变量用{}来保护变量,  而Makefile变量用()来保护变量
(2) Makefile变量定义要独立于规则之外,
 在Makefile当中,所有Shell环境变量都是缺省当做Makefile变量,并且在Makefile中,可以用export把自己变量变成环境变量
    export语句可以独立在规则之外
 境变量也是多个Makefile之 通讯方法之一
(3)  =  与:=  区别
 两者都用于变量赋值,:=是简单赋值,=带递归引用
 如= 后面是变量, 则变量本身值可能还要进行运算
 :=  只是简单赋值, 后面变量只简单取值, 没有定义变量取为空, 一般比较安全
 假设CFLAGS 预先定义有值, 则CFLAGS = $(CFLAGS)-g 变成无限递归调用, 最后变成最终堆栈溢出,正确写法是CFLAGS :=
$(CFLAGS) -g
  #这里foo最终值为Huh,因为foo后面bar还要做递归调用,而ugh也会做递归调用
                   foo = $(bar)
                   bar = $(ugh)
                   ugh = Huh?
 #这里foo最终值为空,定义foo时,bar并未定义,这里取空.
     foo := $(bar)
                   bar := $(ugh)
                   ugh := Huh?
GNU make 的主要预定义变量(1)
   (l) GNU make有许多预定义变量,这些变量具有特殊的含义,可在规则中使用。
   (2) 除这些变量外,GNU make 还将所有的环境变量作为自己的预定义变量。
                  预定义变量                      含义
                    $<            第一个依赖文件的名称。
                    $@            目标的完整名称。
                    $^            所有的依赖文件,以空格分开,不包含重复的依赖文件。 
                    $*            不包含扩展的目标文件名称。
                    $+            所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。             
                    $?            所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。   
                    $%            如果目标是归档成员,则该变量表示目标 归档成员名称。例如,
      如果目标 称为mytarget.so(image.o),则$@为 mytarget.so,而$% 为image.o。
GNU make   的主要预定义变量(2)
                    AR            归档维护程序名称,默认值为ar
                    ARFLAGS       归档维护程序的选项
                    AS            汇编程序名称,默认值为as 
                    ASFLAGS       汇编程序的选项。
                    CC            C  编译器名称,默认值为cc
                    CCFLAGS       C  编译器的选项。
                    CPP           C  预编译器名称,默认值为$(CC) -E      
                    CPPFLAGS      C  预编译的选项。
                    CXX           C++  编译器名称,默认值为g++         
                    CXXFLAGS      C++  编译器的选项。
        FC            FORTRAN  编译器名称,默认值为f77      
                    FFLAGS        FORTRAN  编译器的选项。
 
变量的替换(待补充)
VPATH变量
vpath 关键字
 

二.隐含规则
GNU make 支持两种类型的隐含规则:1.后缀规则  2.模式规则
1.后缀规则(Suffix Rule):
 后缀规则定义了将一个具有某个 后缀的文件(例如,.c 文件)转换为具有另外一种后缀的文件(例如,.o 文件)的方法。每
个后缀规 则以两个成对出现的后缀名定义,例如,将 .c 文件转换为 .o 文件的后缀规则可定义为:
.c.o:
    $(CC) $(CCFLAGS) $(CPPFLAGS) -c -o $@ $<
2.模式规则(pattern rules)
 这种规则更加通用,因为可以利用模式规则定义更加复杂的依赖性规则。 模式规则看起来非常类似于正则规则,但在目标名称
的前面多了一个 % 号,同时可用来定义目标和依赖 文件之间的关系,例如下面的模式规则定义了如何将任意一个 X.c 文件转换为 X.o
文件:
%.o:%.c
    $(CC) $(CCFLAGS) $(CPPFLAGS) -c -o $@ $<
缺省规则,所有规则执行前调用
%::
   touch $@

.DEFAULT :
   touch $@

常见的隐含规则
 编译C程序
执行命令为“$(CC) -c $(CPPFLAGS) $(CFLAGS)”。
编译C++程序
执行命令为“$(CXX) -c $(CPPFLAGS) $(CFLAGS)”。建议使用“.cc”作为C++源文件的后缀,而不是“.C”
汇编和需要预处理的汇编程序
“$(AS) $(ASFLAGS)”
链接单一的object文件
“$(CC) $(LDFLAGS) N.o $(LOADLIBES) $(LDLIBS)”
但一般建议每个Makefile都用自己隐含规则来代替缺省规则,这样比较容易读懂,并且容易调整
 
 
例子
以动态库作为参考
例子1
all:main
main:hello_main.o libhello.so
    gcc hello_main.o -L.  -lhello  -o main
hello_main.o:hello_main.c
    gcc  -c hello_main.c   -o hello_main.o  -I.
libhello.so:hello.o
    gcc   -shared   hello.o    -o  libhello.so
hello.o:hello.c
    gcc  -c -fpic  hello.c  -o hello.o
clean:
    -rm -f  *.o    main  libhello.so
 
run:main
    export LD_LIBRARY_PATH=.;./main
 
例子2:
CC = gcc
EXECUTE = main
LIBHELLO = libhello.so
OBJS = hello_main.o
CCFLAGS = -fpic
LDFLAGS = -L.  -lhello
LIBOBJS = hello.o
 
all:$(EXECUTE)
 
$(EXECUTE):$(LIBHELLO) $(OBJS)
    $(CC) $^ $(LDFLAGS)  -o $@
 
$(LIBHELLO):$(LIBOBJS)
    $(CC)  -shared $^   -o $@ 
 
%.o:%.c
    $(CC) -c $<  -o  $@  $(CCFLAGS)
 
clean:
    rm -f  *.o  $(OBJS) $(LIBHELLO) $(EXECUTE)
 
run:$(EXECUTE)
   export LD_LIBRARY_PATH=.;./$(EXECUTE)
 
 
输入:make
输入:/main  (最后一句可能手动导入,export LD_LIBRARY_PATH=.;./$main)
 
(待补充)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
阅读(1647) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~