Линковка динамических библиотек между собой

Модератор: Модераторы разделов

IMB
Сообщения: 2567
ОС: Debian

Линковка динамических библиотек между собой

Сообщение IMB »

Доброго дня!
Есть необходимость использовать XML во многих частях проекта, для работы с XML используется libxml2.
Что бы избежать дублирования кода думаю написать функции-обёртки на функциями libxml2 и оформить это в виде динамической библиотеки, которую и подключать затем где необходимо.
На первый взгляд получается такая схема программа(ы) -> моя библиотека.so -> libxml2.so
Вопрос - такая схема будет работать? Если нет, то как лучше организовать?
Спасибо.
Спасибо сказали:
Аватара пользователя
agentprog
Сообщения: 362
Статус: Ad Astra per aspera
ОС: openSUSE 11.4, Arch

Re: Линковка динамических библиотек между собой

Сообщение agentprog »

будет. собственно, многие библиотеки подобным образом и работают.
No problems - just solutions!
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Линковка динамических библиотек между собой

Сообщение IMB »

Хорошо.
Заголовочный файл:

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

 #include <libxml/xmlmemory.h>
#include <libxml/parser.h>

xmlDocPtr xml_get_file(const char *file);

C-файл:

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

#include <xml.h>

xmlDocPtr xml_get_file(const char *file)
{
    return xmlParseFile(file);
}

Я компилирую так:

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

$(CC) -fPIC -I$(INC_DIR) -I$(LIBXML2_DIR)/include -c $(SRC_DIR)/$@.c
$(CC) -shared -L$(LIBXML2_DIR)/.libs -lxml -o $(LIB_DIR)/libconfig.so $@.o

Компилятор выдаёт сообщение:

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

arm_v5t_le-gcc -fPIC -Iinc -I../libxml2/include -c src/xml.c
arm_v5t_le-gcc -shared -L../libxml2/.libs -lxml -o lib/libconfig.so xml.o
/home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/bin/../lib/gcc/armv5tl-montavista-linux-gnueabi/4.2.0/../../../../armv5tl-montavista-linux-gnueabi/bin/ld: cannot find -lxml
collect2: ld returned 1 exit status
make: *** [xml] Error 1

Если я компилирую так:

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

$(CC) -fPIC -I$(INC_DIR) -I$(LIBXML2_DIR)/include -c $(SRC_DIR)/$@.c
$(CC) -shared -o $(LIB_DIR)/libconfig.so $@.o

Тогда всё проходит нормально, но произошла ли в этом случае линковка с libxml2?

Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Линковка динамических библиотек между собой

Сообщение IMB »

Собственно позволю себе чуток расширить вопрос.
Компиляция:

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

$(PREFIX)gcc -fPIC -I$(INC_DIR) -I$(LIBXML2_DIR)/include -c $(SRC_DIR)/$@.c
$(PREFIX)ar rc $(LIB_DIR)/libconfig.a $@.o
$(PREFIX)ranlib $(LIB_DIR)/libconfig.a
$(PREFIX)gcc -shared -o $(LIB_DIR)/libconfig.so $@.o

Собственно я собираю статическую и динамическую библиотеку.
Но происходит ли в данном случае линковка с libxml3 если я нигде не указываю фдаг -l?
Спасибо сказали:
Аватара пользователя
Denjs
Сообщения: 1685
ОС: SuSe 10.2

Re: Линковка динамических библиотек между собой

Сообщение Denjs »

а почему вы в #3 указываете -lxml ?
у вас есть библиотека или libxml.so ? вы же вроде писали что у вас libxml2.so

кстати - если не хотите морочиться с -lxml - вы можете делать загружать библиотеку в рантайме руками (простите - не помню как это называется правильно). Мороки побольше, но вы сами можете проверить что вы загружаете, включая наличие файла перед загрузкой....
QDroid - Среда исполнения и фреймворк для QtScript.
OTPD - Открытые драйвера промышленных принтеров чеков и этикеток (кроссплатформенная подсистема печати).
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Линковка динамических библиотек между собой

Сообщение IMB »

Хм, моя ошибка. Привёл make к следующему виду:

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

$(PREFIX)gcc -fPIC -I$(INC_DIR) -I$(LIBXML2_DIR)/include \
        -L$(LIBXML2_DIR)/.libs -lxml2 $(SRC_DIR)/$@.c
$(PREFIX)ar rc $(LIB_DIR)/libconfig.a $@.o
$(PREFIX)ranlib $(LIB_DIR)/libconfig.a
$(PREFIX)gcc -shared -o $(LIB_DIR)/libconfig.so $@.o

Сообщение от компилятора:

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

