返回介绍

第 4 节 Makefile 使用

发布于 2025-02-25 23:29:36 字数 3915 浏览 0 评论 0 收藏 0

一、实验说明

1. 课程说明

在先前的课程中,我们已经学习了 gcc 和 gdb 的使用。本节课程中,我们将介绍 Makefile 的使用。Makefile 带来的好处就是——“自动化编译”,一但写好,只需要一个 make 命令,整个工程便可以完全编译,极大的提高了软件的开发效率(特别是对于那些项目较大、文件较多的工程)。

2. 如果首次使用 Linux,建议首先学习:

  1. Linux 基础入门
  2. Vim 编辑器

3. 环境介绍

本实验环境采用带桌面的 Ubuntu Linux 环境,实验中会用到桌面上的程序: 1.命令行终端: Linux 命令行终端,打开后会进入 Bash 环境,可以使用 Linux 命令

2.Firefox 及 Opera:浏览器,可以用在需要前端界面的课程里,只需要打开环境里写的 HTML/JS 页面即可

3.gvim:非常好用的 Vim 编辑器,最简单的用法可以参考课程 Vim 编辑器

4.gedit 及 Brackets:如果您对 gvim 的使用不熟悉,可以用这两个作为代码编辑器,其中 Brackets 非常适用于前端代码开发

二、Makefile 简介

读者经常看到一个 C 程序的项目常常由很多的文件组成,那么,多文件的好处到底在哪里呢?一个最简单也最直接有力的理由就是,这样可以将一个大项目分成多个小的部分,独立开来,利于结构化管理。在修改和维护的时候,优势就更明显了。例如,需要对代码做一点小的改动,如果这个项目所有的代码都在一个文件中,那么就要重新编译所有这些代码,这是很耗时的,不仅效率低,而且维护难度更大。但是,如果是多个不同的文件,那么只需要重新编译这些修改过的文件就行了,而且其他源文件的目标文件都已经存在,没有必要重复编译,这样就会快捷很多。

因此,通过合理有效的划分,将一个项目分解为多个易于处理的文件,是非常明智的做法。多文件的管理方式非常正确的选择。

一个工程中的源文件不计其数,按其类型、功能、模块分别放在若干个目录中。makefile 定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至进行更复杂的功能操作(因为 makefile 就像一个 shell 脚本一样,可以执行操作系统的命令)。

makefile 带来的好处就是——“自动化编译”,一但写好,只需要一个 make 命令,整个工程完全编译,极大的提高了软件的开发效率。make 是一个命令工具,是一个及时 makefile 中命令的工具程序。

make 工具最主要也是最基本的功能就是根据 makefile 文件中描述的源程序至今的相互关系来完成自动编译、维护多个源文件工程。而 makefile 文件需要按某种语法进行编写,文件中需要说明如何编译各个源文件并链接生成可执行文件,要求定义源文件之间的依赖关系。

二、Makefile 基本规则

下面从一个简单实例入手,介绍如何编写 Makefile。假设现在有一个简单的项目由几个文件组成:prog.c、 code.c、 code.h。这些文件的内容如下:

prog.c

#include <stdio.h>
#include "code.h"

int main(void)
{
  int i = 1;    
  printf ("myfun(i) = %d\n", myfun(i));
}

code.c

#include "code.h"

int myfun(int in)
{
  return in + 1;
}

code.h

extern int myfun(int);

这些程序都比较短,结构也很清晰,因此使用下面的命令进行编译:

$ gcc -c code.c -o code.o
$ gcc -c prog.c -o prog.o
$ gcc prog.o code.o -o test

如上所示,这样就能生成可执行文件test,由于程序比较简单,而且数量也比较少,因此看不出来有多麻烦。但是,试想如果不只上面的 3 个文件,而是几十个或者是成百上千个甚至更多,那将是非常复杂的问题。

那么如何是好呢?这里就是 makefile 的绝佳舞台,下面是一个简单的 makefile 的例子。

首先 $ vim Makefile

test: prog.o code.o
    gcc prog.o code.o -o test
prog.o: prog.c code.h
    gcc -c prog.c -o prog.o
code.o: code.c code.h
    gcc -c code.c -o code.o
clean:
    rm -f *.o test

有了这个 Makefile,不论什么时候修改源文件,只要执行一下 make 命令,所有必要的重新编译将自动执行。make 程序利用 Makefile 中的数据,生成并遍历以 test 为根节点的树;现在我们以上面的实例,来学习一下 Makefile 的一般写法:

test(目标文件): prog.o code.o(依赖文件列表)
tab(至少一个 tab 的位置) gcc prog.o code.o -o test(命令)
.......

一个 Makefile 文件主要含有一系列的规则,每条规则包含一下内容:一个目标,即 make 最终需要创建的文件,如可执行文件和目标文件;目标也可以是要执行的动作,如‘clean’;一个或多个依赖文件的列表,通常是编译目标文件所需要的其他文件。之后的一系列命令,是 make 执行的动作,通常是把指定的相关文件编译成目标文件的编译命令,每个命令占一行,并以 tab 开头(初学者务必注意:是 tab,而不是空格) 执行以上 Makefile 后就会自动化编译:

$ make
gcc -c prog.c -o prog.o
gcc -c code.c -o code.o
gcc prog.o code.o -o test

最后就会多产生: porg.o code.o test 这三个文件,执行 ./test 查看结果

还记得 Makefile 中的 clean 吗? make clean 就会去执行 rm -f *.o test 这条命令,完成 clean 操作。

四、使用带宏的 Makefile

Makefile 还可以定义和使用宏(也称做变量),从而使其更加自动化,更加灵活,在 Makefile 中定义宏的格式为:

macroname = macrotext

使用宏的格式为:

$(macroname)

五、作业思考

用 “宏” 的方式,来改写上面的 Makefile 例子。

参考答案:

OBJS = prog.o code.o
CC = gcc
test: $(BOJS)
    $(CC) $(OBJS) -o test
prog.o: prog.c code.h
    $(CC) -c prog.c -o prog.o
code.o: code.c code.h
    $(CC) -c code.c -o code.o
clean:
    rm -f *.o test

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文