Fortran:包含已编译模块的 makefile
Fortran: makefile with already compiled modules
我有这样的项目结构
-Project
--Common
---types.f90
---global.f90
---common_routines.f90
--Program 1
---program1.f90
---module1.f90
---module2.f90
---etc...
--Program 2
--etc...
其中,Common 是包含一些在所有程序之间共享的模块的文件夹。我如何在我的 makefile 中包含这些模块?
我试过这个:
FC = gfortran
FCFLAGS = -fbounds-check -O3
FCFLAGS += -I ../Common
all: program1
program1: module1.o module2.o module3.o
program1.o: module1.o module2.o module3.o
module2.o: module1.o
module3.o: module2.o module1.o
%: %.o
$(FC) $(FCFLAGS) -o $@ $^
%.o: %.f90
$(FC) $(FCFLAGS) -c $<
clean:
rm -rf *.o *.mod
但是我收到一个未定义的通用模块变量引用错误。
GNU syntax to define additional include directory 是 -Idir
而不是 -I dir
(额外的 space)
还要确保公共模块已经 compiled 并且包括搜索路径指向您编译模块的目录,而不是源文件:
This path is also used to search for .mod files when previously compiled modules are required by a USE statement.
I tried FCFLAGS += -I../Common types.o global.o common_routines.o
这将不起作用,因为 -I
是 GNU Fortran 预处理器的一个选项
指定预处理器搜索要包含的文件的路径
编译 之前。您不能使用它来指定 object 文件 (*.o
) 的路径
会在编译后被linker搜索。没有任何意义
linker 并没有传递给 linker。
为简单起见,我们假设您需要 link 的目标文件
program1
只是 program1/program1.o
加上预先存在的 common/types.o
,
common/global.o
和 common/common_routines.o
然后下面的 Makefile
,放在目录 program1
中,将构建它:
OBJS = program1.o ../common/types.o ../common/global.o ../common/common_routines.o
.phony: all
all: program1
program1: program1.o
$(FC) -o $@ $(FCFLAGS) $(OBJS)
clean:
rm -f *.o program1
只需将所有需要的目标文件列出给 linker,在本例中是通过 $(OBJS)
您可能希望采取预防措施确保公共模块
在您构建 program1
之前是最新的,您现在可能认为您可以做到这一点
只需更换:
program1: program1.o
与:
program1: $(OBJS)
因此提示 make
重新编译 任何 四个目标文件
相对于相应源文件的日期,作为先决条件
建筑物 program1
make
肯定会努力做到这一点,但要小心。那样的话,就会
从 ../common/types.f90
重新编译,比如说 ../common/types.o
从 .f90
生成 .o
的隐式默认配方,因为此 makefile 是
没有告诉它做任何不同的事情。但这可能不是
../common/types.f90
是用来编译的,如果你在common
中也有一个makefile
规定了如何以某种非默认方式执行此操作。
在那种情况下,应该始终按照
common
中的生成文件。最好保留 program1
的先决条件,但将配方更改为:
program1: program1.o
$(MAKE) -C ../common
$(FC) -o $@ $(FCFLAGS) $(OBJS)
现在,任何时候 program1
需要重建,配方将抢先 运行 make
在 ../common
在它之前 link 是四个目标文件。 (这个 $(MAKE) -C ../common
有点不雅
即使它无事可做也会被调用:这可以通过更高级的 make
用法来避免)。
最后你可能还会发现需要(如果不是在这种情况下,那么在另一种情况下)来区分
传递给 预处理的标志之间 and/or 传递给 编译的标志 and/or 传递给 [=84 的标志=]年龄。
按照惯例,这些被分配给不同的 make
变量,例如FPPFLAGS
(预处理器),
FCFLAGS
(编译器),LDFLAGS
(linker)。
我有这样的项目结构
-Project
--Common
---types.f90
---global.f90
---common_routines.f90
--Program 1
---program1.f90
---module1.f90
---module2.f90
---etc...
--Program 2
--etc...
其中,Common 是包含一些在所有程序之间共享的模块的文件夹。我如何在我的 makefile 中包含这些模块?
我试过这个:
FC = gfortran
FCFLAGS = -fbounds-check -O3
FCFLAGS += -I ../Common
all: program1
program1: module1.o module2.o module3.o
program1.o: module1.o module2.o module3.o
module2.o: module1.o
module3.o: module2.o module1.o
%: %.o
$(FC) $(FCFLAGS) -o $@ $^
%.o: %.f90
$(FC) $(FCFLAGS) -c $<
clean:
rm -rf *.o *.mod
但是我收到一个未定义的通用模块变量引用错误。
GNU syntax to define additional include directory 是 -Idir
而不是 -I dir
(额外的 space)
还要确保公共模块已经 compiled 并且包括搜索路径指向您编译模块的目录,而不是源文件:
This path is also used to search for .mod files when previously compiled modules are required by a USE statement.
I tried FCFLAGS += -I../Common types.o global.o common_routines.o
这将不起作用,因为 -I
是 GNU Fortran 预处理器的一个选项
指定预处理器搜索要包含的文件的路径
编译 之前。您不能使用它来指定 object 文件 (*.o
) 的路径
会在编译后被linker搜索。没有任何意义
linker 并没有传递给 linker。
为简单起见,我们假设您需要 link 的目标文件
program1
只是 program1/program1.o
加上预先存在的 common/types.o
,
common/global.o
和 common/common_routines.o
然后下面的 Makefile
,放在目录 program1
中,将构建它:
OBJS = program1.o ../common/types.o ../common/global.o ../common/common_routines.o
.phony: all
all: program1
program1: program1.o
$(FC) -o $@ $(FCFLAGS) $(OBJS)
clean:
rm -f *.o program1
只需将所有需要的目标文件列出给 linker,在本例中是通过 $(OBJS)
您可能希望采取预防措施确保公共模块
在您构建 program1
之前是最新的,您现在可能认为您可以做到这一点
只需更换:
program1: program1.o
与:
program1: $(OBJS)
因此提示 make
重新编译 任何 四个目标文件
相对于相应源文件的日期,作为先决条件
建筑物 program1
make
肯定会努力做到这一点,但要小心。那样的话,就会
从 ../common/types.f90
重新编译,比如说 ../common/types.o
从 .f90
生成 .o
的隐式默认配方,因为此 makefile 是
没有告诉它做任何不同的事情。但这可能不是
../common/types.f90
是用来编译的,如果你在common
中也有一个makefile
规定了如何以某种非默认方式执行此操作。
在那种情况下,应该始终按照
common
中的生成文件。最好保留 program1
的先决条件,但将配方更改为:
program1: program1.o
$(MAKE) -C ../common
$(FC) -o $@ $(FCFLAGS) $(OBJS)
现在,任何时候 program1
需要重建,配方将抢先 运行 make
在 ../common
在它之前 link 是四个目标文件。 (这个 $(MAKE) -C ../common
有点不雅
即使它无事可做也会被调用:这可以通过更高级的 make
用法来避免)。
最后你可能还会发现需要(如果不是在这种情况下,那么在另一种情况下)来区分
传递给 预处理的标志之间 and/or 传递给 编译的标志 and/or 传递给 [=84 的标志=]年龄。
按照惯例,这些被分配给不同的 make
变量,例如FPPFLAGS
(预处理器),
FCFLAGS
(编译器),LDFLAGS
(linker)。