血糖高能吃什么水果| 蝙蝠长什么样| 检查尿液能查出什么病| 抗酸杆菌是什么| 总梦到一个人说明什么| 什么眼镜框最轻最舒服| 百褶裙搭配什么上衣| 2023属什么生肖| 女性尿道口有小疙瘩是什么原因| 胃窦粘膜慢性炎是什么病| 小蓝是什么| 眼角痛什么原因| 炙是什么意思| 申酉是什么时间| 攒是什么意思| 身体逐渐消瘦是什么原因| 嗳气吃什么药| 裹粉是什么粉| 扑炎痛又叫什么| 鸭跖草用什么除草剂| 月经量少什么原因| 总是干咳是什么原因| 新生儿老是打嗝是什么原因| hp检查是什么| 不晨勃是什么原因| 菜鸟什么意思| 饮用水是什么水| 11.22是什么星座| 双侧乳腺小叶增生是什么意思| 结痂什么意思| 脚后跟疼痛是什么原因| 群体是什么意思| 寒潮是什么| 蟑螂喜欢吃什么东西| 金银花有什么功效和作用| 泰迪哼哼唧唧表示什么| 白矾是什么东西| 西洋参泡水喝有什么功效| 阴道骚痒是什么原因| 金牛座跟什么星座最配| 硌得慌是什么意思| 吃什么祛痰化痰最有效| 接吻有什么好处| 肠胃炎吃什么抗生素| 桃子可以做什么美食| 辩证法是什么意思| 什么叫肛裂| 右手臂痛是什么预兆| 滇红属于什么茶| 艾滋病初期皮疹是什么样的| 肚子有腹水是什么症状| 法医是干什么的| 染色体是由什么组成的| 孩子为什么不愿意上学| 人加三笔是什么字| 衣原体阳性是什么意思| 牙科属于什么科| 什么空调| 屁多又臭是什么原因| 什么布料最凉快| 为什么癌症治不好| 9.30号是什么星座| 什么叫高潮| 除夕是什么意思| 藏红花什么时候喝最好| 肾结石炖什么汤喝最好| 脑血栓是什么原因引起的| 湿度大对人体有什么影响| 怀孕脉象是什么样子| 月经量多是什么原因| 近视和远视有什么区别| 舒张压是什么| 地指什么生肖| 头一直疼是什么原因| 木加炎念什么| 5个月宝宝可以吃什么水果| 手抖挂什么科| 暖心向阳是什么意思| 鹅肉不能和什么一起吃| 黑枸杞泡水喝有什么作用和功效| 马上是什么意思| 什么是网球肘| 中暑是什么症状| 什么是烂桃花| 肠易激综合征吃什么中成药| 吃什么丰胸| 什么叫胆固醇| 云南有什么| 耳朵内痒是什么原因| 带id是什么意思| 小孩咳嗽是什么原因引起的| 反流性食管炎吃什么药好| 胆囊毛糙是什么意思| 心语是什么意思| 从商是什么意思| hpv52高危阳性是什么意思| 年底是什么时候| 吃什么食物能升白细胞| 蜥蜴吃什么| 六月十七是什么星座| 嗨体水光针有什么功效| 月经不来是什么原因导致的| 看破不说破什么意思| 绿卡有什么用| 高祖父的爸爸叫什么| 青玉是什么玉| 天下无双是什么生肖| 西梅是什么水果| 肚子痛是什么原因| 女性白细胞高是什么原因| 兰花是什么季节开的| 恕是什么意思| 县级以上医院是指什么| 软笔书法是什么| bench是什么牌子| sob是什么意思| 勃起是什么意思| 高冷什么意思| 嗓子疼吃什么| 动脉硬化吃什么药最好| 心脏跳快吃什么药好| 猪蹄子炖什么好吃| 金木水火土代表什么| 什么叫支原体感染| 女生读什么技校好| 六味地黄丸什么时候吃| 44什么意思| 植物神经紊乱看什么科| 扁桃体切除有什么影响| 男人梦到蛇预示着什么| 血糖突然升高是什么原因| 嘴下面起痘是什么原因| 他不懂你的心假装冷静是什么歌| 都市丽人什么意思| 数字专辑什么意思| 外痔长什么样| 什么牌子的助听器最好| 瘦肚子吃什么水果| 菊花茶为什么会变绿色| 辣椒是什么生肖| 2014属什么生肖| 脂肪酶是什么意思| fox是什么意思| 育字五行属什么| 头皮痒用什么药| 舌头起泡什么原因| 空气棉是什么面料| 浆水是什么| 抓鱼的鸟叫什么| 豆粕是什么| 父母都是b型血孩子是什么血型| 做梦吃面条是什么预兆| 汗毛重的女人意味着什么| 网球肘用什么方法能彻底治好呢| 张柏芝什么星座| 人生的尽头是什么| 猫鼻支是什么症状| 室上性心动过速是什么原因引起的| 上帝叫什么名字| 孕妇喝纯牛奶对胎儿有什么好处| hpv什么意思| 长江后浪推前浪是什么生肖| 洋葱炒什么菜好吃| 五子登科是什么意思| 抓拍是什么意思| 小便粉红色是什么原因| 火龙果对身体有什么好处| 梦见自己手机丢了是什么意思| 110斤穿什么码衣服| 小孩子手脱皮是什么原因引起的| 启蒙是什么意思| 白介素高说明什么| 煸是什么意思| 多管闲事是什么意思| 矿物油是什么| 变卖是什么意思| 袍哥什么意思| 顾家什么意思| 眼睛肿是什么问题| 血压高是什么引起的| 肩胛骨缝疼挂什么科| 土加一笔是什么字| 93什么意思| 怀孕期间吃什么对胎儿发育好| 什么颜色加什么颜色等于什么颜色| 试婚是什么意思啊| dna什么意思| 口巴念什么| 眉头有痣代表什么意思| 口周皮炎用什么药膏| 执行标准是什么意思| b像什么| 右佐匹克隆是什么药| 大雪是什么意思| 解离是什么意思| 香蕉和什么一起吃能减肥| 人为什么会老| sjb是什么意思| 手淫对身体有什么伤害| 拔智齿后可以吃什么| 总是心慌是什么原因| 狮子座前面是什么星座| 查颈椎挂什么科| 幼儿贫血吃什么补血最快| 95年属什么| 纯洁是什么意思| 黄的什么| 右胳膊上长痣代表什么| 栉风沐雨是什么意思| 拔牙后可以吃什么食物| 糜烂性脚气用什么药| 牙龈出血缺什么| 吃什么对肾好| 为什么不能打死飞蛾| eligible是什么意思| 尚清是什么意思| 失眠吃什么| 五更是什么时辰| courvoisier是什么酒| 老是犯困是什么原因| 下降头是什么意思| 皮肤松弛是什么原因造成的| 昆明是什么城| 什么是生化流产| 月经量少吃什么| 覅是什么意思| 怀孕会出现什么状况| 用减一笔是什么字| 外阴瘙痒是什么原因| 经血逆流的症状是什么| 什么姓氏好听| 喝红茶对身体有什么好处| 桑黄是什么东西| 违背是什么意思| 月经不来挂什么科| 国家为什么重视合肥| 佛灯火命是什么意思| 戒指戴左手中指是什么意思| 慢性气管炎吃什么药最有效| 小孩查微量元素挂什么科| 德字五行属什么| 合寿木是什么意思| 学前教育学什么| 什么是安全期和排卵期| 杠杠的是什么意思| 贷款是什么意思| 验孕棒一深一浅代表什么| 西晋之后是什么朝代| b超检查什么| 2012属什么生肖| 乳腺结节有什么症状| 皮肤病吃什么药最好| 半硬半软是什么症状| 属鼠的本命佛是什么佛| 神经递质是什么意思| 三岁属什么生肖| 1965属什么生肖| 猫癣用什么药| 冷面是什么做的| 玫瑰花和什么一起泡水喝好| 喝什么补羊水| 动手术后吃什么对伤口恢复比较快| 嗓子疼咳嗽是什么原因| 有白带发黄是什么原因| 百度

