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

Posted

技术标签:

【中文标题】如何在 C/C++ 中使用带有 OpenSSL 的静态链接【英文标题】:How to use static linking with OpenSSL in C/C++ 【发布时间】:2013-08-12 11:17:33 【问题描述】:

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

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 给出了与我发布的相同的错误 -ldl -lz 应该在 -lcrypto 之后 @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 但我没有在我的代码中使用任何操作系统特定的库 你可以试试 -static-libgcc 代替 -static 吗? @rakib:我当然可以;) 这样做了:gcc -o openssltest openssltest.c -lcrypto -static-libgcc 没有错误,但我不确定它是否提供了真正的静态应用程序,因为它的大小对于静态应用程序来说太小了:(大小是一样的,就像我链接它没有-static 标志 【参考方案1】:

我在尝试使用 openssl 库静态编译一个简单的 DES 程序时遇到了类似的问题。我使用了-lcrypto -lz -ldl -static-libgcc,它对我有用。没有警告或错误。

【讨论】:

它有效,谢谢!你能更新你的答案,提到订单是相关的。 这样编译和运行时可执行文件增加了 2MB,但也有这个警告:“在静态链接的应用程序中使用 'dlopen' 需要在运行时来自 glibc 的共享库用于链接的版本”. 它似乎对我不起作用。如果这有所作为,我正在使用 g++。 C++ 编译器会做不同的事情吗? 这个答案可能是错误的。 file <output> 在编译过程的输出二进制文件上清楚地表明二进制文件是“动态”链接到我的机器上的。【参考方案2】:

您需要注意,需要作为静态链接的 *.a 文件提供。如果不是,那么编译要么失败,要么你最终得到一个动态链接的可执行文件。

如果这得到太多 PITA(所有库依赖项都需要静态编译到,以及它们的 dep 等等),请使用 buildroot 之类的东西

【讨论】:

【参考方案3】:

修补程序:尝试静态链接 libdl。

如果这不起作用,恕我直言,您的 libcrypto.a 编译错误。

【讨论】:

【参考方案4】:

我和你有同样的问题。这是为我解决它的命令:

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 库,它肯定会工作 - 但如果没有,你就注定要失败。所以实际上这意味着二进制文件不是完全静态的——这也不是一个解决方案。 您说“确定它会起作用”,然后以“这不是解决方案”结束。在我的书中,如果有什么可行的,那就是一个解决方案。 因为你排除了一些不明显的东西。并非每个系统(尤其是嵌入式系统)都不一定包含 libgcc。请注意,“确保它会起作用”是“if”语句的一部分。 “if”语句适用于绝大多数 linux 系统,包括默认情况下的 Ubuntu 13.04(提问者指定的操作系统)。 没有看到“13.04 Ubuntu”。

以上是关于如何在 C/C++ 中使用带有 OpenSSL 的静态链接的主要内容,如果未能解决你的问题,请参考以下文章

使用c/c++ Openssl库,建立安全连接流程?

如何使用 OpenSSL 生成带有 SubjectAltName 的自签名证书? [关闭]

如何在openssl生成的java中使用.key和.crt文件?

OpenSSL文档阅读笔记-How to Use OpenSSL to Generate RSA Keys in C/C++

OpenSSL RSA解密随机失败C / C ++

如何使用带有OID 1.3.6.1.4.1.50530.1.1的自定义X.509v3 corda扩展的openssl为corda建立网络映射证书