我当前正在为客户开发一个C库,因此我需要使用其他库,例如:Glib2.0,libxml2,lib,lib,openssl和GMP。完成开发并创建了..因此,我尝试使用它编译一个测试程序,发现我的库不是独立的,并且需要将程序与上面提到的所有其他库联系起来。
客户坚持认为他想要dll或.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
测试代码正常。
我认为您或多或少完成了。
共享库的全部要点是不是包括任何其他库依赖关系中的任何内容。那是运行时链接器的工作,而不是编译时链接器。
由于该应用程序显然已经取决于其他库,因此您的库以及您的库依赖的任何其他库,但该应用程序尚未依赖于该库,只是更多的库添加到列表中。
从理论上讲是可能的,但我想不出一个合理的理由走这条路。同样,很难做到这一点。在代码方面,这是您应该做的:
LDLIBS = $(shell xml2-config --cflags --libs) $(shell pkg-config --cflags --libs glib-2.0) -Bstatic -lssl -lcrypto -lm -lgmp -lz
通过添加 -bstatic ,您指示链接器使用以下库的 static 版本。但是有一个捕获:库的静态版本必须存在于您编译 .so 上的系统上。默认情况下,其中一些可能存在,但是您必须做额外的工作:
- libm , libgmp , libz - OS中很可能有包含静态版本的软件包,您必须安装他们(通常包装名称为 lib $ {libname} -static 或 lib $ {libname} -devel ))
- 对于 libcrypto 和 libssl ,您必须将Openssl重新编译为静态库。