2008-10-19 3 views
1

В recent issue я обнаружил, что DJGPP может принимать только ограничение символов командной строки DOS. Чтобы обойти это ограничение, я решил попытаться написать файл makefile, чтобы разрешить мне pass longer strings. В процессе взлома файла makefile и его тестирования я столкнулся с странной ошибкой. Makefile выглядит следующим образом:Нет правила для создания цели consoleio.c

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 [email protected] $^ 

$(SOBJS) : %.o : %.asm 
    $(AS) $(ASFLAGS) $< -o [email protected] 

$(COBJS) : %.o : %.c 
    $(CC) -c $< $(CFLAGS) -o [email protected] 

При попытке запустить его, я получаю эту ошибку:

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

То, что я не понимаю, почему он пытается найти правила для .c файлов. Насколько я понимаю, если файл есть, он должен просто использовать его. Как сделать make не нужно правило для .c файлов?

+0

(a) Что заставляет вас думать, что make-файл может обойти ограничение командной строки? (b) Каков исходный файл для consoleio.o? (c) Разве это не слишком странно, чтобы кодировать в ассемблере вообще? – 2008-10-19 17:59:02

+0

Продолжение: (d) И какая версия «make» вы нацеливаете с помощью: = присваиваний? Это нестандартная нотация. – 2008-10-19 18:00:04

+0

(a) http://www.delorie.com/djgpp/v2faq/faq16_4.html (b) consoleio.c (c) Он есть для многозадачного заголовка и немного больше. – 2008-10-19 18:05:18

ответ

3

То, что вы пытаетесь сделать, не будет работать без VPATH, и поскольку вы все еще изучаете make-файлы, я бы избегал использования VPATH.

Правило ищет «consoleio.c», который, если я правильно понял ваш makefile, не существует; что существует «source/consoleio.c». Вероятно, вы должны изменить его на нечто вроде «$ (SOURCES) /%. C» вместо «% c».

Однако я не проверял ваш синтаксис для этого правила. Если это неверно, вместо этого будет использовано встроенное правило «% .o:% .c», которое будет иметь ту же проблему.

То, как вы это делаете, это не обычный способ, который я видел. Обычный способ заключается в следующем:

  • Создать неявное правило "% .o:% .c" (или в случае "% .o: $ (ИСТОЧНИКИ) /% с.")
  • Явного список зависимости для каждого файла: «foo.o: foo.c bar.h baz.ч»(без команды, неявное правило имеет команду)
2

Давайте попробуем без комментария ответ ...

Возможность A:

  • Ваш макрос SFILES ищет файлы, оканчивающиеся на '.s'.
  • Ваше правило для составления SOBJS ищет файлы, заканчивающиеся на '.asm'.

Возможность B:

  • Ваше правило SOBJS и COBJS в нотации я не признаю.
  • В соответствии с GNU Make Manual, вы можете написать неявные правила, как:

    % .o:% .c; Команда

Вы, кажется, есть список целевых $ (SOBJS), что зависит от '%.o : %.asm'. Я не уверен, как make интерпретирует это.

Лично я не буду доверять диким картам в правилах сборки. Я бы скорее потратил время на перечисление именно того, какие исходные файлы необходимы для сборки кода. В результате я не часто сталкиваюсь с этой проблемой.

2

@CesarB, кажется, прибили вопрос, я просто добавить пару наблюдений.

  1. Я бы сильно Рекомендуем не использовать подстановочные знаки в правилах сборки. Правила сборки должны четко определять, что именно строится, и не зависеть от того, какие файлы находятся в каталоге.

  2. Я бы также рекомендовал против использования VPATH, если вы не находитесь (1) создание в отдельном каталоге компоновки или (2) распространение исходных файлов на большой количество каталогов. Если все ваши источники находятся в одном каталоге, использование VPATH только запутается.

  3. Форма присваивания обычно используется, когда известно, что оценка переменной занимает много времени, например при использовании $ (shell ...). В противном случае предпочтительнее «=».

  4. Использование «export» для распространения OUTDIR на concat.py (что я полагаю, поскольку concat.py не принимает никаких параметров) является запахом кода. Если возможно, передайте его как параметр.