Makefile 对同一对象中的不同源文件使用不同的编译器或编译器标志

Makefile 对同一对象中的不同源文件使用不同的编译器或编译器标志,makefile,fortran,gfortran,compiler-flags,Makefile,Fortran,Gfortran,Compiler Flags,我是makefiles的新手,目前正在运行代码附带的以下代码,并通过选项FFLAGS_EXT1、COMP_EXT1、以及file1.F90和file2.F90进行扩展: FC = gfortran FFLAGS = -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ FFLAGS_EXT1 = -g -fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbound

我是makefiles的新手,目前正在运行代码附带的以下代码,并通过选项
FFLAGS_EXT1
COMP_EXT1
、以及
file1.F90
file2.F90
进行扩展:

FC = gfortran
FFLAGS = -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
FFLAGS_EXT1 = -g -fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5 -Dno_nans -I ../ # Stricter compiler flags
LDFLAGS =
OBJ_EXT = o
EXE_EXT = x
COMP = $(FC) $(FFLAGS) -c -o $@ $<
COMP_EXT1 = $(FC) $(FFLAGS_EXT1) -c -o $@ $<
LINK = $(FC) $(LDFLAGS) -o $@ $^

MAIN_MODULES = $(a list of file names without extensions)
OUR_MODULES = $(another list of file names without extensions)

# FORTRAN settings
.SUFFIXES: .F90 .$(OBJ_EXT)

# compilation rules
.F90.$(OBJ_EXT):
#   $(COMP)
    $(COMP_EXT1)

.PHONY: all
all: \
    program1.$(EXE_EXT) program2.$(EXE_EXT) ...

program1.$(EXE_EXT): \
    $(addsuffix .$(OBJ_EXT),$(MAIN_MODULES)) \
    $(addsuffix .$(OBJ_EXT),$(OUR_MODULES)) \
    file1.$(OBJ_EXT) \
    file2.$(OBJ_EXT)
    $(LINK)

...
然而,一旦有许多规则和文件,这似乎相当麻烦。简单地使用像
$(COMP_EXT1)
这样的东西是不起作用的,因为它失败了,出现了一个无输入文件错误


有没有办法缩短这个结构?

嗯,无论如何,这是一个风格问题。但让我们尝试一下:

# prefer simple variables over recursive ones...
FC := gfortran
FFLAGS := -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
FFLAGS_EXTRA := -fbacktrace -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5

# ...unless we *do* require deferred expansion
COMP = $(FC) $(FFLAGS) $(FFLAGS_$@) -c -o $@ $<
LINK = $(FC) $(LDFLAGS) -o $@ $^

# this is a matter of choice but one-letter variables could be handy
O := o
X := x

# I assume both file1 and file2 are already mentioned here
MAIN_MODULES := $(a list of file names without extensions)
OUR_MODULES := $(another list of file names without extensions)

# use computed variables for maximum flexibility
FFLAGS_file1.$O := $(FFLAGS_EXTRA)
FFLAGS_file2.$O := $(FFLAGS_EXTRA)

.PHONY: all
all: program1.$X program2.$X ...

program1.$X: $(addsuffix .$O,$(MAIN_MODULES) $(OUR_MODULES))
    $(LINK)
program2.$X: ...
    $(LINK)

# it is recommended to use pattern rules instead of suffix rules
%.$O: %.F90
    $(COMP)

...
#更喜欢简单变量而不是递归变量。。。
FC:=gfortran
FFLAGS:=-g-ffpe陷阱=零,无效,溢出,下溢-Dno_nans-I/
FFLAGS_EXTRA:=-fbacktrace-fbounds check-fcheck=all-Wconversion-std=gnu-O3-fmax errors=5
#…除非我们*确实*需要延期扩展
COMP=$(FC)$(FFLAGS)$(FFLAGS_$@)-c-o$@$<
LINK=$(FC)$(LDFLAGS)-o$@$^
#这是一个选择的问题,但一个字母的变量可能很方便
O:=O
X:=X
#我假设这里已经提到了file1和file2
主模块:=$(不带扩展名的文件名列表)
我们的_模块:=$(另一个不带扩展名的文件名列表)
#使用计算变量以获得最大的灵活性
FFLAGS_文件1.$O:=$(FFLAGS_额外)
FFLAGS_文件2.$O:=$(FFLAGS_额外)
冒牌货:全部
全部:程序1.$X程序2.$X。。。
程序1.$X:$(添加后缀$O,$(主模块)$(我们的模块))
$(链接)
程序2.$X:。。。
$(链接)
#建议使用模式规则而不是后缀规则
%.$O:%.F90
元(比较)
...

也许你想走另一条路,也就是说,使用它是一个库,用于在GNUmake中编程很多东西。它提供了一个表数据结构,用于像您这样的构建配置任务:

include gmtt-master/gmtt.mk

FC = gfortran
FFLAGS = -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
LDFLAGS =
OBJ_EXT = o
EXE_EXT = x
COMP = $(FC) $(FFLAGS) -c -o $@ $<
LINK = $(FC) $(LDFLAGS) -o $@ $^

MAIN_MODULES = $(a list of file names without extensions)
OUR_MODULES = $(another list of file names without extensions)

