Let's suppose I have this directory structure:
-src
|
|-- subdir1
|
|
|-- subdir2
| |
| |-- subdir3
I want to generate automatically a variable that finds the name of each subdir.
So something like:
BASE_DIR = src
# magic_recursive_wildcard_here := ...
DIRS = $(call magic_recursive_wildcard_here)
all:
@echo dirs: $(DIRS)
And I want the output from all to be:
dirs: src subdir1 subdir2 subdir3
Is there any way to do that?
EDIT: If possible, I need a solution that works on both windows and Unix.
EDIT 27/4/2015: I tried Chnossos's answer and the output is this:
[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'.
Considering your edit, you basically have 2 solutions :
Use a linux shell under Windows and use $(shell find $(BASE_DIR) -type d)
.
Use a condition on the OS you're running on :
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:
Note that the space after CHDIR
in $(shell CHDIR )
is mandatory.
John Graham-Cunning wrote this neat recursive wildcard function for make:
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)
$(filter $(subst *,%,$2),$d))
But I don't think that can do files vs. directories.
The only other solution I have is to shell out to find
for this.
dirs := $(shell find '$(BASE_DIR)' -type d)
As Marc Fraioli points out if you want just the bare directory names in the variable then you want:
dirs := $(notdir $(shell find '$(BASE_DIR)' -type d))
For Windows this might work. I tested the dir
command but not how make handles it.
dirs := $(notdir $(shell dir /s /b /ad $(BASE_DIR)))
How you determine which platform you are on to control which you use is a different question but there are a number of ways to do that.
Yes, try this:
BASE_DIR = src
DIRS = $(shell find $(BASE_DIR) -type d -exec basename {} \;)
all:
@echo dirs: $(DIRS)
running:
$ 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
User contributions licensed under CC BY-SA 3.0