1

我正在为 linux 下的 Nuke8 编译一个插件。所有编译都没有问题,但是当我尝试加载插件时出现以下错误:

undefined symbol: _ZN9Imath_2_16Rand325nextfEv

当我对plugin.so执行“ldd”时,我有这个:

linux-vdso.so.1 =>  (0x00007fff44869000)
libDDImage.so => not found
libfftw3f.so.3 => /usr/lib64/libfftw3f.so.3 (0x00007f4609bf5000)
libImath.so.6 => /usr/lib64/libImath.so.6 (0x00007f46099f0000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f46096ea000)
libm.so.6 => /lib64/libm.so.6 (0x00007f4609465000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f460924f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f4608ebb000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4608c9d000)
libIex.so.6 => /usr/lib64/libIex.so.6 (0x00007f4608a7f000)
/lib64/ld-linux-x86-64.so.2 (0x000000300bc00000

所有库似乎都可以加载。我有一个“libDDImage.so => not found”,但是当我在示例插件上执行此操作时,我有同样的事情。

我认为问题来自 Imath 库,但我不知道如何解决它。有人有想法吗?提前致谢。

最好的

4

1 回答 1

1

更新

自从最初发布此答案以来,The Foundry 已经提供了他们修改后的 OpenEXR 源代码可供下载,包括自定义命名空间和一些接口扩展。这应该使编写和成功构建链接到分布式 OpenEXR 库的自定义插件变得容易。

可以在以下位置找到编译后的 bonaries 和源文件的链接:https ://www.thefoundry.co.uk/products/nuke/developers/

他们还有一个开放的拉取请求,将这些更改合并到主要的 OpenEXR 项目中,可以在这里找到:https ://github.com/openexr/openexr/pull/141

原始答案

不幸的是,如果不了解有关您的构建和运行时环境的所有信息,很难确定此类问题,但这里有一些信息和想法,希望能帮助您走上正轨。

总而言之,我认为这可能是以下四件事之一:

  • 符号命名空间问题
  • 二进制兼容性问题(由于库版本不匹配)
  • 库加载问题
  • 编译器版本问题

符号命名空间

Nuke 8 附带了自己的 EXR 2 库(特别是 2.0.1 版),您可以在安装目录中找到它。如果您查看导出的符号(使用nm -D),您会发现这些符号不仅位于自定义命名空间中,而且库版本与您链接的版本不同。

$ nm -D "/usr/local/Nuke8.0v5/libImath-2_0_1_Foundry.so.10" | grep Rand | c++filt
0000000000012590 T Imath_2_0_1_Foundry::Rand32::nextf()

如您所见,Nuke 中的 EXR 2 符号位于命名空间Imath_2_0_1_Foundry中,而您的库正在寻找Imath_2_1命名空间。这似乎表明存在库加载问题(由于未找到它,或者由于 Nuke 无法加载它)。

库加载

始终需要牢记的重要一点是,被解析的库ldd不一定与 Nuke 找到的库相同。检查 Nuke 中实际发生的情况的最简单方法是strace使用以下内容运行它:

$ strace -fqo /var/tmp/nuke_strace_output.txt Nuke

请注意,您可能需要使用Nuke二进制文件的完整路径,具体取决于您的 shell 环境。您应该尝试在不运行其他自定义代码的情况下启动 Nuke(除了将插件放到插件路径所需的任何代码),并且不打开任何 Nuke 脚本,以防止其他任何内容加载Imath库。

运行空 Nuke 会话后,只需尝试创建节点实例,然后退出 Nuke。现在你可以grep通过nuke_strace_output.txt并找到你的插件的加载点,它应该看起来像这样:

open("/path/to/MyPlugin.so", O_RDONLY|O_CLOEXEC) = 50

之后,如果您滚动浏览strace输出,您将看到 Nuke 在尝试加载您的插件所依赖的尚未加载的库时采取了哪些步骤(它尝试了哪些名称,它的外观等),其中应该包括libImath(我猜libfftw3f)。

二进制兼容性

如果可能的话,我建议尝试使用 Nuke 附带的相同版本的 OpenEXR,这样您就可以搭载它的库。您需要获取自己的标头才能编译您的插件,但这对于 Imath 之类的东西来说是微不足道的。

就编译器而言,您应该使用 GCC 4.1.2。如果你不这样做,你很可能会在某个时候遇到二进制兼容性问题。

无论如何,我知道这涉及到很多不同的领域,但我希望它对一些人有所帮助。

于 2014-08-28T23:02:14.650 回答