2015-04-24 2 views
2

Давайте предположим, что у меня есть эта структура каталогов: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 

Есть ли способ сделать это?

EDIT: Если возможно, мне нужно решение, которое работает как в окнах, так и в Unix.

EDIT 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'. 
+0

Что вы используете в Windows? Если вы получаете GNU make из cygwin, тогда решение на основе оболочки должно работать. Если вы используете nmake от Microsoft, потребуется другое. –

+0

Это будет работать, если он будет запускать его из оболочки cygwin. Нет, если он запускал его из cmd.exe, даже если был установлен cygwin (если он не поместил материал cygwin в свой обычный PATH. –

+0

Я пытаюсь сделать мой файл Makefile общим, как он есть. Решение на основе оболочек будет отлично работать unix, но есть ли обходной путь или другой подход для окон? – TheCrafter

ответ

1

Учитывая ваши изменения, вы в принципе есть 2 решения:

  1. Использование Linux-оболочки под Windows, и использование $(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: 
    

Обратите внимание, что пространство после того, как в $(shell CHDIR)CHDIR является обязательным .

+0

Команда работает только на cmd, но в Makefile я получаю эту ошибку: 'process_begin: CreateProcess (NULL, CHDIR, ...) не удалось. DIR:/a \: d: Нет такого файла или directory DIR:/b: Нет такого файла или каталога DIR:/s: Нет такого файла или каталога Dirs: src: dira dirb' – TheCrafter

+0

Вы пытались запустить make из оболочки cmd.exe? – Chnossos

+0

Да, я запускаю make из cmd.exe, и я также добавил эту строку в мой makefile 'SHELL = C: \ Windows \ System32 \ cmd.exe' – TheCrafter

0

John Graham-Хитрый написал эту аккуратную recursive wildcard функцию для макияжа:

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

Но Я не думаю, что это может делать файлы и каталоги.

Единственное другое решение, которое у меня есть, состоит в том, чтобы разорвать его на find.

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

Как Марк Fraioli указывает, если вы хотите только голые имена каталогов в переменной, то вы хотите:

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

Для Windows это мощь работы. Я протестировал команду dir, но не смог обработать ее.

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

Как определить, какую платформу вы на контроль, который вы используете другой вопрос, но есть несколько способов сделать это.

+0

Да, я думал об использовании оболочки тоже, но будет ли она работать на окнах? Я так не думаю! – TheCrafter

+0

Да, я почти добавил, что предостережение от моего ответа, почему вы задали этот вопрос таким образом. Я уверен, что для этого есть сопоставимый ответ Windows. Я просто не знаю, что это такое. –

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 
+0

Да, но это не будет работать в Windows. Я просто обновил свой вопрос, который я забыл добавьте, я тоже хотел это для окон. – TheCrafter

Смежные вопросы