Makefile基础

在说Makefile 之前呢,我给大家介绍一种整理工程的好方法,这个方法会使你编写的项目结构一目了然!

         在简历项目之前首先我们可以先建六个文件夹分别为: bin       dist          docs          include         lib    src

         bin文件夹里放我们的脚本文件,dist看名字我们也知道放垃圾文件,docs放我们的项目文档了,include放.h文件,lib放库文件,src就放我们的.c程序啦!

这方法虽然看起来没什么,但是如果真正用到开发项目的时候,你会发现它为我们节省了很多的时间来找我们需要的代码,所以,想成为高效的程序员,习惯要从开始养成哦~    

大家都知道一般的程序都是由多个源文件编译链接而成的,对这么多的源文件处理就要用到Makefile来管理了!

             makefile和源代码放在同一个目录下,当执行make时,编译器就会自动读取当前目录下的Makefile文件。

             Makefile由一组规则组成,每条规则的格式都是:

                                                            target...:prerequisites...

                                                                    command1

                                                                    command2

                                                                    ....

             例如:main:main.o add.o sub.o  mul.o div.o

                            gcc main.o add.o sub.o mul.o div.o -o main

              main是这条规则的目标target,main.o   add.o  sub.o  mul.o  div.o 是这条规则的条件。command1和command2是命令列表,这里注意了!!!!在Makefile中,命令列表中的每个命令必须以Tab开头啊!不能是空格。还有,第一条规则的目标我们称之为缺省目标,只要缺省目标更新了才算更显完成。

              通常Makefile 都会有一个clean规则,用于清除编译过程中产生的二进制文件,保留源文件,正确写法类似于:

                                           clean:

                                                      @echo"cleaning project

                                                       -rm main *.o

                                                     @echo "clean completed"

                                        .PHONY:clean

              clean 目标是一个约定俗称的名字,类似这样约定俗称的名字还有:all ,执行主要的编译工作,通常用作缺省目标。install,执行编译后的安装工作,把可执行文件、配置文件、文档等分别拷到不同的安装目录。clean,删除编译生成的二进制文件。distclean,不仅删除编译生成的二进制文件,也删除其他生成的文件。


为使Makefile写的更加简洁

                 这里介绍个makefile的隐式规则:如果一个目标在Makefile中的所有规则中都没有命令列表,make会尝试在内建的隐式规则数据库中查找适用的规则。(make的隐式规则可以用make -p打印出来),在隐式规则中要知道,$(CFLAGS)  $(CPPFLAGS)   $(TARGET_ARCH)都表示空,$@取值为规则中的目标,$<的取值为规则中的第一个条件               

                   %.o:%.c是一种特殊的规则,称为模式规则  。

 Makefile中关于变量的语法规则           

                        用"=号"义makefile变量有利有弊,好处是我们可以把变量的值推迟到后面定义,坏处是可能写出我穷递归的定义(例如:A = $(B)   B = $(A))。

                        用“:=”运算符在make时遇到变量定义时立即展开。例如:

                                                      x:=foo

                                                      y:=$(x)bar

                                                       all:

                                                            @echo "-$(y)-"

                                            make后的结果y 的值是 foo bar。但是如果改成下面的例子y的值就是   bar。注意bar前面有空格

                                                      y:=$(x)bar

                                                      x:=foo                       

                                                       all:            

                                                            @echo "-$(y)-"

                       注意的是:一个变量的定义从=后面的第一个非空白字符开始(从$(x)的$开始),包括后面的所有字符,直到注释或换行之前结束。

                   “?=”   的用法直接看例子:foo ?= $(bar)的意思是,如果foo没有定义过,那么?= 相当与=,定义foo的值是$(bar),但不立即展开;如果先前已经定义了foo,则什么也不做,不会给foo重新赋值。

                   “+=”给变量追加值,直接看例子:object:=main.o

                                                                               object += $(foo)

                                                                               foo = foo.o bar.o

                           例子中 由于object是用 := 定义的, += 保持 := 的特性,object的值是main.o $(foo),立即展开得到main.o(这时foo还没有定义),所以main后面的空格该保留。

如果变量object没有定义过就直接赋值,那么+=相当于=。

                        常用的特殊变量有:

                         $@,表示规则中的目标。

                         $<,表示规则中的第一个条件。

                         $? ,表示规则中所有比目标新的条件,组成一个列表,以空格分隔。

                         $^ ,表示规则中的所有条件,组成一个列表,以空格分隔。

 一下列举一些常用的变量

AR--静态库打包命令的名字,缺省值是ar

ARFLAGS--静态库打包命令的选项,缺省值是rv

AS--汇编器的名字,缺省值是as

ASFLAGS--汇编器的选项,没有定义

CC--C编译器的名字,缺省值是cc

CFLAGS--C编译器的选项,没有定义

CXX--C++编译器的名字,缺省值是g++

