Der Versuch mit einer Makefile-Regel wie der folgenden hat nicht funktioniert (GNU Make 4.0):
foo: [email protected] other.o
bar: bar.o other.o
Die Datei foo.c
wurde (zu foo.o
) kompiliert, aber der Linkbefehl war cc -o .o
.
Im Gegensatz dazu bar
wurde korrekt als kompiliert und verknüpft cc bar.o other.o -o bar
.
Wer kann den Unterschied (oder das Problem) erklären?
Antwort1
Dies wird im Abschnitt überAutomatische Variablenim GNU Make-Handbuch:
Es ist sehr wichtig, dass Sie den begrenzten Umfang erkennen, in dem automatische Variablenwerte verfügbar sind: Sie haben nur Werte innerhalb des Rezepts. Insbesondere können Sie sie nirgendwo in der Zielliste einer Regel verwenden; sie haben dort keinen Wert und werden zu einer leeren Zeichenfolge erweitert. Außerdem kann nicht direkt innerhalb der Voraussetzungsliste einer Regel auf sie zugegriffen werden. Ein häufiger Fehler ist der Versuch, sie
$@
innerhalb der Voraussetzungsliste zu verwenden; das funktioniert nicht.
Der Rest des Absatzes bietet eine mögliche Lösung, allerdings eine GNU Make-spezifische:Sekundärerweiterung. Schreiben Sie Ihr Makefile als
.SECONDEXPANSION:
foo: [email protected] other.o
bar: bar.o other.o
ermöglicht $$@
die Angabe des entsprechenden Wertes und dann
$ make foo
cc -c -o foo.o foo.c
cc -c -o other.o other.c
cc foo.o other.o -o foo
tut, was Sie hoffen, dass es tut.
(Meiner Erfahrung nach gibt es in der Regel bessere Möglichkeiten, ein Problem anzugehen, als auf eine sekundäre Erweiterung zurückzugreifen. Dies lässt sich jedoch nur feststellen, wenn man das Gesamtziel dessen versteht, was man zu tun versucht.)