باستخدام جعل $ (dir) أو $ (notdir) على المسار مع المساحات

StackOverflow https://stackoverflow.com/questions/1189781

  •  19-09-2019
  •  | 
  •  

سؤال

أنا أستخدم رمز مشابه لما يلي في 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) وظيفة في جنو تجعل قائمة بالحجج، مفصولة بالمسافات. بعض الوظائف تدعم الهروب من المسافات مع \\, ، لكن $(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 والمسافات في أسماء الملفات، انظر جنو يجعل تلبي أسماء الملفات مع مسافات فيها.

نصائح أخرى

على افتراض أن لديك شل يونيكس، يمكنك قصف:

notdirx = $(shell basename '$1')
dirx = $(shell dirname '$1')

يمكن أن تنطبق استراتيجية مماثلة على وظائف أخرى. فقط تذكر علامات الاقتباس حول المتغير التي تحتوي على النص المصاب بالبييض الذي تريد التعامل معه كوسيطة واحدة. ستحمي هذا أيضا من الشخصيات الخاصة الأخرى (باستثناء علامات الاقتباس!). إليك مثال على المزدوج المزدوج الخط الزائد الهروب من أي مسافات في نتيجة لغرض البرد:

$(shell ls -1 '*.foo' | sed 's/ /\\\\ /g')

يتعرض Windows Presentheses في أسماء الدليل الآن أيضا: C:\Program Files (x86)\ لم يكن واضحا بعد بالنسبة لي ما هي الآثار المترتبة على هذا عند استخدامها make.

هذه مجرد طلقة في الظلام:

TOP='"/home/chris/src/tests/make/space test"'
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top