Skip to content

Latest commit

 

History

History
76 lines (59 loc) · 4.64 KB

exercise-2.md

File metadata and controls

76 lines (59 loc) · 4.64 KB

练习 2: 像Python脚本一样的Make命令


在Python中,你执行一个程序只需要输入Python和你想要执行的程序代码。Python解释器会运行它们,并且在执行过程中会导入一些其他的库和你需要的东西。C语言是完全不同的,你必须编译你的源代码,手动链接成一个可执行的二进制文件。手动做这些事情是痛苦的,在上一个练习中你仅仅是执行make命令就行了。

在本次练习中,你将得到一个GNU make的速成教程,学习使用make是你学习C语言的一部分。Make将会像你的Python脚本一样,成为本书的重要部分。它能够构建你的代码,运行测试,设置 一些东西,为你做所有的事情就像Python通常做得一样。

不同的是,我将会向你展示Makefile的魔力,它将解决你在C程序构建过程中很多烦杂愚蠢的琐事。在本次练习中不会涉及过些,在你掌握了make的一些基础之后,我会向你展示更多make的能力。

使用Make

使用make的第一阶段就是使用它构建程序。Make能够实现各种复杂的功能操作,构建各种各样的文件。在上次练习中你已经使用过如下命令:

$ make ex1
# 或者是下面这行命令
$ CFLAGS="-Wall" make ex1

第一行命令,你告诉make“我要创建一个名为ex1的文件”,Make会执行如下的操作:

  • 判断ex1文件是否存在?
  • 不存在,好,判断是否有一个文件以ex1开头?
  • 有,并且是ex1.c文件。我是否知道如何构建.c文件?
  • 知道,我会运行cc ex1.c -o ex1来构建他们。
  • 我将会使用cc命令把ex1.c编译成ex1

上面列出的第二个命令,用一种给make命令传递修饰参数的方式。如果你不熟悉Unix shell是如何工作的,你可以设置一个影响程序运行的“环境变量”。你可以使用命令 export CFLAGS="-Wall",你也可以把它们放到你的命令前去运行,并且这个环境变量只有在程序运行时才设置。

在这个例子当中,我使用这个命令CFLAGS="-Wall" make ex1,所以它给会cc命令添加一个参数-Wall。这个参数告诉cc编译器反馈所有警告信息(实际上是不可能打印出所有的警告信息)。

像上面那种方式使用make命令实际上是非常不优雅的,我们现在开始使用Makefile以至于你能更好理解make。首先,创建一个文件,输入以下内容:

CFLAGS=-Wall -g

clean:
   rm -f ex1

在当前目录保存文件,并命名为Makefile。Make会自动默认有一个叫Makefile的文件,只需在当前目录运行make命令。注意:确保你在些文件中只输入了TAB字符,不要混合TAB和空格。

Makefile文件定义了一些新的东西。首先在文件中我们设置了CFLAGS,所以我们不再需要一直设置此参数,同时添加了-g标识用来debug。然后我们有一个叫clean的部分,它告诉make如何去清理我们的小项目。

确保Makefileex1.c文件在同一个目录,然后运行如下命令:

$ make clean
$ make ex1

显示结果

如果以上运行正常,你会看到如下输出:

$ make clean
rm -f ex1
$ make ex1
cc -Wall -g    ex1.c   -o ex1
ex1.c: In function 'main':
ex1.c:3: warning: implicit declaration of function 'puts'

从这里我们可以看到,我们运行make clean它告诉make去执行我们的clean目标。再加去看Makefile文件,你会发现在clean缩进的地方,我放置了一条shell命令让make去执行。如果你有需要,你可以放很多命令在这个地方,所以它是一个非常强大的自动化工具。

同时注意到,即使我们在Makefile文件中没有提到ex1make仍然知道如何构建并使用我们的特殊设置。

如何突破

以上的内容作为开始已经足够了,但先让我们对Makefile文件作一些特殊的修改,你再看看会发生什么。在rm -f ex1这一行取消缩进你看看会发生什么。再运行make clean你会看到如下输出:

$make clean
Makefile:4: *** missing separator.  Stop.

请始终记得缩进,如果你看到类似这种奇怪的错误,一般情况请仔细检查你使用的制表符,因为一些make程序对这些是非常挑剔的。

补充内容

  • 创建一个all: ex1的目标,这样你构建ex1只需要执行make命令
  • 阅读man make的内容,你会学到一些如何运行它的知识
  • 阅读man cc的内容,找到-Wall-g相关的信息
  • 研究一些线上的Makefiles文件,看你是否能改善它
  • 在另一个项目叫找到Makefile文件,尝试去理解它在做什么