新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > Linux/Unix环境下的make命令详解

南昌青山湖区新闻--江西频道--人民网

作者: 时间:2025-08-06 来源:网络 收藏
无论是在Linux还是在Unix环境中,都是一个非常重要的编译命令。不管是自己进行项目开发还是安装应用软件,我们都经常要用到 install。利用make工具,我们可以将大型的开发项目分解成为多个更易于管理的模块,对于一个包括几百个源文件的应用程序,使用make和 makefile工具就可以简洁明快地理顺各个源文件之间纷繁复杂的相互关系。而且如此多的源文件,如果每次都要键入gcc命令进行编译的话,那对程序员来说简直就是一场灾难。而make工具则可自动完成编译工作,并且可以只对程序员在上次编译后修改过的部分进行编译。因此,有效的利用make和 makefile工具可以大大提高项目开发的效率。同时掌握make和makefile之后,您也不会再面对着Linux下的应用软件手足无措了。

但令人遗憾的是,在许多讲述Linux应用的书籍上都没有详细介绍这个功能强大但又非常复杂的编译工具。在这里我就向大家详细介绍一下make及其描述文件makefile。

Makefile文件
Make 工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。makefile 文件是许多编译器--包括 Windows NT 下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改 makefile 文件而已。

在 UNIX 系统中,习惯使用 Makefile 作为 makfile 文件。如果要使用其他文件作为 makefile,则可利用类似下面的 make 命令选项指定 makefile 文件:

