Как эффективно написать сборочный файл GNU с несколькими модулями с произвольным числом зависимостей в Fortran - PullRequest
0 голосов
/ 05 ноября 2018

Мой make-файл сейчас выглядит так:

#Source file locations
VPATH = :../AHMCodePara

#Compiler
CC = mpifort

#Debugging Flags
#Flags =

#Regular flags
Flags = -Ofast -mkl=sequential

# File name labels
FF =
DE =
Const =
OBJDIR = OBJ

# make object directory
$(OBJDIR):
        -mkdir $(OBJDIR)
CC += -module $(OBJDIR)

#Object File List
Inputs =
Tools = $(OBJDIR)/$(Const)Inputs.o
Diag$(DE) = $(Tools)
PreAnalysis = $(Tools) $(OBJDIR)/Tools.o
DOSsetupPara$(DE) = $(PreAnalysis) $(OBJDIR)/PreAnalysis.o $(OBJDIR)/Diag$(DE).o
$(Const)AHMRGv3 = $(Tools) $(OBJDIR)/Diag$(DE).o $(OBJDIR)/DOSsetupPARA$(DE).o

#Object File List
obj = $(OBJDIR)/$(Const)Inputs.o $(OBJDIR)/Diag$(DE).o $(OBJDIR)/Tools.o \
$(OBJDIR)/PreAnalysis.o $(OBJDIR)/DOSsetupPARA$(DE).o $(OBJDIR)/$(Const)AHMRGv3.o

# dependence files
$(OBJDIR)/%.o: %.f90 $(%)
#       @$(%)
        @-rm -f #<~
        $(CC) -c $< -o $@ $(Flags)

All: V3.e

# Target
V3.e: $(obj)
        $(CC) $(Flags) -o $@ $^

clean:
        rm $(OBJDIR)/*.o $(OBJDIR)/*.mod

Раньше был похож на этот:

LOC = ../../AHMCode/
CC = gfortran
#Debugging
#Flags = -O0 -g -fcheck=all -Wall -llapack
#Normal
Flags = -O3 -I/usr/lib/ -L/usr/lib/ -lblas -llapack
FF = _Old
IG = #IGNORE or nothing
TT = #TYPE or nothing
V3$(FF).e: Inputs.o Tools.o PreAnalysis.o DOSsetup$(IG).o Diag$(TT).o AHMRGv3_Manyruns.o
        $(CC) $(Flags) AHMRGv3_Manyruns.o Diag$(TT).o DOSsetup$(IG).o PreAnalysis.o Tools.o Inputs.o -o V3$(FF).e

Inputs.o: Inputs.f90
        $(CC) $(Flags) -c Inputs.f90

Tools.o: $(LOC)Tools.f90 Inputs.o
        $(CC) $(Flags) -c $(LOC)Tools.f90

PreAnalysis.o: $(LOC)PreAnalysis.f90 Inputs.o Tools.o
        $(CC) $(Flags) -c $(LOC)PreAnalysis.f90

DOSsetup$(IG).o: $(LOC)DOSsetup$(IG).f90 Inputs.o Tools.o PreAnalysis.o Diag$(TT).o
        $(CC) $(Flags) -c $(LOC)DOSsetup$(IG).f90

Diag$(TT).o: $(LOC)Diag$(TT).f90 Inputs.o
        $(CC) $(Flags) -c $(LOC)Diag$(TT).f90

AHMRGv3_Manyruns.o: AHMRGv3_ManyRuns.f90 DOSsetup$(IG).o Diag$(TT).o Inputs.o
        $(CC) $(Flags) -c AHMRGv3_Manyruns.f90

clean:
        rm *.o *.mod

Раздел, который я хочу сравнить в этих файлах make, - это определения файла .o. Во втором make-файле я выписал все это вручную, и он отлично работал. Мое намерение со вторым make-файлом было сделать то же самое, но более эффективно.

Проблемы возникли с зависимостями. Когда я изначально вносил изменения в мой make-файл, я вообще не помещал никаких зависимостей. Это привело к проблемам, когда я обновлял Inputs, а соответствующие файлы не перекомпилировались (например, Tools.o). Это, как и ожидалось, поэтому я искал способы творческого и эффективного добавления зависимостей, чтобы заставить соответствующие файлы перекомпилироваться.

Как видите, я пытался создать переменные с тем же именем, что и .f90 и .o, чтобы использовать $(%). Это выглядело немного дерзко (и я действительно не думал, что это сработает), но, к сожалению, не решило мою проблему.

Как видно из исходного файла сборки, зависимости не следуют какой-либо схеме. Также вы можете видеть, что я компилирую Фортран, и я почти уверен, что -gen-dep ничего не делает, и если он делает, я делаю это неправильно.

Существующие вопросы по этому вопросу оказались очень бесполезными, поскольку большинство использует C ++, и здесь они могут сильно отличаться.

РЕДАКТИРОВАТЬ: Я "исправил" мою проблему. Он не самый эффективный и не генерирует зависимости автоматически, но мне нравится, что в нем не так много повторяющихся строк.

#Object File List
oInpt =
oTool = $(OBJDIR)/$(Const)Inputs.o
oPreA = $(oTool) $(OBJDIR)/Tools.o
oDOSs = $(oPreA) $(OBJDIR)/PreAnalysis.o $(OBJDIR)/Diag$(DE).o
oDiag = $(oTool)
oMain = $(oTool) $(OBJDIR)/Diag$(DE).o $(OBJDIR)/DOSsetupPARA$(DE).o
obj = $(OBJDIR)/$(Const)Inputs.o $(OBJDIR)/Tools.o $(OBJDIR)/PreAnalysis.o $(OBJDIR)/Diag$(DE).o \
$(OBJDIR)/DOSsetupPARA$(DE).o $(OBJDIR)/$(Const)AHMRGv3.o


# dependence files
$(OBJDIR)/$(Const)Inputs.o: $(oInpt)
$(OBJDIR)/Tools.o: $(oTool)
$(OBJDIR)/PreAnalysis.o: $(oPreA)
$(OBJDIR)/Diag$(DE).o: $(oDiag)
$(OBJDIR)/DOSsetupPARA$(DE).o: $(oDOSs)
$(OBJDIR)/$(Const)AHMRGv3.o: $(oMain)
$(OBJDIR)/%.o: %.f90
        @-rm -f #<~
        $(CC) -c $< -o $@ $(Flags)

All: V3.e
# Target
V3.e: $(obj)
        $(CC) $(Flags) -o $@ $^

Я только что создал несколько правил для каждой цели. Одно правило по умолчанию, которое фактически компилирует файлы .o, а другое - спецификацию зависимостей для каждого .f90 файла.

...