2017-09-07 1 views
1

J'ai besoin de trouver récursivement tous les fichiers d'en-tête dans une liste de répertoires. Je ne peux pas comprendre comment échapper à la commande correctement. J'ai cherché autour et trouvé diverses informations sur l'évasion dans les fichiers makefile mais je n'ai pas été capable de résoudre ce problème.Comment faire pour échapper backslash dans la fonction de shell makefile

En bash ce qui suit fait ce que je veux:

find path1 path2 path3 -type f \(-name *.hpp -o -name *.h -o *.hxx \) 

Dans mon Makefile j'ai essayé quelques combinaisons de foreach, etc. Actuellement, j'ai ceci:

INCLUDE_PATHS ?= path1 path2 path3 
MY_HEADERS := $(shell find $(INCLUDE_PATHS) -type f \(-name *.h -o -name *.hpp -o -name *.hxx \)) 

Ce produit:

find: paths must precede expression 
Usage: find [-H] [-L] [-P] [path...] [expression] 

Si je regarde juste pour une extension telle que « * .hpp » il fonctionne très bien (je suppose parce que le \ (... \) est pas besoin).

J'ai essayé différentes combinaisons de $, », ». \ Pour échapper aux « \ » caractères dans la commande shell sans succès.

Toute aide serait grandement appréciée.

+0

Oops ... Je voulais dire backslash dans le titre. – sjacobs

Répondre

1

Votre problème n'a rien à voir avec make ou la valeur de INCLUDE_PATHS ou comment interpréter les caractères backslash. Le problème est que vous n'échappez pas à votre globbing, et cela correspond à certains fichiers locaux. Ressaisissez votre fonction pour échapper à vos déclarations glob, comme ceci:

MY_HEADERS := $(shell find $(INCLUDE_PATHS) -type f \(-name \*.h -o -name \*.hpp -o -name \*.hxx \)) 

Je serais très surpris si la commande fonctionne d'origine en bash sans citer ces personnages, si vous l'exécutez à partir du même répertoire contenant le même contenu que la marque .

+0

Cela a fonctionné. Merci! – sjacobs

0

Les MY_HEADERS variables devient . correcte, en appelant $($INCLUDE_PATHS) - pas $ (include_paths) Ainsi, votre Makefile serait:

INCLUDE_PATHS ?= path1 path2 path3 
MY_HEADERS := $(shell find $($INCLUDE_PATHS) -type f \(-name *.h -o -name *.hpp -o -name *.hxx \)) 

Vous pouvez continuer à vérifier la valeur de la variable:

all: printme 

printme: 
    @echo $(MY_HEADERS) 

L'exécution de cette Makefile make montrera votre réponse souhaitée.

+0

Mon commentaire précédent concernait une faute de frappe dans ma question initiale que j'ai corrigée. – sjacobs

+0

Votre travail sur le chemin de trouver n'est pas la solution ou pertinent. Si je place un seul chemin là plutôt que de faire référence à une variable make, j'obtiens toujours le même résultat. Le problème est en passant les options à plusieurs noms qui requièrent que les caractères \ (... \) soient passés au shell correctement. En d'autres termes, ce 'MY_HEADERS: = $ (shell find $ (INCLUDE_PATHS) -type f -name * .hpp))' fonctionne très bien. – sjacobs

+0

Que ce soit "échapper backslash" ou non n'était pas la raison pour laquelle vous avez obtenu les premiers résultats. Dans Makefile, nous intégrons la même commande find SAUF il existe différentes conventions d'appel de variables. – popuptoast

0

Bien MadScientist déjà répondu à la question tout à fait, vous pouvez utiliser les éléments suivants pour éviter la coquille tout à fait:

INCLUDE_PATHS ?= path1 path2 path3 
EXTENSIONS := .h .hpp .hxx 
MY_HEADERS := $(shell find $(INCLUDE_PATHS) -type f \(-name \*.h -o -name \*.hpp -o -name \*.hxx \)) 
$(info $(MY_HEADERS)) 
MY_HEADERS := $(foreach p,$(INCLUDE_PATHS),$(foreach e,$(EXTENSIONS),$(wildcard $(p)/*$(e)))) 
$(info $(MY_HEADERS))