amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > AOS4 GCC und makefile-Probleme [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

03.01.2013, 22:57 Uhr

Reth
Posts: 1858
Nutzer
Hallo mal wieder zusammen,

bin eigentlich ein Bewunderer der Möglichkeiten von make, allerdings werd ich da wohl nie richtig durchsteigen, egal, wie viele Tutorials und Beispiele ich dazu noch anschaue!

Habe mir die Sourcen von GigaLoMania runtergeladen und versucht, das Makefile in Codebench auf zu rufen. Allerdings findet dort make keine Regel für das Erstellen von game.o!

Es scheint, als ob make die Regel .cpp.o: nicht versteht. Liegt das an der Version, die für AOS4 benutzt wird? Oder was könnte hier das Problem sein?

Danke schon mal für eure Infos!

Ciao


Anbei mal das makefile:
C code:
CC=g++
CCFLAGS=-O2 -Wall
CFILES=game.cpp gamestate.cpp gui.cpp image.cpp main.cpp panel.cpp player.cpp resources.cpp screen.cpp sector.cpp sound.cpp utils.cpp
HFILES=game.h gamestate.h gui.h image.h panel.h player.h resources.h screen.h sector.h sound.h utils.h common.h stdafx.h
OFILES=game.o gamestate.o gui.o image.o panel.o player.o resources.o screen.o sector.o sound.o utils.o main.o
APP=gigalomania
INC='sdl-config --cflags'
LINKPATH='sdl-config --libs' -L/usr/X11R6/lib/ -L/usr/lib

LIBS=-lSDL_image -lSDL_mixer

all: $(APP)

$(APP): $(OFILES) $(HFILES) $(CFILES)
	$(CC) $(OFILES) $(CCFLAGS) $(LINKPATH) $(LIBS) -o $(APP)

.cpp.o:
	$(CC) $(CCFLAGS) -O2 $(INC) -c $<

# REMEMBER to update debian/dirs if the system directories that we use are changed!!!
install: $(APP)
	mkdir -p $(DESTDIR)/opt/gigalomania # -p so we don't fail if folder already exists
	cp $(APP) $(DESTDIR)/opt/gigalomania
	cp readme.html $(DESTDIR)/opt/gigalomania
	cp -a gfx/ $(DESTDIR)/opt/gigalomania # -a need to copy permissions etc
	cp -a islands/ $(DESTDIR)/opt/gigalomania
	cp -a sound/ $(DESTDIR)/opt/gigalomania
	cp gigalomania.desktop $(DESTDIR)/usr/share/applications/
	cp gigalomania_fullscreen.desktop $(DESTDIR)/usr/share/applications/
	cp gigalomania64.png $(DESTDIR)/usr/share/pixmaps/
# REMEMBER to update debian/dirs if the system directories that we use are changed!!!

uninstall:
	rm -rf $(DESTDIR)/opt/gigalomania # -f so we don't fail if folder doesn't exist
	rm -f $(DESTDIR)/usr/share/applications/gigalomania.desktop
	rm -f $(DESTDIR)/usr/share/applications/gigalomania_fullscreen.desktop
	rm -f $(DESTDIR)/usr/share/pixmaps/gigalomania64.png

install_maemo: $(APP)
	mkdir -p $(DESTDIR)/opt/gigalomania # -p so we don't fail if folder already exists
	cp $(APP) $(DESTDIR)/opt/gigalomania
	cp -a gfx/ $(DESTDIR)/opt/gigalomania # -a need to copy permissions etc
	cp -a islands/ $(DESTDIR)/opt/gigalomania
	cp -a sound/ $(DESTDIR)/opt/gigalomania
	mkdir -p $(DESTDIR)/usr/share/applications/hildon/
	cp gigalomania_maemo.desktop $(DESTDIR)/usr/share/applications/hildon/
	mkdir -p $(DESTDIR)/usr/share/pixmaps
	cp gigalomania48.png $(DESTDIR)/usr/share/pixmaps/
	chmod a+x gigalomania_mobile.sh # workaround for permissions not set in zip file!
	mkdir -p $(DESTDIR)/usr/bin/
	cp gigalomania_mobile.sh $(DESTDIR)/usr/bin/gigalomania_mobile.sh

uninstall_maemo:
	rm -rf $(DESTDIR)/opt/gigalomania # -f so we don't fail if folder doesn't exist
	rm -f $(DESTDIR)/usr/share/applications/hildon/gigalomania_maemo.desktop
	rm -f $(DESTDIR)/usr/share/pixmaps/gigalomania48.png
	rm -f $(DESTDIR)/usr/bin/gigalomania_mobile.sh

install_meego: $(APP)
	mkdir -p $(DESTDIR)/opt/gigalomania # -p so we don't fail if folder already exists
	cp $(APP) $(DESTDIR)/opt/gigalomania
	cp -a gfx/ $(DESTDIR)/opt/gigalomania # -a need to copy permissions etc
	cp -a islands/ $(DESTDIR)/opt/gigalomania
	cp -a sound/ $(DESTDIR)/opt/gigalomania
	cp gigalomania_maemo.desktop $(DESTDIR)/usr/share/applications/
	mkdir -p $(DESTDIR)/usr/share/icons/hicolor/48x48/apps/
	cp gigalomania48.png $(DESTDIR)/usr/share/icons/hicolor/48x48/apps/
	chmod a+x gigalomania_mobile.sh # workaround for permissions not set in zip file!
	mkdir -p $(DESTDIR)/usr/bin/
	cp gigalomania_mobile.sh $(DESTDIR)/usr/bin/gigalomania_mobile.sh

uninstall_meego:
	rm -rf $(DESTDIR)/opt/gigalomania # -f so we don't fail if folder doesn't exist
	rm -f $(DESTDIR)/usr/share/applications/gigalomania_maemo.desktop
	rm -f $(DESTDIR)/usr/share/icons/hicolor/48x48/apps/gigalomania48.png
	rm -f $(DESTDIR)/usr/bin/gigalomania_mobile.sh

clean:
	rm -rf *.o
	rm -f $(APP)


[ - Antworten - Zitieren - Direktlink - ]

04.01.2013, 22:20 Uhr

Reth
Posts: 1858
Nutzer
Ups, habe gerade gesehen, dass ich ja die Header und Sourcen in eigene Unterverzeichnisse gesteckt habe und diese hier im Makefile noch fehlen.

Weiss zufällig jmd., wie ich bei solchen allgemeinen Pattern in makefiles noch Verzeichnisse für die Source-, Header- und Objektdateien angeben kann?

Danke schon mal (werde demnächst erst mal das makefile mit den original-entpackten Dateien testen, dort liegt alles im selben Verzeichnis).

Ciao

[ - Antworten - Zitieren - Direktlink - ]

05.01.2013, 12:15 Uhr

jolo
Posts: 110
Nutzer
Zitat:
Original von Reth:
.cpp.o:
$(CC) $(CCFLAGS) -O2 $(INC) -c $<


Das kann nicht funktionieren; korrekt müsste es so lauten:

code:
%.o: %.cpp


Bei manchen 'Make'-Applikationen darf man den '.' vor der Dateiendung weglassen:

code:
%o: %cpp




Merke, jede Regel wird so formuliert:

code:
Ziel: Voraussetzung [Voraussetzung] [Voraussetzung] [...]
	[Rezeptur]
	[...]
	[...]


Dabei können getrennt durch Freizeichen oder Tabs mehrere Voraussetzungen angegeben werden.
Auch kann man die Rezeptur(en) weglassen, und die voreingestellte Handhabung dieser Regel durch 'make' ausführen lassen.

Z.B. würde ich die Regel für "%.o: %.cpp" gar nicht spezifizieren, sondern am Ende des Quelltextes für 'make' die Regeln aufstellen, und zwar für jeden C++ Quellcode:

# dependencies
name1.o: name1.cpp name1.h name2.h name3.h
name2.o: name2.cpp name2.h name4.h name7.h
name3.o: name3.cpp name3.h name7.h name8.h
usw.

Anbei, Deine Dateien, die in HFILES gelistet sind, spielen nur beim Übersetzen der '.cpp'-Dateien eine Rolle (also deren Voraussetzung), nicht jedoch für das Erstellen des eigentlichen Ziels ("APP=gigalomania")! Ergo, gehören sie nicht in die Regel für "$(APP)", da sie hier nichts bewerkstelligen!



Zitat:
Original von Reth:
Ups, habe gerade gesehen, dass ich ja die Header und Sourcen in eigene Unterverzeichnisse gesteckt habe und diese hier im Makefile noch fehlen.

Weiss zufällig jmd., wie ich bei solchen allgemeinen Pattern in makefiles noch Verzeichnisse für die Source-, Header- und Objektdateien angeben kann?



[code]
Aus,
%.o: %.cpp

das machen:


OBJDIR = deinVerzeichnis/
SRCDIR = deinVerzeichnis/

und dann:

$(OBJDIR)%.o: $(SRCDIR)%.cpp
[code]

Obacht, falls Du GNU-Make verwendest musst Du evtl. die UNIX-Schreibweise für Verzeichnisebenen anwenden, z.B. "../" anstelle von "/" oder "." anstelle von "".

Grüße

[ - Antworten - Zitieren - Direktlink - ]

05.01.2013, 12:50 Uhr

Thore
Posts: 2266
Nutzer
Och das .cpp.o ist durchaus üblich bei make.
Allerdings denke ich daß es Versionsabhängig ist.

Ich hatte auch schon Probleme mit Leerzeichen, Tabulatoren und Returncodes. Hab dazu mal einen Converter geschrieben der die Zeichen für mich anpasst.

[ - Antworten - Zitieren - Direktlink - ]

05.01.2013, 20:11 Uhr

Reth
Posts: 1858
Nutzer
Dank euch! Hab in der Zwischenzeit noch einige Tutorials etc. gewälzt. Aber bin noch nicht darauf gekommen, was .cpp.o: genau bedeuten. Mein Verständnis: Für alle Dateien mit Endung cpp und alle Dateien mit Endung o folgende Regel anwenden. Stimmt das so, oder gibt es da noch einen adäquateren Wortlaut für?

Hab das mit make nochmal ausprobiert. Die Sourcen neu entpackt, ins Verzeichnis gewechselt und make aufgerufen. Funktioniert soweit einwandfrei. Allerdings kennt es sdl-config nicht. Das klappt nur, wenn ich in die sh wechsle und dort make bzw. gmake aufrufe (denn die sh kennt das Verzeichnis, in dem sdl-config liegt).

Weiss jmd., wie ich make aus der Amiga-Shell auch dazu bekomme, sdl-config nutzen zu können? SDL ist normal installiert.

Eine Variante wäre, den Pfad zu erweitern, so dass auch dort gesucht wird, wo sdl-config abgelegt ist. Aber reicht das schon aus im Sinne korrekter Konfiguration der Installationen (SDL und SDK)?

[ Dieser Beitrag wurde von Reth am 05.01.2013 um 20:13 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

06.01.2013, 22:04 Uhr

Reth
Posts: 1858
Nutzer
Also den Fall:
code:
.cpp.o:
	$(CC) $(CCFLAGS) -O2 $(INC) -c $<

hab ich nun auch schon des Öfteren gesehen. Hat ja bei mir dann auch noch geklappt.

Zitat:
Original von jolo:
code:
Aus,
%.o: %.cpp

das machen:


OBJDIR = deinVerzeichnis/
SRCDIR = deinVerzeichnis/

und dann:

$(OBJDIR)%.o: $(SRCDIR)%.cpp



Weiss auch jmd. wie ich getrennte Pfade für src und object in dem o.g. Fall angebe, also in:
code:
.cpp.o:
    $(CC) $(CCFLAGS) -O2 $(INC) -c $<

Danke schon mal!

Ciao

[ - Antworten - Zitieren - Direktlink - ]

07.01.2013, 13:00 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Dank euch! Hab in der Zwischenzeit noch einige Tutorials etc. gewälzt. Aber bin noch nicht darauf gekommen, was .cpp.o: genau bedeuten. Mein Verständnis: Für alle Dateien mit Endung cpp und alle Dateien mit Endung o folgende Regel anwenden. Stimmt das so, oder gibt es da noch einen adäquateren Wortlaut für?

Nein, aus einer Datei mit der Endung cpp soll eine Datei mit der Endung o generiert werden.

Zitat:
Original von Reth:
Weiss auch jmd. wie ich getrennte Pfade für src und object in dem o.g. Fall angebe, …

Ich verstehe die Frage nicht, genau das hat jolo doch gepostet.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

07.01.2013, 19:04 Uhr

jolo
Posts: 110
Nutzer
@Thore

Hast recht, ".cpp.o:" ist die Kurzschreibweise für "%.o: %.cpp", Bisher habe ich dies aber nur unter "nmake" (Windows Visual Studio Tool-Chain) verwendet und nennt sich dort "Suffix-Regel". Dass GNU-Make es auch unterstützt, wusste ich bis dato nicht, da ich selber immer die Standard-Notation unter GNU-Make verwende. Manchmal sollte ich doch mal einen Blick in die Anleitung werfen...

'nmake' (Windows) Beispiel:

code:
# Compile the sources to objects within the root of the sources tree,
# and then move them into the objects directory. Afterwards delete the
# objects in the root of the sources tree.
{$(WRKDIR)}.cpp{$(OBJDIR)}.obj:
	$(CC) $(CCFLAGS) $(DEFINES) /c $<
	copy $(*F).obj $(*R).obj
	erase $(*F).obj


Wie auch immer, es mutet sich komisch für mich an, da bei dieser Suffix-Regel erst die Voraussetzung und dann das Ziel spezifiziert wird. Aber egal; wenn es denn funktioniert kann man es als solches auch benutzen.


@Reth

Vielleicht unterstützt Deine Version von GNU-Make auch das nachstehende, damit kannst Du bei Deinem 'make-file' einiges an Tipparbeit einsparen:

code:
# Alle Quelldateien
SRCS = main.cpp nnn.cpp xxx.cpp yyy.cpp

# Objektdateien anhand der Quelldateien :) 
OBJS = $(SRCS:.cpp=.o)



Zitat:
Weiss jmd., wie ich make aus der Amiga-Shell auch dazu bekomme, sdl-config nutzen zu können? SDL ist normal installiert.

Nee, leider nicht. Habe weder die SDL Header-Dateien noch SDL selber hier installiert.



Mal ein kurzes Beispiel für Objektdateien die *nicht* innerhalb des Quellcodeverzeichnisses erstellt werden; da ich selten in C++ programmiere, hier das Beispiel für den 'vbcc'-Compiler und anhand imaginärer C-Quellcodes:

code:
# Spezielles POSIX-Verzeichnis für vbcc m68k...
POSIXINC = vbcc:targets/m68k-amigaos/posix

# Wohin kommen die Objektdateien?
OBJDIR = objects

# Objektdateien
OBJS =  $(OBJDIR)/main.o  
	$(OBJDIR)/addon.o

# Zielprogramm
TARGET = mytestprogram

# Compiler
CC = vc +aos68k -DAMIGA

# Andere Werkzeuge
MKDIR	= MakeDir
RM	= Delete
RMOPTS	= ALL QUIET

# Merkmale fürs Kompilieren
CFLAGS  = -I$(POSIXINC) -I"" -c99 -cpu=68020 -fpu=68881 -O1 -c

# Merkmale fürs Linken
LDFLAGS = -lvc -lposix -lamiga -lm881

# Erste Regel...
all: $(TARGET)

# Linken...
$(TARGET): $(OBJDIR) $(OBJS)
	$(CC) -o $(TARGET) $(OBJS) $(LDFLAGS)

# Unterverzeichnis erstellen, falls nicht vorhanden...
$(OBJDIR):
	$(MKDIR) $(OBJDIR)

# Alles zurücksetzen...
clean: FORCE
	@$(RM) $(RMOPTS) $(OBJDIR)
	@$(RM) $(RMOPTS) $(TARGET)
FORCE:

# Abhängigkeiten schaffen und kompilieren... (*1)
$(OBJDIR)/main.o: main.c dependencies.h
	$(CC) $(CFLAGS) $< -o $@
$(OBJDIR)/addon.o: addon.c adddon.h rules.h
	$(CC) $(CFLAGS) $< -o $@


(*1) Der Nachteil hier ist dass, falls ein anderes Verzeichnis für die Objektdateien gewählt wurde, man explizit den Compiler-Aufruf angeben muss, inklusive Ausgabedatei (-o $@)! Wenn Quell- und Objektdateien sich im gleichen Verzeichnis befinden, kann dieses "Rezept" entfallen!


Grüße


[ - Antworten - Zitieren - Direktlink - ]

07.01.2013, 22:06 Uhr

Reth
Posts: 1858
Nutzer
Nochmals Dank.
Zitat:
Original von Holger:
Nein, aus einer Datei mit der Endung cpp soll eine Datei mit der Endung o generiert werden.

Hm, aber die Regel wird doch automatisch auf alle cpp-Dateien angewandt. Laut Tutorials bedeutet dabei $< die erste Abhängigkeit (in dem Fall dann die cpp-Datei). Wie wird nun make dazu veranlasst, alle cpp-Dateien dadurch zu compilieren und nicht nur eine? Hatte die Regel so verstanden, dass sie alle cpp-Dateien, die gefunden werden in der angegebenen Art und Weise bearbeitet. Oder werden nur alle cpp-Dateien genommen, die im makefile angegeben sind und mit in der $(APP)-Regel auftauchen?
Zitat:
Original von Holger:
Ich verstehe die Frage nicht, genau das hat jolo doch gepostet.

Hab ich jetzt auch verstanden, nachdem Jolo seinen nächsten Post mit folgendem Teil gemacht hatte:
Zitat:
Original von Jolo:
".cpp.o:" ist die Kurzschreibweise für "%.o: %.cpp"

Das wusste ich nicht. Find ich auch komisch, da die Angabereihenfolge von target und Abhängigkeit komplett umgekehrt ist. War verwirrend.

@Jolo:
Danke nochmal für Deine Ausführungen. Die "normale" Angabe einer Regel mit entsprechenden Variablen für Pfadnamen kannte ich schon. Aber die Kurzschreibweise (oder "Suffix-Regel") war mir dagegen unbekannt.

[ - Antworten - Zitieren - Direktlink - ]

07.01.2013, 22:53 Uhr

thomas
Posts: 7718
Nutzer
@Reth:

Zitat:
Hm, aber die Regel wird doch automatisch auf alle cpp-Dateien angewandt.

Nein. Die einzige Regel, die Make automatisch anwendet, ist die erste. Alle anderen sind davon abhängig.

.cpp.o teilt Make mit, wie man aus einer beliebigen .cpp-Datei eine .o-Datei macht. Dies merkt sich Make, wendet es aber erst bei Bedarf an. Bedarf besteht erst dann, wenn eine .o-Datei von einer anderen Regel angefordert wird. Erst dann prüft Make aufgrund dieser Regel, ob zu der gewünschten .o-Datei eine .cpp-Datei existiert. Falls ja, wird der Befehl ausgeführt. Falls nicht, kommt die Fehlermeldung, dass für die bewusste .o-Datei keine Regel exisitert.

Bedarf besteht außerdem, wenn ein Name in der Kommandozeile angegeben wird. Wenn du z.B.

make hugo.o

eingibst, dann wird aufgrund der .cpp.o-Regel die hugo.cpp zu hugo.o kompiliert sofern hugo.cpp exisitert, auch wenn hugo.o sonst nirgends im Makefile erwähnt wird.


--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/

[ - Antworten - Zitieren - Direktlink - ]

08.01.2013, 10:06 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von thomas:
Bedarf besteht erst dann, wenn eine .o-Datei von einer anderen Regel angefordert wird. Erst dann prüft Make aufgrund dieser Regel, ob zu der gewünschten .o-Datei eine .cpp-Datei existiert. Falls ja, wird der Befehl ausgeführt. Falls nicht, kommt die Fehlermeldung, dass für die bewusste .o-Datei keine Regel existiert.

Nur der Vollständigkeit halber:

Bedarf besteht, wenn eine .o Datei angefordert wird und noch nicht existiert oder wenn eine angeforderte .o Datei existiert, aber eine ebenfalls existierende zugehörige .cpp Datei existiert und neuer als die .o Datei ist.

Wenn die .o Datei existiert und keine .cpp Datei existiert, ist das beispielsweise kein Fehler. Das ist dasselbe wie für .cpp Dateien: für die gibt es üblicherweise keine Regel, wie man sie erzeugt, das ist aber in Ordnung, weil sie ja existieren.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.01.2013, 00:08 Uhr

Reth
Posts: 1858
Nutzer
@thomas:
@Holger:

Danke nochmals für die Erläuterungen. Genau so stelle ich mir Erläuterungen im Rahmen von handbuchartigen Beschreibungen oder Tutorials vor!

Zitat:
Original von Holger:
Ich verstehe die Frage nicht, genau das hat jolo doch gepostet.

Ich meinte, ob man in dieser "verkürzten Schreibweise" (keine Ahnung wie die genau heißt) hier:
code:
.cpp.o:
	$(CC) $(CCFLAGS) -O2 $(INC) -c $<


auch unterschiedliche Pfade für die .cpp und .o Dateien angeben kann, ohne die Pfadvariablen einzeln vor jeder Datei in deren Auflistung anzugeben und ohne auf die normale Schreibweise zu wechseln, wie sie hier angegeben ist:
code:
OBJDIR = deinVerzeichnis/
SRCDIR = deinVerzeichnis/

und dann:

$(OBJDIR)%.o: $(SRCDIR)%.cpp
	$(CC) $(CCFLAGS) -O2 $(INC) -c $<


[ Dieser Beitrag wurde von Reth am 13.01.2013 um 11:41 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

17.01.2013, 21:56 Uhr

Reth
Posts: 1858
Nutzer
Oh man! Ich bin offenbar zu dämlich für make und das ganze Zeuch! Noch dazu hab ich vor lauter Dummheit beim Einspielen der neuen Source-Version von GigaLoMania mein altes, funktionierendes MakeFile überschrieben!

Nun hänge ich fest und komme nicht weiter. gmake sagt mir, dass es keine Regel findet, um das target game.o zu bauen (makefile unten im Anschluss). Hab schon einiges probiert. Das Einzige, was hilft ist, vor jede .o-Datei in der Zeile OFILES=... jeweils $(OBJDIR) anzugeben. Aber wieso? Das kapier ich nicht (hab offenbar die dazu gehörenden Teile der bisher gelesenen Tutorials nicht ganz verstanden)!
Meiner Meinung nach hatte ich die überschriebene Makefile-Version so, dass ich bei der Aufzählung der Einzeldateien keine Verzeichnisangaben machen musste, nur in der Buildregel und bei Angabe der Includepfade.
Einen Fehler hab ich schon eliminiert (hatte die Pfadvariablen innerhalb des makefiles unterschiedlich geschrieben). Vielleicht könnt ihr mir noch helfen, meine anderen Fehler zu finden und mir vor allem beim Verstehen des Ganzen behilflich sein?! Wäre wie immer echt super!
Die Sourcen stehen alle im Verzeichnis src/, die Header im Verzeichnis header/. Hier mein aktuelles, so nicht funktionierendes Makefile. Auch wenn ich statt $(OBJDIR)%.o: nur %.o: schreibe meldet make, dass es keine Regel zur Erstellung von game.o finden kann. Aber wieso? Die steht doch groß und breit da!?
C code:
CC=g++
CCFLAGS=-O2 -Wall
SRCDIR = src/
HEADERDIR = header/
OBJDIR = obj/
CFILES=game.cpp gamestate.cpp gui.cpp image.cpp main.cpp panel.cpp player.cpp resources.cpp screen.cpp sector.cpp sound.cpp utils.cpp
HFILES=game.h gamestate.h gui.h image.h panel.h player.h resources.h screen.h sector.h sound.h utils.h common.h stdafx.h
OFILES=game.o gamestate.o gui.o image.o panel.o player.o resources.o screen.o sector.o sound.o utils.o main.o
APP=gigalomania
INC='sdl-config --cflags' -I$(HEADERDIR)
LINKPATH='sdl-config --libs' -L/usr/X11R6/lib/ -L/usr/lib

LIBS=-lSDL_image -lSDL_mixer -ljpeg -lpng -lvorbisfile -lvorbis -logg -lSDL -lz

all: $(APP)

$(APP): $(OFILES) $(HFILES) $(CFILES)
	$(CC) $(OFILES) $(CCFLAGS) $(LINKPATH) $(LIBS) -o $(APP)

#.cpp.o:
#	$(CC) $(CCFLAGS) -O2 $(INC) -c $<
$(OBJDIR)%.o: $(SRCDIR)%.cpp
	$(CC) $(CCFLAGS) -O2 $(INC) -c $<

clean:
	rm -rf *.o
	rm -f $(APP)


[ - Antworten - Zitieren - Direktlink - ]

18.01.2013, 09:36 Uhr

thomas
Posts: 7718
Nutzer
Vielleicht solltest du mal versuchen, ohne die ganzen Variablen auszukommen. Die machen das Makefile zwar kurz aber auch kompliziert.

Wenn du die einzelnen Regeln ausschreiben würdest, dann würdest du vielleicht auch den Fehler erkennen.

Du hast eine Regel, die besagt

gigalomania: ... game.o ...

und eine zweite Regel, die sagt

obj/game.o: src/game.c

Siehst du jetzt das Problem? Es gibt tatsächlich keine Regel für game.o, es gibt nur eine für obj/game.o. Das wird aber nirgends angefordert.

Außerdem halte ich es für schwachsinnig, das Lademodul von den Headerdateien abhängig zu machen. Wenn du eine Headerdatei änderst, wird dadurch das Lademodul neu gelinkt, aber die Quelldateien, in denen der Header benutzt wird, werden nicht neu kompiliert.


--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/



[ Dieser Beitrag wurde von thomas am 18.01.2013 um 09:40 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

18.01.2013, 11:30 Uhr

Thore
Posts: 2266
Nutzer
Ja das Problem kenn ich auch. Oft muss ich die korrespondierende C-Datei ändern und neu speichern, damit er die H-Datei mitnimmt (oder bei kleinen Projekten ein make clean machen, oder das entsprechende Objekt File löschen)

Es gibt viele Makefiles als Demo :) einfach mal durchwühlen.

[ - Antworten - Zitieren - Direktlink - ]

18.01.2013, 11:57 Uhr

Holger
Posts: 8116
Nutzer
@Reth:
Ohne jetzt was testen zu können, würde ich so etwas in dieser Art vorschlagen:
Makefile code:
CC=g++
CCFLAGS=-O2 -Wall
SRCDIR = src/
HEADERDIR = header/
OBJDIR = obj/
MODULES=game gamestate gui image panel player resources screen sector sound utils
HFILES:=$(MODULES:%=$(HEADERDIR)%.h) common.h stdafx.h
OFILES:=$(MODULES:%=$(OBJDIR)%.cpp) main.o
APP=gigalomania
INC='sdl-config --cflags' -I$(HEADERDIR)
LINKPATH='sdl-config --libs' -L/usr/X11R6/lib/ -L/usr/lib

LIBS=-lSDL_image -lSDL_mixer -ljpeg -lpng -lvorbisfile -lvorbis -logg -lSDL -lz

all: $(APP)

$(APP): $(OFILES)
	$(CC) $(OFILES) $(CCFLAGS) $(LINKPATH) $(LIBS) -o $(APP)

$(OBJDIR)%.o: $(SRCDIR)%.cpp $(HFILES)
	$(CC) $(CCFLAGS) -O2 $(INC) -c $<

clean:
	rm -f $(OFILES)
	rm -f $(APP)



PS: Wieso markierst Du Makefiles als „C-Code“?

--

Edit: HEADERDIR übersehen…


[ Dieser Beitrag wurde von Holger am 18.01.2013 um 11:58 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]

18.01.2013, 12:31 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Thore:
Oft muss ich die korrespondierende C-Datei ändern und neu speichern, damit er die H-Datei mitnimmt

Dann ist Dein Makefile fehlerhaft.

Natürlich ist es lästig, die Abhängigkeiten zu .h-Dateien manuell pflegen zu müssen. Die Alternative, alle Objekt-Dateien von allen .h-Dateien abhängig zu machen, ist auch nicht besser. Dann wird bei jeder Header-Änderung alles übersetzt, was mitunter deutlich zuviel ist.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

18.01.2013, 16:46 Uhr

Thore
Posts: 2266
Nutzer
Das makefile ist das Makefile des MorphOS SDK zur Erstellung von Libraries, also kein selbstgebasteltes (nur an meine Dateien angepasst). Aber schon möglich daß da was unglücklich läuft. Stört mich aber nicht weiter, wenn ichs weiß dann ists gut.
Ich hab keine Regeln für meine h-Dateien drin, das wird der Grund sein, aber es läuft und das reicht mir so. Das Ergebnis am Ende zählt.

[ - Antworten - Zitieren - Direktlink - ]

18.01.2013, 17:35 Uhr

Holger
Posts: 8116
Nutzer
@Thore:
Nur Du kannst wissen, welche Datei von welchen Deiner .h-Dateien abhängt. Also musst Du auch diese Abhängigkeiten ins Makefile schreiben.

Theoretisch wäre es kein Problem, dies zu automatisieren. Vielleicht gibt es solche Tools ja schon. Aber auch dann bist Du wieder derjenige, der das Tool auch benutzen muss.

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

18.01.2013, 18:05 Uhr

Reth
Posts: 1858
Nutzer
@thomas:
Zitat:
Original von thomas:
Du hast eine Regel, die besagt

gigalomania: ... game.o ...

und eine zweite Regel, die sagt

obj/game.o: src/game.c

Siehst du jetzt das Problem? Es gibt tatsächlich keine Regel für game.o, es gibt nur eine für obj/game.o. Das wird aber nirgends angefordert.


Allerdings hatte ich in meinem Post auch erwähnt, dass die Regel nicht funktioniert, wenn sie nur für die .o-Dateien angegeben ist, ohne führendes Verzeichnis.
Also wenn ich statt:
code:
$(OBJDIR)%.o: $(SRCDIR)%.cpp
	$(CC) $(CCFLAGS) -O2 $(INC) -c $<

nun Folgendes schreibe:
code:
%.o: $(SRCDIR)%.cpp
	$(CC) $(CCFLAGS) -O2 $(INC) -c $<


Bekomme ich dennoch den Fehler, dass keine Regel zum Erzeugen von game.o gefunden werden kann.

Woran liegt das aber nun?

(Zudem hatte ich ja auch gesagt, dass die Regel funktioniert, wenn ich $(OBJDIR) im Target vorschalte und wenn ich bei den OFILES auch überall diese Verzeichnisvariable voranstelle. D.h., den von Dir angemerkten Punkt hatte ich schon erkannt, war aber der Meinung, dass ich dies in meinem versehentlich gelöschten Makefile auch ohne Verzeichnisvariable bei den OFILES, dafür aber beim Target geschafft hatte. Aber dann scheint das wohl nicht so zu klappen.)

[ - Antworten - Zitieren - Direktlink - ]

18.01.2013, 19:06 Uhr

Holger
Posts: 8116
Nutzer
@Reth:
Bist Du Dir sicher, dass die Fehlermeldung dieselbe ist?

Dass es nicht funktionieren kann, liegt eigentlich auf der Hand. Du hast geschrieben:
$(APP): $(OFILES) $(HFILES) $(CFILES)

Das heißt, gigalomania hängt von von dem ganzen Bündel *.o, *.h, *.cpp Dateien ab— alles davon soll im aktuellen Verzeichnis zu finden sein. Dass das auch dann nicht funktioniert, wenn Du die Regel für *.o Dateien anpasst, ist klar. Schließlich fehlen immer noch die Regeln für die nicht vorhandenen *.h und *.cpp Dateien.

Nur, dass die Fehlermeldung sich immer noch auf game.o beziehen soll, erscheint mir merkwürdig. Andererseits, wer weiß, wie sich das ganze bei so einer Überlagerung von Fehlern verhält…
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

19.01.2013, 19:16 Uhr

Reth
Posts: 1858
Nutzer
Zitat:
Original von Holger:
@Reth:
Bist Du Dir sicher, dass die Fehlermeldung dieselbe ist?


Ja, hier die Kopie: gmake: *** No rule to make target 'game.o', needed by 'gigalomania'. Stop.

Zitat:
Original von Holger:
Dass es nicht funktionieren kann, liegt eigentlich auf der Hand. Du hast geschrieben:
$(APP): $(OFILES) $(HFILES) $(CFILES)

Das heißt, gigalomania hängt von von dem ganzen Bündel *.o, *.h, *.cpp Dateien ab— alles davon soll im aktuellen Verzeichnis zu finden sein. Dass das auch dann nicht funktioniert, wenn Du die Regel für *.o Dateien anpasst, ist klar. Schließlich fehlen immer noch die Regeln für die nicht vorhandenen *.h und *.cpp Dateien.


Wieso funktioniert das Ganze aber dann, wenn ich nur den *.o-Datein ihren Pfad mitgebe, den anderen aber nicht? Oder würde sich das dann erst beim Linken bemerkbar machen (soweit bin ich nämlich noch nicht gekommen)?
Folgendes MakeFile funktioniert nämlich zunächst mal:
code:
CC=g++
CCFLAGS=-O2 -Wall
SRCDIR = src/
HEADERDIR = header/
OBJDIR = obj/
CFILES=game.cpp gamestate.cpp gui.cpp image.cpp main.cpp panel.cpp player.cpp resources.cpp screen.cpp sector.cpp sound.cpp utils.cpp
HFILES=game.h gamestate.h gui.h image.h panel.h player.h resources.h screen.h sector.h sound.h utils.h common.h stdafx.h
#OFILES=game.o gamestate.o gui.o image.o panel.o player.o resources.o screen.o sector.o sound.o utils.o main.o
OFILES=$(OBJDIR)game.o $(OBJDIR)gamestate.o $(OBJDIR)gui.o $(OBJDIR)image.o $(OBJDIR)panel.o $(OBJDIR)player.o $(OBJDIR)resources.o $(OBJDIR)screen.o $(OBJDIR)sector.o $(OBJDIR)sound.o $(OBJDIR)utils.o $(OBJDIR)main.o
APP=gigalomania
INC='sdl-config --cflags' -I$(HEADERDIR)
LINKPATH='sdl-config --libs' -L/usr/X11R6/lib/ -L/usr/lib

LIBS=-lSDL_image -lSDL_mixer -ljpeg -lpng -lvorbisfile -lvorbis -logg -lSDL -lz

all: $(APP)

$(APP): $(OFILES) $(HFILES) $(CFILES)
	$(CC) $(OFILES) $(CCFLAGS) $(LINKPATH) $(LIBS) -o $(APP)

#.cpp.o:
#	$(CC) $(CCFLAGS) -O2 $(INC) -c $<
$(OBJDIR)%.o: $(SRCDIR)%.cpp
	$(CC) $(CCFLAGS) -O2 $(INC) -c $<

clean:
	rm -rf *.o
	rm -f $(APP)


[ - Antworten - Zitieren - Direktlink - ]

21.01.2013, 13:18 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Reth:
Wieso funktioniert das Ganze aber dann, wenn ich nur den *.o-Datein ihren Pfad mitgebe, den anderen aber nicht?

Vielleicht über irgendeinen impliziten Suchpfad. (g)make besitzt ja einen Haufen vordefinierter Sachen, die oftmals 90% dessen, was in so einem Makefile steht, überflüssig machen (würden), sofern man sie denn kennt.

PS: Hast Du denn mal meinen Vorschlag ausprobiert?

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

22.01.2013, 09:34 Uhr

Thore
Posts: 2266
Nutzer
Scheint in der Tat ein Pfadproblem zu sein. Kannst Du es mit SnoopDos oder Snoopium verifizieren?
Gabs ein Configure Script dabei oder nur das Makefile?

[ - Antworten - Zitieren - Direktlink - ]

22.01.2013, 11:50 Uhr

thomas
Posts: 7718
Nutzer
Zitat:
Original von Reth:
Oder würde sich das dann erst beim Linken bemerkbar machen (soweit bin ich nämlich noch nicht gekommen)?


Genau das ist die Erklärung. Und auch das hättest du erkannt, wenn du die Variablen auflösen würdest.

Deine Regeln (vereinfacht):

code:
gigalomania: obj/game.o game.h game.cpp
	...

obj/game.o: obj/game.cpp
	...


Die Regeln werden der Reihe nach abgearbeitet. Für gigalomania wird zuerst obj/game.o benötigt. Dafür gibt es eine Regel (die zweite). Wenn der Befehl in dieser Regel fehlschlägt (RC größer als 5), dann wird nicht weitergemacht.

Würdest du durch das Kompilieren durchkommen, dann würde als nächstes game.h angefordert und dafür existiert wieder keine Regel -> Fehler.

Ich muss nochmal darauf hinweisen, dass es schwachsinnig ist, das Lademodul von den Headerfiles abhängig zu machen.

Und noch viel schwachsinniger ist es, das Lademodul von den Sourcefiles abhängig zu machen, die bereits durch die Objektdateien abgedeckt sind.

Korrekt wäre

code:
lademodul: objekt1 objekt2 objekt3
	binde objekt1 objekt2 objekt3 zu lademodul

objekt1: quelle1 header1 header2
	kompiliere quelle1 zu objekt1

objekt2: quelle2 header2
	kompiliere quelle2 zu objekt2

objekt3: quelle3 header3 header1
	kompiliere quelle3 zu objekt3


oder

code:
lademodul: objekt1 objekt2 objekt3
	binde $^ zu lademodul
#	$^ bedeutet alle Dateien, die rechts vom : stehen

objekt%: quelle%
	kompiliere $< zu $@
#	$< bedeutet die erste Datei, die rechts vom : steht
#	$@ bedeutet die Zieldatei

objekt1: header1 header2

objekt2: header2

objekt3: header3 header1


--
Email: thomas-rapp@web.de
Home: thomas-rapp.homepage.t-online.de/


[ Dieser Beitrag wurde von thomas am 22.01.2013 um 12:30 Uhr geändert. ]

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > AOS4 GCC und makefile-Probleme [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.