# FORTRAN settings
.SUFFIXES: .F90 .$(OBJ_EXT)

# Construct a gmtt table. The one caveat is that we must escape the space characters in the
# second column until we select entries from the table.
define COMPILE_FLAGS_TBL
2
file1.$(OBJ_EXT) $(call spc-mask,-fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5)
file2.$(OBJ_EXT) $(call spc-mask,-fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5)
endef

# Special flags: "select column 2 from COMPILE_FLAGS_TBL where first column is string-equal to the target"
# ...and recover the space characters afterwards:
FFLAGS_SPECIAL =  $(call spc-unmask,$(call select,2,$(COMPILE_FLAGS_TBL),$$(call str-eq,$$1,$@)))

# compilation rules
.PHONY: all
all: foo.o bar.o file1.o file2.o

%.F90:
    touch $@

%.o: %.F90
    @echo flags: $(FFLAGS) $(FFLAGS_SPECIAL)
通过使用globs,您可以更灵活地选择文件:

include gmtt-master/gmtt-master/gmtt.mk

FFLAGS = -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
OBJ_EXT = o

# Construct a gmtt table. The one caveat is that we must escape the space characters in the
# second column until we select entries from the table.
define COMPILE_FLAGS_TBL
2
file1.$(OBJ_EXT) $(call spc-mask,-fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5)
file2.$(OBJ_EXT) $(call spc-mask,-fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5)
endef

define PATTERN_FLAGS_TBL
2
*_frobozz_[7-9].$(OBJ_EXT)  $(call spc-mask,-ffrobozz)
X_frabazz_*.$(OBJ_EXT)      $(call spc-mask,-ffrabazz -dwhatever)
endef


# Special flags: "select column 2 from COMPILE_FLAGS_TBL where first column is string-equal to the target"
# ...and recover the space characters afterwards:
FFLAGS_SPECIAL =  $(call spc-unmask,$(call select,2,$(COMPILE_FLAGS_TBL),$$(call str-eq,$$1,$@)))

# Very special flags: "select column 2 from PATTERN_FLAGS_TBL where target matches glob in first column"
# ...and recover the space characters afterwards
FFLAGS_VERY_SPECIAL = $(call spc-unmask,$(call select,2,$(PATTERN_FLAGS_TBL),$$(call glob-match,$@,$$1)))

# compilation rules
.PHONY: all
all: foo.o bar.o file1.o file2.o A_frobozz_8.o A_frobozz_6.o X_frabazz_mike.o X_frabazz_mandy.o

%.F90:
    @touch $@

%.o: %.F90
    @echo $@ flags: $(FFLAGS) $(FFLAGS_SPECIAL) $(FFLAGS_VERY_SPECIAL)
输出:

$ make
touch foo.F90
flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
touch bar.F90
flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
touch file1.F90
flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5
touch file2.F90
flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5
rm bar.F90 file1.F90 foo.F90 file2.F90
$ make
foo.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
bar.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
file1.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5
file2.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5
A_frobozz_8.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -ffrobozz
A_frobozz_6.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
X_frabazz_mike.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -ffrabazz -dwhatever
X_frabazz_mandy.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -ffrabazz -dwhatever
rm X_frabazz_mandy.F90 A_frobozz_8.F90 bar.F90 file1.F90 foo.F90 A_frobozz_6.F90 file2.F90 X_frabazz_mike.F90

读和读。还有,谢谢你,马特。我想出了上面的修改,但我还是不太满意。你还有什么进一步的提示吗?非常感谢你的回答。但是,我遇到了以下问题:如果我在
我们的\u模块之后定义
我们的\u文件:=file1 file2
,然后定义
FFLAGS\u我们的\u文件。$O:=$(FFLAGS\u EXTRA)
FFLAGS\u文件1.$O:=$(FFLAGS\u EXTRA)
,和
FFLAGS\u文件2.$O:=$(FFLAGS\u EXTRA)
,然后定义
file1
file2
没有使用附加标志进行编译。@gothicVI我猜不出你做错了什么。检查编译规则和COMP变量。仅供参考,链接规则与编译标志无关。我是个白痴……我写了
$(FFLAGS\u EXTRA)
,而不是
$(FFLAGS\u EXT)
。它现在正在工作。非常感谢!谢谢你的回答。但是,这对于这个项目来说太深入了。但是我以后会记住它。@gothicVI我以“曾经有很多规则和文件”作为推广gmtt的借口;)
$ make
foo.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
bar.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
file1.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5
file2.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -fbacktrace -ffpe-trap=zero,invalid,overflow,underflow -fbounds-check -fcheck=all -Wconversion -std=gnu -O3 -fmax-errors=5
A_frobozz_8.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -ffrobozz
A_frobozz_6.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../
X_frabazz_mike.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -ffrabazz -dwhatever
X_frabazz_mandy.o flags: -g -ffpe-trap=zero,invalid,overflow,underflow -Dno_nans -I ../ -ffrabazz -dwhatever
rm X_frabazz_mandy.F90 A_frobozz_8.F90 bar.F90 file1.F90 foo.F90 A_frobozz_6.F90 file2.F90 X_frabazz_mike.F90