Unix/Linux C++应用开发-make工具的使用

    经常使用Windows平台IDE做开发的人员,可能对于makefile多少有些陌生。因为Windows下的IDE通常都将这一步封装了,只提供编译按钮,不需要开发人员人为地参与这个过程。Unix/Linux下软件开发工程项目需要开发者自己编写makefile文件。从某种程度上来讲,熟练编写makefile文件也说明了开发者具备完成大型工程的一个方面地能力。

    makefile关系到整个工程的编译规则。通常一个大型的软件工程项目拥有的源文件往往不计其数。按照工程化的思想,这些不计其数的源文件按照功能、模块分别需要放在规划好的不同的目录中。而makefile则定义了一系列的规则来指定源文件的编译顺序,以及哪些文件需要重新编译更新,甚至一些比较复杂的编译操作。通常编写好makefile文件后,就可以执行make命令进行自动化编译,从而提高开发效率。迄今为止,make工具是应用最为广泛,也是使用最多的工具。下面主要介绍makefile编写的基本规则和命令使用。更多的makefile的使用会在后续加以讲述。

1.makefile基本规范

    一个典型的makefile文件包含目标文件、编译连接过程以及删除编译产生的目标文件和依赖文件。其基本的构成形式如下所示。

[目标文件…]:先决条件…

command

clean:

rm …

    其中,目标文件可以为生成的最终可执行程序、中间工程文件以及具体执行动作等。先决条件就是生成目标文件所需要依赖的文件。这些文件生成的规则在下面的command中实现。通常,只要先决条件中有一个文件比目标文件新的话,command命令就会被执行。这就是makefile的基本规则。为了能让初学者有一个清晰的认识,这里一个完整的实际例子如下所示。

testMain : a.o b.o testMain.o                        //目标文件为程序名testMain,它依赖a.o b.o testMain.o三个中间文件

g++ a.o b.o testMain.o -o testMain    //具体执行程序编译的命令

testMain.o :                                                      //目标文件为testMain.o中间文件命令执行

g++ -c testMain.cpp                              //具体程序编译成中间文件testMain.o的命令执行

a.o : a.h a.cpp                                                 //目标文件为a.o中间文件命令执行,依赖于a.h a.cpp文件

g++ -c a.cpp                                           //具体程序编译成中间文件a.o的命令执行

b.o : b.h b.cpp                                                 //目标文件为b.o中间文件命令执行,依赖于b.h b.cpp文件

g++ -c b.cpp                                           //具体程序编译成中间文件b.o的命令执行

clean :                                                               //清理程序目录动作

rm -f testMain core *.o                         //具体程序中清除文件的操作命令

    如上例子中,整个程序文件包含2个头文件,3个C++源文件。上述例子可以保存为makefile、Makefile或者任意可以命名的文件。用户可以通过make命令加-f选项来指定执行哪个makefile文件。

    根据上述实例配置的makefile在当前目录执行后的过程如下所示。

[developer @localhost ~]$ make

g++ -c a.cpp

g++ -c b.cpp

g++ -c testMain.cpp

g++ a.o b.o testMain.o -o testMain

[developer @localhost ~]$ make clean

rm -f testMain core *.o

[developer @localhost ~]$ make -f makefile

g++ -c a.cpp

g++ -c b.cpp

g++ -c testMain.cpp

g++ a.o b.o testMain.o -o testMain

    上述演示通过make命令执行实例make文件,默认情况下执行的文件名称为makefile,编译代码中间工程文件,最终完成可执行程序编译。也可以执行make的clean命令清除生成的工程文件和可执行程序文件,通过make的-f选项执行指定的名为“makefile”编译依赖关系定义文件,最终生成可执行程序。

    上述实例最终产生的一个目标文件为可执行程序testMain。它的生成依赖于a.o、b.o、testMain.o三个中间工程文件。随后下一行为其生成可执行程序的具体命令。

    这里需要注意执行具体命令的行,其开头一定要以Tab键开作为空格,这是makefile的规定。下面依次是目标文件、依赖文件和具体的执行命令。最后有一个clean,这里的clean并不是像前面的作为目标文件出现的,它是一个动作。当前shell下执行make

    clean命令时,执行其下面的具体清除目标文件的命令。

