2016-11-04 127 views
1

我現在有這個Makefile其中:與子目錄通用的makefile

  • 查找所有* .F在它運行
  • 看起來匹配的目錄*的.o指定子目錄(如Objets_dir定義)
  • 編譯和鏈接

代碼:

# Paths 
    # ----- 

    # Where to put the *.o 
    Objets_dir = temp\Win 

    # Where to check for the *.o 
    VPATH = $(Objets_dir) 

    # Where to put the resulting binary 
    Executable = D:\Documents\out.exe 

    # List of needed objects 
    Objets = $(patsubst %.f,%.o,$(wildcard *.f)) 

    # Rules 
    # ----- 

    F_compilo = gfortran 
    F_compilo_options = -O3 -ffpe-trap=invalid,zero,overflow -mfpmath=sse -fmax-errors=3 
    Link = x86_64-w64-mingw32-gfortran 
    Link_options = 

    # Let's go 
    # -------- 

    # Compile (generation of .o) 
    %.o:%.f 
     $(F_compilo) $(F_compilo_options) -c $< -o $(Objets_dir)\[email protected] 

    # Link (generation of .exe) 
    $(Executable): $(Objets) 
     $(Link) $(Link_options) -o [email protected] $(addprefix $(Objets_dir)\, $(Objets)) 

有關信息,我正在使用mingw32-make來執行此Makefile。

我想編輯它,以便我可以指定一個子文件夾列表(除了當前文件夾外)尋找源文件(* .f)。它會有點不那麼通用,但我會很好。

這個makefile是我在幾年前從互聯網上收回的東西,除了添加一些註釋或編輯編譯標誌之外幾乎沒有碰過。 我想,需要編輯的行是帶有「通配符」調用的行,但我對Make語言完全(完全)無知。

你能建議如何編輯它嗎?

回答

1

有在子目錄的列表中找到文件的一個啓發性的例子:在此基礎上https://www.gnu.org/software/make/manual/html_node/Foreach-Function.html

,我想出了以下內容。我已經在linux系統上使用了一些示例文件測試過這些文件,所以無法保證它能在Windows上「開箱即用」,但不應該太遠。

它尋找在dirs給出的目錄中的所有.f文件,然後繼續前進。

# Paths 
# ----- 

# Where to put the *.o 
Objets_dir = temp\Win 

# Where to put the resulting binary 
Executable = D:\Documents\out.exe 

# List of directories to search for .f files: 
dirs := . a b c d 

# Extra directories to check for dependencies 
VPATH = a b c d 

# Make a list of *.f source files found in dirs 
Sources := $(foreach dir,$(dirs),$(wildcard $(dir)\*.f)) 

# List of needed objects 
Objets = $(patsubst %.f,%.o,$(Sources)) 

# Objects with full path names to their location in temp dir. 
TempObjets = $(addprefix $(Objets_dir)\, $(notdir $(Objets))) 

# Rules 
# ----- 

F_compilo = gfortran 
F_compilo_options = -O3 -ffpe-trap=invalid,zero,overflow -mfpmath=sse -fmax-errors=3 
Link = x86_64-w64-mingw32-gfortran 
Link_options = 

# Let's go 
# -------- 

# Compile (generation of .o) 
$(Objets_dir)\%.o:%.f 
    $(F_compilo) $(F_compilo_options) -c $< -o $(Objets_dir)\$(notdir [email protected]) 

# Link (generation of .exe) 
$(Executable): $(TempObjets) 
    $(Link) $(Link_options) -o [email protected] $^ 

clean: 
    rm -f $(TempObjets) $(Executable) 

注意,它剝去文件名建築和鏈接的子目錄,否則你需要創建一批符合臨時目錄中。所以將所有.o文件轉儲到臨時目錄中很方便。但是,請注意,如果子目錄中的某些.f文件共享相同的名稱,則會失敗。在這種情況下,您需要將VPATH設置爲臨時目錄列表(列表分隔符在Windows上爲;,在其他系統上爲:),並從構建和鏈接規則中刪除$(nordir ...)子句。但是,您需要在temp\Win中創建一個目錄以匹配每個源目錄。

最後,應該指出的是,這並不算作make的遞歸使用。對此,請參閱:How to generate a Makefile with source in sub-directories using just one makefile

+0

好吧,一切運行良好......除了每個子代中的所有文件都會重新編譯。我把'dirs'設爲'dirs:=。 aaa'。當前目錄中的所有.f文件都能正確找到,並且只有在需要時(如果已修改)才能重新編譯,這是預期的行爲。但是'aaa'目錄內的每次都會重新編譯。幫幫我 ? –

+0

做了一些編輯。希望現在應該做正確的事情。 – Halzephron

+0

謝謝。它似乎只適用於最後幾次編輯:儘管我在Windows上,但Sources的行定義必須是Sources:= $(foreach dir,$(dirs),$(通配符$(dir)/ *。f ))'(注意'/',而不是'\'),否則它不會找到任何源文件並停在那裏。 TempObjets = $(addprefix $(Objets_dir)/,$(notdir $(Objets)))''和'$(Objets_dir)/%。o:%。f'的修改相同。其他'''雖然:) –