arm_v5t_le-gcc -fPIC -Iinc -I../libxml2/include -L../libxml2/.libs -lxml2 src/xml.c
/home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/lib/crt1.o: In function `_start':
init.c:(.text+0x30): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [xml] Error 1
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Линковка динамических библиотек между собой

Сообщение watashiwa_daredeska »

IMB писал(а):
01.03.2011 12:54
/home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/bin/../target/usr/lib/crt1.o: In function `_start':
init.c:(.text+0x30): undefined reference to `main'
Флажок -c забыли, он пытается выполняемый бинарь создать.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Линковка динамических библиотек между собой

Сообщение IMB »

Хм, возможно я неправильно представляю концепцую динамических библиотек?
Хорошо, динамическая библиотека собрана так:

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

$(PREFIX)gcc -fPIC -I$(INC_DIR) -I$(LIBXML2_DIR)/include \
        -L$(LIBXML2_DIR)/.libs -lxml2 -c $(SRC_DIR)/$@.c
$(PREFIX)gcc -shared -o $(LIB_DIR)/libconfig.so $@.o

Вывод компилятора:

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

arm_v5t_le-gcc -fPIC -Iinc -I../libxml2/include \
                -L../libxml2/.libs -lxml2 -c src/xml.c
arm_v5t_le-gcc: -lxml2: linker input file unused because linking not done
arm_v5t_le-gcc -shared -o lib/libconfig.so xml.o

Данные ldd

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

libc.so.6 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libc.so.6 (0xdead1000)
/lib/ld-linux.so.3 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/ld-linux.so.3 (0xdead2000)

Честно говоря, я ожидал увидеть в выводе упоминание о libxml2.
Пытаюсь собрать программа:

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

arm_v5t_le-gcc -I../../Libconfig/inc -I../../libxml2/include -L../../Libconfig/lib -lconfig \
                test2.c -o xmltest2
../../Libconfig/lib/libconfig.so: undefined reference to `xmlFreeDoc'
../../Libconfig/lib/libconfig.so: undefined reference to `xmlParseFile'
collect2: ld returned 1 exit status
make: *** [all] Error 1

Т.е. мою библиотеку подлинковать удалось, но я рассчитывал, что мне при сборке программ надо будет указывать только мою библиотеку.
А она, потянет libxml2 при запуске программы.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Линковка динамических библиотек между собой

Сообщение IMB »

Похоже со сборкой динамической библиотеки разобрался.
Сборка:

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

[ -d lib ] || mkdir lib
arm_v5t_le-gcc -fPIC -Iinc -I../libxml2/include -c src/xml.c
arm_v5t_le-gcc -shared -o lib/libconfig.so \
                -L../libxml2/.libs -lxml2 xml.o

Вывод ldd:

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

libxml2.so.2 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/usr/lib/libxml2.so.2 (0xdead1000)
libc.so.6 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libc.so.6 (0xdead2000)
libdl.so.2 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libdl.so.2 (0xdead3000)
libz.so.1 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/usr/lib/libz.so.1 (0xdead4000)
libm.so.6 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libm.so.6 (0xdead5000)
/lib/ld-linux.so.3 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/ld-linux.so.3 (0xdead6000)

Теперь осталось проверить это на реальной программе.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Линковка динамических библиотек между собой

Сообщение IMB »

Что ж, похоже всё работает.
Привожу полный Makefile.

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

PREFIX := arm_v5t_le-
LIB_DIR := lib
INC_DIR := inc
SRC_DIR := src
LIBXML2_DIR := ../libxml2

.PHONY: clean cleanall

all: xml

xml: prepare
    $(PREFIX)gcc -fPIC -I$(INC_DIR) -I$(LIBXML2_DIR)/include -c $(SRC_DIR)/$@.c
    $(PREFIX)ar rc $(LIB_DIR)/libconfig.a $@.o
    $(PREFIX)ranlib $(LIB_DIR)/libconfig.a
    $(PREFIX)gcc -shared -o $(LIB_DIR)/libconfig.so -Wl,-R/usr/lib \
        -L$(LIBXML2_DIR)/.libs -lxml2 $@.o

prepare:
    [ -d $(LIB_DIR) ] || mkdir $(LIB_DIR)

clean:
    rm --force $(LIB_DIR)/* *.o

cleanall:
    rm --force --recursive $(LIB_DIR) *.o

Из "дополнительных" возможностей только указание пути к библиотеке в системе (-Wl,-R/usr/lib). Без этого программа ищет библиотеку в своей директории.

P.S. Всё собирается для работы на встраиваемой плате с ARM-процессором, система построена на BusyBox.
Работу статической библиотеки не проверял.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Линковка динамических библиотек между собой

Сообщение IMB »

Что-то сломалось снова. Итак, необходимо свои функции по работе с XML собрать в виде динамической библиотеки и подключать её, и только её, к другим программам.
Makefile

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

lib:
    [ -d $(LIB_DIR) ] || mkdir $(LIB_DIR)
    $(CROSS)gcc -fPIC -I$(INC_DIR) -I$(LIBXML2_DIR)/include \
        -c $(SRC_DIR)/xml.c
    $(CROSS)gcc -fPIC -I$(INC_DIR) -I$(LIBXML2_DIR)/include \
        -c $(SRC_DIR)/network.c
    $(CROSS)gcc -fPIC -I$(INC_DIR) -I$(LIBXML2_DIR)/include \
        -c $(SRC_DIR)/video.c
    $(CROSS)ar rc $(LIB_DIR)/$(LIB_NAME).a network.o video.o xml.o
    $(CROSS)ranlib $(LIB_DIR)/$(LIB_NAME).a
    $(CROSS)gcc -shared -o $(LIB_DIR)/$(LIB_NAME).so -Wl,-R$(TARGET_DIR) \
        -L$(LIB_DIR) -L$(LIBXML2_DIR)/.libs -lxml2 \
        network.o video.o xml.o

bin: lib
    [ -d $(BIN_DIR) ] || mkdir $(BIN_DIR)
    $(CROSS)gcc -DTEST -I$(INC_DIR) -I$(LIBXML2_DIR)/include -L$(LIB_DIR) \
        -lconfig -o $(BIN_DIR)/$(NET_TEST) $(SRC_DIR)/network.c xml.o
    $(CROSS)gcc -DTEST -I$(INC_DIR) -I$(LIBXML2_DIR)/include -L$(LIB_DIR) \
        -lconfig -o $(BIN_DIR)/$(VIDEO_TEST) $(SRC_DIR)/video.c xml.o

Сама библиотека собирается и в выводе ldd видно, что она зависит от libxml2.

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

libxml2.so.2 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/usr/lib/libxml2.so.2 (0xdead1000)
libgcc_s.so.1 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libgcc_s.so.1 (0xdead2000)
libc.so.6 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libc.so.6 (0xdead3000)
libdl.so.2 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libdl.so.2 (0xdead4000)
libz.so.1 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/usr/lib/libz.so.1 (0xdead5000)
libm.so.6 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libm.so.6 (0xdead6000)
/lib/ld-linux.so.3 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/ld-linux.so.3 (0xdead7000)

Но при сборке тестовых программ, цель bin, вываливаются ошибки на этапе линковки:

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

[ -d bin ] || mkdir bin
/home/kirill/CodeSourcery/Sourcery_G++_Lite/bin/arm-none-linux-gnueabi-gcc -DTEST -Iinc -I/home/kirill/CombineIP/src/libxml2/include -Llib \
                -lconfig -o bin/nettest src/network.c xml.o
/home/kirill/CodeSourcery/Sourcery_G++_Lite/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/../../../../arm-none-linux-gnueabi/bin/ld:
warning: libxml2.so.2, needed by lib/libconfig.so, not found (try using -rpath or -rpath-link)
/tmp/ccmbil6D.o: In function `config_net_gen_xml':
network.c:(.text+0x4c): undefined reference to `xmlNewDoc'
network.c:(.text+0x78): undefined reference to `xmlNewNode'
network.c:(.text+0xa4): undefined reference to `xmlDocSetRootElement'
network.c:(.text+0xd0): undefined reference to `xmlNewChild'
network.c:(.text+0x100): undefined reference to `xmlNewProp'
..................

Если я правильно понимаю, причина в в том, что линковщик не находит libxml2.so.2. Если я в строку компиляции добавляю -L/path/to/libxml2 -lxml2, то всё собирается.
Но это противоречит первоначальной идее.
Есть предположение, что сборка "сломалась" из за смены компилятора, которая произошла в следствии смена sdk. Ранее я пользовался gcc version 4.2.0 (MontaVista 4.2.0-16.0.32.0801914 2008-08-30), сейчас используется gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203).
Или проблема в другом?
Спасибо.
Спасибо сказали:
IMB
Сообщения: 2567
ОС: Debian

Re: Линковка динамических библиотек между собой

Сообщение IMB »

Предположение о проблеме из за смены компилятора подтвердилось.
Предыдущим компилятором всё успешно собралось.

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

[ -d bin ] || mkdir bin
arm_v5t_le-gcc -Iinc -I/home/kirill/CombineIP/src/libxml2/include -c src/xml.c
arm_v5t_le-gcc -DTEST -Iinc -I/home/kirill/CombineIP/src/libxml2/include -Llib \
                -lconfig -o bin/nettest src/network.c xml.o
arm_v5t_le-gcc -DTEST -Iinc -I/home/kirill/CombineIP/src/libxml2/include -Llib \
                -lconfig -o bin/videotest src/video.c xml.o

arm_v5t_le-ldd bin/nettest

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

libconfig.so => not found //моя библиотека
libc.so.6 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libc.so.6 (0xdead1000)
libxml2.so.2 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/usr/lib/libxml2.so.2 (0xdead2000)
/lib/ld-linux.so.3 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/ld-linux.so.3 (0xdead3000)
libdl.so.2 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libdl.so.2 (0xdead4000)
libz.so.1 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/usr/lib/libz.so.1 (0xdead5000)
libm.so.6 => /home/kirill/MVK-IP/SDK/montavista/pro/devkit/arm/v5t_le/target/lib/libm.so.6 (0xdead6000)

Спасибо сказали: