0

現在、クライアント用の C ライブラリを開発しています。そのためには、glib2.0、libxml2、lib、openssl、gmp などの他のライブラリを使用する必要がありました。開発を終えて .so を作成した後、それを使ってテスト プログラムをコンパイルしようとしたところ、私のライブラリは自己完結型ではなく、プログラムを上記の他のすべてのライブラリとリンクする必要があることがわかりました。

クライアントは、dll または .so 製品のいずれかが必要であり、他のライブラリと同じように、アプリケーションがそれを使用できるように 1 つのファイルだけで自己完結型である必要があると主張します。

どうすればよいかわかりません。この自己完結型の .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

テストコードは正常に動作します。

4

2 に答える 2

0

私はあなたが多かれ少なかれ終わったと思います。

共有ライブラリの要点は、他のライブラリの依存関係から何も含めないことです。これは、コンパイル時リンカーではなく、実行時リンカーの仕事です。

アプリケーションはすでに他のライブラリに依存しているように見えるため、ライブラリ、およびライブラリが依存しているがアプリケーションがまだ依存していない追加のライブラリは、リストに追加するライブラリです。

于 2015-05-15T18:50:14.107 に答える
0

理論的には可能ですが、その道を進む合理的な理由が思いつきません。また、それを行うのはかなり難しいでしょう。コードに関しては、次のことを行う必要があります。

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

-Bstaticを追加することにより、リンカーに、後続のライブラリの静的バージョンを使用するように指示します。ただし、落とし穴があります。ライブラリの静的バージョンは、.soをコンパイルするシステムに存在する必要があります。それらのいくつかはデフォルトで存在するかもしれませんが、追加の作業を行う必要があります:

  • libmlibgmplibz - ほとんどの場合、それらの静的バージョンを持つパッケージが OS に存在する可能性が高く、それらをインストールする必要があります (通常、パッケージ名はlib${LIBNAME}-staticまたはlib${LIBNAME}-devel です) 。
  • libcryptolibsslの場合、OpenSSL を静的ライブラリとして再コンパイルする必要があります。
于 2015-05-15T19:09:13.453 に答える