make使用入门

原创 2003年10月20日 15:38:00

 GNU Make是一个开发源代码的Make工具。Make是什么?在命令行下写程序的人应该都知道,它是一个项目管理工具。它的最基本用途就是管理项目的编译、连接。它会按照规则(定义在规则文件中)、依赖顺序对项目中的文件进行编译、连接或把它们安装到系统中。GNU Make的可执行程序通常就是make.exe。
一个简单的例子—基本规则
 下面来看一个简单的例子(以下内容均以Win32平台为例):
文件名:makefile
1. # makefile
2. # this is a example of make file
3. all:a1 a2
4.   @echo this is all!
5. a1:
6.   @echo this is a1!
7. a2:
8.   @echo this is a2!

运行make后,结果如下:
this is a1!
this is a2!
this is all!

现在让我们来分析一下这个简单的规则文件。
第1、2行不用说,一眼就可以看出是注释。在Make规则文件中,注释是以“#”开始,是行注释,和C++中的“//”功能一样。不过你可不能把它放到其它的语句之后,否则就错了。第3行就是规则开始了!all:a1 a2一行中,规则的名字就是all,它通常是目标名(target)。一条规则可以有不止一个名字,像这一行,你也可以把它写成all all2:a1 a2。这时,规则就有了两个名称—all和all2。当然,还可以有更多,都看你自己。后面的5、7两行也分别是两条规则的起始。在“:”之后的,就是依赖项。在这一行里,依赖项有两个,分别是a1和a2。这些依赖项可以是其它的规则名(目标名),也可以是文件名。依赖和目标之间的关系就是“依赖关系”。一条规则中,可以有零个(像后面的两条规则)、一个或多个依赖。第4行@echo this is all!是命令行。它是执行all规则时要执行的命令。要注意的是,一条规则内的命令要以tab为一行的起始,以表示命令是属于一个规则。一条规则也可以有多条命令,每条命令占一行(要以tab开头)。至于可以使用哪些命令,这完全取决于你使用的OS和SHELL。
当执行make时,它会找到第一条规则。然后,make就会检查依赖和目标之间的关系。如果目标比依赖旧,就执行规则,以更新目标。执行完规则就结束。如何判定目标和依赖的新旧呢?如果目标(文件)不存在,目标的时间就为0;如果目标(文件存在),目标的时间就为文件的修改时间。如果依赖项是一条规则,就执行依赖的规则(这里是一个递归),然后依赖的时间就是当前最新时间;如果是一个存在的文件,就为文件的修改时间,否则就报错。之后,就可以比较目标和依赖之间的关系。不过,有一点特殊的是,在没有依赖项时,依赖的时间为1。
在这个例子中,make先找到规则“all”,发现目标不存在,所以目标的时间为0;然后在查找依赖“a1”,结果“a1”不存在;于是,执行规则“a1”。“a1”不存在,所以它的时间为0,而“a1”没有依赖,它的依赖时间为1;1>0,所以,执行规则“a1”。然后返回规则“all”,再检查依赖“a2”。“a2”执行过程同“a1”。这时,“all”的目标时间为0,依赖时间为最新时间。于是,执行规则“all”的命令。
当然,大家也可以指定一条规则让make执行,比如:make a1这个命令就是告诉make程序不去找第一条规则,而是规则“a1”来执行。并且我们还可以一次执行多条规则,比如:执行make a1 a2就会连续执行“a1”、“a2”两条规则。
OK,虽然讲得很混乱,但也费了我半天的力气。大家应该有一点了解make规则的执行过程了吧。
现在来总结一下依赖的写法。如下(中括号中的内容是可选内容):
Target : [dependence] [dependence2] […]
 [command]
 [command2]
 […]
Target可以是文件名。Dependence可以是其它的target名或文件名。Command就是操作系统所运行的命令行。
变量
  一个make规则文件有这些内容就已经基本可以工作了。可是,当我们在编译一个程序时,如果有些内容要反复用到,每次都要写一长串的话,是很麻烦的。于是,make就引入了宏这个概念(其实也可以看成简单的脚本语言)。
