【问题标题】:Generic makefile with subdirs带有子目录的通用 makefile
【发布时间】:2016-11-04 12:10:27
【问题描述】:

我目前有这个 Makefile :

  • 在它运行的目录中查找所有 *.f
  • 在指定的子目录(如 Objets_dir 中定义)中查找匹配的 *.o
  • 编译和链接

代码:

    # 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)\$@

    # Link (generation of .exe)
    $(Executable): $(Objets)
        $(Link) $(Link_options) -o $@ $(addprefix $(Objets_dir)\, $(Objets))

关于信息,我正在使用 mingw32-make 来执行这个 Makefile。

我想编辑它,以便我可以指定一个子文件夹列表,它还会(除了当前文件夹)在其中查找源文件 (*.f)。然后它会不那么通用,但我会很好。

这个 makefile 是我几年前从互联网上检索到的,除了添加一些评论或编辑编译标志之外几乎没有碰过。 我想需要编辑的行是带有“通配符”调用的行,但我对 Make 语言完全(完全)一无所知。

你能建议如何编辑它吗?

【问题讨论】:

    标签: gnu-make makefile


    【解决方案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 $@)
    
    # Link (generation of .exe)
    $(Executable): $(TempObjets)
        $(Link) $(Link_options) -o $@ $^
    
    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

    【讨论】:

    • 好的,一切运行良好...除了子目录中的所有文件每次都会重新编译。我将dirs 设置为dirs:= . aaa。当前目录中的所有 .f 都正确找到,并且仅在需要时重新编译(如果已修改),这是预期的行为。但是aaa 目录中的那些每次都会重新编译。帮助?
    • 进行了一些修改。希望现在应该做正确的事。
    • 谢谢。它似乎与最后的一些编辑一起工作:虽然我在 Windows 上,Sources 行定义需要是Sources := $(foreach dir,$(dirs),$(wildcard $(dir)/*.f))(注意/,而不是\ ),否则它找不到任何源文件并停在那里。 TempObjets = $(addprefix $(Objets_dir)/, $(notdir $(Objets)))$(Objets_dir)/%.o:%.f 的修改相同。不过其他\ 很好:)
    • 另外,我更改了VPATH = $(dirs) 以避免复制粘贴整个子目录列表。似乎工作正常。
    猜你喜欢
    • 2015-07-04
    • 1970-01-01
    • 2020-06-29
    • 1970-01-01
    • 2011-12-23
    • 2020-11-24
    • 2011-03-30
    • 2021-05-19
    相关资源
    最近更新 更多