を利用し$(dir)は$(notdir)のワンデーパスが付いた空間
質問
私が使っているコード、例えば次のようなものになり、Makefile:
empty:=
space:= $(empty) $(empty)
path_escape = $(subst $(space),\$(space),$(1))
TOP=$(call path_escape,$(abspath .))
TARGET=$(TOP)/foo
$(info TOP='$(TOP)')
$(info TARGET='$(TARGET)')
all: $(TARGET)
$(TARGET):
touch '$(notdir $@)'
.PHONY: $(TARGET)
を利用した場合、このディレクトリにない空間と言う space-test
, で動作す:
$ make
TOP='/tmp/space-test'
TARGET='/tmp/space-test/foo'
touch 'foo'
ただし、使ってもディレクトリを半角スペースという space test
, その $(notdir)
は間違ったもの:
TOP='/tmp/space\ test'
TARGET='/tmp/space\ test/foo'
touch 'space foo'
ということは $(notdir)
解釈 /tmp/space test/foo
として 二つの パスを返します"ファイル部"の 両 ( space
や foo
).の奇妙なこと TARGET
が適切にエスケープされた;なんだか、内側のルールや内部 $(notdir)
, のバックスラッシュエスケープは無視されます。
なぜですか。
解決
の $(notdir)
機能にGNU Makeコマンドの、引数のリスト、スペースで区切られた.一部の機能支援の脱出空間 \\
, ものの、 $(notdir)
ではない。
この仕事:
s? = $(subst $(empty) ,?,$1)
?s = $(subst ?, ,$1)
notdirx = $(call ?s,$(notdir $(call s?,$1)))
$(TARGET):
touch '$(call notdirx,$@)'
この"空間-安全"バージョンの notdir
という notdirx
.これはシンプルです: s?
最初のすべての出力スペース問題(えることはできませんの現在のファイル名) ?s
に変換します。としての独自の notdir
機能です。
優れた概要にGNU Makeコマンドの名前空間ファイル名は、 GNU Makeを満たすファイル名を半角スペースにて.
他のヒント
あなたはUnixシェルを持っていると仮定すると、あなたが支払うことができます:
notdirx = $(shell basename '$1')
dirx = $(shell dirname '$1')
同様の戦略は、他の関数にも適用することができます。ちょうどあなたが1つの引数として扱いたい空白に感染したテキストを格納する変数の周りに引用符を覚えています。また、これは他の特殊文字からあなたを守ります(引用符を除きます!)。ここでは、二重のバックスラッシュにワイルドカードグロブの結果にスペースをエスケープ例です。
$(shell ls -1 '*.foo' | sed 's/ /\\\\ /g')
Windowsは、あまりにも、今のディレクトリ名に括弧を入れている:それは、この使用C:\Program Files (x86)\
の意味が何であるか、まだ私にははっきりしないmake
これは、暗闇の中でだけでショットです。
TOP='"/home/chris/src/tests/make/space test"'