代码之家  ›  专栏  ›  技术社区  ›  ggambetta

来自Makefile子目录的源

  •  47
  • ggambetta  · 技术社区  · 14 年前

    我有一个使用Mag文件构建的C++库。直到最近,所有的源都在一个目录中,Makefile做了类似的事情

    SOURCES = $(wildcard *.cpp)

    现在我添加了一些位于子目录中的源,比如 subdir . 我知道我能做到

    SOURCES = $(wildcard *.cpp) $(wildcard subdir/*.cpp)

    细分市场 wildcard 查看子目录,或者以某种方式生成子目录列表并用几个 通配符 功能。在这一点上,有一个非递归的解决方案(也就是说,只扩展第一个级别)是可以的。

    我什么也没找到-我猜是用 find -type d

    7 回复  |  直到 6 年前
        1
  •  75
  •   Beta    14 年前

    这应该做到:

    SOURCES = $(wildcard *.cpp) $(wildcard */*.cpp)
    

    编辑:
    杰克·凯利指出 $(wildcard **/*.cpp) 使用GNUMake 3.81可以在任何深度工作,至少在某些平台上是这样。(他怎么知道的,我不知道。)

        2
  •  21
  •   LightStruk    12 年前

    递归通配符完全可以在Make中完成,而无需调用shell或find命令。使用only Make进行搜索意味着这个解决方案也可以在Windows上运行,而不仅仅是*nix。

    # Make does not offer a recursive wildcard function, so here's one:
    rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
    
    # How to recursively find all files with the same name in a given folder
    ALL_INDEX_HTMLS := $(call rwildcard,foo/,index.html)
    
    # How to recursively find all files that match a pattern
    ALL_HTMLS := $(call rwildcard,foo/,*.html)
    

    文件夹名称中的尾随斜杠是必需的。这个rwildcard函数不像Make的内置通配符函数那样支持多个通配符,但是如果再使用foreach,添加这种支持就很简单了。

        3
  •  17
  •   Christoph    14 年前

    如果不想使用递归生成文件,这可能会给您一些建议:

    subdirs := $(wildcard */)
    sources := $(wildcard $(addsuffix *.cpp,$(subdirs)))
    objects := $(patsubst %.cpp,%.o,$(sources))
    
    $(objects) : %.o : %.cpp
    
        4
  •  9
  •   Fred Foo    10 年前

    Common practice 就是放一个 Makefile

    all: recursive
        $(MAKE) -C componentX
        # stuff for current dir
    

    all: recursive
        cd componentX && $(MAKE)
        # stuff for current dir
    
    recursive: true
    

    为每个 生成文件 Makefile.inc 在根源目录中。这个 recursive 目标部队 make 进入子目录。确保它不会在需要的目标中重新编译任何内容 递归的 .

        5
  •  8
  •   istudy0    14 年前
        6
  •  3
  •   Yukulélé    5 年前

    wildcard :

    SOURCES := $(wildcard *.cpp */*.cpp)
    

    SOURCES := $(wildcard *.cpp */*.cpp */*/*.cpp */*/*/*.cpp)
    

    不幸的是,和我们有时读到的相反,glob( ** )makefile不支持,将被解释为普通通配符( **/*.cpp 比赛 */*.cpp 但不是 */*/*.cpp ).

    如果你需要无限深度的使用 shell

    SOURCES := $(shell find . -name "*.cpp")
    
        7
  •  2
  •   Achimnol    13 年前

    如果你能使用 find

    recurfind = $(shell find $(1) -name '$(2)')
    SRCS := $(call recurfind,subdir1,*.c) $(call recurfind,subdir2,*.cc) $(call recurfind,subdir2,*.cu) \
            ...