Makefile:生成包含子目录的列表

时间:2015-04-24 11:17:23

标签: recursion makefile

假设我有这样的目录结构:

-src
  |
  |-- subdir1
  |
  |
  |-- subdir2
  |      |
  |      |-- subdir3

我想自动生成一个变量,找到每个子目录的名称。

类似于:

BASE_DIR = src
# magic_recursive_wildcard_here := ...
DIRS = $(call magic_recursive_wildcard_here)

all:
    @echo dirs: $(DIRS)

我希望所有人的输出都是:

dirs: src subdir1 subdir2 subdir3

有没有办法做到这一点?

编辑:如果可能,我需要一个适用于Windows和Unix的解决方案。

编辑27/4/2015:我尝试过Chnossos的答案,输出是这样的:

[21:59:27] ~\Desktop\makefileproj\src> make -d
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i386-pc-mingw32
Reading makefiles...
Reading makefile `makefile'...
CreateProcess(NULL,CHDIR,...)
process_begin: CreateProcess(NULL, CHDIR, ...) failed.
CreateProcess(F:\Programs\CmdTools\coreutils\bin\DIR.exe,DIR /A:D /B /S .,...)
DIR: /A\:D: No such file or directory
DIR: /B: No such file or directory
DIR: /S: No such file or directory
Main thread handle = 0x000000e0
.: dira dirb Makefile
Updating makefiles....
 Considering target file `makefile'.
  Looking for an implicit rule for `makefile'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.o'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.c'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.cc'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.cpp'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.p'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.f'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.r'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.s'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.mod'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.sh'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile,v'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `RCS/makefile,v'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `RCS/makefile'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `s.makefile'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `SCCS/s.makefile'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.o'.
  Looking for a rule with intermediate file `makefile.o'.
   Avoiding implicit rule recursion.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.c'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.cc'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.cpp'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.p'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.f'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.r'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.s'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.mod'.
   Trying pattern rule with stem `makefile.o'.
   Trying implicit prerequisite `makefile.o,v'.
   Trying pattern rule with stem `makefile.o'.
   Trying implicit prerequisite `RCS/makefile.o,v'.
   Trying pattern rule with stem `makefile.o'.
   Trying implicit prerequisite `RCS/makefile.o'.
   Trying pattern rule with stem `makefile.o'.
   Trying implicit prerequisite `s.makefile.o'.
   Trying pattern rule with stem `makefile.o'.
   Trying implicit prerequisite `SCCS/s.makefile.o'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.c'.
   Looking for a rule with intermediate file `makefile.c'.
    Avoiding implicit rule recursion.
    Avoiding implicit rule recursion.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.y'.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.l'.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.w'.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.w'.
    Trying pattern rule with stem `makefile.c'.
    Trying implicit prerequisite `makefile.c,v'.
    Trying pattern rule with stem `makefile.c'.
    Trying implicit prerequisite `RCS/makefile.c,v'.
    Trying pattern rule with stem `makefile.c'.
    Trying implicit prerequisite `RCS/makefile.c'.
    Trying pattern rule with stem `makefile.c'.
    Trying implicit prerequisite `s.makefile.c'.
    Trying pattern rule with stem `makefile.c'.
    Trying implicit prerequisite `SCCS/s.makefile.c'.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.y'.
    Looking for a rule with intermediate file `makefile.y'.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Trying pattern rule with stem `makefile.y'.
     Trying implicit prerequisite `makefile.y,v'.
     Trying pattern rule with stem `makefile.y'.
     Trying implicit prerequisite `RCS/makefile.y,v'.
     Trying pattern rule with stem `makefile.y'.
     Trying implicit prerequisite `RCS/makefile.y'.
     Trying pattern rule with stem `makefile.y'.
     Trying implicit prerequisite `s.makefile.y'.
     Trying pattern rule with stem `makefile.y'.
     Trying implicit prerequisite `SCCS/s.makefile.y'.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.l'.
    Looking for a rule with intermediate file `makefile.l'.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Trying pattern rule with stem `makefile.l'.
     Trying implicit prerequisite `makefile.l,v'.
     Trying pattern rule with stem `makefile.l'.
     Trying implicit prerequisite `RCS/makefile.l,v'.
     Trying pattern rule with stem `makefile.l'.
     Trying implicit prerequisite `RCS/makefile.l'.
     Trying pattern rule with stem `makefile.l'.
     Trying implicit prerequisite `s.makefile.l'.
     Trying pattern rule with stem `makefile.l'.
     Trying implicit prerequisite `SCCS/s.makefile.l'.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.w'.
    Looking for a rule with intermediate file `makefile.w'.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Trying pattern rule with stem `makefile.w'.
     Trying implicit prerequisite `makefile.w,v'.
     Trying pattern rule with stem `makefile.w'.
     Trying implicit prerequisite `RCS/makefile.w,v'.
     Trying pattern rule with stem `makefile.w'.
     Trying implicit prerequisite `RCS/makefile.w'.
     Trying pattern rule with stem `makefile.w'.
     Trying implicit prerequisite `s.makefile.w'.
     Trying pattern rule with stem `makefile.w'.
     Trying implicit prerequisite `SCCS/s.makefile.w'.
    Trying pattern rule with stem `makefile'.
    Rejecting impossible implicit prerequisite `makefile.w'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.cc'.
   Looking for a rule with intermediate file `makefile.cc'.
    Avoiding implicit rule recursion.
    Avoiding implicit rule recursion.
    Trying pattern rule with stem `makefile.cc'.
    Trying implicit prerequisite `makefile.cc,v'.
    Trying pattern rule with stem `makefile.cc'.
    Trying implicit prerequisite `RCS/makefile.cc,v'.
    Trying pattern rule with stem `makefile.cc'.
    Trying implicit prerequisite `RCS/makefile.cc'.
    Trying pattern rule with stem `makefile.cc'.
    Trying implicit prerequisite `s.makefile.cc'.
    Trying pattern rule with stem `makefile.cc'.
    Trying implicit prerequisite `SCCS/s.makefile.cc'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.cpp'.
   Looking for a rule with intermediate file `makefile.cpp'.
    Avoiding implicit rule recursion.
    Avoiding implicit rule recursion.
    Trying pattern rule with stem `makefile.cpp'.
    Trying implicit prerequisite `makefile.cpp,v'.
    Trying pattern rule with stem `makefile.cpp'.
    Trying implicit prerequisite `RCS/makefile.cpp,v'.
    Trying pattern rule with stem `makefile.cpp'.
    Trying implicit prerequisite `RCS/makefile.cpp'.
    Trying pattern rule with stem `makefile.cpp'.
    Trying implicit prerequisite `s.makefile.cpp'.
    Trying pattern rule with stem `makefile.cpp'.
    Trying implicit prerequisite `SCCS/s.makefile.cpp'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.p'.
   Looking for a rule with intermediate file `makefile.p'.
    Avoiding implicit rule recursion.
    Avoiding implicit rule recursion.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.web'.
    Trying pattern rule with stem `makefile.p'.
    Trying implicit prerequisite `makefile.p,v'.
    Trying pattern rule with stem `makefile.p'.
    Trying implicit prerequisite `RCS/makefile.p,v'.
    Trying pattern rule with stem `makefile.p'.
    Trying implicit prerequisite `RCS/makefile.p'.
    Trying pattern rule with stem `makefile.p'.
    Trying implicit prerequisite `s.makefile.p'.
    Trying pattern rule with stem `makefile.p'.
    Trying implicit prerequisite `SCCS/s.makefile.p'.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.web'.
    Looking for a rule with intermediate file `makefile.web'.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Trying pattern rule with stem `makefile.web'.
     Trying implicit prerequisite `makefile.web,v'.
     Trying pattern rule with stem `makefile.web'.
     Trying implicit prerequisite `RCS/makefile.web,v'.
     Trying pattern rule with stem `makefile.web'.
     Trying implicit prerequisite `RCS/makefile.web'.
     Trying pattern rule with stem `makefile.web'.
     Trying implicit prerequisite `s.makefile.web'.
     Trying pattern rule with stem `makefile.web'.
     Trying implicit prerequisite `SCCS/s.makefile.web'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.f'.
   Looking for a rule with intermediate file `makefile.f'.
    Avoiding implicit rule recursion.
    Avoiding implicit rule recursion.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.r'.
    Trying pattern rule with stem `makefile.f'.
    Trying implicit prerequisite `makefile.f,v'.
    Trying pattern rule with stem `makefile.f'.
    Trying implicit prerequisite `RCS/makefile.f,v'.
    Trying pattern rule with stem `makefile.f'.
    Trying implicit prerequisite `RCS/makefile.f'.
    Trying pattern rule with stem `makefile.f'.
    Trying implicit prerequisite `s.makefile.f'.
    Trying pattern rule with stem `makefile.f'.
    Trying implicit prerequisite `SCCS/s.makefile.f'.
    Trying pattern rule with stem `makefile'.
    Trying implicit prerequisite `makefile.r'.
    Looking for a rule with intermediate file `makefile.r'.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Avoiding implicit rule recursion.
     Trying pattern rule with stem `makefile'.
     Rejecting impossible implicit prerequisite `makefile.l'.
     Trying pattern rule with stem `makefile.r'.
     Trying implicit prerequisite `makefile.r,v'.
     Trying pattern rule with stem `makefile.r'.
     Trying implicit prerequisite `RCS/makefile.r,v'.
     Trying pattern rule with stem `makefile.r'.
     Trying implicit prerequisite `RCS/makefile.r'.
     Trying pattern rule with stem `makefile.r'.
     Trying implicit prerequisite `s.makefile.r'.
     Trying pattern rule with stem `makefile.r'.
     Trying implicit prerequisite `SCCS/s.makefile.r'.
   Trying pattern rule with stem `makefile'.
   Rejecting impossible implicit prerequisite `makefile.r'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.s'.
   Looking for a rule with intermediate file `makefile.s'.
    Avoiding implicit rule recursion.
    Avoiding implicit rule recursion.
    Trying pattern rule with stem `makefile.s'.
    Trying implicit prerequisite `makefile.s,v'.
    Trying pattern rule with stem `makefile.s'.
    Trying implicit prerequisite `RCS/makefile.s,v'.
    Trying pattern rule with stem `makefile.s'.
    Trying implicit prerequisite `RCS/makefile.s'.
    Trying pattern rule with stem `makefile.s'.
    Trying implicit prerequisite `s.makefile.s'.
    Trying pattern rule with stem `makefile.s'.
    Trying implicit prerequisite `SCCS/s.makefile.s'.
   Trying pattern rule with stem `makefile'.
   Trying implicit prerequisite `makefile.mod'.
   Looking for a rule with intermediate file `makefile.mod'.
    Avoiding implicit rule recursion.
    Avoiding implicit rule recursion.
    Trying pattern rule with stem `makefile.mod'.
    Trying implicit prerequisite `makefile.mod,v'.
    Trying pattern rule with stem `makefile.mod'.
    Trying implicit prerequisite `RCS/makefile.mod,v'.
    Trying pattern rule with stem `makefile.mod'.
    Trying implicit prerequisite `RCS/makefile.mod'.
    Trying pattern rule with stem `makefile.mod'.
    Trying implicit prerequisite `s.makefile.mod'.
    Trying pattern rule with stem `makefile.mod'.
    Trying implicit prerequisite `SCCS/s.makefile.mod'.
  Trying pattern rule with stem `makefile'.
  Rejecting impossible implicit prerequisite `makefile.c'.
  Trying pattern rule with stem `makefile'.
  Rejecting impossible implicit prerequisite `makefile.cc'.
  Trying pattern rule with stem `makefile'.
  Rejecting impossible implicit prerequisite `makefile.cpp'.
  Trying pattern rule with stem `makefile'.
  Rejecting impossible implicit prerequisite `makefile.p'.
  Trying pattern rule with stem `makefile'.
  Rejecting impossible implicit prerequisite `makefile.f'.
  Trying pattern rule with stem `makefile'.
  Rejecting impossible implicit prerequisite `makefile.r'.
  Trying pattern rule with stem `makefile'.
  Rejecting impossible implicit prerequisite `makefile.s'.
  Trying pattern rule with stem `makefile'.
  Rejecting impossible implicit prerequisite `makefile.mod'.
  Trying pattern rule with stem `makefile'.
  Trying implicit prerequisite `makefile.sh'.
  Looking for a rule with intermediate file `makefile.sh'.
   Avoiding implicit rule recursion.
   Trying pattern rule with stem `makefile.sh'.
   Trying implicit prerequisite `makefile.sh,v'.
   Trying pattern rule with stem `makefile.sh'.
   Trying implicit prerequisite `RCS/makefile.sh,v'.
   Trying pattern rule with stem `makefile.sh'.
   Trying implicit prerequisite `RCS/makefile.sh'.
   Trying pattern rule with stem `makefile.sh'.
   Trying implicit prerequisite `s.makefile.sh'.
   Trying pattern rule with stem `makefile.sh'.
   Trying implicit prerequisite `SCCS/s.makefile.sh'.
  No implicit rule found for `makefile'.
  Finished prerequisites of target file `makefile'.
 No need to remake target `makefile'.
Updating goal targets....
Considering target file `all'.
 File `all' does not exist.
 Finished prerequisites of target file `all'.
