如何在Linux中进行C语言多文件编译

今天写C语言的时候,我突然遇到需要做一个项目.以前没有接触过,通过简单的了解,Windows下可以通过IDE来进行共同编译 vs就是很好的选择.
而我们今天讨论的重点是如何在Linux中进行多文件编译,一般简单的项目会有三个文件 (xxx.c ,xxx.c,xxx.h)其中一个执行程序主要功能,一个描述抽象数据类型的函数,一个进行函数原型的声明,在Linux下,大家都是手动达人,我们在编译的时候是需要把怎么编译都写出来,比如编译顺序,那个文件和那个文件进行链接,那些文件在什么情况下需要重新编译等等,或者一些更加复杂的操作,用来写这些具体操作的文件就是这个项目的makefile.
而且,我们在写好了一个makefile之后就可以自动编译了,只需用一个make命令就行.而且更加建议先学了makefile之后用IDE,因为学习了mmakefile之后你就对其中怎样把编程语言变成可执行程序有了更加深刻的理解,基础更加扎实.好了,接下来我们就来一起看看怎么写Makefile,
我是以c语言作为源码,编译器是Ubuntu 下默认的gcc.

首先我们来聊聊有关程序的编译和链接 无论是 C、 C++、还是 pas,首先要把源文件编译成中间代码文件,在 Windows 下也就是 .obj 文件,UNIX 下是 .o 文件,即 Object File,这个动作叫做编译( compile)。然后再把大量的 Object File合成执行文件,这个动作叫做链接( link),windows下大部分的IDE都将这两个动作结合成一个并且集合到一个快捷键上,这样对初学者友好但是对于深刻理解缺有点缺陷。
Makefile就是一个怎样编译多文件的脚本,我们写好之后在终端下输入make 这个命令就可以开始编译了.

target ... : prerequisites ... command ... ...
形如这样的就是一个Makefile,其中 target 也就是一个目标文件,可以是 Object File,也可以是执行文件。还可以是一个标签( Label)。prerequisites 就是,要生成那个 target 所需要的文件或是目标。command 也就是 make 需要执行的命令。(任意的 Shell 命令)
这 是 一 个 文 件 的 依 赖 关 系 , 也 就 是 说 , target 这 一 个 或 多 个 的 目 标 文 件 依 赖 于prerequisites 中 的 文 件 , 其 生 成 规 则 定 义 在 command 中 。 说 白 一 点 就 是 说 ,prerequisites 中如果有一个以上的文件比 target 文件要新的话, command 所定义的命令就会被执行。这就是 Makefile 的规则。
好了,我说完了,Makefile的核心内容就是这样了,

Image.png

这就是一个实例,其中film 就是编译之后要生成的文件,它依赖的就是后面的film4.c ,list.c和list.h这三个文件.
make 的具体工作方式是这样,当你在默认界面或者是终端中输入了make命令之后,

make 会在当前目录下找名字叫“ Makefile”或“ makefile”的文件
如果找到,它会找文件中的第一个目标文件( target),在上面的例子中,他会找到“ film”这个文件,并把这个文件作为最终的目标文件。
如果 film 文件不存在,或是 film 所依赖的后面的文件的文件修改时间要比film这个文件新,那么,他就会执行后面所定义的命令来生成 film这个文件。

好了,这样就通过编译器生成了film 这个文件.
Makefile中还可以使用变量,让我们看这样一个例子,

edit : main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o cc -o edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o

我们可以看到[.o]文件的字符串被重复了两次,如果我们的工程需要加入一个新的[.o]文
件,那么我们需要在两个地方加,但如果 makefile 变得复杂,那么我们就有可能会忘掉一个需要加入的地方,而导致编译失败所以,为了 makefile 的易维护,在 makefile 中我们可以使用变量。 makefile 的变量也就是一个字符串,理解成 C语言中的宏可能会更好。比如,我们声明一个变量,叫 objects, OBJECTS, objs, OBJS, obj, 或是 OBJ,反
正不管什么啦,只要能够表示 obj 文件就行了。我们在 makefile 一开始就这样定义:

objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o

于是,我们就可以很方便地在我们的 makefile 中以“ $(objects)”的方式来使用这个变
量了,于是我们的改良版 makefile 就变成下面这个样子:

objects = main.o kbd.o command.o display.o \ insert.o search.o files.o utils.o edit : $(objects) cc -o edit $(objects) main.o : main.c defs.h cc -c main.c kbd.o : kbd.c defs.h command.h cc -c kbd.c command.o : command.c defs.h command.h cc -c command.c display.o : display.c defs.h buffer.h cc -c display.c insert.o : insert.c defs.h buffer.h cc -c insert.c search.o : search.c defs.h buffer.h cc -c search.c files.o : files.c defs.h buffer.h command.h cc -c files.c utils.o : utils.c defs.h cc -c utils.c clean : rm edit $(objects)

如果有新的.o文件加入,我们只用在开始的变量声明中修改就可以了.
最后我告诉大家一下Makefile的书写规则
它的语法就是下面这个样子

targets : prerequisites command ...
或是这样:
targets : prerequisites ; command command ...

targets 是文件名,以空格分开,可以使用通配符。一般来说,我们的目标基本上是一个文件,但也有可能是多个文件。command 是命令行,如果其不与“ target:prerequisites”在一行,那么,必须以[Tab键]开头,如果和 prerequisites 在一行,那么可以用分号做为分隔。(见上)prerequisites 也就是目标所依赖的文件(或依赖目标)。如果其中的某个文件要比目标文件要新,那么,目标就被认为是“过时的”,被认为是需要重生成的。这个在前面已经讲过了。如果命令太长,你可以使用反斜框(‘ \’)作为换行符。 make 对一行上有多少个字符没有限制。规则告诉 make 两件事,文件的依赖关系和如何成成目标文件。
一般来说, make 会以 UNIX 的标准 Shell,也就是/bin/sh 来执行命令。
好了,简单的Makefile的就到这,看过这个之后大家就学会在linux下进行件简单的工程的编译,如果想要对于Makefile进行系统的学习可以去参考一下相关的书籍.

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

推荐阅读更多精彩内容