جنو يصنع مع العديد من الدلائل المستهدفة
-
06-09-2019 - |
سؤال
لا بد لي من دمج جيل العديد من ملفات HTML في موجودة Makefile
وبعد المشكلة هي أن ملفات HTML تحتاج إلى الإقامة في العديد من الدلائل المختلفة. فكرتي هي كتابة قاعدة ضمنية تقوم بتحويل الملف المصدر (* .st) إلى ملف HTML المقابل
%.html: %.st
$(HPC) -o $@ $<
وقاعدة تعتمد على جميع ملفات HTML
all: $(html)
إذا كان ملف HTML ليس في Builddir make
لا تجد القاعدة الضمنية: *** No rule to make target
وبعد إذا قمت بتغيير القاعدة الضمنية مثل ذلك
$(rootdir)/build/doc/2009/06/01/%.html: %.st
$(HPC) -o $@ $<
تم العثور عليه، ولكن بعد ذلك، يجب أن أحصل على قاعدة ضمنية لكل ملف تقريبا في المشروع. وفق خوارزمية البحث الضمنية في جنو make
دليل، قاعدة البحث يعمل مثل هذا:
- انقسام t في جزء دليل، يسمى D، والباقي، يسمى ن. على سبيل المثال، إذا ر هو
src/foo.o', then d is
SRC / 'و N هو `foo.o'.- قم بإجراء قائمة بجميع قواعد النمط الأول من أهدافها تطابق T أو N. إذا كان النمط المستهدف يحتوي على مائل، فإنه يتناسب مع T؛ خلاف ذلك، ضد ن.
لماذا لا يتم العثور على القاعدة الضمنية، وما سيكون الحل الأكثر أناقة، على افتراض جنو make
يستخدم؟
هنا نسخة مخطوعة من بلدي Makefile
:
rootdir = /home/user/project/doc
HPC = /usr/local/bin/hpc
html = $(rootdir)/build/doc/2009/06/01/some.html
%.html: %.st
$(HPC) -o $@ $<
#This works, but requires a rule for every output dir
#$(rootdir)/build/doc/2009/06/01/%.html: %.st
# $(HPC) -o $@ $<
.PHONY: all
all: $(html)
المحلول
مثل Maria Shalnova، أحب إجراء العودية (على الرغم من أنني لا أتفق مع "العودية تجعل ضارا")، وبشكل عام من الأفضل أن أجعل شيئا هنا من مصدر هناك، وليس العكس. ولكن إذا طلب منك ذلك، أقترح تحسين طفيف: هل تولد GendateHTML القاعدة فقط، وليس الأوامر.
نصائح أخرى
أفضل حل وجدت حتى الآن هو إنشاء قاعدة ضمنية لكل دليل الهدف عبر foreach-eval-call, ، كما هو موضح في جنو make
كتيب. وبعد ليس لدي أي فكرة عن كيفية هذه الموازين إلى بضعة آلاف من الدلائل المستهدفة، لكننا سنرى ...
إذا كان لديك حل أفضل، فيرجى نشرها!
هنا هو الرمز:
rootdir = /home/user/project/doc
HPC = /usr/local/bin/hpc
html = $(rootdir)/build/doc/2009/06/01/some.html \
$(rootdir)/build/doc/2009/06/02/some.html
targetdirs = $(rootdir)/build/doc/2009/06/01 \
$(rootdir)/build/doc/2009/06/02
define generateHtml
$(1)/%.html: %.st
-mkdir -p $(1)
$(HPC) -o $$@ $$<
endef
$(foreach targetdir, $(targetdirs), $(eval $(call generateHtml, $(targetdir))))
.PHONY: all
all: $(html)
القاعدة الضمنية النشطة تجعل $(rootdir)/build/doc/2009/06/01/some.html
يعتمد على $(rootdir)/build/doc/2009/06/01/some.st
. وبعد إذا $(rootdir)/build/doc/2009/06/01/some.st
غير موجود ثم لن يتم استخدام القاعدة / وجدت.
حكم علق يجعل $(rootdir)/build/doc/2009/06/01/some.html
يعتمد على some.st
.
أحد الحلول هو جعلك تخطيط المصدر الذي تطابق تخطيط وجهتك / نتيجة.
خيار آخر هو إنشاء القواعد كما هو مطلوب مع eval
. وبعد ولكن سيكون ذلك معقدا جدا:
define HTML_template
$(1) : $(basename $(1))
cp $< $@
endef
$(foreach htmlfile,$(html),$(eval $(call HTML_template,$(htmlfile))))
احتمال آخر هو الحصول على كوماندوز make
اتصل بنفسها بشكل متكرر مع وسيطة -c مع كل دليل الإخراج. العودية make
هو الطريقة القياسية إلى حد ما للتعامل مع الدلائل الفرعية، ولكن احذر من الآثار المذكورة في المقالة "التراكف جعل ضار"