$ make -f Makefile.debug

例如,一个名为prog的程序由三个C源文件filea.c、fileb.c和filec.c以及库文件LS编译生成,这三个文件还分别包含自己的头文件 a.h 、b.h和c.h。通常情况下,C编译器将会输出三个目标文件filea.o、fileb.o和filec.o。假设filea.c和fileb.c都要声明用到一个名为defs的文件,但filec.c不用。即在filea.c和fileb.c里都有这样的声明:

#include defs

那么下面的文档就描述了这些文件之间的相互联系:

#It is a example for describing makefile
prog : filea.o fileb.o filec.o
cc filea.o fileb.o filec.o -LS -o prog
filea.o : filea.c a.h defs
cc -c filea.c
fileb.o : fileb.c b.h defs
cc -c fileb.c
filec.o : filec.c c.h
cc -c filec.c

这个描述文档就是一个简单的makefile文件。

从上面的例子注意到,第一个字符为 # 的行为注释行。第一个非注释行指定prog由三个目标文件filea.o、fileb.o和filec.o链接生成。第三行描述了如何从prog所依赖的文件建立可执行文件。接下来的4、6、8行分别指定三个目标文件,以及它们所依赖的.c和.h文件以及defs文件。而5、7、9行则指定了如何从目标所依赖的文件建立目标。

当filea.c或a.h文件在编译之后又被修改,则 make 工具可自动重新编译filea.o,如果在前后两次编译之间,filea.C 和a.h 均没有被修改,而且 test.o 还存在的话,就没有必要重新编译。这种依赖关系在多源文件的程序编译中尤其重要。通过这种依赖关系的定义,make 工具可避免许多不必要的编译工作。当然,利用 Shell 脚本也可以达到自动编译的效果,但是,Shell 脚本将全部编译任何源文件,包括哪些不必要重新编译的源文件,而 make 工具则可根据目标上一次编译的时间和目标所依赖的源文件的更新时间而自动判断应当编译哪个源文件。

Makefile文件作为一种描述文档一般需要包含以下内容:

◆ 宏定义
◆ 源文件之间的相互依赖关系
◆ 可执行的命令

Makefile中允许使用简单的宏指代源文件及其相关编译信息,在Linux中也称宏为变量。在引用宏时只需在变量前加$符号,但值得注意的是,如果变量名的长度超过一个字符,在引用时就必须加圆括号()。

下面都是有效的宏引用:

$(CFLAGS)
$2
$Z
$(Z)

其中最后两个引用是完全一致的。

需要注意的是一些宏的预定义变量,在Unix系统中,$*、$@、$?和$四个特殊宏的值在执行命令的过程中会发生相应的变化,而在GNU make中则定义了更多的预定义变量。关于预定义变量的详细内容,宏定义的使用可以使我们脱离那些冗长乏味的编译选项,为编写makefile文件带来很大的方便。

# Define a macro for the object files
OBJECTS= filea.o fileb.o filec.o
# Define a macro for the library file
LIBES= -LS
# use macros rewrite makefile
prog: $(OBJECTS)
cc $(OBJECTS) $(LIBES) -o prog
……

此时如果执行不带参数的make命令,将连接三个目标文件和库文件LS;但是如果在make命令后带有新的宏定义:

make LIBES= -LL -LS

则命令行后面的宏定义将覆盖makefile文件中的宏定义。若LL也是库文件,此时make命令将连接三个目标文件以及两个库文件LS和LL。

在Unix系统中没有对常量NULL作出明确的定义,因此我们要定义NULL字符串时要使用下述宏定义:

STRINGNAME=

Make命令

在make命令后不仅可以出现宏定义,还可以跟其他命令行参数,这些参数指定了需要编译的目标文件。其标准形式为:

