Verknüpfen von zwei Versionen der gemeinsam genutzten Bibliothek in einer AppC++

Programme in C++. Entwicklerforum
Guest
 Verknüpfen von zwei Versionen der gemeinsam genutzten Bibliothek in einer App

Post by Guest »

Grundlegende Problembeschreibung:
  • Anwendung verwendet Bibliothek A 1.0.
  • Bibliothek B verwendet eine neuere Version der Bibliothek A 2.0 mit inkompatiblem ABI/Verhalten.
  • Anwendung möchte ältere Version der Bibliothek A 1.0 und B verwenden auch mit letzterem implizit Verwendung einer neueren Version der Bibliothek A 2.0 im gleichen Anwendungskontext.
Derzeit schlägt dieses Szenario aufgrund von Symbolkonflikten auf der Linux-Plattform fehl. Einige Antworten auf ähnliche Fragen schlagen die Verwendung von --version-script vor – die Art und Weise, wie Glibc Versionierungsprobleme löst.
Ich habe versucht, diesen Ansatz für mein Szenario umsetzbar zu machen , und fand, dass es „fast“ funktioniert.
Bedenken Sie, dass wir eine Bibliothek A 1.0 haben wie folgt:

Code: Select all

// liba1.cpp
const char* doSomeA() { return "liba1::doSomeA()"; }
Bibliothek A 2.0 wie folgt:

Code: Select all

// liba2.cpp
const char* doSomeA() { return "liba2::doSomeA()"; }
Bibliothek B wie folgt:

Code: Select all

// libb.cpp
#include 
extern const char* doSomeA();
void doSomeB() { printf("libb::doSomeB(%s)\n", doSomeA()); }
und Anwendung:

Code: Select all

// app.cpp
#include 
extern const char* doSomeA();
extern const char* doSomeB();

int main() {
printf("%s  ..  ", doSomeA());
doSomeB();
return 0;
}
Jetzt können wir versuchen, Bibliothek A 1.0 und 2.0 mit und ohne Symbolversionierung liba1.map zu erstellen:

Code: Select all

LIBA_1.0 {
global: *;
};
und liba2.map:

Code: Select all

LIBA_2.0 {
global: *;
};
Gebäude:

Code: Select all

rm -f lib*.so
rm -f app00 app10 app11

# build library 'a 1.0' with (liba1v.so) and without (liba1.so) symbol versions
g++ liba1.cpp -g -fpic -shared -o liba1.so  -Wl,-soname,liba1.so
g++ liba1.cpp -g -fpic -shared -o liba1v.so -Wl,-soname,liba1v.so -Wl,--version-script,liba1.map

# build library 'a 2.0' with (liba2v.so) and without (liba2.so) symbol versions
g++ liba2.cpp -g -fpic -shared -o liba2.so  -Wl,-soname,liba2.so
g++ liba2.cpp -g -fpic -shared -o liba2v.so -Wl,-soname,liba2v.so -Wl,--version-script,liba2.map

# build library 'b' linked to either versioned (liba2v.so) or unversioned (liba2.so) library 'a'
g++ libb.cpp -g -fpic -shared -o libb2.so  -Wl,-soname,libb2.so  -Wl,--no-undefined -L. -la2
g++ libb.cpp -g -fpic -shared -o libb2v.so -Wl,-soname,libb2v.so -Wl,--no-undefined -L. -la2v

# build application linking to libraries 'b' (implicitly depending on 'a 2.0') and 'a 1.0'.
g++ app.cpp -g  -o app00 -Wl,-rpath,`pwd` -L. -lb2  -la1
g++ app.cpp -g  -o app10 -Wl,-rpath,`pwd` -L. -lb2v -la1
g++ app.cpp -g  -o app11 -Wl,-rpath,`pwd` -L. -lb2v -la1v

LD_LIBRARY_PATH=$PWD ./app00
LD_LIBRARY_PATH=$PWD ./app10
LD_LIBRARY_PATH=$PWD ./app11
Ausgabe:

Code: Select all

liba1::doSomeA()  ..  libb::doSomeB(liba1::doSomeA())
liba1::doSomeA()  ..  libb::doSomeB(liba1::doSomeA())
liba1::doSomeA()  ..  libb::doSomeB(liba2::doSomeA())
Die erste Kombination (Bibliothek A hat nicht versionierte Symbole) zeigt das ursprüngliche Problem (falsche Version von Bibliothek A wird verwendet).
Die dritte Kombination (beide Bibliotheken A 1.0 und 2.0 haben versionierte Symbole) zeigt, dass das Problem gelöst ist. Für diese Option müssen jedoch beide Versionen 1.0 und 2.0 von Bibliothek A geändert werden.
Die 2. Kombination (Bibliothek A 1.0 verwendet nicht versionierte Symbole und A 2.0 - versioniert) schlägt immer noch fehl. Es scheint, dass der Linker selbst dann, wenn die Bibliothek auf versionierte Symbole verweist, immer noch nicht versionierte Symbole akzeptiert, wenn diese bereits geladen sind.
In Anbetracht der Tatsache, dass Bibliothek A 1.0 nicht geändert werden kann (aber A 2.0 und Bibliothek B könnten geändert werden) – gibt es eine Möglichkeit, dieses Verhalten zu vermeiden?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post