ICMAKE 第 1 部分

作者:Frank B. Brokken
简介

Icmake 最初是作为在 MS-DOS 下使用的 make 工具开发的。虽然 MS-DOS 下存在 make 实用程序,但由于以下两个主要原因,我们倾向于不使用这些实用程序

  1. 由于我们的主要语言是 C (C++),我们认为 make 实用程序的语法很笨拙。

  2. 在程序开发周期中,源代码被编译,包含在库中,然后链接到主目标模块,我们在设置文件之间正确的依赖关系时遇到了问题。

一旦 icmake 开发完成,很快就被移植到 UNIX,现在它不仅是我们首选的 make 实用程序。然而,到现在为止,它也成为我们发现编写 shell 脚本很容易的实用程序。

目前,icmake 已被移植到多个 UNIX 平台,例如 LINUX、SCO-UNIX、HP-UX 和 SunOS。因此,Icmake 几乎完美地反映了我们自己经历的从 DOS 到 UNIX 的过渡:最初在 MS-DOS 下开发,现在主要成为 UNIX 工具。但是,我们在 MS-DOS 下已经使用了“行业工具”:bison 和 flex 都用于构建 icmake 编译器 icm-comp。第一个版本的 icmake 在大约九天后可用,包括我们必须就其应采取的形式做出的决定。由于当时我们也在使用一些 UNIX 平台(SunOS 和 AIX),因此“移植守护程序”也开始影响我们的实现决策。icmake 的第一个 UNIX 操作系统端口仅用了几天时间,这些时间主要用于将一些特定的 MS-DOS 函数移植到可接受的 UNIX 形式。

在本文中,我们从用户的角度描述 icmake。本文的其余部分描述了软件的组织结构、icmake 文件的语法、icmake 脚本以及 - 首先 - 获取 icmake 的方法。最后,给出了一些 icmake 脚本的说明性示例。

2. 获取 Icmake

可以从站点 beatrix.icce.rug.nl 通过匿名 ftp 获取 Icmake,它位于目录 pub/unix 中。

该软件包由一个存档组成,通常为 icmake-X.XX.tar.gz 形式,其中 icmake 的当前版本由 X.XX 表示。此存档包含一个 tar 压缩和 gzip 压缩的目录结构,其中可以找到 icmake 的源文件(以及 MS-DOS 的可执行程序)。在 beatrix.icce.rug.nl 上也可以找到文件 icmake.doc,它是 icmake 安装指南。后一个文件对于 UNIX 安装尤其有用。

或者,也可以在 tsx-11.mit.edu 上找到 icmake,它是 Linux 操作系统发行版的一部分。在 tsx-11.mit.edu 上,icmake 文件通常位于 pub/linux/sources/usr.bin 中。

除了源代码发行版和安装指南外,beatrix.icce.rug.nl 还提供了一个 icmake.dvi 文件,其中对 icmake 的描述比本文中可能提供的更详细。此外,还提供了文档的 postscript 版本 (icmake.ps)。

软件的组织结构。

Icmake 由五个程序组成。其中一个程序是 nitor 程序,用于监视 icmake 文件的构建和执行。监视程序可以调用 icmake 预处理器、icmake 编译器和 icmake 执行器。第五个程序是 icmake 反汇编器,以人类可读的形式显示 icmake 编译器生成的代码。

这些程序可以分为两类:icmake 的普通用户必须知道的程序(顶层程序)和 icmake 内部调用的程序(嵌套层程序)。顶层程序是 icmake 监视程序和 icmake 反汇编器。通常,只有监视程序在命令行启动,但嵌套层程序有时会被显式调用。所有 icmake 程序都可以作为独立程序启动。

icmake 脚本的正常处理过程如下

  1. 编写 icmake 源代码脚本,其中包含要由 icmake 执行的任务的描述。此脚本非常类似于 C 语言。

  2. 启动监视器,接收包含 icmake 源代码脚本的文件名作为其参数。

  3. 监视程序可以调用 icmake 预处理器和 icmake 编译器,将源文件转换为二进制文件,以便 icmake 执行器处理。

  4. icmake 执行器由监视器启动。执行器读取编译后的 icmake 脚本,执行在编译后的脚本中找到的指令。

一旦 icmake 脚本被编译,监视程序将跳过编译和预处理阶段,并立即调用 icmake 执行器。通过这种方式,icmake 监视其自身在 icmake 源代码脚本和编译后的 icmake 脚本之间的依赖关系。