target1 [target2 …]:[:][dependent1 …][;commands][#…]
[(tab) commands][#…]

方括号中间的部分表示可选项。Targets和dependents当中可以包含字符、数字、句点和/符号。除了引用,commands中不能含有#,也不允许换行。

在通常的情况下命令行参数中只含有一个:,此时command序列通常和makefile文件中某些定义文件间依赖关系的描述行有关。如果与目标相关连的那些描述行指定了相关的command序列,那么就执行这些相关的command命令,即使在分号和(tab)后面的aommand字段甚至有可能是 NULL。如果那些与目标相关连的行没有指定command,那么将调用系统默认的目标文件生成规则。

如果命令行参数中含有两个冒号::,则此时的command序列也许会和makefile中所有描述文件依赖关系的行有关。此时将执行那些与目标相关连的描述行所指向的相关命令。同时还将执行build-in规则。

如果在执行command命令时返回了一个非0的出错信号,例如makefile文件中出现了错误的目标文件名或者出现了以连字符打头的命令字符串,make操作一般会就此终止,但如果make后带有-i参数,则make将忽略此类出错信号。

Make命本身可带有四种参数:标志、宏定义、描述文件名和目标文件名。其标准形式为:

Make [flags] [macro definitions] [targets]

Unix系统下标志位flags选项及其含义为:

-f file 指定file文件为描述文件,如果file参数为-符,那么描述文件指向标准输入。如果没有-f参数,则系统将默认当前目录下名为 makefile或者名为Makefile的文件为描述文件。在Linux中, GNU make 工具在当前工作目录中按照GNUmakefile、makefile、Makefile的顺序搜索 makefile文件。

-i   忽略命令执行返回的出错信息。
-s   沉默模式,在执行之前不输出相应的命令行信息。
-r   禁止使用build-in规则。
-n   非执行模式,输出所有执行命令,但并不执行。
-t   更新目标文件。
-q   make操作将根据目标文件是否已经更新返回0或非0的状态信息。
-p   输出所有宏定义和目标文件描述。
-d   Debug模式,输出有关文件和检测时间的详细信息。

Linux下make标志位的常用选项与Unix系统中稍有不同,下面我们只列出了不同部分:

-c dir   在读取 makefile 之前改变到指定的目录dir。
-I dir   当包含其他 makefile文件时,利用该选项指定搜索目录。
-h   help文挡,显示所有的make选项。
-w   在处理 makefile 之前和之后,都显示工作目录。

通过命令行参数中的target ,可指定make要编译的目标,并且允许同时定义编译多个目标,操作时按照从左向右的顺序依次编译target选项中指定的目标文件。如果命令行中没有指定目标,则系统默认target指向描述文件中第一个目标文件。

通常,makefile 中还定义有 clean 目标,可用来清除编译过程中的中间文件,例如:

clean:
rm -f *.o

运行 make clean 时,将执行 rm -f *.o 命令,最终删除所有编译过程中产生的所有中间文件。

隐含规则
在make 工具中包含有一些内置的或隐含的规则,这些规则定义了如何从不同的依赖文件建立特定类型的目标。Unix系统通常支持一种基于文件扩展名即文件名后缀的隐含规则。这种后缀规则定义了如何将一个具有特定文件名后缀的文件(例如.c文件),转换成为具有另一种文件名后缀的文件(例如.o文件):

.c:.o
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $
系统中默认的常用文件扩展名及其含义为:
.o  目标文件
.c  C源文件
.f  FORTRAN源文件
.s  汇编源文件
.y  Yacc-C源语法
.l  Lex源语法

在早期的Unix系统系统中还支持Yacc-C源语法和Lex源语法。在编译过程中,系统会首先在makefile文件中寻找与目标文件相关的.C文件,如果还有与之相依赖的.y和.l文件,则首先将其转换为.c文件后再编译生成相应的.o文件;如果没有与目标相关的.c文件而只有相关的.y文件,则系统将直接编译.y文件。

而GNU make 除了支持后缀规则外还支持另一种类型的隐含规则--模式规则。这种规则更加通用,因为可以利用模式规则定义更加复杂的依赖性规则。模式规则看起来非常类似于正则规则,但在目标名称的前面多了一个 % 号,同时可用来定义目标和依赖文件之间的关系,例如下面的模式规则定义了如何将任意一个 file.c 文件转换为 file.o 文件:

%.c:%.o
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $
#EXAMPLE#

下面将给出一个较为全面的示例来对makefile文件和make命令的执行进行进一步的说明,其中make命令不仅涉及到了C源文件还包括了Yacc语法。本例选自Unix Programmer's Manual 7th Edition, Volume 2A Page 283-284

下面是描述文件的具体内容:

#Description file for the Make command
#Send to print
P=und -3 | opr -r2
#The source files that are needed by object files
FILES= Makefile version.c defs main.c donamc.c misc.c file.c dosys.c gram.y lex.c gcos.c
#The definitions of object files
OBJECTS= vesion.o main.o donamc.o misc.o file.o dosys.o gram.o
LIBES= -LS
LINT= lnit -p
CFLAGS= -O
make: $(OBJECTS)
cc $(CFLAGS) $(OBJECTS) $(LIBES) -o make
size make
$(OBJECTS): defs
gram.o: lex.c
cleanup:
-rm *.o gram.c
install:
@size make /usr/bin/make
cp make /usr/bin/make ; rm make
#print recently changed files
print: $(FILES)
pr $? | $P
touch print
test:
make -dp | grep -v TIME>1zap
/usr/bin/make -dp | grep -v TIME>2zap
diff 1zap 2zap
rm 1zap 2zap
lint: dosys.c donamc.c file.c main.c misc.c version.c gram.c
$(LINT) dosys.c donamc.c file.c main.c misc.c version.c gram.c
rm gram.c
arch:
ar uv /sys/source/s2/make.a $(FILES)

通常在描述文件中应象上面一样定义要求输出将要执行的命令。在执行了make命令之后,输出结果为:

$ make
cc -c version.c
cc -c main.c
cc -c donamc.c
cc -c misc.c
cc -c file.c
cc -c dosys.c
yacc gram.y
mv y.tab.c gram.c
cc -c gram.c
cc version.o main.o donamc.o misc.o file.o dosys.o gram.o -LS -o make
13188+3348+3044=19580b=046174b

最后的数字信息是执行@size make命令的输出结果。之所以只有输出结果而没有相应的命令行,是因为@size make命令以@起始,这个符号禁止打印输出它所在的命令行。

描述文件中的最后几条命令行在维护编译信息方面非常有用。其中print命令行的作用是打印输出在执行过上次make print命令后所有改动过的文件名称。系统使用一个名为print的0字节文件来确定执行print命令的具体时间,而宏$?则指向那些在print 文件改动过之后进行修改的文件的文件名。如果想要指定执行print命令后,将输出结果送入某个指定的文件,那么就可修改P的宏定义:

make print P= cat>zap

在Linux中大多数软件提供的是源代码,而不是现成的可执行文件,这就要求用户根据自己系统的实际情况和自身的需要来配置、编译源程序后,软件才能使用。只有掌握了make工具,才能让我们真正享受到到Linux这个自由软件世界的带给我们无穷乐趣。
百度 老师从旗袍的起源开始,简述了中国历代女袍服到旗袍的演变历程,让大家对旗袍有了全新的认识,并且希望在座的女科技工作者能够通过旗袍,彰显出东方女性的典雅、温柔、清丽的性情与气质。

linux相关文章:linux教程




关键词: make

评论


技术专区

关闭
什么是屈光不正 退烧吃什么药 由是什么意思 8五行属什么 幽门螺旋杆菌什么意思
献血后吃什么 热锅上的蚂蚁是什么意思 睡觉喜欢流口水是什么原因 三维b片主治什么病 陛下的陛是什么意思
试纸一条红杠是什么意思 口蜜腹剑是什么意思 大姨妈有血块是什么原因 虾跟什么不能一起吃 世界上最长的蛇是什么蛇
血管瘤吃什么药 唐氏综合征是什么原因造成的 全身发冷是什么原因 迎合是什么意思 二级警督是什么级别
什么人容易得间质瘤hcv8jop7ns6r.cn 动脉瘤是什么hcv9jop0ns4r.cn 什么叫匝道hcv9jop0ns4r.cn 为什么男生hcv9jop6ns3r.cn 心绞痛吃什么药最好hcv9jop1ns8r.cn
嘴唇不红润是什么原因hcv7jop9ns1r.cn ootd什么意思hcv8jop9ns9r.cn 四维是什么意思hcv9jop8ns1r.cn 生源地是指什么hcv9jop1ns9r.cn 高半胱氨酸是什么意思hcv9jop6ns2r.cn
来月经吃什么对身体好hcv9jop0ns0r.cn 艾灰有什么作用和功效hcv9jop7ns0r.cn 吴京和吴樾什么关系hcv8jop4ns6r.cn 雪村和赵英俊什么关系hcv9jop6ns4r.cn 福星贵人是什么意思hcv7jop6ns1r.cn
油墨用什么可以洗掉naasee.com 什么是压缩性骨折hcv9jop3ns5r.cn 自带bgm是什么意思hlguo.com 降血压吃什么药hcv8jop5ns9r.cn 吃桃胶有什么作用hcv9jop0ns3r.cn
百度