
我正在嘗試從 Fortran 原始程式碼建立兩個不同的庫,一個支援 OMP,另一個不支援。因此,來自同一來源的 %.o 檔案會根據編譯器標誌的不同而有所不同。當更改/重新編譯一個原始檔時,ar 仍然需要所有 o 檔案來重建函式庫。為了避免重新編譯所有原始文件,我想將未更改的原始檔案中的 o 文件儲存在兩個不同的目錄中,一個目錄包含 omp 支援的 o 文件,另一個目錄不包含 omp 支援。我很高興必須在庫最終所在的目錄中產生文件。
但是,由於 vpath 變數行為,我無法在單一命令中重建庫。這是製作文件:
SRC :=
FORTRAN = ifort
OPTSSEQ = -mkl=sequential -DThreadUnSafe -warn nounused -warn declarations -O3 -DTIMEDETAIL
DRVOPTS = $(OPTS)
NOOPT =
LOADER = ifort
LOADOPTS =
kernel=$(shell uname -r)
ARCH = ar
ARCHFLAGS= cr
RANLIB = ranlib
LibName=Lib_LM_$(FORTRAN)_$(kernel)_1.0.a
.SUFFIXES:
.SUFFIXES: .f90 .o
include Moduls.mk
vpath %.f90 src/
vpath %.o NoOMP/
OBJS = $(patsubst %.f90,%.o,$(SRC))
$(LibName): $(OBJS)
$(ARCH) $(ARCHFLAGS) $@ $?
$(RANLIB) $@
%.o : %.f90
$(FORTRAN) $(OPTSSEQ) -c $? -o $(addprefix NoOMP/,$@)
clean:
-rm *.mod
-rm NoOMP/*.o
-rm *.smod
-rm $(LibName)
這會導致在“make clean”後成功構建所有 %.o 文件,因為所有 %.f90 文件均從 src/ 讀取,並且所有 %.o 文件均寫入 NoOMP/。但是,建置存檔失敗,因為 %.o 檔案上的“NoOMP”前綴被刪除。因此,ar 抱怨它找不到 %.o 檔案。只有當我再次運行“make”時,才會建立存檔,因為 %.o 檔案具有 NoOMP 前綴。如果從頭開始構建,則將前綴命令新增至存檔建置行可以正常運作。但是,如果只有一個檔案發生了更改,則未更改的檔案具有“NoOMP/NoOMP/”前綴,從而導致再次中止。
雖然這非常煩人,但據我了解,這是 GNU make 的預設行為的手冊。如果我錯了,我該如何修復makefile,如果我是對的,我該如何規避這個問題。
答案1
解決了
這些範例在更改線路時有效
$(ARCH) $(ARCHFLAGS) $@ $?
到
$(ARCH) $(ARCHFLAGS) $@ $(addprefix NoOMP/,$?)
上面我已經排除了這個解決方案,但我的試驗是基於$^
而不是$?
。雖然第一個將從舊的和新的 %.o 檔案重建整個存檔,但最後一個只會使用新的 %.o 檔案更新現有檔案。當從舊的和新的 %.o 檔案重建整個檔案時,舊的 %.o 檔案將具有錯誤的前綴,新的則正確。因此,透過使用新編譯的 %.o 檔案更新檔案來排除舊的 %.o 檔案可以避免該問題。
乾杯