Must remake target `all'.
Successfully remade target file `all'.
make: Nothing to be done for `all'.

3 个答案:

答案 0 :(得分:1)

考虑到您的编辑,您基本上有两个解决方案:

  1. 在Windows下使用Linux shell并使用$(shell find $(BASE_DIR) -type d)

  2. 在您正在运行的操作系统上使用条件:

    BASE_DIR := .
    
    ifeq ($(OS),Windows_NT)
    DIRS := $(patsubst $(shell CHDIR )\\%,%,$(shell DIR /A:D /B /S $(BASE_DIR)))
    else
    DIRS := $(shell find $(BASE_DIR) -type d)
    endif
    
    $(info $(DIRS)) # print the variable
    
    .PHONY: all
    
    all:
    
  3. 请注意,CHDIR$(shell CHDIR )之后的空格必填

答案 1 :(得分:0)

John Graham-Cunning为make编写了这个整洁的recursive wildcard函数:

rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)
  $(filter $(subst *,%,$2),$d))

但我不认为可以做文件与目录。

我唯一的另一个解决方案是为此find支持。

dirs := $(shell find '$(BASE_DIR)' -type d)

正如Marc Fraioli所指出的那样,你只想要变量中的裸目录名称,那么你想要:

dirs := $(notdir $(shell find '$(BASE_DIR)' -type d))

对于Windows,此可能有效。我测试了dir命令,但没有测试make如何处理它。

dirs := $(notdir $(shell dir /s /b /ad $(BASE_DIR)))

如何确定您所使用的平台来控制您使用的是一个不同的问题,但有很多方法可以做到这一点。

答案 2 :(得分:0)

是的,试试这个:

BASE_DIR = src
DIRS = $(shell find $(BASE_DIR) -type d -exec basename {} \;)

all:
    @echo dirs: $(DIRS)

运行:

$ ls -lR src
src:
total 8
drwxrwxr-x. 2 mfraioli mfraioli 4096 Apr 24 07:41 subdir1
drwxrwxr-x. 3 mfraioli mfraioli 4096 Apr 24 07:41 subdir2

src/subdir1:
total 0

src/subdir2:
total 4
drwxrwxr-x. 2 mfraioli mfraioli 4096 Apr 24 07:41 subdir3

src/subdir2/subdir3:
total 0
$ make
dirs: src subdir1 subdir2 subdir3