www.mikrocontroller.net

Forum: Compiler & IDEs Bibliotheken mit Makefile erstellen?


Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Libs werden anschließend gelinkt; das stimmt schon.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
recht kompaktes Beispiel findet sich im Makefile der newlib-lpc

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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}

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.)

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du einen Beweis dafür?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

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

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

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Welt ist eben doch eine Scheibe!

Autor: ---- (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Im Anhang mal ein "Library Makefile" auf Basis des
WinAVR-Standardmakefiles.

Entpacken (wie immer):

  $ tar -xvvjf lib-makefile.tar.bz2

Autor: ope (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rolf F. (Gast)
Datum:

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

Autor: ope (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: ope (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.