icmake 系列的每个程序都有一个版本号。版本号由主版本号和次版本号组成。例如,在版本号 6.03 中,主版本是 6,次版本是 03。只有当所有 icmake 程序的主版本号相等时,程序才能通信。因此,一组工作程序必须都具有相同的主版本号。次版本号用于指示各个程序中的小更改。

3.1. 顶层程序。

在 icmake 的顶层可以找到两个程序。icmake 本身和 icmun。“icmake”程序是监视程序,用于监视 icmake 脚本的执行。“icmun”程序是反汇编器,以人类可读的形式显示编译后的 icmake 脚本的内容。通常,不使用 icmun:它主要用作调试工具(尽管我们也使用 icmun 进行教学,向人们展示一些汇编语言编程的基本概念)。

Icmake

icmake 程序监视 icmake 脚本的执行,因此充当用户和嵌套层 icmake 程序之间的接口。通常,嵌套层 icmake 程序不是在命令行显式启动的,而是由 icmake 本身调用的。

ICCE Make 实用程序版本 6.00

可以使用以下两个命令行之一调用 Icmake

icmake [标志] asciifile [binaryfile] [arguments]

icmake [标志] -i asciifile [arguments]

这两种调用模式的区别在于,第一种调用(不带 i 标志)可以显式指定编译后的 icmake 文件的名称(“binaryfile”)。第二种模式为编译后的 icmake 文件使用预定义的名称。在这种形式中,使用 asciifile 的名称,扩展名为“.bim”。

对于这两种调用模式,“标志”、两个连续的连字符和参数都是可选的。参数传递给 makefile,可以在那里检查。标志用于请求 icmake 的特定操作。asciifile 的规范在两种调用中都是强制性的:此文件是 make 脚本,由 icmake 解释并定义要执行的操作。

当从 icmake 系列启动程序时,如果没有任何参数,则会显示帮助摘要。

当在没有任何参数的情况下激活 icmake 时,帮助信息会显示 icmake 识别的标志等内容。在这种情况下,屏幕上将出现如下表所示的内容

以下标志被识别

-b。当使用此标志时,不执行最新性测试。相反,二进制 make 文件按原样立即执行。当此标志不存在时,如果输入文件更新,icmake 会将输入文件(.im 文件)编译为二进制文件(.bim 文件)。

-c。当使用此标志时,ascii 输入文件被编译为二进制 makefile,但不执行。编译的发生与输入文件和二进制文件的最新性无关。

-i 文件。此选项指定文件作为 icmake 的输入文件,并停止对参数的进一步处理。在这种情况下,二进制 makefile(.bim 文件)的名称等于输入文件的名称,并接收扩展名 .bim。当给出此标志时,icmake 不提供默认输入文件扩展名 .im:指定的名称按字面意思采用。

-p。当使用此选项时,仅激活 icmake 预处理器。预处理器的输出被发送到与输入文件同名的文件,但扩展名为 .pim。当此标志不存在时,icmake 的预处理器仍然生成 .pim 文件。但是,此文件在编译阶段后被删除。

-q。当使用此选项时,icmake 静默运行。即,不显示版权横幅。

--。默认情况下,命令行上的第一个非标志参数是输入文件,假定扩展名为 .im。当给出第二个非标志参数时,则此名称用于二进制文件(.bim 文件)。只有当遇到两个连续的连字符时,参数的处理才会停止。所有跟随 — 标志的参数都可以由 icmake 文件检查。

请注意,当使用 -i 标志激活 icmake 时,不需要 — 标志。

asciifile 规范是强制性的。这是 icmake 源文件,将由 icmake 编译和测试。Icmake 假定默认扩展名 .im。例如,命令行

icmake test 将激活 icmake 以处理 icmake 源文件 test.im。但请注意,命令行

icmake -i test 将启动 icmake 以处理 makefile test。-i 标志的存在阻止 icmake 提供扩展名。

binaryfile 规范是可选的。如果给出,icmake 将此文件用作制作过程中的二进制中间文件。扩展名 .bim 是默认值。默认情况下,icmake 使用 asciifile 的基本名称和扩展名 .bim

在 binaryfile 规范之后,可以给出 makefile 本身的几个参数。但是,在指定任何额外参数之前,需要两个连续的连字符。在这些连字符之后,可以跟随将传递给 icmake 相关程序的额外参数。如上所述,当使用 -i 标志时,分隔符两个连字符不是必需的。

