【问题标题】:Overcome DLL Hell with Code::Blocks使用 Code::Blocks 克服 DLL 地狱
【发布时间】:2014-01-05 09:21:54
【问题描述】:

我正在为一个项目使用 Code::Blocks。我已经好几年没在 Linux 上使用过 IDE了,所以我对 Linux IDE 有点脱节。

我正在处理一个使用 FIPS 验证库的 OpenSSL 项目。我复制了 GCC 编译器工具链并将其修改为使用 OpenSSL 的 fipsld(并将其设置为默认值)。

当项目的代码通过 F8 在 Code::Blocks 下执行时,FIPS_mode_set 失败并出现错误 252104805 (0xF06D065)。 0xF06D065 是:

$ openssl errstr 0xF06D065
error:0F06D065:common libcrypto routines:FIPS_mode_set:fips mode not supported

这告诉我 Code::Blocks 没有使用我在 /usr/local/ssl/lib 中指定的 OpenSSL。相反,该程序正在使用 Debian 在/usr/lib/x86_64-linux-gnu/ 中提供的非 FIPS 库。

链接库设置的图像如下。请注意,库是完全指定的,没有任何机会。

CodeBlocks 显然正在使用 LD_LIBRARY_PATH(如下所示)。

我还验证了该项目使用了正确的搜索目录 - /usr/local/ssl/include 用于标头,/usr/local/ssl/lib 用于链接器。

将编译器日志记录设置为“完整命令行”设置,这是我从构建日志中得到的:

-------------- Build: Debug in ac ---------------

Compiling: main.cpp
/home/jwalton/Desktop/ac/main.cpp:8:5: warning: unused parameter ‘argc’ [-Wunused-parameter]
/home/jwalton/Desktop/ac/main.cpp:8:5: warning: unused parameter ‘argv’ [-Wunused-parameter]
Linking console executable: bin/Debug/ac
Output size is 569.67 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 2 warnings

我知道 Basile Starynkevitch 对 rpathLD_PRELOAD 技巧的建议,但这似乎是 IDE 应该为我处理的事情之一(Visual Studio 会正确处理它,甚至给我们set Working Directories to find additional libraries 的输入框。

在调试器下执行程序时,任何想法如何使 Code::Blocks 使用/usr/local/ssl/lib 中的共享对象?

【问题讨论】:

标签: c linux dll shared-libraries codeblocks


【解决方案1】:

您的 IDE 指示编译器链接指定的库,而不是在运行时加载它们。对于后一种情况,您需要将另一个选项传递给链接器,即

-rpath=/path/to/directory/with/your/libraries

或者,如果编译器调用了链接器,

-Wl,-rpath=/same/thing

【讨论】:

  • 谢谢 n.m.我通过 F8 在 Code::Blocks 下运行它。所以 Code::Blocks 不处理事情,所以它们像 Visual Studio 一样“工作”?不好意思问。我已经多年没有在 Linux IDE 中工作了。
  • 这不是 Code::Blocks 与 Visual Studio。这是 Unix 与 Windows。它们是不相同的。学习他们,爱他们。
【解决方案2】:

Code::Blocks 不要使用shared objectsDLL 是 Windows 的东西)。因为Code::Blocks 只是一个IDE。 IDE 被赞誉为 source code editors,能够运行 external software development tools。您可以(有时您应该,至少要了解事情是如何发生的)使用像emacs 这样的普通编辑器编辑您的代码,并使用命令构建它。您的 IDE 只是在运行命令,特别是 compilerlinker,可能使用 gcc

那么在/usr/local/ssl/lib/ 中使用共享对象的是编译器和链接器(以及运行时dynamic linker)。顺便说一句,/usr/local/ssl/lib/ 是一个非常奇怪的名称,用于包含共享对象的目录;您应该已经将 OpenSSL 配置为安装在 /usr/local/lib/ 中!

首先,我真的认为您应该重新配置、重新编译、重新构建和重新安装您的 SSL,以将其安装在 /usr/local/(或者可能是 /opt/)前缀下(即 /usr/local/lib 中的共享库)。

然后您可以为ld linker(来自binutils)添加适当的选项。您可能想要-L/usr/local/ssl/lib(到正在运行ldgcc 命令),并且您可能想要传递-Wl,-rpath(参见this)。

我建议在 /usr/local/ 中重新安装您的 SSL,将 /usr/local/lib/ 添加到 /etc/ld.so.conf(或至少添加到您的 LD_LIBRARY_PATH...)并运行 ldconfig

否则,至少在您的LD_LIBRARY_PATH 前面添加/usr/local/ssl/lib/(以及在您的链接命令中添加-L/usr/local/ssl/lib/)。

阅读Program Library HowTothis 的答案以及Drepper 的How To Write Shared libraries 论文

【讨论】:

  • Thnaks Basile。 “......使用像 emacs 这样的普通编辑器编辑您的代码,并使用命令构建它” - 这通常是我在 Linux 上所做的,因为过去 IDE 遇到了很多麻烦(Visual Studio 非常好,很难少接受)。我什至在 Linux 上手动编写我的 makefile。我希望 IDE 的自动完成功能能够加快开发速度,因为我讨厌在 OpenSSL 源文件中查找函数名称。
  • 不,IDE 正在减慢开发速度,因为它们隐藏东西。也许你想要ctagsetags(和emacs)?
  • 再次感谢巴西尔。 “您应该已将 OpenSSL 配置为安装在 /usr/local/lib/ 中” - 在使用 OpenSSL FIPS 对象模块时,您必须小心执行此类操作。如果偏离程序,则使验证无效。在config 期间设置目录就是这样的违规行为。
  • 然后使用我的回答中提到的LD_LIBRARY_PATH-Wl,-rpath 技巧(如果合适就接受它)。
【解决方案3】:

只需打开终端并输入

export LD_LIBRARY_PATH=/path/to/your/libraries 
sudo ldconfig

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-05-29
    • 1970-01-01
    • 2019-01-21
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 2011-03-20
    相关资源
    最近更新 更多