2017-05-06 7 views
0

Fehler: Makefile: 12: *** Rezept beginnt vor dem ersten Ziel. Halt.Rezept beginnt vor dem ersten Ziel

Mein Make-Datei:

objDir := obj 
incDir := include 
srcDir := src 
binDir := bin 
files := matrix palindrome encryption 

define generateObject 
    @nasm -f elf32 -o $(objDir)/$(1).o $(srcDir)/$(1).asm 
endef 

object: $(addprefix $(srcDir)/,$(addsuffix .asm,$(files))) 
    @echo -n "Generating object files... " 
    $(foreach file,$(files),$(eval $(call generateObject,$(file)))) 
    @echo "Done" 

ich in einem Beitrag gelesen, dass dies zu unerwünschten Leerzeichen/Tab aufgrund sein könnte, aber ich konnte keine finden.

Ich versuchte cat -e -t -v Makefile und der Ausgang war:

objDir := obj$ 
incDir := include$ 
srcDir := src$ 
binDir := bin$ 
files := matrix palindrome encryption$ 
$ 
define generateObject$ 
^[email protected] -f elf32 -o $(objDir)/$(1).o $(srcDir)/$(1).asm$ 
endef$ 
$ 
object: $(addprefix $(srcDir)/,$(addsuffix .asm,$(files)))$ 
^[email protected] -n "Generating object files... "$ 
^I$(foreach file,$(files),$(eval $(call generateObject,$(file))))$ 
^[email protected] "Done"$ 
+0

Es ist nichts falsch mit diesem Makefile, das ich sehen kann, und wenn ich damit mache, bekomme ich keinen Fehler so. Welches Betriebssystem benutzen Sie? Welche Version von make benutzt du (rufe 'make --version')? – MadScientist

+0

Ich verwende GNU Make 4.1 auf Ubuntu 16.04. –

Antwort

0

Ihr Problem Nutzung der eval Funktion ist. eval wird verwendet, um make Konstrukte zu analysieren, aber Sie übergeben es einen Shell-Befehl. Betrachten Sie die folgende Zeile:

$(foreach file,$(files),$(eval $(call generateObject,$(file)))) 

Jedes Mal, durch die Liste, die Sie generateObject mit einem Dateinamen nennen wollen. Das wird zu einem Shell-Befehl erweitert; zum Beispiel, wenn file ist Matrix dann call erweitern:

^[email protected] -f elf32 -o obj/matrix.o src/matrix.asm 

Dann nehmen Sie diese Textzeichenfolge und es eval geben, die das als Make-Datei zu lesen versucht. Beachten Sie, dass der an eval übergebene Text in sich ein vollständiges und gültiges Makefile sein muss; Es ist so, als ob Sie reconcursiv aufrufen und diese Zeichenfolge als Makefile angeben, außer dass das Ergebnis der Analyse auf das aktuelle Makefile angewendet wird. Sie können eval nicht nur einen Teil eines gültigen Makefiles (wie eine Befehlszeile in einem Rezept) geben und es in das aktuelle Makefile einfügen. Da diese Zeile für sich nicht gültig ist, erhalten Sie diesen Fehler.

Statt eval auf die Ergebnisse, die Sie in einem Shell-Befehl verketten möchten. Versuchen Sie dies:

define generateObject 
    nasm -f elf32 -o $(objDir)/$(1).o $(srcDir)/$(1).asm 
endef 

object: $(addprefix $(srcDir)/,$(addsuffix .asm,$(files))) 
     @echo -n "Generating object files... " 
     @$(foreach file,$(files),$(call generateObject,$(file)) &&) true 
     @echo "Done" 

Allerdings ist das wirklich nicht "der Weg". Sie möchten nicht mehrere Ziele innerhalb einer einzigen Regel erstellen: Das verhindert den Hauptpunkt von make, da es nur die veralteten Dateien wiederherstellt.

Sie sollten Ihre Make-Datei wie folgt schreiben:

object: $(files:%=$(objDir)/%.o) 

$(objDir)/%.o : $(srcDir)/%.asm 
     @nasm -f elf32 -o [email protected] $< 

Sie brauchen nicht die generateObject Variable oder call oder eval oder sogar foreach.

+0

Danke für die Lösung und Beratung. –

Verwandte Themen