makefile-Problem
-
Ich versuche seit Tagen ein Makefile zu bauen, steige aber nicht durch die Syntax durch.
Mein GTK+2-Programm benötigt unter Linux eine weitere Bibliothek und einen etwas
anderen Compiler-Aufruf als unter OpenBSD.Mein Versuch:
all: prog CC = gcc CFLAGS=-O3 -std=c99 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 `pkg-config --cflags gtk+-2.0` CFLAGS_L=-O3 -std=c99 -lbsd -D_GNU_SOURCE -D_BSD_SOURCE -D_FILE_OFFSET_BITS=64 `pkg-config --cflags gtk+-2.0` LDFLAGS=`pkg-config --libs gtk+-2.0` prog: prog.c export OS=`uname`; \ if [ $(OS)$ = "Linux" ]; then\ .include <bsd/stdlib.h>; \ $(CC) -o prog prog.c $(CFLAGS_L) $(LDFLAGS);\ else\ $(CC) -o prog prog.c $(CFLAGS) $(LDFLAGS);\ endif
Als Fehlerausgabe bekomme ich:
export OS=`uname`; if [ OpenBSD= "Linux" ]; /bin/sh: syntax error: `if' unmatched
Der Vergleich der beiden Strings sollte doch syntaktisch richtig sein, oder?
Vor den Shell-Befehlen steht immer ein Tab.Vielen Dank für Hilfe, bin am Verzweifeln.
-
Mach keine ifs in Makefiles. Das bringts nicht. Nimm lieber include.
Makefile:ifndef OS OS:=$(shell uname) endif # Defaultwerte hier CC = cc # Überschreiben da include Variablen-fuer-$(OS).mk all: prog prog: $(wildcard *.c) $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS)
CFLAGS=-O3 -std=c99 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 `pkg-config --cflags gtk+-2.0` -DLINUX LDFLAGS=`pkg-config --libs gtk+-2.0`
CFLAGS=-O3 -std=c99 -lbsd -D_GNU_SOURCE -D_BSD_SOURCE -D_FILE_OFFSET_BITS=64 `pkg-config --cflags gtk+-2.0` -DOPEN_BSD LDFLAGS=`pkg-config --libs gtk+-2.0`
Im Code:
#if OPEN_BSD #include <bsd/stdlib.h> // so hab ich das zumindest verstanden #endif
So sieht ein schönes Build-System aus. Plattformabhängige Sachen in externe Dateien auslagern. Und natürlich ist es wichtig, die Syntax zu lernen, das hättest du in den Tagen, in denen du dein Makefile versuchen hast zu erstellen, lernen können.
-
Vielen Dank für deine Hilfe, das werde ich gleich ausprobieren.
Natürlich habe ich versucht, die Syntax zu lernen, aber ich muss sagen,
dass mich die Komplexität von make echt überfordert hat.Danke
-
Hallo nochmal, habe es jetzt so umgesetzt, wie in dem Beispiel.
Bekomme aber folgende Fehlermeldung:
*** Parse error in /home/user/code: Need an operator in 'OS' (Makefile 1) *** Parse error: Need an operator in 'endif' (Makefile 3) *** Parse error: Could not find Variablen-fuer-.mk (Makefile 9)
-
In der Manpage steht:
The ! operator is a BSD extension.
Wenn ich im Makefile den operator ! setze:
!ifndef OS OS:=$(shell uname) !endif
verschwinden die ersten beiden Parse-Fehler, aber die Variable OS wird trotzdem
nicht in den Dateinamen eingesetzt. Hat vielleicht noch jemand eine Idee?Danke
-
Makefiles sind echt übel. Das Problem mit dem if ist, dass da ein Backslash am Ende fehlt:
if [ $(OS)$ = "Linux" ]; \ then\ .include <bsd/stdlib.h>; \ $(CC) -o prog prog.c $(CFLAGS_L) $(LDFLAGS);\ else\ $(CC) -o prog prog.c $(CFLAGS) $(LDFLAGS);\ endif
Wobei ich das .include nicht kenne.
Es seien Dir die Autotools Mythbuster ans Herz gelegt. Autotools sind echt nicht so schwer, wie sie zunächst scheinen. Insbesondere im Vergleich zu händisch geschriebenen Makefiles sind die Autotools weit besser.
-
tntnet schrieb:
Makefiles sind echt übel.
Danke. Ich dachte schon, dass nur mir das so geht.
GNU-autotools habe ich ausprobiert und war nachher noch verwirrter, da es ja noch einige Dateien mehr zu konfigurieren gibt und ein korrektes Makefile auch erstmal Voraussetzung ist. Das Beispiel für das build-system finde ich ganz gut, habe jetzt auch schon ein bisschen mehr begriffen. Ich programmiere unter OpenBSD, es scheint hier doch einige Eigenheiten zu geben, die ich berücksichtigen muss. Es geht eigentlich nur noch darum, der Variable OS die shell-Ausgabe des Befehls 'uname' zu übergeben. Warum das nicht klappt, verstehe ich nicht.
-
Das OpenBSD make funktioniert echt anders. Habe es jetzt folgendermaßen gelöst:
OS!=uname CC = cc .include <$(OS).mk> all: prog prog: $(.c) $(CC) -o $@ $< $(CFLAGS) $(LDFLAGS) all: prog
Das funktioniert unter OpenBSD, allerdings nicht unter Linux.
Ich werde einfach make so aufrufen:
make OS=Linux
oder eben
make OS=OpenBSD
So bin ich das Problem los. Vielen Dank für eure Hilfe.