CXXFLAGS--C++编译器的选项,没有定义

CPP--C预处理器的名字,缺省值是$(CC) -E

CPPFLAGS--C预处理器的选项,没有定义

LD--链接器的名字,缺省值是ld

LDFLAGS--连接器的选项,没有定义

TARGET_ARCH--和目标平台相关的命令行选项,没有定义

OUTPUT_OPTION--输出的命令行选项,缺省值是-o$@

LINK.o--把.o文件链接在一起的命令行,缺省值是$(CC) $(LDFLAGS)  $(TARGET_ARCH)

LINK.c--把.c文件链接在一起的命令行,缺省值是$(CC)  $(CFLAGS)   $(CPPFLAGS)  $(LDFLAGS)  $(TARGET_ARCH)

LINK.cc--把.cc文件(C++源文件)链接在一起的命令行,缺省值是$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)                        $(TARGET_ARCH)

COMPILE.c--编译.c文件的命令行,缺省值是$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c

COMPILE.cc--编译.cc文件的命令行,缺省值是$(CXX)  $(CXXFLAGS)  $(CPPFLAGS)  $(TARGET_ARCH) -c

RM--删除命令的名字,缺省值是rm -f

在Makefile中使用函数!!!!!!!!!!!!!!!!!!!

首先我先说下注意事项,再把makefile的函数依依列出来,供以后参考

Makefile 里的函数跟它的变量很相似——使用的时候,你用一个$符合跟开括号,函数名,空格后面跟一列由逗号分隔的参数,最后用关括号结束。

函数调用语法:$(<function>;<arguments>;)或者是${<function>;<arguments>},其中<function>是函数名,<arguments>是函数的参数,参数之间以逗号隔开,函数名与参数之间用空格分开。函数和变量的括号最好一样。

好啦,下面我们要列举函数了,用到是查方便。

1》SOURCES = $(wildcard *.c)表示,所有以.c结尾的文件的列表,然后存入变量SOURCES里

字符串处理函数

2》$(subst <from>;,<to>;,<text>;)把字符串<text>中的<from>;字符串替换成<to>;。

3》$(patsubst <pattern>;,<replacement>;,<text>;)模式字符串替换函数。示例:$(patsubst  %.c,%.o,x.cc bar.c)把字串“x.cc bar.c"符合模式[%.c]的单词替换成[%.o],返回结果是”x.c.o bar.o“

4》$(strip <string>;)去空格函数。去掉<string>;字串中开头和结尾的空格符。

5》$(findstring  <find>;,<in>;)查找字符串函数。在字符串<in>;.中查找<find>;字串,如果找到返回<find>如果没有找到返回空字符串。

6》$(filter <pattern...>;,<text>;)过滤函数,返回符合模式<pattern>;的字串。例子:sources:=foo.c bar.c baz.s ugh.h

                                                                                                                                                foo: $(sources)

                                                                                                                                                cc $(filter %.c %.s,$(sources)) -o foo

                                                                                               其中(filter %.c %.s,$(sources))的返回值是"foo.c  bar.c  baz.s"。

7》$(filter-out  <pattern...>;,<text>;)反过滤函数

8》$(sort  <list>;)排序函数——sort。给字符串<list>;中的单词排序(升序).备注:sort函数会去掉<list>;中相同单词。

文件名操作函数

9》$(dir  <names...>;)取目录函数——dir。功能;从文件名序列<names>;中取出目录部分。目录部分是指最后一个反斜杠(”/“)之前的部分。如果没有反斜杠,那么返回”./“。例子:$(dir src/foo.c  hacks)返回值是"src/  ./"。

10》$(notdir <names...>;取文件函数:从文件名序列<names>;中取出非目录部分。非目录部分是最后一个反斜杠之后的部分。例子:$(notdir src/foo.c hacks)返回值是“foo.c hacks"。

11》$(suffix <names...>;)取后缀函数suffix。从文件名序列<names>;中取出各文件名的后缀。如果文件没有后缀就返回空字串。例子:$(suffix src/foo.c src1.c hacks)返回值是”.c .c“

12》$(basename  <name...>;)取前缀函数。取出各文件名的前缀部分。例子$(basename src/foo.c src1.c hacks)返回值是“src/foo   src1   hacks"。

 13》$(addsuffix  <suffix>;,<names...>;)加后缀函数,把<suffix>加到<names>中的每个单词后面。

14》$(addprefix  <prefix>;,<names...>;)加前缀函数。

15》$(join  <list1>;,<list2>;)连接函数,返回连接后的函数,功能是:把<list2>;中的单词对应的加到<list1>;的单词后面。如果<list1>;的单词个数要比<list2>;的多,那么,<list1>;中的多出来的单词将保持原样。反之,<list2>中多出来的单词将被复制到<list2>;中。例子:$(join  aaa    bbb  ,111  2222   3333)返回“aaa111   bbb2222   3333"





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值