GNU make 支持内置函数和自定义函数。函数调用看起来很像变量引用,但是包含用一个或多个用逗号分隔的参数。大多数内置函数扩展为某个值,然后将该值赋给变量或传递给子 shell。自定义的函数存储在变量或宏中,并期望调用者传递一个或多个参数。 自定义函数 将命令序列存储在变量中为广泛的应用打开了大门。例如,这里有一个用来终止进程的宏: 你可能会问:“为什么要在 makefile 中做这个?”,好吧,在 Windows 上,打开一个文件会锁定它,防止其他进程写入。在我写这本书的时候,PDF 文件经常会被 A
我们知道 makefile 变量已经有一段时间了,我们看到了许多在内置规则和用户定义规则中使用它们的例子。但我们看到的例子只是触及了表面。变量和宏会变得更加复杂,并赋予 GNU make 强大的功能。 在我们继续之前,重要的是要理解 make 是两种语言的结合体。第一种语言描述由目标和依赖组成的依赖关系图。(这门语言在第二章中介绍过) 第二语言是执行文本替换的宏语言。您可能熟悉的其他语言的宏,例如,C 预处理器、m4、TEX 和 宏汇编器。与其他宏语言一样,make 允许您为更长的字符序列定义一个简写术语,
make 工具是一个有吸引力的仆人,总是在那里与人方便。像许多小说和电影中必不可少的助手一样,make 一开始总是被低估的,你给它扔了一些奇怪的工作,然后它将慢慢地接管整个企业。 当我的主管、最初 O’Reilly 经典《Make 项目管理》的作者 史蒂夫·塔尔伯特(Steve Talbott)注意到我的痴迷并要求我写第二版时。我已经达到了将 make 置于每个我接触项目的中心的不可救药的阶段。对我来说,这是一次关键的成长经历(也是一次疯狂的旅行),也是我进入 O’Reilly 奇妙世界的关键,但是我们并没
编程技巧通常遵循及其简单的流程,编辑源文件、编译源文件到可执行的形式,然后调试编译结果。尽管将源程序转换到可执行程序是常规操作,但是如果操作不当,程序员可能会浪费大量的时间来跟踪问题。大多开发者都经历过修改功能和运行新代码的挫败感,仅仅是发现刚才的改动无法解决某个bug。然后他们发现由于某些流程错误,例如重编译源码失败,链接失败,或重构建 jar 包失败,程序并没有执行他们修改的功能,此外,随着程序复杂度的增加这些简单的任务可能会随着开发不同版本的程序而变得越来越容易出错。也可能其他平台或者其他版本的库等。
在上一章中,我们编写了一些规则来编译和链接我们的单词计数程序。这些规则中的每一个都定义一个目标,即要更新的文件。每个目标文件都依赖于一组文件。当要求更新目标时,如果任何依赖文件比目标修改时间最近,make 将执行规则的命令脚本。由于一个规则的目标可以作为另一条规则的依赖来引用,因此目标和依赖的集合形成了依赖关系链或图。构建并处理此依赖关系图以更新需要的目标是 make 的全部目的。 由于规则在 make 中是如此重要,因此存在许多不同种类的规则。与上一章中的规则一样,显式规则指出了要更新的特定目标,如果该目
什么样的项目才配称为大项目?对我而言,可能需要一个团队的开发者,可能需要在多种体系结构上运行,也可能有多种领域需要维护。当然,不是所有的大项目都满足以上所有要求。单一平台百万行代码级别的 C++ 的预发布版本同样也是大项目。但是软件不会永远停留在预发布版本。如果它是成功的,那么终将有人想让它运行在其他的平台。所以一段时间之后,大多数大型软件系统都十分相似。 大型软件系统通常通过将系统拆分多个主要的组件来简化复杂性。一般包括程序、库,或者二者皆有。这些组件通常保存在它们自己的目录中而且通过它们自己的 make