سؤال

لا بد لي من دمج جيل العديد من ملفات 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 دليل، قاعدة البحث يعمل مثل هذا:

  1. انقسام t في جزء دليل، يسمى D، والباقي، يسمى ن. على سبيل المثال، إذا ر هو src/foo.o', then d isSRC / 'و N هو `foo.o'.
  2. قم بإجراء قائمة بجميع قواعد النمط الأول من أهدافها تطابق 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 هو الطريقة القياسية إلى حد ما للتعامل مع الدلائل الفرعية، ولكن احذر من الآثار المذكورة في المقالة "التراكف جعل ضار"

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top