我正在为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 =>未找到”,但是好吧,当我在示例插件上执行此操作时,我也有同样的事情。

我认为问题出在Imath lib,但我不知道如何解决。
有人有主意吗?提前致谢。

最好

最佳答案

更新

自从最初发布此答案以来,The Foundry已使其修改后的OpenEXR源代码可供下载,包括自定义 namespace 和某些接口(interface)扩展。这应该使编写和成功构建可与分布式OpenEXR库链接的自定义插件变得容易。

可以在以下位置找到指向已编译的二进制文件和源文件的链接:https://www.thefoundry.co.uk/products/nuke/developers/

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

原始答案

不幸的是,如果不了解有关构建和运行时环境的所有信息,就很难确定这类问题,但是这里的一些信息和想法将有助于您走上正确的道路。

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

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

  • 符号命名空间

    Nuke 8附带了自己的EXR 2库(特别是版本2.0.1),您可以在安装目录中找到该库。如果查看导出的符号(使用nm -D),则不仅会看到自定义 namespace 中的符号,而且库版本与链接的库版本也不相同。
    $ 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
    

    请注意,根据您的Shell环境,您可能需要使用Nuke二进制文件的完整路径。您应该尝试在不运行任何其他自定义代码的情况下启动Nuke(将插件插入插件路径所需的操作除外),并且不要打开任何Nuke脚本,以防止其他任何东西加载Imath库。

    一旦您运行了空的Nuke session ,只需尝试创建节点的实例,然后退出Nuke。现在,您可以通过grep进行nuke_strace_output.txt并找到加载插件的位置,其外观应如下所示:
    open("/path/to/MyPlugin.so", O_RDONLY|O_CLOEXEC) = 50
    

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

    二进制兼容性

    如果可能的话,我建议尝试使用Nuke随附的相同版本的OpenEXR,以便您可以piggy带其库。您需要获得自己的 header 才能编译插件,但这对于诸如Imath之类的应用来说并不重要。

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

    无论如何,我知道这会跳入很多不同的领域,但是我希望它能对某些领域有所帮助。

    关于c++ - Nuke undefined symbol :_ZN9Imath_2_16Rand325nextfEv,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25191963/

    10-10 07:19