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?
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.
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.
@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.