2012-02-06 11 views
5

Ecco la situazione, ho una base di codice C++ che usa un GCC recente (4.3.3), ma ho bisogno di collegarmi a una vecchia libreria che è stata costruita usando GCC 3.2. 3. Non esiste una versione più recente della libreria disponibile, non posso farne a meno, ed è closed source quindi non può essere ricostruita.Combinare gli ABI C++ per costruire contro le librerie legacy

Questo sembra rappresentare un problema poiché ci sono incompatibilità ABI tra GCC 4.3.3 e 3.2.3, quindi sto provando a vedere quali sono le mie opzioni per risolverlo.

Alcuni dettagli aggiuntivi:

  • posso ricostruire tutto nella mia base di codice con -fabi-version = 1 per ottenere la versione corretta ABI, ma io sono dipendente da alcune caratteristiche più recenti da libstdC++ versione 6.
  • Tutte le dipendenze della libreria C++ al di fuori della base di codice sono open source, quindi posso ricostruirle secondo necessità, eccetto per questa libreria.
  • Molte dipendenze della libreria C che non possono essere ricostruite o sarebbero difficili da ricostruire.
  • La vecchia biblioteca sembra essere dipendente da un po 'di libstdC++ versione 5 caratteristiche

Finora ho provato:

  • Ricostruire tutto il codice e dipendenti librerie C++ con -fabi-version = 1 e il collegamento contro libstdC++ versione 6. Ciò non riesce con una manciata di errori di simboli non definiti per i simboli di libreria standard C++.
  • Come sopra, ma anche un collegamento nella libreria condivisa per libstdC++ 5, risolve i problemi del linker ma sembra generare una combinazione delle due versioni in runtime all'interno della libreria legacy e provoca un arresto anomalo.

Ho letto questa pagina: http://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html che sembra indicare che è possibile combinare versioni ABI C++ in un'applicazione per soddisfare dipendenze variabili tra le varie librerie. Non sembra funzionare molto bene qui, però, a meno che mi manchi qualcosa.

Qualche idea?

+0

Le opzioni del linker '-Bsymbolic' e' --exclude-libs' dovrebbero essere d'aiuto se si collega staticamente il vecchio libstdC++ in una libreria condivisa. –

risposta

3

Ok, la tua soluzione è:

  • scrivere un'interfaccia "C" per la vecchia libreria C++, compilare con 3.2.3 in modo da funzionare.
  • Ora è possibile utilizzare l'interfaccia C nel nuovo compilatore.

È possibile scrivere un codice "wrapper" C++ attorno alla libreria C in modo da utilizzarlo come C++ ma questo codice verrà creato nel nuovo compilatore.

+1

Ovviamente, questo ha lo svantaggio di aggiungere un po 'di codice di colla, ma ha il vantaggio di lavorare con QUALSIASI coppia di compilatori/versioni C. – kibibu

+0

Sembra un approccio ragionevole. Se creo una libreria condivisa, continuerà comunque a dipendere dalla vecchia libreria condivisa libstdC++. Non avrò lo stesso problema? O dovrei collegare staticamente nella versione precedente? –

+0

Dopo aver fatto qualche altro scavo, sembra che la cosa giusta da fare sia collegare staticamente in libstdC++ dal vecchio GCC in questa libreria condivisa.Tuttavia, sospetto che il solo collegamento con questo non sia abbastanza, dal momento che avresti effettivamente lo stesso problema di prima con i simboli condivisi attraverso il confine della biblioteca. Penso che tu possa eliminare ogni possibilità facendo un dlopen all'interno dell'applicazione e usando RTLD_NOW | RTLD_DEEPBIND | RTLD_LOCAL. –

Problemi correlati