Hallo zusammen, will in die PC-Programmierung einsteigen, habe mir wxWidgets und mingw instaliert, habe alle Lib's mit mingew gebildet und auch die Beispiele die dann auch laufen, d.h. ein make mit Target all funktioniert aber wenn ich eine einzelne Datei compilieren will werden die Variablen nicht gesetzt oder verwertet, im makefile steht: $(OBJS)\\%.o: %.cpp $(CXX) -c -o $@ $(PRJ_CXXFLAGS) $(CPPDEPS) $< und wenn ich das aufrufe: C:\wxWidgets\_myProjects\Bombs>mingw32-make -f makefile BUILD=debug bombs.o -e g++ -c -o bombs.o bombs.cpp bombs.cpp:12:23: fatal error: wx/wxprec.h: No such file or directory #include "wx/wxprec.h" ^ compilation terminated. <builtin>: recipe for target 'bombs.o' failed mingw32-make: *** [bombs.o] Error 1 PRJ_CXXFLAGS und CPPDEPS sind im selben makefile definiert, warum werden die nicht gesetzt?
Hartmut schrieb: > ... ein make mit Target all funktioniert ... Wie rufst du das auf? Nur "make all", oder mit "-f ..." ?
Problem: Du definierst eine Regel für $(OBJS)\bombs.o Hartmut schrieb: > $(OBJS)\\%.o: %.cpp > $(CXX) -c -o $@ $(PRJ_CXXFLAGS) $(CPPDEPS) $< rufst aber eine Regel für "bombs.o", ohne das "$OBJS"-Unterverzeichnis ab: Hartmut schrieb: > mingw32-make -f makefile BUILD=debug bombs.o -e Eh schöner für die NSA-Suchbots: bombs: $(OBJS)\\bombs.o Dann: "make bombs"
Hallo Ernst, ich glaube das könnte trotzdem funktionieren wenn $(OBJS) in dem Falle leer definiert ist, oder ? Aber erstaunlich ist doch wenn man die makefile-Zeile und die ausgegebene Kommandozeile anschaut, dass die beiden Makros $(PRJ_CXXFLAGS) $(CPPDEPS) offenba leer definiert sind, daher fehlt dem Compiler wohl die Angabe wo die includes zu finden sind. @Hartmut: Du schreibst " PRJ_CXXFLAGS und CPPDEPS sind im selben makefile definiert, warum werden die nicht gesetzt?" Vielleicht wird die Definition aus irgendeinem Grunde nicht benutzt, kannst Du das ganez makefile mal zeigen (anhaengen)? Gruß Erik
Hallo zusammen, ich habe mal den kompletten makefile angeängt; diesen makefile habe ich aus den Demos "Bombs" von wxWidgets, im orginal sind alle *.o-Files einzeln als Ziel definiert ich habe die regeln nur verallgemeinert; ich will diesen makefile in das Basis-Verzeichnis für meine Projecte belassen und in den Project-Verz. ein makefile mit den Dateien für das jeweilige Prj. machen in dem der angehängte makefile includiert wird; zum Testen habe ich "Bombs" genommen, wenn ich: "mingw32-make -f makefile BUILD=debug" aufrufe funktioniert alles, aber will ich nur eine Datei kompilieren: "mingw32-make -f makefile BUILD=debug bombs.o" werden die Variablen nicht gesetzt?! sodas es zum Fehler kommt, siehe am Anfang dieses Threads; Gruß Hartmut.
Sorry falls ich daneben liege, Windows ist nicht so mein Ding, aber das hier schaut schon seltsam aus:
1 | OBJS = \ |
2 | $(COMPILER_PREFIX)$(COMPILER_VERSION)_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)$(WXDLLFLAG)$(CFG) |
d.H. OBJS enthält nacher einen aus X-Verschiedenen Variablen zusamengebauten String, der mit einem *Newline*-Zeichen beginnt. Später versuchst du dann:
1 | -if not exist $(OBJS) mkdir $(OBJS) |
IIRC ist unter Windows "\n" kein gültiger Bestandteil eines Verzeichnisnamens. Vorschlag: Schau mal, ob dein make nicht auch mit "/" statt "\" oder "\\" als Path-Seperator klarkommt, und stell alles darauf um. Und: Nachdem "OBJS" eben nicht leer ist, trifft meine Vermutung von oben wohl zu. d.H. du musst an der Kommandozeile den kompletten Pfad zu dem zu erstellenden bomb.o angeben.
Hallo Ernst, OBJS ist ein Verzeichnisname mit dem im Prj-Verz. ein Unterverz. erstellt wird in dem das Prj gebildet wird; mit "/" oder "\" habe ich es auch versucht, ohne Erfolg; die Regel: $(OBJS)\\%.o: %.cpp $(CXX) -c -o $@ $(PRJ_CXXFLAGS) $(CPPDEPS) $< wird ja ausgeführt: "g++ -c -o bombs.o bombs.cpp" wird ja ausgegeben aber was ist mit PRJ_CXXFLAGS u. CPPDEPS die ja definiert sein sollten ? Gruß Hartmut.
Zum Dritten Mal: Wenn du willst das make die Regel "$(OBJS)\\%.o" ausführt, dann musst du make auch an der Kommandozeile einen Parameter mitgeben, der auf diese Regel passt. "build.o" passt nicht auf "$(OBJS)\\%.o" Warum? Weil bei "build.o" der "$(OBJS)"-Teil fehlt. Ergebnis: Make führt seine vordefinierte (nicht im Makefile enthaltene!) Standard-Regel für ".cpp" aus. Und die kennt deine Variablen natürlich nicht. evtl Lösung: Neue Phony-Regel %.o : $(OBJS)/%.o einführen.
Hallo zusammen, sehe ich genauso wie Ernst ! ich glaube (gnu)make hat so eine Option wie --print-data-base, die einiges an Info ausgibt, dürfte zum debuggen und lernen praktisch sein. (bin kein gnu make Spezialist, nutze beruflich einen anderen make Dialekt, aber möchte gnu make mal genauer ansehen, deshalb ist das hier interessant !) siehe auch http://www.gnu.org/software/make/manual/make.html Gruß Erik
Hallo zusammen >Ergebnis: Make führt seine vordefinierte (nicht im Makefile enthaltene!) >Standard-Regel für ".cpp" aus. Und die kennt deine Variablen natürlich >nicht. wenn dem so wäre warum meckert make wenn ich keine Regel angebe das keien Regel vorhanden ist ? ich habe es auch mit der option -d (Print debugging information in addition to normal processing.) versucht, da waren die Variablen alle gesetzt?! make gibt aus: "g++ -c -o bombs.o bombs.cpp" und dann die Liste mit den gestzten Variablen ? Gruß Hartmut.
Make hat für manche Dinge VORDEFINIERTE Regeln dabei. Diese kann man im Makefile überschreiben, muss es aber nicht. Eine dieser Regeln ist: %.o: %.cpp $(COMPILE.cpp) $(OUTPUT_OPTION) $< $(COMPILE.cpp) ist (über ein paar Ecken) als "g++ -c" vordefiniert. $(OUTPUT_OPTION) als "-o $@". Dein Makefile überschreibt diese Regel nicht. Sie bleibt also gültig. Und wird aufgerufen, wenn du "make ... bomb.o" startest. Probiers gerne mit einer LEEREN DATEI statt Makefile aus.
ich hab noch ein paar Tests gemacht, das mit den vordefinierten Regeln stimmt offenbar; wie bringe ich dem make dann bei in ein anderes Verzeichnis zu compilieren als das Source-Verzeichnis; Gruß Hartmut.
Hartmut schrieb: > wie bringe ich dem make dann bei in ein anderes Verzeichnis zu > compilieren als das Source-Verzeichnis; Macht er ja. z.B. wenn du ein Make all machst, compiliert er alle .o - Files im richtigen Verzeichnis, oder? Was du willst: Du willst einen internen Zwischenschritt davon händisch anstoßen. Auch das geht. Du musst dem make nur sagen, welchen. und der Zwischenschritt heißt halt nicht "bomb.o" sondern z.B. "GCC_4.123_XXX_ABC12345_USW\\bomb.o" Wenn dir das zu kompliziert ist, und du nicht immer den ganzen Pfadnamen zu dem Zwischen-Object-file angeben willst: Εrnst B✶ schrieb: > evtl Lösung: > Neue Phony-Regel > > %.o : $(OBJS)/%.o > > einführen. make bomb.o => bomb.o hängt ab von $(OBJS)/bomb.o => $(OBJS)/bomb.o matched auf deine "$(OBJS)\\%.o: %.cpp" Regel. Ausprobieren & ggfs. / durch \\ ersetzen...
ich will einfach nur mal die Datei kompilieren an der ich gerade arbeite um zu sehen ob da Fehler drin sind ohne ein komplettes Build abzuwarten, das kann bei größeren Projekten schon einiges an Zeit kosten; jetzt habe ich im makefile zu stehen: ".PHONY: all clean %.o:$(OBJS)/%.o" mit dem Effect das make zu dieser Zeile sagt: "*** multiple target patterns. Stop."; wenn ich "%.o : $(OBJS)/%.o" als Regel mit nachfolgender Leerzeile angebe bringt das keien Besserung; oder wie gibt man sonst eine Phony-Regel an ? Gruß Hartmut.
so, wie es in der Doku steht: http://www.gnu.org/software/make/manual/html_node/Phony-Targets.html Man schreibt nicht vor Target und Regel .PHNOY, sondern lässt die Regel wie gehabt und schreibt in einer eigenen Zeile .PHONY mit einem und mehreren Targets.
@mfwg: danke für den Link, aber das mit dem .PHONY habe ich trotzdem nicht verstanden, auch Dein Kommentar widerspricht sich; ich habe es anders gelöst: ich habe noch eine Regel "%.o: %.cpp" eingefügt, d.h. ohne Verzeichnis; dann habe ich "clean:" noch erweitert mit dem Löschen im Project-Verzeichnis weil bei der eingefügten Regel die Objectdatei(n) nicht im Unterverzeichnis landen; so funktioniert es bei mir; Gruß Hartmut.
Hartmut schrieb: > so funktioniert es bei mir; Nö. Tut es nicht. Es macht jetzt zwar was, was dem von dir gewünschten Effekt nahe kommt, aber: Dein Makefile wird dieses komplizierte "Multi-Versionen-Gewurschtel-mit-getrennten-Build-Dirs" ja nicht ohne Grund beinhalten, was du mit deinem Hack umgehst. Nun gut, für einen schnellen Syntax-Check zwischendurch wird's reichen, und du musst nicht verstehen, warum zwei Dateien mit selben Namen trotzdem verschiedene Inhalte haben können, wenn sie in verschiedenen Verzeichnissen liegen. Und, viel wichtiger: Wir müssen nicht weiter versuchen, dir zu erklären, wie make funktioniert.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.