Объединение двух версий общей библиотеки в одном приложенииLinux

Ответить
Anonymous
 Объединение двух версий общей библиотеки в одном приложении

Сообщение Anonymous »

Основное описание проблемы:
  • Приложение использует библиотеку A 1.0.
  • Библиотека B использует более новую версию библиотеки A 2.0 с несовместимым ABI/поведением.
  • Приложение хочет использовать более старую версию библиотеки A 1.0 и B также, с последним неявно использование более новой версии библиотеки A 2.0 в том же контексте приложения.
В настоящее время этот сценарий не работает из-за конфликтов символов на платформе Linux. Некоторые ответы на подобные вопросы предлагают использовать --version-script — способ, которым glibc решает проблемы управления версиями.
Я проверил осуществимость этого подхода в моем сценарии. , и обнаружил, что она «почти» работает.
Предположим, что у нас есть библиотека A 1.0, такая:

Код: Выделить всё

// liba1.cpp
const char* doSomeA() { return "liba1::doSomeA()"; }
библиотека A 2.0 такая:

Код: Выделить всё

// liba2.cpp
const char* doSomeA() { return "liba2::doSomeA()"; }
библиотека B вот так:

Код: Выделить всё

// libb.cpp
#include 
extern const char* doSomeA();
void doSomeB() { printf("libb::doSomeB(%s)\n", doSomeA()); }
и применение:

Код: Выделить всё

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

int main() {
printf("%s  ..  ", doSomeA());
doSomeB();
return 0;
}
Теперь мы можем попытаться собрать библиотеку A 1.0 и 2.0 с управлением версиями символов liba1.map и без них:

Код: Выделить всё

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

Код: Выделить всё

LIBA_2.0 {
global: *;
};
Здание:

Код: Выделить всё

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
Выход:

Код: Выделить всё

liba1::doSomeA()  ..  libb::doSomeB(liba1::doSomeA())
liba1::doSomeA()  ..  libb::doSomeB(liba1::doSomeA())
liba1::doSomeA()  ..  libb::doSomeB(liba2::doSomeA())
Первая комбинация (библиотека A имеет неверсионные символы) показывает исходную проблему (используется неверная версия библиотеки A).
Третья комбинация (обе библиотеки A 1.0 и 2.0 имеют версии символов) показывает, что проблема решена. Но этот вариант требует изменения обеих версий 1.0 и 2.0 библиотеки A.
Вторая комбинация (библиотека A 1.0) использует неверсионные символы, а A 2.0 - версионный) по-прежнему не работает. Кажется, что даже когда библиотека ссылается на версионные символы, компоновщик по-прежнему принимает неверсионные символы, если они уже загружены.
Учитывая, что библиотеку A 1.0 нельзя изменить (но A 2.0 и библиотеку B можно изменить) – есть ли способ избежать такого поведения?

Подробнее здесь: https://stackoverflow.com/questions/793 ... in-one-app
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»