【问题标题】:g++ compile static with OpenSSL and MySQLClientg++ 使用 OpenSSL 和 MySQLClient 编译静态
【发布时间】:2019-09-15 15:28:41
【问题描述】:

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

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

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,而不是 here。但是,在使用以下任何 OpenSSL 版本进行编译时,我仍然会收到此错误:

  • OpenSSL 0.9.8
  • OpenSSL 1.1.0g
  • OpenSSL 1.1.1

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

【问题讨论】:

标签: openssl g++ libmysql


【解决方案1】:

我看起来您使用的是较旧的 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++ 文件,您可能需要使用名称拆解;而且我自己没有尝试过,所以不确定会产生什么后果——你需要认真测试你的应用程序。希望这个符号没有被任何代码路径使用,因此删除它将允许成功的编译和应用程序行为。

【讨论】:

  • 嗨达伦,非常感谢您的回复!好吧。但是,我已经通过命令apt-get install libmysqlcppconn-devapt-get install libmysqlclient-dev 安装了MySQL。我虽然这应该安装最新版本。你能告诉我如何安装最新版本的 MySQL 吗?或者您能否详细说明如何构建 MySQL?我对手动构建不太熟悉。我找到了构建 OpenSSL 的良好而清晰的文档,但是正如已经说明的那样。那些升级和降级 OpenSSL 的构建都没有解决错误
  • 你的包管理器可以为你提供已安装的libmysqlclient版本;我有兴趣看看它是否确实是版本 8 之前的版本。要手动构建 libmysqlclient,您可能需要下载 MySql 源代码,并参考其构建说明。要么尝试构建整个 MySql 项目,要么只构建客户端库部分。通常这是相当直截了当的,有时可能会很棘手。您可以尝试重建 OpenSSL(在重命名 ERR_remove_thread_state 之后),尽管我认为重建 libmysqlclient 更安全。
  • MySQL Client 版本为:5.7.27-0ubuntu0.16.04.1 我想尝试自己构建MySQL。你能帮我从源代码构建它吗?我不知道如何使用所有可能的选项等来构建它?我应该重命名哪些文件等?非常感谢!
  • 我已经通过替换ssl.cpp.o-文件中的符号来尝试您的更新(第三种方法)。这消除了错误,但我认为修改会导致以下错误:/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libmysqlclient.a(yassl_int.cpp.o): In function 'default_password_callback': (.text+0x100): undefined reference to 'yassl_mysql_get_tty_password_ext'
  • 但是,如果你静态链接到这个修改后的 libmysqlclient.a,为什么上面的错误指的是系统 libmysqlclient.a ?我希望您修改后的 libmysqlclient.a 位于临时目录或用户目录下。
猜你喜欢
  • 2019-08-10
  • 1970-01-01
  • 1970-01-01
  • 2017-07-17
  • 2012-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多