Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran:已编译模块的makefile_Makefile_Fortran_Gfortran - Fatal编程技术网

Fortran:已编译模块的makefile

Fortran:已编译模块的makefile,makefile,fortran,gfortran,Makefile,Fortran,Gfortran,我有一个这样的项目结构 -Project --Common ---types.f90 ---global.f90 ---common_routines.f90 --Program 1 ---program1.f90 ---module1.f90 ---module2.f90 ---etc... --Program 2 --etc... 其中,Common是一个文件夹,其中包含一些在所有程序中共享的模块。如何在makefile中包含这些模

我有一个这样的项目结构

-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
FC=gfortran
FCFLAGS=-fbounds检查-O3
FCFLAGS+=-I../Common
所有:方案1
程序1:模1.o模2.o模3.o
程序1.o:模1.o模2.o模3.o
模2.o:模1.o
模3.o:模2.o模1.o
%:%
$(FC)$(FCFLAGS)-o$@$^
%.o:%.f90
$(FC)$(FCFLAGS)-c$<
清洁:
rm-rf*.o*.mod
但是我得到了一个公共模块变量的未定义引用错误。

-Idir
不是
-I dir
(额外空间)

另外,请确保公共模块已经存在,并且包含指向已编译模块的目录(而不是源文件)的搜索路径点:

当USE语句需要以前编译的模块时,此路径还用于搜索.mod文件

我尝试了FCFLAGS+=-I../Common-types.o global.o Common_-routines.o

这将不起作用,因为
-I
是GNU Fortran预处理器的一个选项 指定预处理器搜索要包含的文件的路径 在汇编之前。您不能使用它来指定对象文件的路径(
*.o
) 将在编译后由链接器搜索。这对我来说毫无意义 链接器,而不会传递给链接器

为了简单起见,我们假设需要链接的对象文件
program1
只是
program1/program1.o
加上预先存在的
common/types.o
common/global.o
common/common\u例程.o

然后,放置在目录
program1
中的以下
Makefile
将构建它:

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
只需通过
$(OBJS)

您可能希望采取预防措施,确保公共模块 在您构建
程序1
之前是最新的,您现在可能认为您可以做到这一点 只需更换:

program1: program1.o
与:

从而提示
make
重新编译四个输出的目标文件中的任何一个 相对于相应源文件的日期,作为 建筑
program1

make
肯定会努力做到这一点,但要小心。那样的话,它会 重新编译,比如说,
。/common/types.o
来自
。/common/types.f90
,只需按其 从
.f90
生成
.o
的隐式默认配方,因为此生成文件是 不告诉它做任何不同的事情。但这可能不是
。/common/types.f90
是要编译的,如果您在
common
这就规定了如何以某种非默认的方式进行操作

在这种情况下,公共对象文件应始终按照 在
common
中生成文件。最好不要使用
program1
的先决条件,但将配方更改为:

program1: program1.o
    $(MAKE) -C ../common
    $(FC) -o $@ $(FCFLAGS) $(OBJS)
现在,任何时候需要重建
program1
,配方都将在
中抢先运行
make
。/common
在链接四个对象文件之前。(这个
$(MAKE)-C../common
将被调用,即使它不需要执行任何操作:这可以通过更高级的
make
usage)来避免

最后,您可能还需要(如果不是在这种情况下,那么是在另一种情况下)进行区分 在传递给预处理的标志和/或传递给编译的标志和/或传递给链接的标志之间。 通常,这些变量被分配给不同的
make
变量,例如
FPPFLAGS
(预处理器),
FCFLAGS
(编译器),
LDFLAGS
(链接器)。

这是链接时的“未定义引用”吗(您似乎没有链接到与模块对应的任何对象文件)?更准确地说:您应该更改
%:%.o
,以包含公共模块。我该怎么做?我尝试了
FCFLAGS+=-I../Common-types.o global.o Common\u routines.o
,但现在我没有创建目标类型的规则。o需要模块1.o.Stop。
program1: program1.o
    $(MAKE) -C ../common
    $(FC) -o $@ $(FCFLAGS) $(OBJS)