Von einem Makefile brauche ich einige Bibliotheken, bekomme es aber
nicht hin:
CSOURCES = flag.c i2c.c main1.c mmc.c portablec.c rand.c rs232.c
signal.c temp.c times.c stackcheck.c
OBJECTS = ${CSOURCES:.c=.o}
${LIBNAMES}: ${OBJECTS}
${AR} ${ARFLAGS} ${LIBNAMES} ${CSOURCES}
Aber das funktioniert nicht, weil der ar die Dateien nur paarweise
verarbeitet:
> msp430-ar -rcs flag.a i2c.a main1.a mmc.a portablec.a rand.a rs232.a
signal.a temp.a times.a stackcheck.a flag.c i2c.c main.c mmc.c
portablec.c rand.c rs232.c signal.c temp.c times.c stackcheck.c
msp430-ar: 'i2c.a': No such file
...
Irgendwelche Vorschläge?
Was willst du denn eigentlich machen? Dein Makefile sieht für mich so aus, als wolltest du die C-Source-Files (nicht die Object-Files), jedes für sich in ein eigenes .a-File schreiben. Das geht zwar, erscheint mir aber nicht arg sinnvoll.
Ne Du, das ist genau das, was ich vermeiden wollte (im anderen Thread!). Du solltest für jede Funktion ein Object-File erzeugen, nicht für jede Funktion eine Library...
Ja, zuerst ein Objekt-File und daraus eine Library. Von Hand kein Problem oder auch mit einem Shell-Skript, aber das muß doch mit einem Make-File besser gehen.
recht kompaktes Beispiel findet sich im Makefile der newlib-lpc
> Ja, zuerst ein Objekt-File und daraus eine Library. Nein. Aus jedem C-File ein Object-File, dann die zusammen in ein Archiv packen. Was dein Makefile tut, ist jedes C-File in ein eigenes Archiv zu packen. Ein Archiv mit einem C-File ist zwar nett, und man kann es natürlich auch wieder entpacken, aber als Library sollten dann doch besser die Object-Files drin stehen. Vor allem auch alle zusammen in einem Archiv, denn dazu ist es ja da. > Von Hand kein Problem oder auch mit einem Shell-Skript, aber das > muß doch mit einem Make-File besser gehen. Etwas in der Art: MCU=attiny13 CSOURCES = flag.c i2c.c main1.c mmc.c portablec.c rand.c rs232.c signal.c temp.c times.c stackcheck.c CC=avr-gcc AR=avr-ar CFLAGS=-mmcu=$(MCU) -W -Wall -Os LDFLAGS= ARFLAGS= OBJECTS = ${CSOURCES:.c=.o} ${LIBNAME}: ${OBJECTS} ${AR} ${ARFLAGS} ${LIBNAME} ${OBJECTS}
@Rolf: Ja, so ähnlich; natürlich müssen die Opjekt- und nicht die Quellcodedateien dem Archivierer übergeben werden. Das Problem ist aber, daß das nur paarweise geht, also im ersten Lauf flag.a flag.o im zweiten i2c.a i2c.o usw. @mthomas: Wo ist die newlib-lpc?
Rolf, du hast es leider immer noch nicht kapiert. Rolf Magnus' Beispiel ist genau das, was du suchst. Selbstverständlich archivert sein Beispiel auch keine Quelldateien, sondern Objektdateien. Und nein, du willst wirklich nicht eine Bibliothek pro Objektdatei haben, eine einzige für alle Objekte funktioniert. (NB: ,Objekt' hier im Sinne von ,Objektcode' benutzt, nicht im Sinne eines Objekts im Quellcode.)
@Jörg Wunsch (dl8dtl) > Und nein, du willst wirklich nicht eine > Bibliothek pro Objektdatei haben, eine einzige für alle Objekte > funktioniert. (NB: ,Objekt' hier im Sinne von ,Objektcode' > benutzt, nicht im Sinne eines Objekts im Quellcode.) Doch, genau eine Bibliothek pro Objektdatei. Dadurch entsorgt der Linker noch ein bischen toten Code. Das zeigt mir msp430-size beim Vergleich ohne/mit Libs. Außerdem sollen ganz automatisch aktuell ungenutzte Objektdateien NICHT gelinkt werden und das wäre bei nur einer Lib nicht sichergestellt.
> Außerdem sollen ganz automatisch aktuell ungenutzte Objektdateien > NICHT gelinkt werden und das wäre bei nur einer Lib nicht > sichergestellt. Selbstverständlich wäre das auch bei einer Lib sichergestellt -- genau das versuchen wir dir hier seit Tagen geschlossen zu vermitteln, aber du verhälst dich -- sorry -- ziemlich lernresistent.
> Selbstverständlich wäre das auch bei einer Lib sichergestellt ...
Das funktioniert nur nicht; wenn die Objekt-Dateien gelinkt werden,
dann leider auch unbenutzte. Genau deshalb brauche ich separate Libs.
Rolf: Bitte, bring einen Beweis. Ein .map-File wäre die beste Lösung, um so etwas nachvollziehen zu können. Ich beweise Dir in dem Artikel im Wiki nämlich genau das Gegenteil. Wenn Du jede Funktion in einem eigenen .c-Sorucefile hinterlegst, Kompilierst, und danach sämtliche .o-Files in eine Library packst, dann werden nur die .o-Files aus der Library in das Endprodukt übernommen, die auch referenziert wurden.
Ob das wirklich genau so gut funktioiniert will ich nicht testen; es funktioniert mit einzelnen Libs und wenn man schon einzelne Quellcode (.c-)Dateien und einzelne Objektdateien macht, ist es doch logisch einzelne Libs zu machen.
Nein, ist es nicht! Das ist mehr als doppelt gemoppelt und nicht das, was Du haben willst! projekt1.c -> projekt1.o projekt2.c -> projekt2.o projekt3.c -> projekt3.o main.c -> main.o projekt1.o, projekt2.o, projekt3.o -> libprojekt.a SRC = main.c LDFLAGS += -L. -lprojekt Ganz grob aufgeführt...
> Ob das wirklich genau so gut funktioiniert will ich nicht testen;
Sorry, aber dann ist dir auch nicht mehr zu helfen.
> Ob das wirklich genau so gut funktioiniert will ich nicht testen; > es funktioniert mit einzelnen Libs und wenn man schon einzelne > Quellcode (.c-)Dateien und einzelne Objektdateien macht, ist es > doch logisch einzelne Libs zu machen. Überhaupt nicht. Wenn du eh alle einzeln hast, nimm einfach direkt die Object-Files. Eine Bibliothek ist nichts weiter als ein Archiv (so ähnlich wie zip, nur ohne Kompression), in dem mehrere Object-Files enthalten sind. Der einzige Grund, warum sie existieren, ist, damit man eben mehrere Objectfiles zu einer größeren Einheit zusammenpacken kann und nicht jedes einzeln für sich verwenden muß. Wenn du eh jedes einzeln verwenden willst, gibt es also absolut keinen Grund, jedes in ein eigenes Archiv zu packen.
Genau das stimmt nicht; wenn nur Objekt-Dateien gelinkt werden, dann auch ungenutzte; wenn Libs genommen werden, werden nur wirklich genutzte gelinkt. Zudem wird auch aus benutzten Links nicht alles übernommen. Deshalb sollen möglichst nur Libs gelinkt werden und zwar möglichst einzelne.
> Deshalb sollen möglichst nur Libs gelinkt werden und zwar > möglichst einzelne. Wenn du deine "möglichst einzelnen Libs" in eine gemeinsame Lib zusammenbastelst, die du zuvor aus einzelnen C-Modulen zusammengeklöppelt hast (wichtig!), dann bekommst du eine Lib, aus der nur diejenigen Funktionen gelinkt werden, die auch genutzt werden. So habe ich die Aussagen von Jörg, Patrick und Rolf M. verstanden. Überleg nochmal. > Die Welt ist eben doch eine Scheibe! Deshalb darf man dem Rand auch nicht zu nahe kommen, sonst fällt man runter. Immer schön beim schon Bekannten bleiben... ;-) ----, (QuadDash).
Im Anhang mal ein "Library Makefile" auf Basis des WinAVR-Standardmakefiles. Entpacken (wie immer): $ tar -xvvjf lib-makefile.tar.bz2
> Genau das stimmt nicht; wenn nur Objekt-Dateien gelinkt werden, dann > auch ungenutzte; wenn Libs genommen werden, werden nur wirklich > genutzte gelinkt. s.o., wenn Du aber die die Symbole des Linkers/debuggers raus haben möchtest und dieses möglichwerweise meintest, hilft evtl. der strip bei avr-gcc (man strip). BTW, woher nimmst Du die Erkenntnis, dass alle *.o auch in die Exe/Bin einfliessen? Weil der linker die komplette lib als Argument nimmt? Etwas mehr Vertrauen würde ich in den Linker schon haben ;-) BTW #2, es gibt irgendwo im Netz ein pdf "Linker and Loader" -evtl. klärt dies einiges auf. Viele Grüße Olaf
@ope: Ich habe das mit msp430-size überprüft. Durch Vergleich der verschiedenen Varianten sieht man genau, welche Variante wieviel RAM/Flash belegt.
mmhh, speziell zum msp430 kann ich nichts sagen, aber wenn der linker wirklich einfach alles zusammenklatsch, ist etwas im Argen. Normalerweise löst er alle Symbole innerhalb der object files auf (export/import symbols). Wenn er unused code mit reinschmeisst, wird dieser jedoch niemals ausgeführt werden und es wäre ein entsprechender Bug Report fällig, sicher siehst Du aber an den Antworten, dass sich dieses hier niemand so recht vorstellen kann. U.U. wäre strip wirklich Dein Freund als Notbehelf. Allerdings, wenn die msp430 Tool Chain wirklich so "tapsig" ist, wird strip wohl auch Mist bauen (lange Zeit war der strip Befehl der gcc suite auf HPUX unbrauchbar, da er die exe zerstörte). Viele Grüße Olaf
ope: Aus Objektdateien (.o) nimmt der Linker grundsätzlich alles mit! Aus einer vernünftig erstellten Lib nimmt er nur die Objektdateien mit, aus denen auch Code referenziert wird! Das ist der gravierende Unterschied. Nämlich eigentlich gar keiner ;-) Man muss halt dafür sorgen, daß in jeder Objektdatei immer nur der Code drinsteckt, der beim referenzieren eines Symboles auch wirklich gebraucht wird. Ein (vielleicht nicht immer passendes) Beispiel ist die Kombination malloc & free: Man sieht sie in vielen Implementationen in demselben C-Sourcefile, wogegen realloc und Konsorten optional in eigenen C-Sourcefiles stehen. Grund? free ohne malloc ergibt keinen Sinn, free und malloc ohne realloc allerdings schon...
yep, "löst er alle Symbole innerhalb der object files ..." war unklar/unvollständig ausgedrückt. Sollte heissen "... in statischen (object) libs wie foo.a". Wenn dem so sei, müssten alle Programme, die statisch zB gegen die (g)libc gelinkt werden riesig werden, konkret größer als die lib selbst + programmcode. Größer wird allemal, da die shared libs entfallen. Ein nm zeigt zeigt nur die symbole des programms + importierte Symbole der static (ggf. shared) lib (kann es nicht nachprüfen, da bei cygwin alles gestripped ist). Oder haben wir uns falsch verstanden? Einen Blick in die gcc suite/binutils möchte ich mir ersparen ;) ist auch schon 'ne Weile her. Viele Grüße Olaf
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.