Forum: PC-Programmierung mingw32-make.exe kann nicht einzelne Dateien compilieren


von Hartmut (Gast)


Lesenswert?

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?

von Klaus W. (mfgkw)


Lesenswert?

Hartmut schrieb:
> ... ein make mit Target all funktioniert ...

Wie rufst du das auf?
Nur "make all", oder mit "-f ..." ?

von Εrnst B. (ernst)


Lesenswert?

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"

von Erik L. (erikl)


Lesenswert?

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

von Hartmut (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Εrnst B. (ernst)


Lesenswert?

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.

von Hartmut (Gast)


Lesenswert?

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.

von Εrnst B. (ernst)


Lesenswert?

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.

von Erik L. (erikl)


Lesenswert?

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

von Hartmut (Gast)


Lesenswert?

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.

von Εrnst B. (ernst)


Lesenswert?

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.

von Hartmut (Gast)


Lesenswert?

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.

von Εrnst B. (ernst)


Lesenswert?

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

von Hartmut (Gast)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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.

von Hartmut (Gast)


Lesenswert?

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

von Εrnst B. (ernst)


Lesenswert?

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
Noch kein Account? Hier anmelden.