簡體   English   中英

Fortran Makefile-循環依賴關系下降且m2c

[英]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)

(1)我無法簡化規則

在編譯對象的規則中明確包含“ $(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

(2)我無法為f90添加規則

現在,我希望能夠將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

編譯配置1:

生成文件:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM