Nessuna regola per rendere target consoleio.c
-
03-07-2019 - |
Domanda
In un problema recente , ho scoperto che DJGPP può solo accetta il limite di caratteri della riga di comando DOS. Per aggirare questa limitazione, ho deciso di provare a scrivere un makefile per consentirmi di passa stringhe più lunghe . Nel processo di hacking di un makefile e testarlo, ho riscontrato uno strano errore. Il makefile è il seguente:
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 $@
Quando tento di eseguirlo, ricevo questo errore:
make: *** No rule to make target `consoleio.c', needed by `consoleio.o'. Stop.
Quello che non capisco è perché sta cercando di trovare una regola per i file .c. Da quello che ho capito, se il file è lì, dovrebbe semplicemente usarlo. Come faccio a rendere non necessaria una regola per i file .c?
Soluzione
Quello che stai cercando di fare non funzionerà senza VPATH, e poiché stai ancora imparando i makefile, eviterei di usare VPATH.
La regola sta cercando " consoleio.c " ;, che se ho capito bene il tuo makefile non esiste; ciò che esiste è " source / consoleio.c " ;. Probabilmente dovresti cambiarlo in qualcosa come & Quot; $ (SOURCES) /%. C & Quot; anziché "% c " ;.
Non ho verificato la tua sintassi per quella regola, comunque. Se non è corretto, il built-in & Quot;%. O:% .c & Quot; verrà invece utilizzata la regola, che avrebbe lo stesso problema.
Il modo in cui stai facendo non è il solito modo che ho visto, comunque. Il solito modo è:
- Crea una regola implicita "%. o:% .c " (o nel tuo caso "%. o: $ (SOURCES) /%. c ")
- Elenco esplicito delle dipendenze per ciascun file: " foo.o: foo.c bar.h baz.h " (senza comando, la regola implicita ha il comando)
Altri suggerimenti
Proviamo una risposta senza commenti ...
Possibilità A:
- La tua macro per SFILES sta cercando i file che terminano con '
.s
'. - La tua regola per la compilazione di SOBJS è la ricerca di file che terminano con '
.asm
'.
Possibilità B:
- La tua regola per SOBJS e COBJS è in una notazione che non riconosco.
-
Secondo il manuale di GNU Make, puoi scrivere regole implicite come:
% .o:% .c; comando
Sembra che tu abbia un elenco di target $ (SOBJS) che dipende da '%.o : %.asm
'.
Non sono sicuro di come interpreterà make.
Personalmente, non mi fiderei dei caratteri jolly nelle regole di costruzione. Preferirei di gran lunga passare il tempo a elencare esattamente quali file di origine sono necessari per creare il codice. Di conseguenza non mi imbatto spesso in questo problema.
@CesarB sembra aver risolto il problema, aggiungerò solo un paio di osservazioni.
-
Consiglio vivamente di non usare i caratteri jolly nelle regole di compilazione. Le regole di compilazione dovrebbero definire chiaramente ciò che viene creato e non dipendere da quali file si trovano nella directory.
-
Vorrei anche sconsigliare l'uso di VPATH a meno che tu non stia (1) costruendo in una directory di build separata o (2) i tuoi file sorgente siano distribuiti su un gran numero di directory. Se tutte le tue fonti si trovano in una singola directory, l'uso di VPATH confonderà solo.
-
Il modulo di assegnazione: = è di solito usato solo quando la valutazione della variabile impiega molto tempo, come quando si usa un $ (shell ...). Altrimenti, & Quot; = & Quot; è preferibile.
-
Uso di " export " propagare OUTDIR a concat.py (cosa che presumo sia, poiché concat.py non accetta alcun parametro) è un odore di codice. Se possibile, passalo invece come parametro.