如何在C/C++中使用静态链接OpenSSL

18

我用C和C++使用Openssl编写了简单的应用程序。我将它们编译成这样:

gcc openssltest.c -o openssltest -lcrypto
g++ openssltest.cpp -o openssltest -lcrypto

只有当您安装了Openssl时,才可以使用它且一切正常。

我想编译它,以便在没有安装Openssl的操作系统(类似Linux的操作系统)上运行。我尝试了以下方法:

gcc -c openssltest.c -lcrypto -static
gcc openssltest.o -o openssltest -lcrypto -static

同样适用于C++:

g++ -c openssltest.cpp -lcrypto -static
g++ openssltest.o -o openssltest -lcrypto -static

但是存在这些错误:

/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
(.text+0x19): undefined reference to `dlopen'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
(.text+0x2c): undefined reference to `dlsym'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
(.text+0x37): undefined reference to `dlclose'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_func':
(.text+0x354): undefined reference to `dlsym'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_func':
(.text+0x3fb): undefined reference to `dlerror'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_var':
(.text+0x474): undefined reference to `dlsym'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_var':
(.text+0x52e): undefined reference to `dlerror'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_load':
(.text+0x5a2): undefined reference to `dlopen'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_load':
(.text+0x60b): undefined reference to `dlclose'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_load':
(.text+0x638): undefined reference to `dlerror'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_pathbyaddr':
(.text+0x6cd): undefined reference to `dladdr'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_pathbyaddr':
(.text+0x731): undefined reference to `dlerror'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_unload':
(.text+0x78a): undefined reference to `dlclose'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `bio_zlib_free':
(.text+0x4d): undefined reference to `inflateEnd'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `bio_zlib_free':
(.text+0x6b): undefined reference to `deflateEnd'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `bio_zlib_ctrl':
(.text+0x284): undefined reference to `deflate'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `bio_zlib_ctrl':
(.text+0x342): undefined reference to `zError'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `zlib_stateful_expand_block':
(.text+0x411): undefined reference to `inflate'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `zlib_stateful_compress_block':
(.text+0x4ca): undefined reference to `deflate'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `zlib_stateful_finish':
(.text+0x51f): undefined reference to `inflateEnd'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `zlib_stateful_finish':
(.text+0x528): undefined reference to `deflateEnd'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `zlib_stateful_init':
(.text+0x5d7): undefined reference to `inflateInit_'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `zlib_stateful_init':
(.text+0x659): undefined reference to `deflateInit_'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `bio_zlib_read':
(.text+0x893): undefined reference to `inflate'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `bio_zlib_read':
(.text+0x90d): undefined reference to `zError'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `bio_zlib_read':
(.text+0x97c): undefined reference to `inflateInit_'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `bio_zlib_write':
(.text+0xa6f): undefined reference to `deflate'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `bio_zlib_write':
(.text+0xaec): undefined reference to `zError'
/usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(c_zlib.o): In function `bio_zlib_write':
(.text+0xb7e): undefined reference to `deflateInit_'
collect2: error: ld returned 1 exit status

我怎样才能制作这个?我记得一段时间前我做过,但现在忘了怎么做。我用的是Ubuntu 13.04 x64 - 这可能是个问题吗?


@billz:gcc -static -o openssltest openssltest.c -ldl -lz -lcrypto 给出了我发布的相同错误。 - yak
2
-ldl -lz 应该在 -lcrypto 之后。 - billz
1
@billz:gcc -o openssltest openssltest.c -lcrypto -ldl -lz -static 命令会出现以下警告信息: /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function dlfcn_globallookup: (.text+0x19): warning: Using dlopen in statically linked applications requires at runtime the shared libraries from the glibc version used for linking,但是我的代码中没有使用任何特定于操作系统的库。 - yak
3
你可以尝试使用-static-libgcc代替-static。 - rakib_
@rakib 很有趣...我该如何检查它是否真的是统计相关的应用程序?大小不大,我已经检查过了,这是确定的。 - yak
显示剩余9条评论
4个回答

5

我曾经尝试使用openssl库静态编译一个简单的DES程序时,遇到了相似的问题。我使用了-lcrypto -lz -ldl -static-libgcc,这个方法对我有效,没有任何警告或错误。


1
它可以工作,谢谢!你能否更新你的答案,提到顺序是相关的。 - Zskdan
这样编译后,可执行文件增加了2MB,并出现以下警告:“在静态链接的应用程序中使用'dlopen'需要在运行时使用与链接时使用的glibc版本相对应的共享库”。 - Hack06
对我似乎不起作用。如果有区别,我正在使用g++。C++编译器做事情是否有所不同? - AjB
这个答案可能是错误的。在编译过程的输出二进制文件上运行 file <output> 命令,明确显示该二进制文件在我的机器上是“动态”链接的。 - C--

2

您需要知道,库文件需要作为静态链接的*.a文件可用。如果不是这样,编译将会失败或者最终得到一个动态链接的可执行文件。

如果这变得太麻烦(所有库文件依赖关系都需要静态编译,以及它们的依赖关系等等),可以使用类似buildroot的工具。


0

我曾经和你一样遇到了同样的问题。这是解决问题的命令:

gcc yourfile.c -o yourfile -static -lcrypto -lz -ldl

它生成了这个警告:

/usr/lib/gcc/i686-linux-gnu/4.7/../../../i386-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup': (.text+0x1b): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

但可执行文件仍然可以运行。


只要您的目标设备上有libgcc/libc库,它肯定可以工作 - 但如果没有,您就会失败。因此,实际上这意味着二进制文件并不完全静态 - 这也不是一个解决方案。 - drahnr
你说“肯定能行”,然后又说“这不是一个解决方案”。在我看来,如果某件事情能够运作,那就是一个解决方案。 - schulwitz
由于你排除了一些不明显的东西。并非所有系统(特别是嵌入式系统)都必须包含libgcc。请注意,“确定它会工作”是“如果”语句的一部分。 - drahnr
这个“if”语句对于绝大多数的Linux系统都是成立的,包括默认情况下的Ubuntu 13.04(提问者指定的操作系统)。 - schulwitz
没有看到“13.04 Ubuntu”。 - drahnr

0
一个热修复:尝试静态链接libdl。
如果这样不行,我认为你的libcrypto.a编译有问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接