宏变量的定义如下:
var1 = this is a macro demo!
var1就是变量名,它的值就是“this is a macro demo!”
如果我们要使用这个变量的值,那只有通过$这个运算符才行—$(var1)代表的就是“this is a macro demo!”。
如下makefile
1. var1 = this is a macro demo!
2. all:
3.   @echo $(var1)
结果输出:
this is a macro demo!
用户在执行命令行时也可以定义宏变量。其形式如下:
make all var1=”this is a test”
执行结果为:
this is a test
我们不仅可以使用自定义变量,还可以通过这种方式使用系统环境变量。这样可以大大方便我们建议灵活的规则。如下makefile
1. all:
2.   @echo $(windir)
执行结果为:
C:/WinNT
(注意:makefile中的变量是大小写敏感的)
除此之外,makefile中还有一些内定的特殊变量。这些变量可以代替在不同的规则中的目标、依赖等内容。使得规则的建立更加便利。请看如下例子:
1. all : a.exe
2. a.exe : a.obj
3.   cl $< /Fo$@ /nologo
4. a.obj : a.c
5.   cl $< /c /Fo$@ /nologo
大家可以看到,这里用了$<和$@这两个奇怪的符号。运行一下吧!
cl a.c /c /Foa.obj /nologo
a.c
cl a.obj /Foa.exe /nologo
很明显,$<变成了a.c和a.obj,$@变成了a.obj和a.exe。应该明白了吧?
$@代表规则中的目标名(也就是规则名)。
$<代表规则中的依赖项目。注意,它只代表规则所有依赖项目中的第一项!
其它还有:
$^代表规则中所有的依赖项目。
$?代表规则中时间新于目标的依赖项目。
不仅如此,还可以给这些特殊的变量加一些限制。
如:
在规则
debug/out.exe : out.obj
中,$@代表debug/out.exe,而$(@D)代表目录名debug,$(@F)代表文件名out.exe。其它如$(<D)、$(<F)、$(^D)、$(^F)、$(?D)、$(?F)与此类似。
内建规则
为了方便使用,makefile中加入了一些基本规则。在没有写明命令的情况下,程序会按目标以及依赖的类型自动选择一些默认的命令来编译程序。
如下表:

类型<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

目标类型

依赖类型

命令

C程序

*.o

*.c

$(CC) -c $(CPPFLAGS) $(CFLAGS)

C++程序

*.o

*.cc

$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)

汇编程序

*.o

*.s

$(AS) $(ASFLAGS)

Frotran

*.o

*.f

$(FC) -c $(FFLAGS)

Pascal

*.o

*.p

$(PC) -c $(PFLAGS)

连接

*.out

*.o

$(CC) $(LDFLAGS) name.o $(LOADLIBES) $(LDLIBS)

大家可以看到,在这个表中使用了很多不同的宏。这些宏都是编译器内建的,我们也可以手工修改它们,这样,就可以实现对内建规则的修改。
请看如下makefile:
1. CC = gcc
2. a : a.o
呵呵,是不是很奇怪?什么都没有写,只写了一个没有内容的规则,怎么能运行呢?试试吧!结果如下:
gcc    -c -o a.o a.c
gcc   a.o   -o a
在第1行中,我把内建变量CC的值改成了gcc(默认是cc)。这样,在编译时就会使用我所设定的gcc来工作。第2行,我给出了目标a和依赖a.o。由于有从a.c到a.o的默认规则,如果有a.c这个文件的话make就会自动使用内建规则来编译。一切OK!
其它的规则你也可以试试。
除了这种传统规则,还有一种内建规则,叫后缀规则。请看如下makefile:
1. a.exe : a.o
2.   cl a.o /MD /nologo
3. .c.o :
4.   cl $^ /c /Fo$@ /MD /nologo
在这个规则文件中,没有说明a.o是由哪一个源文件生成,只给了一个.c.o的奇怪规则。这个规则的意思是对于以.o为扩展名的目标,都以相应的.c源程序来生成。生成的命令就是规则中给出的那条命令。
  当然,make中并没有包含所有的可用扩展名。它包含了.c、.o、.s、.cc等UNIX下常用的扩展名。在Windows下,我们还要手工添加几个名称,否则不是很方便。要添加扩展名,就要通过.SUFFIXES这个预处理标识来完成。比如我要添加.asm和.inc这两种扩展名。只要在makefile中加上.SUFFIXES .asm .inc就可以了。
  其它的内建规则大家可要自己去试了,不自己摸索,很难掌握好的!
