Forum: Compiler & IDEs wie vermeide ich *.o Files bei den Sourcen?


von Jörg (Gast)


Lesenswert?

Sorry wenn das FAQ/RTFM ist:
Ich verwende WinAVR mit dem entsprechendem Makefile-Template. Leider
landen die .o und .lst Files in meinen Source-Verzeichnissen. Wie kann
ich das vermeiden? Ich hätte die Dinger lieber in meinem
Build-Directory, oder besser dort in Unterverzeichnissen.
Ist speziell blöd, weil ich ein Verzeichnis mit gemeinsamem Code habe,
der aber von verschiedenen Projekten per #ifdef unterschiedlich
übersetzt wird. Die Makefiles fallen drauf rein, daß da schon ein
Object liegt.

von Andreas Lang (andreas) (Gast)


Lesenswert?

Wie du verhindern kannst, das GCC dir da die objects reinlegt, weiß ich
jetzt zwar auch nicht so aus dem stehgreif, aber weg bekommst du sie
mit "make clean".

Ansonsten im Makefile nachsehen. irgendwo wird dort ja Compiler
aufgerufen. Da musst du was ändern.

------------------------
~/devel_avr/keypad $ ls
ezLCD.c    glcd.c    keypad      keypad.hex  keypad.sym  sed1520.lst
statbar.o
ezLCD.h    glcd.c~   keypad.c    keypad.lss  Makefile    sed1520.o
ezLCD.lst  glcd.h    keypad.c~   keypad.lst  mkhex.pl    statbar.c
ezLCD.o    glcd.lst  keypad.eep  keypad.map  sed1520.c   statbar.h
fnt5x7.h   glcd.o    keypad.elf  keypad.o    sed1520.h   statbar.lst
~/devel_avr/keypad $ make clean

-------- begin --------

