2017-07-05 1 views
0

Say, dans un Makefile, j'ai les objectifs suivants:Comment créer les sous-répertoires nécessaires pour les cibles avec make?

EXES=dir1/subdir1/abc dir1/subdir1/def dir1/subdir2/ghi dir1/subdir2/jkl dir2/subdir3/mno dir2/subdir3/pqr 

Chaque élément représente un $(EXES) binaire à créer. Je veux m'assurer que les répertoires nécessaires (dans l'exemple: dir1/subdir1, dir1/subdir2, dir2/subdir3) sont créés s'ils n'existent pas.

Comment pourrais-je y parvenir avec gnu-make?

Répondre

1

Utiliser des conditions préalables d'ordre uniquement:

target: prerequisites | order-only-prerequisites 

order-only-prerequisites: 
    recipe 

Leur recette est exécutée que si elles ne sont pas encore réunies. Exemple:

$(BUILDDIR)/foo.o: src/foo.c | $(BUILDDIR) 
    $(CC) $(CFLAGS) -o [email protected] $< 

$(BUILDDIR): 
    mkdir -p [email protected] 

Et si vous voulez extraire la liste des répertoires pour créer de la définition de votre variable EXES:

$(EXES): | $(dir $(EXES)) 

$(dir $(EXES)): 
    mkdir -p [email protected] 

Ou, pour instancier exactement une règle par cible:

define DIR_rule 
$(1): | $$(dir $(1)) 
endef 
$(foreach e,$(EXES),$(eval $(call DIR_rule,$(e)))) 

$(dir $(EXES)): 
    mkdir -p [email protected] 
+0

Ceci suppose qu'il n'y a pas de sous-répertoire dans '$ (BUILDDIR)'. –

+0

@ RenéNyffenegger: Je ne comprends pas. Que changerait-il s'ils étaient des sous-répertoires dans '$ (BUILDDIR)'? –

+0

@ RenéNyffenegger: Oh! Je vois de votre propre réponse que vous vouliez extraire les répertoires de la définition 'EXES'. J'ai ajouté ceci à ma réponse. –

-1

J'ai finalement trouvé une solution avec $(dir ...)

EXE_DIRS=$(dir $(EXES)) 

EXE_DIRS_UNIQUE=$(shell for DIR in $(EXE_DIRS); do echo $$DIR; done | sort | uniq) 

$(shell for DIR in $(EXE_DIRS_UNIQUE); do if [ ! -d $$DIR ]; then mkdir -p $$DIR; fi; done) 

all: $(EXES) 
+1

Essayez de ne pas utiliser '$ (shell)' dans vos fichiers makefiles. Utilisez _make_ à la place. Ici, par exemple, vous exécutez une boucle for même si tout est déjà à jour. La solution de Renaud est la voie à suivre. Il fera même tout en parallèle quand vous utilisez '-j' – bobbogo