[英]Fortran Makefile - Circular dependency dropped and m2c
以下是工作作品; 它是較復雜版本的簡化版本,但是當我嘗試進行一些更改時,它可以重現問題。 文件“ myobj.f”和“ mymod.f”分別位於文件夾“ src1”和“ src2”中,並且幾乎為空(mymod是聲明了變量的模塊,而myobj是初始化並打印該變量的子例程)。
我為此嘗試了谷歌搜索,但是我發現的所有循環依賴錯誤似乎都比這更清楚。 您能否幫助我確定我的Makefile出了什么問題?
all : mylib.so
makefiles := Makefile
FC = gfortran
FFLAGS = -I$(obj_path) -J$(obj_path) -fPIC
LFLAGS = -shared -fPIC
obj_path := obj
src_paths = src1 src2
vpath %.o $(obj_path)
vpath %.mod $(obj_path)
vpath %.f $(src_paths)
objects = myobj.o mymod.o
obj/myobj.o : obj/mymod.mod
mylib.so : $(objects:%.o=$(obj_path)/%.o)
$(FC) $(LFLAGS) $^ $(LIBS) -o $@
$(obj_path)/%.mod : %.o
@touch $@
$(obj_path)/%.o : %.f $(makefiles) | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $@
$(obj_path) :
mkdir -p $@
.PHONY: clean
clean:
rm -rf mylib.so $(obj_path)
在編譯對象的規則中明確包含“ $(obj_path)”似乎是不必要的:我知道vpath不適用於在編譯期間更改的文件,並且僅用於源代碼,但是我不明白為什么在我解釋時要澄清路徑列出對象,因為庫的依賴關系不足夠。
mylib.so : $(objects:%.o=$(obj_path)/%.o)
$(FC) $(LFLAGS) $^ $(LIBS) -o $@
%.mod : %.o
@touch $@
%.o : %.f $(makefiles) | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $@
但這是行不通的。 我收到了循環依賴項刪除警告,並嘗試使用m2c編譯模塊。 以防萬一,注釋.o和.mod的vpath不能解決此問題。 make --debug的輸出:
Reading makefiles...
Updating goal targets....
File 'all' does not exist.
File 'mylib.so' does not exist.
File 'obj/myobj.o' does not exist.
make: Circular obj/myobj.mod <- obj/myobj.o dependency dropped.
File 'obj/mymod.mod' does not exist.
File 'obj/mymod.o' does not exist.
make: Circular obj/mymod.o <- obj/mymod.mod dependency dropped.
Must remake target 'obj/mymod.o'.
m2c -o obj/mymod.o
make: m2c: Command not found
<builtin>: recipe for target 'obj/mymod.o' failed
make: *** [obj/mymod.o] Error 127
現在,我希望能夠將f90代碼合並到我的庫中。 如果沒有其他變化,添加規則似乎不會影響該過程,但是當我將mymod.f的擴展名更改為mymod.f90時,它將返回與其他情況類似的錯誤。 修改后的部分是:
$(obj_path)/%.mod : %.o
@touch $@
$(obj_path)/%.o : %.f $(makefiles) | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $@
$(obj_path)/%.o : %.f90 $(makefiles) | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $@
make --debug的輸出是這樣的:
Reading makefiles...
Updating goal targets....
File 'all' does not exist.
File 'mylib.so' does not exist.
File 'obj/myobj.o' does not exist.
File 'obj' does not exist.
Must remake target 'obj'.
mkdir -p obj
Successfully remade target file 'obj'.
File 'obj/mymod.mod' does not exist.
File 'obj/mymod.o' does not exist.
make: Circular obj/mymod.o <- obj/mymod.mod dependency dropped.
Must remake target 'obj/mymod.o'.
m2c -o obj/mymod.o
make: m2c: Command not found
<builtin>: recipe for target 'obj/mymod.o' failed
make: *** [obj/mymod.o] Error 127
生成文件:
all : mylib.so
makefiles := Makefile
FC = gfortran
FFLAGS = -I$(obj_path) -J$(obj_path) -fPIC
LFLAGS = -shared -fPIC
obj_path := obj
src_paths = src1 src2
#vpath %.o $(obj_path)
#vpath %.mod $(obj_path)
vpath %.f $(src_paths)
objects = myobj.o mymod.o
obj/myobj.o : obj/mymod.mod
mylib.so : $(objects:%.o=$(obj_path)/%.o)
$(FC) $(LFLAGS) $^ $(LIBS) -o $@
%.mod : %.o
@touch $@
%.o : %.f $(makefiles) | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $@
$(obj_path) :
mkdir -p $@
.PHONY: clean
clean:
rm -rf mylib.so $(obj_path)
src1 / myobj.f:
subroutine myobj
use mymod
implicit none
mymodx=1
print*,'mymod was included', mymodx
return
end subroutine
src2 / mymod.f:
module mymod
implicit none
integer :: mymodx
end module
終端輸出:
make --debug
GNU Make 4.1
Built for x86_64-unknown-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Updating goal targets....
File 'all' does not exist.
File 'mylib.so' does not exist.
File 'obj/myobj.o' does not exist.
make: Circular obj/myobj.mod <- obj/myobj.o dependency dropped.
File 'obj/mymod.mod' does not exist.
File 'obj/mymod.o' does not exist.
make: Circular obj/mymod.o <- obj/mymod.mod dependency dropped.
Must remake target 'obj/mymod.o'.
m2c -o obj/mymod.o
make: m2c: Command not found
<builtin>: recipe for target 'obj/mymod.o' failed
make: *** [obj/mymod.o] Error 127
您的方法存在一些問題。 vpath
搜索僅適用於先決條件,而不適用於目標,因此類似
%.o: %.f
會在$(src_paths)
搜索源,但不會嘗試匹配$(obj_path)
中的目標。 這導致了下一個問題,由於將對象放入中間目錄,因此您的規則需要考慮到這一點,因為vpath
將無濟於事。 構建庫的主要目標取決於$(obj_path)/blah.f
因此您想使用類似以下規則:
$(obj_path)/%.o: %.f
匹配對象。 可能有一種更清潔的方法來執行此操作,但我不知道它們。
同樣,目標為%.mod
的規則與對象目錄中的要求不匹配,並且似乎正在調用默認的隱式規則來處理它們,從而嘗試調用m2c
。
具體來說,請嘗試將mod文件編譯為modula-2源,並且自動將其編譯為與%.o:%.mod
規則沖突並產生循環依賴關系。 通過修改該規則以正確匹配mod文件,可以避免這種混亂情況。
另外,不要忘記為%.f90
添加一個vpath
,以便您的規則可以找到那些源文件。
我可以使用此稍作修改的Makefile成功構建您的測試項目。 我還使用了名為.f90
文件來表明它也可以解決您的第二個問題。
FC = gfortran
FFLAGS = -I$(obj_path) -J$(obj_path) -fPIC
LFLAGS = -shared -fPIC
src_paths = src1 src2
obj_path := obj
vpath %.o $(obj_path)
vpath %.mod $(obj_path)
vpath %.f90 $(src_paths)
vpath %.f $(src_paths)
mylib_objects = myobj.o mymod.o
mylib_target = mylib.so
all: $(mylib_target)
$(mylib_target) : $(mylib_objects:%.o=$(obj_path)/%.o)
$(FC) $(LFLAGS) $^ $(LIBS) -o $@
$(obj_path)/myobj.o: myobj.f90 $(obj_path)/mymod.mod
$(obj_path) :
mkdir -p $@
$(obj_path)/%.mod : %.o $(obj_path)
@true
$(obj_path)/%.o: %.f | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $@
$(obj_path)/%.o: %.f90 | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $@
clean:
rm -rf $(mylib_target) $(obj_path)
從一開始, make --debug
的輸出為:
% make --debug
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Updating goal targets....
File 'all' does not exist.
File 'mylib.so' does not exist.
File 'obj/myobj.o' does not exist.
File 'obj' does not exist.
Must remake target 'obj'.
mkdir -p obj
Successfully remade target file 'obj'.
File 'obj/mymod.mod' does not exist.
File 'obj/mymod.o' does not exist.
Must remake target 'obj/mymod.o'.
gfortran -Iobj -Jobj -fPIC -c src2/mymod.f90 -o obj/mymod.o
Successfully remade target file 'obj/mymod.o'.
Must remake target 'obj/mymod.mod'.
Successfully remade target file 'obj/mymod.mod'.
Must remake target 'obj/myobj.o'.
gfortran -Iobj -Jobj -fPIC -c src1/myobj.f90 -o obj/myobj.o
Successfully remade target file 'obj/myobj.o'.
Must remake target 'mylib.so'.
gfortran -shared -fPIC obj/myobj.o obj/mymod.o -o mylib.so
Successfully remade target file 'mylib.so'.
Must remake target 'all'.
Successfully remade target file 'all'.
還要注意,您可以通過在另一個對象文件中規定目標文件來處理模塊依賴性,以保證將生成必要的mod文件。 例如,改變
objects = myobj.o mymod.o
至
objects = mymod.o myobj.o
使不必要的規則和涉及mod文件的先決條件成為可能,因為這將導致在嘗試myobj.o
之前先構建mymod.o
(和副產品mymod.mod
)。 該解決方案有可能在並行構建中中斷,因此我保持了對象的順序並確保規則按預期工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.