首页 > 解决方案 > g++ 使用 OpenSSL 和 MySQLClient 编译静态

问题描述

我一直在互联网上寻找这个问题,但找不到解决方案。我想要实现的是构建一个同时具有OpenSSL和依赖关系的 CGI 应用程序MySQLClient

当我编译我的程序时,使用以下命令:

g++ -Wall -o test.cgi test.cpp -I/usr/include/mysql -lcgicc -lmysqlcppconn -lmysqlclient -lcurl -lnghttp2 -lssl -lcrypto -lpthread -ldl -DCURL_STATICLIB -std=c++11 -lz -static

我收到以下错误:

//usr/local/lib/libcrypto.a(err.o): In function `ERR_remove_thread_state':
err.c:(.text+0xe40): multiple definition of `ERR_remove_thread_state'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libmysqlclient.a(ssl.cpp.o):(.text+0x1df0): first defined here

我已经尝试了多种解决方案,例如向下和升级到其他版本的 OpenSSL,与此处相反。但是,在使用以下任何 OpenSSL 版本进行编译时,我仍然会收到此错误:

我应该怎么做才能克服这个错误并能够静态编译我的程序?

标签: opensslg++libmysql

解决方案


我看起来您使用的是较旧的 MySQL(即,早于版本 8)。

在早期版本中,确实有一个文件 ssl.cpp 定义ERR_remove_thread_state

void ERR_remove_thread_state(const void *)
{
    GetErrors().Remove();
}

因此,您可以探索两种方法。(1) 尝试升级到更新版本的 MySQL。或 (2) 使用您系统上安装的版本构建您自己的 MySQL 版本,但将此函数重命名为其他名称(即在构建之前编辑 MySQL 的源代码)。

更新:尝试的第三种方法——绝对是在“黑客”领域——是修改libmysqlclient.a以删除有问题的符号。这可能有效,也可能无效,但尝试起来相当简单。

为此,您需要获取一份副本,libmysqlclient.a然后将其解压缩 ( ar -x)。您应该找到一个名为ssl.cpp.o. 然后,您可以列出该文件中的符号(例如,使用类似的符号readelf -s),并确认ERR_remove_thread_state已找到。然后从该文件中删除该符号(例如strip -N ERR_remove_thread_state ssl.cpp.o),然后将目标文件重新组合到存档中。最后静态链接到修改后的档案,而不是系统档案。一些注意事项:因为这些是 C++ 文件,您可能需要使用名称拆解;而且我自己没有尝试过,所以不确定会产生什么后果——你需要认真测试你的应用程序。希望这个符号没有被任何代码路径使用,因此删除它将允许成功的编译和应用程序行为。


推荐阅读