Cleaning project:
rm -f keypad.hex
rm -f keypad.eep
rm -f keypad.cof
rm -f keypad.elf
rm -f keypad.map
rm -f keypad.sym
rm -f keypad.lss
rm -f sed1520.o glcd.o statbar.o ezLCD.o keypad.o
rm -f sed1520.lst glcd.lst statbar.lst ezLCD.lst keypad.lst
rm -f sed1520.s glcd.s statbar.s ezLCD.s keypad.s
rm -f sed1520.d glcd.d statbar.d ezLCD.d keypad.d
rm -f .dep/*
-------- end --------

~/devel_avr/keypad $ ls
ezLCD.c   glcd.c   keypad     Makefile   sed1520.h
ezLCD.h   glcd.c~  keypad.c   mkhex.pl   statbar.c
fnt5x7.h  glcd.h   keypad.c~  sed1520.c  statbar.h

von tom (Gast)


Lesenswert?

Hi Jörg,

hast Recht, ist RTFM! ;-) RTFM bedeutet in diesem Fall aber sich das
Manual für das verwendete Make zu beschaffen! Nun ist Makefiles
schreiben nix für DAU oder Anfänger. :-) Ich weiß, wovon ich schreibe,
auch die sog. Profi's in großen Firmen schaffen es immer wieder, mich
zu "erstaunen" (um es mal höflich auszudrücken).

Da ich nicht unter Win arbeite, kann ich nix zu WinAVR sagen.
MakeTemplates klingt aber schon mal nicht schlecht. Das Hauptproblem
wird aber sein, das Du für die Umsetzung *.c nach *.o nur eine sehr
einfache Builtin-Regel verwenden wirst. GCC selbst kann dir C-Files aus
beliebigen Verzeichnissen lesen und Dateien in beliebig angegebenen
Verzeichnissen erzeugen. Das Hauptproblem sind die Make-Regeln, die Du
benötigst und wie Du die dazu notwendigen Dependencies erzeugst oder
angibst, die Du zwingend benötigst, wenn Du die Objekte in andere
Verzeichnisse ausgeben willst, als das C-File enthalten ist. Also auch
wieder RTFM, diesmal WinAVR und das Handling mit Make-Templates! :-)

Schönen Tag noch,
Thomas

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Die Kurzfassung ist allerdings: es gibt keinen trivialen Weg dafür.
Zusammen mit all den generierten Files ist das ein ziemlich
aufwändiges Projekt.  Leider bietet GNU Make kein Feature wie BSD
make, bei dem man ein OBJDIR definiert, und dann da drin alles
abgelegt wird, indem make einfach vorher ein "cd" in dieses
Verzeichnis macht (und dann die Pfadnamen zu den Quellen absolut
übergibt).  Bei der BSD Make-Variante ist man dann auch vor
,,Überraschungen'' gefeit (wie einem coredumpenden Executable :),
die
Intention lag dort eindeutig darauf, dass man den gesamten source tree
read/only haben kann.

Prinzipiell müsste man sowas mit .VPATH hinbekommen.  Eric hat's aber
mal (beim vorigen WinAVR) versucht und hat aufgegeben.  Es ist
zumindest außerhalb dessen, wofür ich mich auch mit Mfile zuständig
fühlen möchte: Mfile soll eine schnelle Hilfe für Anfänger sein, damit
sie nicht gleich zusätzlich zu GCC und AVR auch noch alles über make
lernen müssen, aber für ausgefeiltere Wünsche geht wohl nichts um das
Erstellen eigener Makefiles herum.

Alternativ kannst du dir noch eins der zahlreichen ``meta-makes''
ansehen (autoconf/automake, Cmake, ...), dort schreibst du eine
Beschreibungsdatei der Umgebung auf einer höheren Ebene und die haben
meiner Erinnerung nach auch bereits Vorkehrungen für separate build
directories, d. h. sie generieren dann die ganzen Makefile-Details für
dich.

von Daniel aka Khani (Gast)


Lesenswert?

Hallo,

ich habe da einen alternativen Vorschlag. Der geht zwar nicht in die
Richtung make-file- und Optionsverbiegung, aber wird von mir
erfolgreich verwendet.

Schau Dir doch einfach mal ein ein Versionshaltungssystem wie
Subversion (subversion.tigris.org) mit einem netten Frontend wie
tortoiseSVN (tortoiseSVN.tigris.org) oder etwas vergleichbares an.

Ich habe meinen wiedereverwendbare Code in das System eingecheckt und
für jedes Projekt, das den Code verwendet eine Kopie wieder
ausgecheckt. Das hat mehrere Vorteile:
- Jedes Projekt kann unberührt von allen anderen Projekten compilieren,
linken und was auch immer (sogar gleichzeitig, wenn man das will). Wenn
ich nun der Meinung bin, man müsste an dem Modul was ändern, dann wird
das veränderte (und getestete) Modul eingecheckt und in den Projekten
der Modulcode aktualisiert.
Ein weiterer Vorteil ist, dass man bei Änderungen, die sich im
Nachhinein als Schrott herausstellen leicht wieder zur vorherigen
Version zurückkehren kann.
Man kann desweiteren sogar ein Modul erst mal auf ein bestimmtes
Projekt zuschneiden und dann versuchen die Änderungen soweit zu
generalisieren, dass auch die anderen Projekte damit arbeiten können.
Während den laufenden Änderungen können die anderen Projekte jederzeit
problemlos mit der alten Version des Moduls arbeiten.

Diese Lösung braucht vielleicht ein bißchen mehr Speicherplatz und vor
allem ein bißchen Einarbeitung in eine Versionshaltung. Wenn man das
aber mal geschafft hat (geht recht schnell), dann ist das ein sehr
praktikabler und vor allem ein langfristig solider Weg.

MfG, Daniel.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Was hat das mit ${subject} zu tun?

Das eine will man ohnehin haben, wenn man ernsthaft arbeitet, das
andere ist halt ein "nice to have" feature.

von Daniel aka Khani (Gast)


Lesenswert?

Hallo Jörg,

falls Du mich meinst - mein Vorschlag entschärft das folgende Problem
des Original-Posters:
"Ist speziell blöd, weil ich ein Verzeichnis mit gemeinsamem Code
habe,
der aber von verschiedenen Projekten per #ifdef unterschiedlich
übersetzt wird. Die Makefiles fallen drauf rein, daß da schon ein
Object liegt."

Daher meine Antwort. Ich bin davon ausgegangen, dass der OP genau
dieses Problem lösen möchte und daher die .o und .lst-Geschichten in
ein anderes Verzeichnis schieben will. Das ist bei mir nicht notwendig
- insofern wird der Post dem Titel des Threads nicht gerecht, löst aber
das Problem ;-).

MfG, Daniel.

von tom (Gast)


Lesenswert?

Hi Jörg W.,

böses Gerücht!

> Leider bietet GNU Make kein Feature wie BSD
> make, bei dem man ein OBJDIR definiert, und dann da drin *alles*
> abgelegt wird, indem make einfach vorher ein "cd" in dieses
> Verzeichnis macht (und dann die Pfadnamen zu den Quellen absolut
> übergibt).  Bei der BSD Make-Variante ist man dann auch vor

geht so: "make -C dir makefile"! Ist auch ein Fall von RTFM! ;-)

Schönen Tag noch,
Thomas

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

make -C dir makefile macht aber was anderes.

$ mkdir foo
$ cat > Makefile
all: doit.x

doit.x: doit.y
        cp doit.y doit.x
^D
$ echo hi > doit.y
$ gmake -C foo -f Makefile
gmake: Entering directory `/tmp/foo/foo'
gmake: Makefile: No such file or directory
gmake: *** No rule to make target `Makefile'.  Stop.
gmake: Leaving directory `/tmp/foo/foo'

Mit BSD Make würde man das Makefile geringfügig anders schreiben:

$ cat > Makefile
MAKEOBJDOR=foo

all: doit.x

doit.x: doit.y
        cp ${.CURDIR}/doit.y doit.x
^D
$ make
cp /tmp/foo/doit.y doit.x

Wenn das build directory den magischen Namen "obj" hätte, könnte man
sogar das Setzen von MAKEOBJDIR weglassen, da das der Default ist.

Ich wollte damit auch nicht GNU Make miesmachen oder sowas, aber das
ist eins der Features, die BSD Make IMHO besser gemacht hat.  Klar,
man könnte auch das GNU Makefile oben einigermaßen auf dieses
Verhalten ziehen, man hat aber weniger Support seitens make (z. B.
fehlt eben ${.CURDIR}, man müsste dann eine implizite Annahme über das
Sourcedir in Form von ../ einbauen oder es explizit über
make-Variablen setzen), und es lässt sich auch nicht mehr einfach mit
"make" starten.

von tom (Gast)


Lesenswert?

Hi,

na ja, vom GNU-Make das selbe Verhalten zu verlangen, wie vom BSD-Make
macht aber auch nicht wirklich Sinn! :-)

Du hattest ohnehin einen Fehler gemacht! Vor dem Aufruf von gmake
sollte wohl zum einen ein "cd .." kommen, denn /tmp/foo/foo hast Du
ja gar nicht angelegt! Und dann "gmake -C foo Makefile"!

So als kleine Korrektur!
cu tom

von tom (Gast)


Lesenswert?

Hi nochmal,

und, weils ja so schön peinlich ist: dummer Anfängerfehler!

Also Korrektur der Korrektur - entweder: "gmake -C foo" (dann, wenn
das Makefile ebend Makefile oder makefile heißt!) oder "gmake -C foo
-f <name des makefile>"!

cu tom

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Doch, /tmp/foo/foo hatte ich angelegt.  Dort lag eben nur das
Makefile nicht drin, das lag in /tmp/foo/Makefile (meinem
Arbeitsverzeichnis, von dem aus ich alles angefangen hatte).

Ich schrob ja auch, dass man GNU Make irgendwie schon zu etwas
Ähnlichem austricksen kann, aber es gibt seitens "make" weniger
Unterstützung dafür (namentlich fehlt ${.CURDIR}) und es geht
nicht, dass man dann einfach nur "make" schreibt.

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.