调试makefile
大多数UNIX®和Linux®程序都是通过运行make
构建的。 make实用程序读取包含指令并执行各种操作以构建程序的文件(通常称为“ makefile”或“ Makefile”,但以下仅称为“ makefile”)。 在许多构建过程中,makefile本身完全由其他软件生成。 例如, autoconf/automake
程序用于开发构建例程。 其他程序可能会要求您直接编辑一个makefile,当然,新的开发可能需要您编写一个。
短语“ make实用程序”具有误导性。 至少有三种常用的不同变体:GNU make,System V make和Berkeley make。 每一个都来自UNIX早期的核心规范,并且每个都增加了新功能。 这导致了一个困难的局面:相当常用的功能(例如通过引用将其他文件包含在makefile中)无法移植! 一个简单的决定就是编写一个程序来创建makefile文件是一个解决方案。 由于GNU make是免费的并且分布广泛,因此一些开发人员只需为其编写代码; 同样,一些源自BSD的项目要求您使用Berkeley make(这也是免费的)。
smake
席林( smake
的smake
较不常见,但仍很相关,该家族的第五个缺席成员是历史品牌,它定义了其他所有成员共享的共同特征子集。 尽管smake不是任何系统上的默认make,但它是一个好的make实现,并且某些程序(尤其是Schilling的程序)优先使用它。
让我们回顾一下使用Makefile时会遇到的一些最常见的问题。
了解makefile
要调试make,您必须能够读取makefile。 如您所知,makefile的目的是提供有关构建程序的说明。 make的主要功能之一是依赖管理 :尝试仅在程序更新时重新构建它。 通常,这通过一系列依赖性规则来表达。 依赖关系规则如下所示:
清单1.依赖性规则的形式
target: dependencies
instructions
人们在编写第一个makefile时遇到的主要问题在此构造中可见; 更确切地说,是看不见的。 缩进是一个制表符。 它没有任何数量的空格。 对于使用这种格式的空格的文件,伯克利制作错误消息的帮助不大:
清单2. Berkeley make错误消息
make: "Makefile" line 2: Need an operator
make: Fatal errors encountered -- cannot continue
GNU make虽然仍然无法处理文件,但给出了更有用的建议:
清单3. GNU make错误消息
Makefile::2: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.
注意,依赖和指令都是可选的; 仅需要目标和冒号。 所以,这就是语法。 语义是什么? 语义是,如果希望构建target
,它将首先查看依赖项。 实际上,它将递归地尝试构建它们。 如果依存关系又具有依存关系,则在继续执行此规则之前将对其进行处理。 如果target
存在并且至少与dependencies
项中