Forum: Compiler & IDEs Bibliotheken mit Makefile erstellen?


von Rolf F. (Gast)


Lesenswert?

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?

von Rolf Magnus (Gast)


Lesenswert?

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.

von Rolf F. (Gast)


Lesenswert?

Die Libs werden anschließend gelinkt; das stimmt schon.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

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

von Rolf F. (Gast)


Lesenswert?

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.

von mthomas (Gast)


Lesenswert?

recht kompaktes Beispiel findet sich im Makefile der newlib-lpc

von Rolf Magnus (Gast)


Lesenswert?

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

von Rolf F. (Gast)


Lesenswert?

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

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


Lesenswert?

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

von Rolf F. (Gast)


Lesenswert?

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

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Hast Du einen Beweis dafür?

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


Lesenswert?

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

von Rolf F. (Gast)


Lesenswert?

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

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

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.

von Rolf F. (Gast)


Lesenswert?

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.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

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

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


Lesenswert?

> Ob das wirklich genau so gut funktioiniert will ich nicht testen;

Sorry, aber dann ist dir auch nicht mehr zu helfen.

von Rolf Magnus (Gast)


Lesenswert?

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

von Rolf F. (Gast)


Lesenswert?

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.

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

Die Welt ist eben doch eine Scheibe!

von ---- (Gast)


Lesenswert?

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

von Patrick D. (oldbug) Benutzerseite


Angehängte Dateien:

Lesenswert?

Im Anhang mal ein "Library Makefile" auf Basis des
WinAVR-Standardmakefiles.

Entpacken (wie immer):

  $ tar -xvvjf lib-makefile.tar.bz2

von ope (Gast)


Lesenswert?

> 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

von Rolf F. (Gast)


Lesenswert?

@ope:
Ich habe das mit msp430-size überprüft.
Durch Vergleich der verschiedenen Varianten sieht man genau, welche
Variante wieviel RAM/Flash belegt.

von ope (Gast)


Lesenswert?

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

von Patrick D. (oldbug) Benutzerseite


Lesenswert?

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

von ope (Gast)


Lesenswert?

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