Я создал оболочку для своего приложения, используя boost :: python.
Это сработало до сих пор:
(количество статических библиотек / исходный код) -> python_mapping.so
Таким образом, мой общий объект состоит из многих статических библиотек, в том числе самого boost (особенно boost_thread). Я предполагаю, что это будет содержать ВСЕ данные моего приложения, так как я статически связал все в.
Это компилируется просто отлично.
ldd python_mapping.so
librt.so.1 => /lib64/librt.so.1 (0x00002b7cbad37000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b7cbaf40000)
libm.so.6 => /lib64/libm.so.6 (0x00002b7cbb240000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b7cbb4c4000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b7cbb6d2000)
libc.so.6 => /lib64/libc.so.6 (0x00002b7cbb8ed000)
/lib64/ld-linux-x86-64.so.2 (0x000000327ee00000)
Тем не менее, когда я запускаю свое примерное приложение Python, я получаю эту ошибку компоновки во время выполнения:
неопределенный символ: _ZTIN5boost6detail16thread_data_baseE
Кажется, что те библиотеки повышения, которые хорошо связаны со статической библиотекой, на самом деле не существуют?
Эй, ребята, я добился определенного прогресса в этом. По-видимому, мой общий объект не содержит много символов, которые, по мнению компилятора, не использовались (потому что он никогда не видел, чтобы мои объекты c ++ когда-либо создавались, поскольку они создаются путем создания экземпляров объектов Python).
Вроде как:
//This is a class only created in python
#include "CPlusPlusClass.h"
PythonClass
{
public:
PythonClass() { }
private:
CPlusPlusClass _cplusplus;
};
//PythonMappings for PythonClass
#python file
import python_mapping
pythonClass = python_mapping.PythonClass() #This fails saying it can't find the symbol for CPlusPlusClass
Компилятор оптимизирует класс CPlusCPlus, потому что он никогда не увидит, что он фактически используется, что совершенно неприятно. Кажется, он сохраняет сам PythonClass (возможно, из-за макроса Python Boost Mapping.
Вы можете обойти это несколькими способами:
-Xlinker --whole-archive
Мне было интересно, если кто-нибудь может придумать другое решение, потому что это действительно раздражает, чтобы просмотреть все возможные библиотеки и добавить их в —whole-archive
Спасибо!
Хорошо, поскольку никто не ответил, я обнаружил, что самое простое (и единственное известное мне решение) — это включить КАЖДУЮ статическую библиотеку, которая у вас есть:
-Xlinker --whole-archive
Конечно, вы можете динамически связывать свои библиотеки, что потребует от вас установки LD_LIBRARY_PATH при выполнении вашего приложения на Python (хотя для многих библиотек это было не вариант для меня).
Итак, в этом смысле явный динамическое связывание может считаться более элегантным решением.
Кроме того, если ваши библиотеки используют другие библиотеки:
python_mapping.so -> статические ссылки в utility1.a -> статические ссылки в utility2.a
Если вы забыли указать ссылку на utility1.a, запустив приложение python, вы узнаете, что он не может найти символы, однако он НЕ будет жаловаться на utility2.a и будет вести себя странно, когда достигнет этой части библиотека. Так что … будьте осторожны и убедитесь, что вы явно связаны в ВСЕ.
Вы можете использовать параметр компоновщика -rpath для встраивания пути поиска библиотеки, включая «текущий каталог» в ваш исполняемый файл (g ++ -Wl, -rpath,.), Чтобы вы могли точно указать, откуда загружать разделяемые библиотеки. Это помогает, если вы перемещаете свое приложение на другие машины, чьи файлы .so неизвестны. Вам также придется перемещаться по .so файлам, которые вы явно указали. Это компромисс между статической связью и полной динамической связью, потому что вы на самом деле не будете «делиться» .so-файлом с другими приложениями на коробке (вы перенесли свои собственные копии), одно из преимуществ экономии памяти при использовании общих библиотек ,
Этот пост предназначен главным образом для публикации редко используемого, но очень полезного параметра -rpath.