2.makefile中使用变量

    通常工程实践中,makefile文件会大量的使用变量定义。这也可能造成初学者学习makefile文件困难之处。大型的工程项目中,源文件、目标中间文件、库等应用非常的多。为了便于维护makefile文件,会使用变量来替换makefile中可能会发生变化的地方。例如,生成目标文件所依赖的中间工程文件就可以采用变量来灵活替换。下面通过一个具体的实例给初学者对makefile应用有一个初步的认识。该makefile编辑如下所示。

OBJECTS=a.o b.o testMain.o                      //定义变量为OBJECTS,表示a.o b.o testMain.o三个中间工程文件

CC=g++                                                           //定义变量为CC,表示使用g++编译器

testMain: $(OBJECTS)                                  //目标文件为可执行程序testMain,依赖于变量OBJECTS的生成

$(CC) $(OBJECTS) -o testMain         //生成可执行程序的命令,可以使用具体变量替换查看

testMain.o:                                                       //目标文件为中间文件testMain.o

$(CC) -c testMain.cpp                          //生成中间文件testMain.o的具体命令

a.o:a.h a.cpp                                                   //目标文件为中间文件a.o

$(CC) -c a.cpp                                       //生成中间文件a.o的具体命令

b.o:b.h b.cpp                                                   //目标文件为中间文件b.o

$(CC) -c b.cpp                                       //生成中间文件b.o的具体命令

clean:                                                                //清理程序目录动作

rm -f testMain core $(OBJECTS)       //具体程序中清除文件的操作命令

    从之前的例子中可以看出,中间生成的工程文件在makefile中被使用了两次。也就是说,一旦有新的object文件加入时,就只需要修改两处的先决条件。当前的makefile文件比较简单,所以这里添加显得不是很复杂。但是,一旦makefile文件比较复杂后,就容易造成修改地方的遗漏。那么,这种变量定义使用的方式使得删减或增加object文件只需要一处修改即可,这样makefile文件维护更加方便了。变量定义类似于C语言中宏的定义使用,变量基本定义形式很简单,取一个变量名之后,makefile文件中这样定义。

OBJECTS=example1.o example2.o …

    变量内容可以换行,其后加“\”符号即可。另外,编译器g++也可以采用变量来定义。在单个平台下开发通常只使用单一的C++编译器,但是Unix/Linux系统下C++编译器有多种。不同平台之间的程序移植带来的C++编译器置换,为makefile维护带来麻烦。大型的软件项目中可以将编译器的变量放在单一的文件中,根据检测系统的不同平台替换不同的C++编译器,为软件在不同平台的移植带来极大的方便。

3.一种更为简便的方式

    makefile文件还有一种更为简便的定义方式,那就是让make程序自动推导目标文件及依赖文件之后的命令。上例修改之后如下所示。

OBJECTS=a.o b.o testMain.o                      //定义变量为OBJECTS,表示a.o b.o testMain.o三个中间工程文件

CC=g++                                                            //定义变量为CC,表示使用g++编译器

testMain: $(OBJECTS)                                  //目标文件为可执行程序testMain,依赖于变量OBJECTS的生成

$(CC) $(OBJECTS) -o testMain         //生成可执行程序的命令,可以使用具体变量替换查看

a.o:a.h                                                             //目标文件为中间工程文件a.o,其生成依赖于头文件a.h

b.o:b.h                                                             //目标文件为中间工程文件b.o,其生成依赖于头文件b.h

clean:                                                                //清理程序目录动作

rm -f testMain core $(OBJECTS)                     //具体程序中清除文件的操作命令

    如上所示,目标文件为中间工程文件下具体执行命令就不需要了。只要列出中间工程文件文件以及其依赖的头文件,make可以自动的推导出需要执行的编译的命令。可见make工具的功能是相当的强大。

    make工具基本使用情况大致如上所述。这里只简单介绍基本makefile文件的组成及其使用情况,更多的实际项目使用会在后面的项目实践中详细讲述。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容