2015-02-22 2 views
1

У меня есть проект foo, который зависит от a, который, в свою очередь, зависит от b, в свою очередь зависит от c. Мой скрипт сборки pull/configure/make - это три зависимости от источника в правильном порядке, и они компилируются в порядке.Статически связывайте несколько библиотек в один .so

Прямо сейчас, распространять foo.so, мне также нужно распределить все его зависимости (a.so, b.so и c.so) рядом. Я хочу построить foo.so, содержащий все объекты как foo, так и все его зависимости; таким образом я могу распространять одну библиотеку.

a, b и c все используют Autotools и генерировать связанные * .o файлы в SRC/каталога, а также .libs/каталог, содержащий обычное поверхностное знание * .ar * .lo * .lai и * .so, все действительные. Сейчас я использую этот набор флагов GCC, чтобы построить мой foo.so:

gcc -shared ./my/src/*.c \ 
    -I./a/include -I./b/include -I./c/include \ 
    -L ./a/.libs -L./b/.libs -L./c/.libs \ 
    -la -lb -lc \ 
    -o ./foo.so \ 
    -w -fPIC -m64 \ 
    -std=c99 

(обратите внимание, что «-la -lb -lc» просто «-l» флаги для каждой зависимости, я не просто испортить флаги).

Использование readelf -d на итоговой foo.so действительно показывает, что оно имеет зависимость от a. Учитывая, что у меня есть все файлы сборки для всех зависимостей, мне кажется, что я просто пропускаю некоторый флаг для «включить этот путь при поиске * .o файлов для ссылки».

Я пробовал разные вещи и, честно говоря, даже не могу вспомнить различные ошибки и условия, которые привели к ним. Наиболее перспективным является this question, но после удаления моих линий «-l» в пользу строк «-Wl, - whole-archive», я получаю эту ошибку (обратите внимание, что «aa» - это просто * .a для a) :

/usr/bin/ld: ./a/.libs/a.a(bands.o): relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC 
./a/.libs/a.a(bands.o): error adding symbols: Bad value 

Который не имеет смысла для меня, так как эти файлы должны быть PIC для того, чтобы построить их в * .so, верно? Процесс сборки для этих зависимостей делает * .so.

Я на Mint Linux, если это имеет значение.

+1

Если у вас есть '.la' файлов, используйте' libtool' для обрабатывать [ссылки] (http://www.gnu.org/software/libtool/manual/libtool.html#Linking-libraries) , например, 'libtool --mode = link gcc -o foo.la ./my/src/*.lo ./a/a.la ./b/b.la./c/c.la' - требуется источник объекты, которые должны быть построены с помощью 'libtool --mode = compile gcc -c file.c' –

ответ

3

Сообщение об ошибке очень ясно, что нужно сделать.

/usr/bin/ld: ./a/.libs/a.a(bands.o): relocation R_X86_64_32S against 
`.rodata' can not be used when making a shared object; recompile with -fPIC 
                 ^^^^^^^^^^^^^^^^^^^^^ 

./a/.libs/a.a(bands.o): error adding symbols: Bad value 

код объекта, который мы часть статических библиотек не могут быть помещены в общей библиотеке, если они не скомпилирован с опцией -fPIC.

+0

Но разве он уже не был скомпилирован как PIC, так как процесс autotools/make создает' a.so'? – Knetic

+0

Я не знаю, как были настроены autotools и make. Они явно не добавляют '-fPIC' в компилятор при компиляции файлов перед добавлением результирующих объектных файлов в статическую библиотеку (-и). –

1

С помощью ответчиков здесь я смог получить рабочее решение. Я в корне неправильно понял, что autotools генерирует два набора файлов * .o, один из которых является PIC, а это не тот. Место для каждого из них находится в файле * .lo. Мои зависимости (a, b и c) были построены с помощью autotools, и мне нужно было связать их с версиями PIC, а не с комбинированной статической * .a версией.

Мне также нужно было разделить процесс сборки на две части с помощью libtool. Скомпилируйте фазу только для создания моего кода и фазы компоновщика, которая рассмотрела версии зависимостей PIC.

У меня не было симпатичного скрипта, но если кто-то попадает в тот же сценарий, мои уродливые линии gcc выглядят. Надеюсь, это будет точка прыжка на что-то меньшее ...ужасно, чем я придумал.

find ./my/src -name "*.c" -exec \ 
libtool --mode=compile gcc -c -O -g \ 
    -I./a/include -I./b/include -I./c/include \ 
    -L./a/.libs/*.lo -L./b/.libs/*.lo -L./c/.libs/*.lo \ 
    -la -lb -lc \ 
    -w -m64 \ 
    -std=c99 \ 
    {} \; 

gcc \ 
    -g -O -w -fPIC -m64 -std=c99 -shared \ 
    -o ./foo.so \ 
    $(find . -wholename "*.libs/*.o"); 
Смежные вопросы