我想为两个编译器制作一个makefile。我喜欢英特尔在其oneAPI中的例子,见下文。基本上,在每个目标规则下,它都有明确的编译规则。但我的makefile就像:
# compile old fortran files
$(BLD)/%.o: $(SRC)/%.for
$(FC) -c $(FFLAGS) -o $@ $<
# compile new fortran files
$(BLD)/%.o: $(SRC)/%.f90
$(FC) -c $(FFLAGS) -o $@ $<
# link everything
$(target): $(objects)
$(FC) -o $@ $(FFLAGS) -I $(BLD) $^ $(LDFLAGS)我看到一种方法是将$(FC)变量加上标志更改为目标中的适当值。英特尔的优势在于,它可以非常具体地改变额外的开关,所以如果对于gfortran,我有一行$(FC) -o $@ $(FFLAGS) -I $(BLD) $^ $(LDFLAGS),如果我需要它看起来像ifort的$(FC) -o $@ $(FFLAGS) -J $(BLD) $^ $(LDFLAGS),那么有什么方法可以在另一个规则中制定规则,比如:
GFORT_EXE = $(target).gfort
IFORT_EXE = $(target).ifort
#
gfort: $(GFORT_EXE)
ifort: $(IFORT_EXE)
$(GFORT_EXE):
$(BLD)/%.o: $(SRC)/%.for
$(FC) -c $(FFLAGS) -o $@ $<
# compile new fortran files
$(BLD)/%.o: $(SRC)/%.f90
$(FC) -c $(FFLAGS) -o $@ $<
# link everything
$(FC) -o $@ $(FFLAGS) -I $(BLD) $^ $(LDFLAGS)或者,如果我需要命令行在每个编译器的原则上看起来不同,那么什么才是最好的方法呢?
英特尔makefile
# Copyright Intel Corporation 2014
#
# To compile with the GNU* C/C++ compiler, creating an execution file with the
# extension ".gcc" for binary instrumentation, issue:
#
# > make
#
# To compile with the Intel(R) C++ Compiler for Linux*, creating an execution
# file with the extension ".icc":
#
# Source <path_to_compiler_bin>/compilervars.sh or iccvars.csh;
#
# > make icc
#
# To compile with the Intel(R) C++ Compiler for Linux* with Intel(R) MKL library
# creating an executionfile with the extension ".mkl":
#
# Source <path_to_compiler_bin>/compilervars.sh or iccvars.csh;
#
# > make mkl
#
# To compile with the Intel(R) C++ Compiler for Linux to cross compile for the
# Intel(R) Xeon Phi(TM) coprocessor, creating an execution file with the
# extension ".mic":
#
# Source <path_to_compiler_bin>/compilervars.sh intel64
#
# > make mic
#
# To compile them all, use the source line from the Intel MIC architecture
# option above, then type:
#
# > make all
SHELL = /bin/sh
PARAMODEL = -DUSE_THR # Default parallelism using pthreads/Win threads
#PARAMODEL = -DUSE_OMP -fopenmp # Use OpenMP for multithreading
GCC = gcc
ICC = icc
CFLAGS = -g -O3 -fno-asm
OPTFLAGS = -xSSE3
# OPTFLAGS = -xHost -fno-alias
# add -DALIGNED to the multiply.c and matrix.c
LDFLAGS = -lpthread -lm
GCFLAGS = $(CFLAGS) $(PARAMODEL)
ICFLAGS = $(CFLAGS) $(PARAMODEL)-DICC -debug inline-debug-info #-vec-report3 -qopt-report -qopt-report-phase=vec
MKFLAGS = $(CFLAGS) -DUSE_MKL -DICC -mkl -debug inline-debug-info
GCC_EXE = matrix.gcc
ICC_EXE = matrix.icc
MKL_EXE = matrix.mkl
srcdir = ../src
gcc: $(GCC_EXE)
icc: $(ICC_EXE)
mkl: $(MKL_EXE)
all: $(GCC_EXE) $(ICC_EXE) $(MKL_EXE)
OBJS = util.o thrmodel.o multiply.o matrix.o
matrix.gcc: $(srcdir)/matrix.c $(srcdir)/multiply.c $(srcdir)/multiply.h $(srcdir)/util.c $(srcdir)/thrmodel.c
$(GCC) $(GCFLAGS) -c $(srcdir)/util.c -D_LINUX
$(GCC) $(GCFLAGS) -c $(srcdir)/thrmodel.c -D_LINUX
$(GCC) $(GCFLAGS) -c $(srcdir)/multiply.c -D_LINUX
$(GCC) $(GCFLAGS) -c $(srcdir)/matrix.c -D_LINUX
$(GCC) $(GCFLAGS) -g $(OBJS) -o ../matrix $(LDFLAGS)
matrix.icc: $(srcdir)/matrix.c $(srcdir)/multiply.c $(srcdir)/multiply.h $(srcdir)/util.c $(srcdir)/thrmodel.c
$(ICC) $(ICFLAGS) -c $(srcdir)/util.c -D_LINUX
$(ICC) $(ICFLAGS) -c $(srcdir)/thrmodel.c -D_LINUX
$(ICC) $(ICFLAGS) $(OPTFLAGS) -c $(srcdir)/multiply.c -D_LINUX
$(ICC) $(ICFLAGS) $(OPTFLAGS) -c $(srcdir)/matrix.c -D_LINUX
$(ICC) $(ICFLAGS) $(OBJS) -o ../matrix $(LDFLAGS)
matrix.mkl: $(srcdir)/matrix.c $(srcdir)/multiply.c $(srcdir)/multiply.h $(srcdir)/util.c $(srcdir)/thrmodel.c
$(ICC) $(MKFLAGS) -c $(srcdir)/util.c -D_LINUX
$(ICC) $(MKFLAGS) -c $(srcdir)/thrmodel.c -D_LINUX
$(ICC) $(MKFLAGS) $(OPTFLAGS) -c $(srcdir)/multiply.c -D_LINUX
$(ICC) $(MKFLAGS) $(OPTFLAGS) -c $(srcdir)/matrix.c -D_LINUX
$(ICC) $(MKFLAGS) $(OBJS) -o ../matrix $(LDFLAGS)
clean:
@rm -rf $(OBJS) $(GCC_EXE) $(ICC_EXE) $(MKL_EXE)
# * Other names and brands may be claimed as the property of others.发布于 2022-04-21 20:04:33
不,您不能在规则中重新定义规则(坦率地说,您可能不想这样做,因为这种方法有很多尖锐的地方,您肯定会被绊倒)。对于这种情况,我建议您执行两个单独的输出目录,并具有基于输出目录的规则,如下所示:
objects := ...
FC_gfort := ...
FC_ifort := ...
$(BLD)/gfort/%.o: $(SRC)/%.for
$(FC_gfort) -c $(FFLAGS) -o $@ $<
$(BLD)/gfort/%.o: $(SRC)/%.f90
$(FC_gfort) -c $(FFLAGS) -o $@ $<
$(BLD)/ifort/%.o: $(SRC)/%.for
$(FC_ifort) -c $(FFLAGS) -o $@ $<
$(BLD)/ifort/%.o: $(SRC)/%.f90
$(FC_gfort) -c $(FFLAGS) -o $@ $<
# link everything
$(target).gfort: $(BLD)/gfort/$(objects)
$(FC_gfort) -o $@ $(FFLAGS) -J $(BLD)/gfort $^ $(LDFLAGS)
$(target).ifort: $(BLD)/ifort/$(objects)
$(FC_ifort) -o $@ $(FFLAGS) -I $(BLD)/ifort $^ $(LDFLAGS)现在,如果您有很多规则,并且重复使用,那么您可以使用一个定义和eval,这样就可以了:
LINK_FLAG_gfort:=-J
LINK_FLAG_ifort:=-I
define RULES_template =
$$(BLD)/$(1)/%.o: $$(SRC)/%.for
$$(FC_$(1)) -c $$(FFLAGS) -o $$@ $$<
$$(BLD)/$(1)/%.o: $$(SRC)/%.f90
$$(FC_$(1)) -c $$(FFLAGS) -o $$@ $$<
$$(target).$(1): $$(BLD)/$(1)/$$(objects)
$$(FC_$(1)) -o $$@ $$(FFLAGS) $$(LINK_FLAG_$(1)) $$(BLD)/$(1) $^ $$(LDFLAGS)
endef
$(eval $(call RULES_template,ifort))
$(eval $(call RULES_template,gfort))注意双$$在这里(但不是在$(1)前面.)
另外,我还提到了尖棒和你最初的想法,你推翻了规则--比如你建造了ifort,然后做了一个随后的gfort构建,中间没有干净。不会重建.o文件,因为时间戳将比源文件更新,但是链接器将运行并使用过时的工件。
希望这能有所帮助
https://stackoverflow.com/questions/71959057
复制相似问题