Самодостаточная общая библиотека C

В настоящее время я занимаюсь разработкой библиотеки C для клиента, и для этого мне нужно было использовать другие библиотеки, такие как: glib2.0, libxml2, lib, openssl и gmp. После того, как я закончил свою разработку и создал.so, я попытался скомпилировать с ним тестовую программу и обнаружил, что моя библиотека не является автономной и что мне нужно связать программу со всеми другими библиотеками, которые я упомянул выше.

Клиент настаивает на том, что ему нужен продукт dll или.so и что он должен быть автономным, всего один файл, чтобы его приложение могло его использовать, так же, как он это делает с другими библиотеками.

Я не уверен, что делать, есть ли способ создать это самодостаточный.so? Если это невозможно, какие еще есть варианты? Я занимаюсь разработкой в ​​Solaris 11, и целевой системой является сервер Solaris.

Большое спасибо.

Код Makefile:

# C compiler 
CC = gcc 

# C flags
CFLAGS = -fPIC -O3 -g 

# linking flags
LDFLAGS = -shared 
LDLIBS = $(shell xml2-config --cflags --libs) $(shell pkg-config --cflags --libs glib-2.0) -lssl -lcrypto -lm -lgmp -lz 

# target lib
TARGET_LIB = libservices.so
SRCS = lib1.c lib2.c lib3.c lib4.c # source files

OBJS = $(SRCS:.c=.o)
# Compilation 
.PHONY: all
all: ${TARGET_LIB}

$(TARGET_LIB): $(OBJS) 
    ${CC} ${LDFLAGS} $(OBJS) -o ${TARGET_LIB}

# pull in dependency info for *existing* .o files
-include $(OBJS:.o=.d)

# Compiles and Generates Dependency Info
%.o: %.c
    gcc $(CFLAGS) -c $*.c -o $*.o ${LDLIBS}
    gcc -MM $(CFLAGS) $*.c > $*.d

Пример вывода компиляции тестового кода

gcc -I/path/to/libservices -L/path/to/libservices services_test.c -o test -lservices

libservices.so: undefined reference to `EVP_CipherInit'
libservices.so: undefined reference to `g_free'
libservices.so: undefined reference to `xmlFreeDoc'
libservices.so: undefined reference to `g_str_equal'
libservices.so: undefined reference to `g_hash_table_lookup'
libservices.so: undefined reference to `__gmpz_get_str'
libservices.so: undefined reference to `EVP_CIPHER_CTX_block_size'
libservices.so: undefined reference to `xmlCheckVersion'
libservices.so: undefined reference to `EVP_EncryptFinal'
libservices.so: undefined reference to `g_hash_table_new'
libservices.so: undefined reference to `EVP_CIPHER_CTX_init'
libservices.so: undefined reference to `xmlNodeGetContent'
libservices.so: undefined reference to `xmlCleanupParser'
libservices.so: undefined reference to `__gmpz_pow_ui'
libservices.so: undefined reference to `EVP_EncryptUpdate'
libservices.so: undefined reference to `__gmpz_clear'
libservices.so: undefined reference to `xmlParseDoc'
libservices.so: undefined reference to `g_hash_table_insert'
libservices.so: undefined reference to `EVP_DecryptInit_ex'
libservices.so: undefined reference to `EVP_EncryptInit_ex'
libservices.so: undefined reference to `g_hash_table_destroy'
libservices.so: undefined reference to `g_list_free'
libservices.so: undefined reference to `EVP_DecryptFinal'
libservices.so: undefined reference to `g_str_hash'
libservices.so: undefined reference to `__gmpz_init_set_str'
libservices.so: undefined reference to `EVP_DecryptUpdate'
libservices.so: undefined reference to `EVP_CipherFinal'
libservices.so: undefined reference to `__gmpz_sizeinbase'
libservices.so: undefined reference to `xmlDocGetRootElement'
libservices.so: undefined reference to `g_hash_table_foreach'
libservices.so: undefined reference to `EVP_CIPHER_CTX_cleanup'
libservices.so: undefined reference to `EVP_CipherUpdate'
collect2: error: ld returned 1 exit status

Если я связываю это с другими библиотеками, делающими:

gcc -I/path/to/libservices -L/path/to/libservices servicios_test.c -o test -lservices -lssl -lcrypto -lm -lgmp -lz `pkg-config --cflags --libs glib-2.0` `xml2-config --cflags --libs`

А затем добавьте путь, используя:

export LD_LIBRARY_PATH=/path/to/libservices:$LD_LIBRARY_PATH

тестовый код работает нормально.

2 ответа

Я думаю, что вы более или менее сделали.

Весь смысл разделяемых библиотек состоит в том, чтобы не включать ничего из каких-либо других библиотечных зависимостей. Это работа компоновщика времени выполнения, а не компоновщика времени компиляции.

Поскольку приложение, очевидно, зависит уже от других библиотек, ваша библиотека и любые дополнительные библиотеки, от которых зависит ваша библиотека, но от которых приложение еще не зависит, представляют собой просто дополнительные библиотеки, которые можно добавить в список.

Теоретически это возможно, но я не могу придумать разумную причину пойти по этому пути. И это было бы довольно сложно сделать. С точки зрения кода вот что вы должны сделать:

LDLIBS = $(shell xml2-config --cflags --libs) $(shell pkg-config --cflags --libs glib-2.0) -Bstatic -lssl -lcrypto -lm -lgmp -lz

Добавляя -Bstatic, вы указываете компоновщику использовать статические версии следующих библиотек. Но есть одна загвоздка: статическая версия библиотек должна существовать в системе, в которой вы компилируете свой .so. Некоторые из них могут существовать по умолчанию, но вам придется проделать дополнительную работу:

  • libm, libgmp, libz - скорее всего, в ОС есть пакеты, которые имеют статическую версию, их нужно устанавливать (обычно имена пакетов: lib${LIBNAME}-static или lib $ {LIBNAME} -devel)
  • для libcrypto и libssl вам придется перекомпилировать OpenSSL как статические библиотеки.
Другие вопросы по тегам