Forum: Compiler & IDEs Bedingte Einbindung von Bibliotheken


von MartinK (Gast)


Lesenswert?

Guten Tag,
ich suche schon eine Weile nach einer vernünftigen Lösung für folgendes 
Problem und hatte leider hier oder bei Google nichts gefunden :(

Ich habe ein Projekt, welches für verschiedene 
Kommunikationsschnittstellen und für verschiedene Übertragungsformate 
(Binärframe/ASCII) genutzt werden soll. Also ein Projekt für 
verschiedene Ergebnisse.

Dazu hatte ich geplannt 4 Bibliotheken anzulegen (Uart, SPI, Ascii, 
Binär) und diese dann abhängig von einem #define einzubinden. Für die 
Headerdateien ist dies auch kein Problem, für das Objektfile (.a) habe 
ich jedoch keine Ahnung, ob bzw. wie sich dieses abhängig von einem 
define Einbinden lässt.

Gibt es dafür eine Lösung oder ein generell anderes Herangehen an das 
geschilderte Problem?

Grüße
Martin

von ... (Gast)


Lesenswert?

MartinK schrieb:
> für das Objektfile (.a) habe
> ich jedoch keine Ahnung, ob bzw. wie sich dieses abhängig von einem
> define Einbinden lässt.

Nein, das geht nicht. Kanns Du höchsten über ein Makefile machen. Ist 
aber eigentlich überflüssig. Du kannst einfach alle Bibliotheken 
dazulinken, der Linker ist schlau genug nur die Teile zu nehmen, die 
tatsächlich gebraucht werden.

von MartinK (Gast)


Lesenswert?

Mein Gedanke war die selbe Funktion verschieden zu implementieren, also 
z.b: SendData(u8* Data, u8 Len), selche dann mit SPI anders 
implementiert ist als mit Uart. Aber ich muss wohl getrennte 
Bibliotheken machen, jeweils unterschiedliche Namen geben (UartSendData, 
SpiSendData) und dann per Makro zuweisen. Ist das praktikabel oder ein 
Problem?
Also z.B.

#if USE_SPI
#define SendData(Data,Len) SpiSendData(Data,Len)
#endif
#if USE_UART
#define SendData(Data,Len) UartSendData(Data,Len)
#endif

den könnte ich dann ja als Header einbinden.
Danke für die Anregung alle zu Linken und auswählen zu lassen.

von DirkB (Gast)


Lesenswert?

Du kannst im make-file auch verschiedene Targets angeben.
Und dann mit make SPI entsprechen compilieren
Im Zweifelsfall gibst du dem Compiler noch mit -DUSE_SPI hilfe.

von Peter II (Gast)


Lesenswert?

... schrieb:
> Nein, das geht nicht. Kanns Du höchsten über ein Makefile machen. Ist
> aber eigentlich überflüssig. Du kannst einfach alle Bibliotheken
> dazulinken, der Linker ist schlau genug nur die Teile zu nehmen, die
> tatsächlich gebraucht werden.

und was ist mit Globalen Variablen?

von Andreas B. (Gast)


Lesenswert?

MartinK schrieb:
> #if USE_SPI
> #define SendData(Data,Len) SpiSendData(Data,Len)
> #endif

Ich würde statt dessen ein SendData() als static inline im Header 
definieren, das nur SpiSendData() mit den selben Argumenten aufruft. 
Dann kennt der Compiler SendData() als Funktion und kann Fehlermeldungen 
passender anzeigen. Wenn Optimierungen eingeschaltet sind, ist der 
erzeugte Code identisch zu dem mit Defines.


Peter II schrieb:
> und was ist mit Globalen Variablen?

Die .a Dateien, die von den GNU Tools als statische Libraries verwendet 
werden, sind einfach mit ar zusammengepackte Objektdateien. Wenn ld ein 
solches Archiv einbinden soll, nimmt er daraus nur die Objektdateien, 
die eine bisher unaufgelöste Referenz als Symbol anbieten (deshalb ist 
auch die Reihenfolge wichtig). Damit kommt auch der Rest dieser 
Objektdatei rein.

Oder war die Frage anders gemeint?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

MartinK schrieb:
> Mein Gedanke war die selbe Funktion verschieden zu implementieren, also
> z.b: SendData(u8* Data, u8 Len), selche dann mit SPI anders
> implementiert ist als mit Uart. Aber ich muss wohl getrennte
> Bibliotheken machen, jeweils unterschiedliche Namen geben (UartSendData,
> SpiSendData) und dann per Makro zuweisen. Ist das praktikabel oder ein
> Problem?
> Also z.B.
>
> #if USE_SPI
> #define SendData(Data,Len) SpiSendData(Data,Len)
> #endif
> #if USE_UART
> #define SendData(Data,Len) UartSendData(Data,Len)
> #endif
>
> den könnte ich dann ja als Header einbinden.
> Danke für die Anregung alle zu Linken und auswählen zu lassen.

Wozu denn diese Verunstaltung mit Makros? Wenn du eh Bibliotheken 
machst:

- Es gibt Bibliotheken wie libuart, libspi, libusb, ...
- Alle implementieren die benötigten Interfaces SandData et.al.
  jeweils auf ihre Weise.
- Die Interfaces werden in einem Header bekannt gemacht, zB:
1
extern void SendData (const void*, size_t);
- Es wird die Bibliothek hinzugelinkt, welche die Interfaces auf die
  gewünschte Art implementiert. Soll eine UART-Kommunikation
  stattfinden, gibt's einfach ein -luart bei den Linkeroptionen.

von MartinK (Gast)


Lesenswert?

Genau da liegt ja das Problem (siehe Titel): Ich möchte die gelinkten 
Bibliotheken nicht jedes mal händisch ändern, sondern per #define 
USE_UART 1 einbinden bzw. #define USE_UART 0 entfernen. Nun war der 
Vorschlag ja einfach alle Libraries zu linken und nur jene Funktionen zu 
nutzen, die passen. Das gerade sollen die Makros ermöglichen.

von Εrnst B. (ernst)


Lesenswert?

MartinK schrieb:
> sondern per #define
> USE_UART 1 einbinden bzw. #define USE_UART 0 entfernen.

Wie schon geschrieben: Mach das alles im Makefile.
Da kannst so sowohl die Defines ändern (-DUSE_UART in die C-Flags) als 
auch die Bibliotheken auswählen (-luart in die LD-Flags).

Machen 10000 andere Projekte auch so, nur das da meist noch ein autoconf 
o.Ä. vorgeschaltet ist, um auch noch das Makefile-parametrieren zu 
automatisieren.

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.