Линковка динамических библиотек между собой
Модератор: Модераторы разделов
-
- Сообщения: 2567
- ОС: Debian
Линковка динамических библиотек между собой
Доброго дня!
Есть необходимость использовать XML во многих частях проекта, для работы с XML используется libxml2.
Что бы избежать дублирования кода думаю написать функции-обёртки на функциями libxml2 и оформить это в виде динамической библиотеки, которую и подключать затем где необходимо.
На первый взгляд получается такая схема программа(ы) -> моя библиотека.so -> libxml2.so
Вопрос - такая схема будет работать? Если нет, то как лучше организовать?
Спасибо.
Есть необходимость использовать XML во многих частях проекта, для работы с XML используется libxml2.
Что бы избежать дублирования кода думаю написать функции-обёртки на функциями libxml2 и оформить это в виде динамической библиотеки, которую и подключать затем где необходимо.
На первый взгляд получается такая схема программа(ы) -> моя библиотека.so -> libxml2.so
Вопрос - такая схема будет работать? Если нет, то как лучше организовать?
Спасибо.
-
- Сообщения: 362
- Статус: Ad Astra per aspera
- ОС: openSUSE 11.4, Arch
Re: Линковка динамических библиотек между собой
будет. собственно, многие библиотеки подобным образом и работают.
No problems - just solutions!
-
- Сообщения: 2567
- ОС: Debian
Re: Линковка динамических библиотек между собой
Хорошо.
Заголовочный файл:
C-файл:
Я компилирую так:
Компилятор выдаёт сообщение:
Если я компилирую так:
Тогда всё проходит нормально, но произошла ли в этом случае линковка с libxml2?
Заголовочный файл:
Код: Выделить всё
#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?
-
- Сообщения: 2567
- ОС: Debian
Re: Линковка динамических библиотек между собой
Собственно позволю себе чуток расширить вопрос.
Компиляция:
Собственно я собираю статическую и динамическую библиотеку.
Но происходит ли в данном случае линковка с libxml3 если я нигде не указываю фдаг -l?
Компиляция:
Код: Выделить всё
$(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?
-
- Сообщения: 1685
- ОС: SuSe 10.2
Re: Линковка динамических библиотек между собой
а почему вы в #3 указываете -lxml ?
у вас есть библиотека или libxml.so ? вы же вроде писали что у вас libxml2.so
кстати - если не хотите морочиться с -lxml - вы можете делать загружать библиотеку в рантайме руками (простите - не помню как это называется правильно). Мороки побольше, но вы сами можете проверить что вы загружаете, включая наличие файла перед загрузкой....
у вас есть библиотека или libxml.so ? вы же вроде писали что у вас libxml2.so
кстати - если не хотите морочиться с -lxml - вы можете делать загружать библиотеку в рантайме руками (простите - не помню как это называется правильно). Мороки побольше, но вы сами можете проверить что вы загружаете, включая наличие файла перед загрузкой....
-
- Сообщения: 2567
- ОС: Debian
Re: Линковка динамических библиотек между собой
Хм, моя ошибка. Привёл 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
-
- Бывший модератор
- Сообщения: 4038
- Статус: Искусственный интеллект (pre-alpha)
- ОС: Debian GNU/Linux
Re: Линковка динамических библиотек между собой
Флажок -c забыли, он пытается выполняемый бинарь создать.
Мои розовые очки
-
- Сообщения: 2567
- ОС: Debian
Re: Линковка динамических библиотек между собой
Хм, возможно я неправильно представляю концепцую динамических библиотек?
Хорошо, динамическая библиотека собрана так:
Вывод компилятора:
Данные ldd
Честно говоря, я ожидал увидеть в выводе упоминание о libxml2.
Пытаюсь собрать программа:
Т.е. мою библиотеку подлинковать удалось, но я рассчитывал, что мне при сборке программ надо будет указывать только мою библиотеку.
А она, потянет libxml2 при запуске программы.
Хорошо, динамическая библиотека собрана так:
Код: Выделить всё
$(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 при запуске программы.
-
- Сообщения: 2567
- ОС: Debian
Re: Линковка динамических библиотек между собой
Похоже со сборкой динамической библиотеки разобрался.
Сборка:
Вывод ldd:
Теперь осталось проверить это на реальной программе.
Сборка:
Код: Выделить всё
[ -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)
Теперь осталось проверить это на реальной программе.
-
- Сообщения: 2567
- ОС: Debian
Re: Линковка динамических библиотек между собой
Что ж, похоже всё работает.
Привожу полный Makefile.
Из "дополнительных" возможностей только указание пути к библиотеке в системе (-Wl,-R/usr/lib). Без этого программа ищет библиотеку в своей директории.
P.S. Всё собирается для работы на встраиваемой плате с ARM-процессором, система построена на BusyBox.
Работу статической библиотеки не проверял.
Привожу полный 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.
Работу статической библиотеки не проверял.
-
- Сообщения: 2567
- ОС: Debian
Re: Линковка динамических библиотек между собой
Что-то сломалось снова. Итак, необходимо свои функции по работе с XML собрать в виде динамической библиотеки и подключать её, и только её, к другим программам.
Makefile
Сама библиотека собирается и в выводе ldd видно, что она зависит от libxml2.
Но при сборке тестовых программ, цель bin, вываливаются ошибки на этапе линковки:
Если я правильно понимаю, причина в в том, что линковщик не находит 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).
Или проблема в другом?
Спасибо.
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).
Или проблема в другом?
Спасибо.
-
- Сообщения: 2567
- ОС: Debian
Re: Линковка динамических библиотек между собой
Предположение о проблеме из за смены компилятора подтвердилось.
Предыдущим компилятором всё успешно собралось.
arm_v5t_le-ldd bin/nettest
Предыдущим компилятором всё успешно собралось.
Код: Выделить всё
[ -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)