常用的参数
  前面介绍了半天makefile的写法,现在来说说make程序的基本参数吧。
-f参数可以指定makefile的名称,这样,就可以不用makefile做为规则文件的名字了。
-i参数可以使make程序忽略运行时的错误,继续运行。
-v参数用来显示make程序的版本号。
--help参数可以显示make程序的参数帮助。
好了,我只说这四个最常用的参数吧!其它的参数大家自己摸索吧!写了一下午,头都大了!还有,这只是一入门资料。Make中还有更复杂的控制语句和一些函数,有空再写!想学的朋友最好还是到GNU的网站找文档,自己学吧!

最后给大家一些资源,可以找到GNU make。
http://sourceforge.net/projects/mingw
http://www.cygwin.com/

make使用入门

GNU Make 使用手册(中译版)GNU make中文手册(来自Linuxsir.org的针对3.80版的中文文档)GNU Make是一个开发源代码的Make工具。Make是什么?在命令行下写程序的...
  • tommy_lgj
  • tommy_lgj
  • 2006年10月12日 16:55
  • 2573

使用make命令编译项目文件入门

使用make命令编译项目文件入门 目录: 一、make命令的运行过程 二、基本gcc编译命令 三、简单Makefile文件的编写 四、实例 一、make命令的运行过程    ...
  • ycl295644
  • ycl295644
  • 2015年12月15日 09:19
  • 11539

GNU Make 简明教程 (一)

写Linux代码也有段时间了,一直都是采用make的方式来编译工程,但对Makefile掌握的并不是很全面。前段时间看到了《GNU Make项目管理》这本书,决定系统的学习一下Makefile语法,这...
  • fz2543122681
  • fz2543122681
  • 2017年02月14日 16:18
  • 532

使用make命令编译入门

今天有学长讲了关于虚拟机中make的高级用法,故整理一篇博客进行梳理。 一、建立一个放置头文件的库函数——address.h以备调用(项目运行时可将全部头文件放入其中) vim address.h...
  • vivien1997
  • vivien1997
  • 2018年02月02日 21:16
  • 12

make入门

1. 简介 1.1 rule target ... : prerequisites ... recipe ... ... r...
  • bitcold_robin
  • bitcold_robin
  • 2013年03月08日 21:29
  • 410

深入讲解GCC和Make的区别(有涉及makefile文件哟!!!)

刚接触linux编程,很多概论都比较模糊,今天突然用到makefile文件,想到了make与gcc的关系。于是查阅了一些资料,在此做一个小结: 1.gcc是编译一个文件,make是编译多个源文件的工...
  • haluoluo211
  • haluoluo211
  • 2016年11月23日 20:29
  • 3152

CMake 入门实战(精)

http://www.hahack.com/codes/cmake/ 从实例入手,讲解 CMake 的常见用法。 Contents 什么是 CMake入门案例:单个源文件...
  • lwljava
  • lwljava
  • 2014年08月12日 16:25
  • 1939

在windows中使用make

在windows中使用make使用dev-cpp来构建环境是很方便的。 下载安装dev-cpp在环境变量中添加dev-cpp的安装路径就可以自己编写makefile文件在dos模拟终端运行了。 de...
  • kee131
  • kee131
  • 2014年11月26日 10:14
  • 5555

Make 学习笔记三-使用变量

定义一个空值的变量: nullstring := space := $(nullstring) # end of the line nullstring是一个Empty变量,其中什么也没有,而我们的s...
  • carolzhang8406
  • carolzhang8406
  • 2017年02月17日 13:52
  • 220

windows 下使用make命令,编译代码

Windows安装GNU WinGW编译器使用makefile Windows安装GNU编译器使用makefile 一、下载安装MinGW MinGW下载网页:http://...
  • Nicholas_Liu2017
  • Nicholas_Liu2017
  • 2017年10月23日 21:10
  • 4122
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:make使用入门
举报原因:
原因补充:

(最多只允许输入30个字)