سؤال

في العدد الأخير, ، لقد وجدت أن DJGPP يمكنه فقط قبول عدد الأحرف المسموح به في سطر أوامر DOS.للتغلب على هذا القيد، قررت أن أحاول كتابة ملف تعريف للسماح لي بذلك تمرير سلاسل أطول.أثناء عملية اختراق ملف makefile واختباره، واجهت خطأً غريبًا.ملف التعريف هو كما يلي:

AS  :=  nasm
CC  :=  gcc
LD  :=  ld

TARGET      :=  $(shell basename $(CURDIR))
BUILD       :=  build
SOURCES     :=  source

CFLAGS  :=  -Wall -O -fstrength-reduce -fomit-frame-pointer -finline-functions \
            -nostdinc -fno-builtin -I./include
ASFLAGS :=  -f aout

export OUTPUT   :=  $(CURDIR)/$(TARGET)

CFILES      :=  $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
SFILES      :=  $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))

SOBJS   :=  $(SFILES:.s=.o)
COBJS   :=  $(CFILES:.c=.o)
OBJS    :=  $(SOBJS) $(COBJS)

build   :   $(TARGET).img

$(TARGET).img   :   $(TARGET).bin
    concat.py

$(TARGET).bin   :   $(OBJS)
    $(LD) -T link.ld -o $@ $^

$(SOBJS)    :   %.o :   %.asm
    $(AS) $(ASFLAGS) $< -o $@

$(COBJS)    :   %.o :   %.c
    $(CC) -c $< $(CFLAGS) -o $@

عند محاولة تشغيله، أتلقى هذا الخطأ:

make: *** No rule to make target `consoleio.c', needed by `consoleio.o'.  Stop.

ما لا أفهمه هو سبب محاولته العثور على قاعدة لملفات .c.مما أفهمه، إذا كان الملف موجودًا، فيجب استخدامه فقط.كيف أجعل make لا يحتاج إلى قاعدة لملفات .c؟

هل كانت مفيدة؟

المحلول

ما تحاول القيام به لن يعمل بدون VPATH، وبما أنك لا تزال تتعلم ملفات الإنشاء، فإنني سأتجنب استخدام VPATH.

القاعدة تبحث عن "consoleio.c"، والذي إذا فهمت ملف تعريفك بشكل صحيح فهو غير موجود؛الموجود هو "source/consoleio.c".ربما يتعين عليك تغييره إلى شيء مثل "$(SOURCES)/%.c" بدلاً من "%c".

ومع ذلك، لم أتحقق من بناء الجملة الخاص بك لهذه القاعدة.إذا كان غير صحيح، فإن المدمج "%.o:سيتم استخدام قاعدة "%.c" بدلاً من ذلك، والتي ستكون لها نفس المشكلة.

الطريقة التي تفعل بها ليست الطريقة المعتادة التي رأيتها.الطريقة المعتادة هي:

  • إنشاء قاعدة ضمنية "%.o:%.c" (أو في حالتك "%.o:$(المصادر)/%.c")
  • قائمة صريحة بالتبعيات لكل ملف:"foo.o:foo.c bar.h baz.h" (بدون أمر، القاعدة الضمنية لها الأمر)

نصائح أخرى

دعونا نحاول الإجابة بدون تعليق ...

الاحتمال أ:

  • يبحث الماكرو الخاص بـ SFILES عن الملفات التي تنتهي بـ '.s'.
  • القاعدة الخاصة بك لتجميع SOBJS هي البحث عن الملفات التي تنتهي بـ ".asm'.

الاحتمال ب:

  • القاعدة الخاصة بك لـ SOBJS و COBJS موجودة في ملاحظة لا أعرفها.
  • وفقًا لدليل GNU Make، يمكنك كتابة القواعد الضمنية على النحو التالي:

    %.o :%.ج ; يأمر

يبدو أن لديك قائمة بالأهداف $(SOBJS) التي تعتمد على "%.o : %.asm'.لست متأكدًا من كيفية تفسير ذلك.

أنا شخصياً لا أثق في البطاقات البرية في قواعد البناء.أفضل قضاء الوقت في سرد ​​الملفات المصدر المطلوبة لإنشاء الكود بالضبط.لا أواجه هذه المشكلة غالبًا نتيجة لذلك.

يبدو أن @CesarB قد نجح في حل المشكلة، وسأضيف بعض الملاحظات فقط.

  1. أوصي بشدة بعدم استخدام أحرف البدل في قواعد البناء.يجب أن تحدد قواعد البناء بوضوح ما يتم إنشاؤه بالضبط، ولا تعتمد على الملفات الموجودة في الدليل.

  2. أوصي أيضًا بعدم استخدام VPATH إلا إذا كنت (1) تقوم بالإنشاء في دليل بناء منفصل، أو (2) تنشر ملفات المصدر الخاصة بك على عدد كبير من الدلائل.إذا كانت جميع مصادرك موجودة في دليل واحد، فإن استخدام VPATH لن يؤدي إلا إلى الإرباك.

  3. عادة ما يتم استخدام نموذج المهمة := فقط عندما يكون من المعروف أن تقييم المتغير يستغرق وقتًا طويلاً، كما هو الحال عند استخدام $(shell ...).خلاف ذلك، "= هو الأفضل.

  4. يعد استخدام "تصدير" لنشر OUTDIR إلى concat.py (وهو ما أفترضه، نظرًا لأن concat.py لا يأخذ أي معلمات) بمثابة رائحة رمزية.إذا أمكن، قم بتمريرها كمعلمة بدلاً من ذلك.

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