icmake 规范文件是作为 C 程序编写的,并且包含一个 main() 函数,该函数接收在命令行上指定的一些参数。第一个参数始终是二进制 make 文件的名称(通常具有 .bim 扩展名)。剩余参数是跟随两个连字符的参数。连字符本身不包含在传递给 main() 的参数系列中(用户定义的函数 main() 在下面描述)。

Icmun

Icmun 主要用于开发 icmake。icmun 程序是为 icmake 创建的编译后的 icmake 文件而设计的反汇编器。Icmun 生成编译后的 makefile 中包含的指令的类似汇编的列表。通常几乎从未使用过它。有关 icmun 的更多信息超出了本文的范围,但可以在 icmake 文档中找到,例如,可以从 beatrix.icce.rug.nl 获取。

嵌套层程序。

以下程序是 icmake 的“嵌套层”程序。通常,这些程序不是在命令行启动的,而是作为 icmake 本身的子进程或覆盖进程启动的。

预处理器 icm-pp。

Icm-pp 是 icmake 编译器的预处理器(在下一节中描述)。此程序扫描 icmake 源文件中的预处理器指令(例如,#include,请参阅下面关于预处理器指令的部分)。并在遇到它们时采取适当的措施。Icm-pp 写入一个输出文件,其中预处理器指令已被“扩展”。此(临时)文件随后由 icmake 编译器使用。

编译器 icm-comp。

预处理之后的阶段是编译。icmake 编译器称为 icm-comp,此程序将 icmake 源代码文件(由 icm-pp 生成)转换为二进制格式并执行错误检查。生成的二进制文件包含操作码,很像编程语言编译器的输出文件。生成二进制 makefile 后,不再需要预处理器的中间输出文件,并将其删除。

执行器 icm-exec。

Icm-exec 是由 icm-comp 生成的二进制 makefile 的执行器。在此阶段,读取编译后的 icmake 文件。它包含被解释的操作码,从而执行在 icmake 源文件中定义的命令:构建文件列表,按日期比较文件,以及可能采取的其他操作。

Linux (Unix) 下的可执行 makefile

在 Linux (UNIX) 操作系统下,可以为 icmake 创建 makefile,这些 makefile 本身是可执行的。例如,这可能会导致设置中存在 icmakefile “backup”,可以简单地启动为

backup

在这种设置中,可以通过创建 icmakefile backup.im 来实现相同的效果,然后使用命令启动它

icmake backup

前一种形式肯定更易于使用,并且需要一个名为“backup”的可执行 icmake 脚本。要创建可执行 makefile,应采取以下步骤

  1. makefile 可以给定一个合适的名称。此名称稍后用于调用执行 makefile 的进程。因此,名称 backup 可能比 backup.im 更受欢迎。

  2. makefile 使用 UNIX chmod 程序使其可执行:chmod +x backup

    这会将文件 backup 标记为可执行程序。此外,makefile 可以放置在 PATH 环境变量指向的目录中。例如,makefile 可以放置在用户的私有 bin 目录中。

  3. 以下行作为 icmake 源文件中的第一行添加

    #!/usr/local/bin/icmake -qi
    

此行通知操作系统,当执行此文件时,应启动程序 /usr/local/bin/icmake,使用标志 -qi,然后附加 icmake 文件的名称。如前所述,标志 -q 抑制 icmake 的版权横幅,而标志 -i 使 icmake 将以下文件参数作为文字输入文件,而不是提供默认扩展名 .im

请注意,此行必须包含对程序 icmake 的完整引用,包括路径。在此示例中,此路径被视为 /usr/local/bin

编译后的 icmake 文件 (.bim 文件) 由 icmake 放置在与 icmake 源相同的目录中。因此,此目录必须可供调用 makefile 的用户访问。如果 icmake 脚本和关联的 .bim 文件要系统范围内可访问,则 root 可以安装 icmake 脚本。再次使用备份脚本的示例,root 可以在存储“backup”脚本的目录中使用以下命令安装“backup”脚本

icmake -c backup

这将仅导致“backup”的编译,从而生成 backup.bim

Frank B. Brokken, ICCE, 格罗宁根大学教育系。荷兰格罗宁根。

K. Kubat, ICCE, 格罗宁根大学教育系。荷兰格罗宁根。

加载 Disqus 评论