Sun Studio 12:Fortran 编程指南

3.1 使用 make 实用程序简化程序构建

make 实用程序使用智能化方法执行程序编译和链接任务。通常,大型应用程序由一组源文件和 INCLUDE 文件组成,需要与许多库进行链接。修改任何一个或多个源文件,都需要对那一部分程序进行重新编译,并且要重新链接。指定组成应用程序的各文件间的相互依赖性以及重新编译和重新链接每一程序块所需的命令,可以自动执行这一过程。指令文件中有了这些说明,make 便会确保只重新编译那些需要重新编译的文件,并确保重新链接时使用生成可执行文件所需要的那些选项和库。以下讨论内容提供了一个如何使用 make 的简单示例。有关摘要信息,请参见 make(1S)。

3.1.1 Makefile

名为 makefile 的文件以结构化方式告知 make,哪些源文件和目标文件依赖其他文件。它还定义了编译和链接文件所需的命令。

例如,假设您的程序有四个源文件以及相应的 makefile 文件:


demo% ls
makefile
commonblock
computepts.f
pattern.f
startupcore.f
demo%

假设 pattern.f 和 computepts.f 都有一个名为 commonblock 的 INCLUDE,并且您希望编译每个 .f 文件并将这三个可重定位的文件与一系列库一起链接成一个名为 pattern 的程序。

这时,makefile 将会如下所示:


demo% cat makefile
pattern: pattern.o computepts.o startupcore.o
      f95 pattern.o computepts.o startupcore.o -lcore95 \
      -lcore -lsunwindow -lpixrect -o pattern
pattern.o: pattern.f commonblock
      f95 -c -u pattern.f
computepts.o: computepts.f commonblock
      f95 -c -u computepts.f
startupcore.o: startupcore.f
      f95 -c -u startupcore.f
demo%

makefile 的第一行表明 pattern 的创建取决于 pattern.o、computepts.o 和 startupcore.o。下一行及其后续各行给出了由可重定位的 .o 文件和库创建 pattern 的命令。

makefile 中的每一条目都是一项规则,它描述了目标对象的依赖性以及创建该对象所需的命令。规则的结构为:

target: dependencies-listTAB build-commands

3.1.2 make 命令

make 命令可以进行无参数调用,只需键入:


demo% make

make 实用程序在当前目录中查找名为 makefile 或 Makefile 的文件并从该文件中获取指令。

make 实用程序:

3.1.3 宏

make 实用程序的宏功能允许进行简单的无参数字符串替换。例如,可将组成目标程序 pattern 的可重定位文件的列表表示为单个宏字符串,使其更易于更改。

宏字符串定义具有以下格式:

NAME = string

宏字符串的使用方式如下所示:

$(NAME)

make 会用宏字符串的实际值来替换它。

以下示例将命名所有目标文件的宏定义添加到 makefile 的开头:


OBJ = pattern.o computepts.o startupcore.o

现在便可在依赖性列表以及与 makefile 中的目标 pattern 相应的 f95 链接命令中同时使用宏了。


pattern: $(OBJ)
      f95 $(OBJ) -lcore95 -lcore -lsunwindow \
      -lpixrect -o pattern

对于名称为单个字母的宏字符串,可以省略括号。

3.1.4 覆盖宏值

make 宏的初始值可以用 make 的命令行选项进行覆盖。例如:


FFLAGS=–u
OBJ = pattern.o computepts.o startupcore.o
pattern: $(OBJ)
      f95 $(FFLAGS) $(OBJ) -lcore95 -lcore -lsunwindow \
      -lpixrect -o pattern
pattern.o: pattern.f commonblock
      f95 $(FFLAGS) -c pattern.f
computepts.o:
      f95 $(FFLAGS) -c computepts.f

现在,简单的无参数 make 命令将会使用上面设置的 FFLAGS 值。不过,这可以通过命令行来覆盖:


demo% make "FFLAGS=–u -O"

这里,make 命令行中的 FFLAGS 宏定义会覆盖 makefile 的初始值,并且会将 -O 标志和 -u 标志一起传递给 f95。请注意,也可以在命令中使用 "FFLAGS=",将宏重置为空字符串使其不再有效。

3.1.5 make 中的后缀规则

为使 makefile 更易编写,make 将根据目标文件的后缀,使用自身的缺省规则。

缺省规则在文件 /usr/share/lib/make/make.rules 中。在识别缺省的后缀规则时,make 会将 FFLAGS 宏指定的任何标志、-c 标志以及要编译的源文件名都作为参数进行传递。此外,make.rules 文件还使用 FC 宏赋予的名称作为要使用的 Fortran 编译器的名称。

以下示例两次说明了这一规则:


FC = f95
OBJ = pattern.o computepts.o startupcore.o
FFLAGS=–u
pattern: $(OBJ)
      f95 $(OBJ) -lcore95 -lcore -lsunwindow \
      -lpixrect -o pattern
pattern.o: pattern.f commonblock
      f95 $(FFLAGS) -c pattern.f
computepts.o: computepts.f commonblock
startupcore.o: startupcore.f

make 使用缺省规则编译 computepts.f 和 startupcore.f。

.f90 文件存在缺省的后缀规则,这些规则将会调用 f95 编译器。

然而,除非将 FC 宏定义为 f95,否则 .f 和 .F 文件的缺省后缀规则会调用 f77 而非 f95。

而且,当前没有为 .f95 和 .F95 文件定义后缀规则,.mod Fortran 95 模块文件将会调用 Modula 编译器。要对此进行补救,需要在调用 make 的目录下为 make.rules 文件创建您自己的本地副本,同时对该文件进行修改,添加 .f95 和 .F95 后缀规则,删除 .mod 的后缀规则。有关详细信息,请参见 make(1S) 手册页。

3.1.6 .KEEP_STATE 与特殊依赖性检查

使用特殊目标 .KEEP_STATE 检查命令的依赖性及隐藏依赖性。

当 .KEEP_STATE: 目标有效时,make 会根据状态文件检查用于生成目标的命令。如果自上次 make 运行以来命令已更改,make 会重新生成此目标。

当 .KEEP_STATE: 目标有效时,make 将从 cpp(1) 以及其他编译处理器中读取任何“隐藏”文件(例如 #include 文件)的相应报告。如果目标相对于这些文件中的任何文件已过期,make 会重新生成它。