2014-04-15 23 views
8

Voglio creare una libreria .a statica per il mio progetto da più fonti, alcune definiscono funzioni deboli e altre le implementano. Diciamo che come esempio ho:Sovrascrivi simboli deboli nella libreria statica

lib1.c:

void defaultHandler() 
{ 
    for(;;); 
} 
void myHandler() __attribute__((weak, alias ("defaultHandler"))); 

lib2.c:

void myHandler() 
{ 
    /* do my stuff here */ 
} 

allora voglio metterli in una singola libreria, in modo che sembra trasparente per l'applicazione finale

$ ar -r libhandlers.a lib1.o lib2.o 

Ma v'è ora 2 simboli myHandler in libhandlers:

$ nm libhandlers.a | grep "myHandler" 
00000001 W myHandler 
00000581 T myHandler 

E quindi quando si utilizza la lib, il riferimento debole è collegato. L'unica soluzione che ho per il momento è di non includere nella libreria lib2.c ma aggiungerla come sorgente nel Makefile dell'applicazione ... non è soddisfacente dato che mi piacerebbe fornire solo poche librerie da usare e non un intero gruppo di file.

L'opzione --whole-archive non è soddisfacente in quanto lavoro su sistemi embedded e non voglio includere tutte le cose che non mi servono.

C'è un modo per compilare la libreria in modo che il simbolo debole scompaia se ne viene fornito uno forte?

NOTA: sto usando il braccio-nessuno-EABI-gcc v4.8

risposta

9

Questo è un sottoprodotto del modo in cui funzionano le biblioteche .a - sono semplicemente una raccolta di .o file.

Che succede durante il collegamento di compilazione è che il primo riferimento al nome viene risolto al riferimento debole e il nome sicuro non viene mai uno sguardo in.

è possibile verificare da soli per fare effettivamente sia il nome identico e forte e vedrai esattamente lo stesso comportamento.

Se si desidera risolvere prima i riferimenti forti, quindi inserirli prima nell'archivio oppure creare un archivio forte separato e collegarlo per primo nella linea di collegamento.

Anche se non si applica direttamente al caso, poiché si utilizza un ambiente incorporato, i riferimenti deboli o intensi entrano in vigore correttamente quando si creano/consumano librerie dinamiche .so anziché .a. Quando si crea un file .so, tutti i riferimenti deboli che compongono la libreria non generano un errore e solo uno di essi verrà utilizzato per il prodotto finale; e se c'è una definizione forte ovunque, viene utilizzata piuttosto che una di quelle deboli (funziona solo se, quando si crea un .so, si collegano tutti i file .o che lo compongono separatamente o si utilizza lo --whole-archive quando si crea il .so se si collega a un .a).

+1

Non credo che l'utilizzo di librerie condivise sia possibile su sistemi embedded (praticamente nessun sistema operativo) – Quentin

+2

@Quentin L'ultimo paragrafo era un breve "quando si verifica la risoluzione debole/forte". Riformulerò il paragrafo – Petesh

+0

Da quello che spiegate, dovrebbe essere possibile risolvere il problema eseguendo un file .o univoco da 'lib1.c' e 'lib2.c' e poi inserirli in .a (insieme ad altri file .o), ho ragione? – Quentin