我有一个像这样的项目结构
-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
但是我得到了常见模块变量的未定义引用错误。
答案 0 :(得分:1)
我试过FCFLAGS + = -I ../ Common types.o global.o common_routines.o
这不起作用,因为-I
是GNU Fortran预处理器的一个选项
指定预处理器应搜索要包含的文件的路径
在编译之前。您无法使用它来指定 object 文件(*.o
)的路径
将在编译后由链接器搜索。它没意义
链接器并没有传递给链接器。
为简单起见,我们假设您需要链接的目标文件
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
只需将所有必需的目标文件列入链接器,在本例中为$(OBJS)
您可能希望采取预防措施以确保通用模块
在构建program1
之前是最新的,你现在可能认为你可以做到这一点
只是替换:
program1: program1.o
使用:
program1: $(OBJS)
因此提示make
重新编译出现的四个目标文件中的任何
作为先决条件的日期相对于相应的源文件
建立program1
make
肯定会努力做到这一点,但要小心。这样,它会
例如,../common/types.o
从../common/types.f90
重新编译,仅仅通过它
从.o
创建.f90
的隐式默认配方,因为此makefile是。{
不要告诉它做任何不同的事情。但这可能不是那种方式
如果你在../common/types.f90
中有一个makefile,那么common
是要编译的。
它规定了如何以某种非默认方式进行。
在这种情况下,应始终按照常规对象文件进行编译
common
中的makefile。最好只留下program1
的先决条件,但将配方更改为:
program1: program1.o
$(MAKE) -C ../common
$(FC) -o $@ $(FCFLAGS) $(OBJS)
现在,只要需要重建program1
,配方就会在make
中抢先运行../common
在它链接四个目标文件之前。 ($(MAKE) -C ../common
这是一个小小的优雅
即使没有任何内容可以调用,也会被调用:更高级的make
用法可以避免这种情况。
最后,您可能还会发现需要(如果不是在这种情况下,则在另一个情况下)进行区分
传递给预处理的标志之间和/或传递给编译的标志和/或传递给链接的标志。
通常,这些被分配给不同的make
变量,例如, FPPFLAGS
(预处理器),
FCFLAGS
(编译器),LDFLAGS
(链接器)。
答案 1 :(得分:0)
GNU syntax to define additional include directory为-Idir
而非-I dir
(额外空格)
还要确保公共模块已经compiled并包含指向已编译模块的目录的搜索路径点,而不是源文件:
此路径还用于在USE语句需要以前编译的模块时搜索.mod文件。