2009-03-20 6 views
7

Je souhaite utiliser GNUMake pour exécuter un fichier Make basé sur des règles qui génère un ensemble de fichiers C dans une structure de répertoires (sur un système de fichiers Windows).Quelle est la manière la plus fiable d'utiliser GNUMake avec des noms de fichiers contenant des espaces?

Le répertoire racine, certains sous-répertoires et certains fichiers contiennent des espaces.

fichier Exemple: "C:\Documents and Settings\<username>\My Documents\Test Dir\Build Me.c"

gnumake ne fonctionne pas vraiment quand les chemins de fichiers contiennent des espaces. J'ai lu sur les moyens possibles de contourner ce problème (en supprimant les espaces de mes noms de fichiers, en utilisant le format 8.3, en remplaçant les espaces par ? ou \\ etc.) mais aucun d'eux n'est parfait (ou sont-ils?)

Y at-il une solution miracle qui résoudra ce problème?

BTW Je suis coincé avec GNUMake, je ne peux pas utiliser un autre outil de création.

Répondre

2

Vous pourriez être en mesure d'échapper aux espaces dans votre makefile, à savoir:

$(CC) $(CFLAGS) 'C:\Documents\ and\ Settings\<username>\My\ Documents\Test\ Dir\Build Me.c' 

J'ai ajouté les guillemets simples juste au cas où, mais je ne sais pas si cela fonctionne si vous êtes en utilisant le terminal windows (plutôt que cygwin etc).

+0

Donc cela pourrait fonctionner, ou il ne pourrait pas? –

+0

Peut être capable, comme je n'ai pas une installation Windows à portée de main pour tester avec pour être sûr. Je ne peux pas penser à une raison pour laquelle cela ne fonctionnera pas. –

3

Le plus simple est en effet de réparer les noms de fichiers. A défaut, cependant, écrivez vos commandes pour mettre des guillemets autour des noms de fichiers. Le plus simple et le plus sûr est de placer tous les noms de fichiers dans des macros; l'astuce, c'est que vous devez échapper aux doubles guillemets, ce qui veut dire que vous aurez envie de manger tout seul.

donc: FN = "\" C: \ Mes Documents \ myfiles.c \ "" FN2 = "C: \ Mes documents \ myfile2.c"

ou utiliser $ (CC) $ (CFLAGS) « $ (FN2) »

L'astuce ici est de faire écho à votre ligne de commande avec écho

echo $(CC) $(CFLAGS) "$(FN2)" 

ou utiliser make -d pour obtenir tous les détails de ce faire est d'essayer de le faire.

Vous devrez peut-être pirater environ avec cela un peu, en particulier, vous devrez peut-être doubler les évasions

+10

"Corriger les noms de fichier"? Les noms ne sont pas cassés. Les outils qui ne peuvent pas gérer les espaces sont brisés. Le chemin d'exemple est un standard MS, même (je suppose que c'était une tactique pour pousser les développeurs à réparer leurs outils cassés qui ne peuvent pas gérer les espaces.) – Qwertie

+1

Nah, c'est des outils qui utilisent des noms de fichiers qui ne correspondent pas au standard UNIX sont brisé. Aussi les systèmes d'exploitation. –

+0

Les systèmes d'exploitation et les outils * autorisant * les espaces sont-ils cassés ?! – Qwertie

0

Si les espaces ne sont que dans la partie « racine » du chemin, vous pouvez monter ce répertoire sur un chemin sans espaces. Il y a plusieurs façons de le faire: à partir de la ligne de commande ("net use" ou "subst") ou de l'explorateur (Tools> Map Network Drive). Donc, C: \ Documents and Settings \\ Mes documents \ Test Dir "peut devenir X: \ BuildMe.c

Cependant, s'il y a des espaces dans les noms de fichiers, ou dans les répertoires sous le répertoire de construction" root ", alors il n'y a probablement pas de solutions parfaites.J'ai utilisé les autres suggestions que vous avez mentionnées (8.3 noms, en remplaçant les blancs avec un caractère différent) et ceux-ci travaillent mais ils ont leurs propres problèmes

+0

Il doit fonctionner dans tous les cas. c'est-à-dire lorsque le répertoire racine contient un espace, ainsi que les sous-répertoires eux-mêmes, ainsi que les noms de fichiers eux-mêmes. – demoncodemonkey

2

J'ai trouvé une grande inspiration à http://www.mail-archive.com/[email protected]/msg05201.html ce qui m'a fait partir.Ma propre application de test consiste en un répertoire de fichiers FLV Jazz de la seconde guerre mondiale téléchargés depuis YouTube et d'un sous-répertoire audio dans lequel j'aimerais stocker les versions audio OGA de chacun. Et, bien sûr, les noms de fichiers contiennent des espaces. Je voudrais ensuite exécuter ffmpeg2theora à

Voici le Makefile GNUMake que j'ai piraté ensemble pour fonctionner. Merci à toutes les astuces sur ce site et aussi au site référencé ci-dessus!

sq = $(subst $(sp),?,$1) 
qs = $(subst ?,$(sp),$1) 

e := 
sp := $(e) $(e) 

FLVS := $(foreach file,var,$(call sq,$(wildcard *.flv))) 
FLVS := $(subst .flv?,.flv ,$(FLVS)) 

AUDIOS := $(patsubst %.flv,audio/%.oga,$(FLVS)) 

.PHONY: audios show 

audios: $(AUDIOS) 

$(AUDIOS) : $(FLVS) 
    ffmpeg2theora --novideo -o "$(call qs,[email protected])" "$(call qs,$(notdir $(patsubst %.oga,audio/%.flv,[email protected])))" 

show: 
    echo $(FLVS) 
    echo $(AUDIOS) 
+0

Vous pouvez également remplacer d'autres caractères et les convertir dans des espaces en cas de besoin. 's + = $ (subst \, +, $ 1)' '+ s = $ (subst +, \, $ 1)' '$ (appel de +, foo bar): $ (+ s appel, bar baz ' ' @echo Création de $ (call + s, $ @) à partir de $ (call + s, $ <) ' –

1

J'ai généralement utilisé ce qui est en quelque sorte une combinaison de la réponse de Dana le Sane et de la réponse de Brian Yoder.

Vous utilisez simplement la fonction $(subst) pour remplacer toutes les occurrences d'espaces avec des espaces échappés. EG:

empty := 
space := $(empty) $(empty) 
program_files := $(subst $(space),\$(space),$(ProgramFiles)) 

(Notez que certaines versions plus anciennes de faire sous Windows, vous devez également utiliser un autre $(subst) changer chemin antislashs à barres obliques)

0

j'ajouter simplement « guillemets simples » autour de la chaîne incriminée : - '$ (TARGET_DIR)'

Exemple: (ce qui m'a aidé à erlang.mk fonctionne correctement sur les fenêtres!)

app:: $(C_SRC_ENV) 
    @mkdir -p priv/ 
    $(c_src_verbose) $(CC) $(CFLAGS) $(C_SRC_DIR)/*.c -fPIC -shared -o $(C_SRC_OUTPUT) \ 
     -I '$(ERTS_INCLUDE_DIR)' $(C_SRC_OPTS) 

'$(ERTS_INCLUDE_DIR)' développe maintenant correctement 'c:/Program Files/erl7.0/erts-7.0/include/'

utilisant make -d permet également de révéler des chemins invalides

Questions connexes