找不到版本GLIBCXX_3.4.11(buildW.mexglx所需)。

8

我正在尝试通过Matlab这里编译一个Ubuntu C++项目。当我使用make命令进行编译后,尝试使用它时,我会遇到以下错误:

Invalid MEX-file
'////fashionista_v0.2/lib/+bsr/buildW.mexglx':
 //local/MATLAB/R2011a/bin/glnx86/../../sys/os/glnx86/libstdc++.so.6: version
`GLIBCXX_3.4.11' not found (required by
 ////fashionista_v0.2/lib/+bsr/buildW.mexglx)

我不熟悉这些过程,所以无法理解像此类提出的几种解决方案。libstdc++和GLIBCXX到底是什么,我该如何解决这个问题?
我正在尝试使用nkjt提供的链接来解决这个问题。
export LD_LIBRARY_PATH=${prefix}/lib:$LD_LIBRARY_PATH

然而,由于缺乏Unix shell知识,我不知道在命令中应该输入什么。 我已经找到了位于gcc文件夹/usr/lib/gcc/i686-linux-gnu/4.6中的libstdc ++ .a和.so文件,并尝试以下操作:

 export LD_LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/4.6:$LD_LIBRARY_PATH

然而我的Matlab错误依旧存在。我正在使用Ubuntu 12.04版本,gcc 4.6和matlab r2011a。

编辑:我已经将Matlab升级到r2012a版本,问题仍然存在。我也尝试了以下方法:

sudo ln -s /usr/lib/cc/i686-linux-gnu/4.6/libstdc++.so libstdc++.so.6 

我尝试创建文件,但失败了,因为该文件已经存在。

运行 usr/lib/libstdc++.so.6 | grep GLIBC 命令的输出:

        GLIBCXX_3.4
        GLIBCXX_3.4.1
        ...
        GLIBCXX_3.4.10
        GLIBCXX_3.4.11
        GLIBCXX_3.4.12
        GLIBCXX_3.4.13
        GLIBCXX_3.4.14
        GLIBCXX_3.4.15
        GLIBCXX_3.4.16
        GLIBC_2.0
        GLIBC_2.3
        GLIBC_2.4
        GLIBC_2.3.4
        GLIBC_2.1
        GLIBC_2.1.3
        GLIBC_2.3.2
        GLIBC_2.2
        GLIBCXX_DEBUG_MESSAGE_LENGTH

我如何确保我已经定义了正确的libstdc++版本?


1
http://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.how_to_set_paths - nkjt
那么这里的错误是 libstdc++ 版本错误还是链接库错误? - Jose Ramon
1
你所需要做的就是将其链接以定义为默认版本。 - SamuelNLP
其他类似的问题:https://dev59.com/9mkw5IYBdhLWcg3wV5ID,http://stackoverflow.com/q/22564357/97160,http://stackoverflow.com/q/16084323/97160,https://dev59.com/SG435IYBdhLWcg3wxDP_ - Amro
2个回答

13

Matlab(以及大量其他商业软件,如Steam、Mathematica等)都会发行自己版本的libstdc++.so库:

/usr/local/MATLAB/R2011a/bin/glnx86/../../sys/os/glnx86/libstdc++.so.6

问题在于当您启动matlab时,它首先加载这个版本,并且因为已经被加载,所以所有动态加载器依赖项都使用此版本来解决。

您使用系统GCC编译并链接到系统的libstdc++,该版本较新。然后生成的二进制文件请求某个(更新的)版本的符号,但加载程序在已加载的版本中(即Matlab的版本)找不到这些符号。

有两种解决方法:

1.删除/重命名Matlab的libstdc++.so并将您系统的版本建立符号链接到完全相同的名称:

    ```
    sudo rm /usr/local/MATLAB/R2011a/bin/glnx86/../../sys/os/glnx86/libstdc++.so.6
    sudo ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6 /usr/local/MATLAB/R2011a/bin/glnx86/../../sys/os/glnx86/libstdc++.so.6
    ```

* Delete Matlab's version and let your OS's loader pick up the system's `libstdc++`:

    ```
    sudo rm /usr/local/MATLAB/R2011a/bin/glnx86/../../sys/os/glnx86/libstdc++.so.6
    ```

* Use the environment variable `LD_PRELOAD` to "inject" the system's version of `libstdc++` into the execution environment before anything else, which prevents the old Matlab version to be loaded:
    ```
    LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6 matlab
    ```
  1. 安装Matlab所需的GCC版本,并修改Mex构建选项(或使用update-alternatives),以使用该版本而不是系统GCC。

请注意,对于1-3,您可能需要像libgcc_s.so这样的其他库,以同样的方式进行操作。

使用新版本的原因是由于在libstdc ++内部采用的符号版本控制方案(因此还有详细的错误消息提到版本)。 在例如Arch Linux上为Steam执行类似的“修复”时,还需要对Steam使用的几个系统库链接到更新的libstdc ++

真正的解决方案是Matlab不要发行libstdc ++.so,而是使用操作系统提供的版本。


2
+1 很好的解释。顺便说一下,同一项目作者在另一个项目中有针对这种问题的故障排除步骤:http://kyamagu.github.io/mexopencv/#linux。因此,解决这个问题的第四种方法是使用[`LD_PRELOAD`](https://dev59.com/QXRC5IYBdhLWcg3wD8tV)来强制操作系统加载系统的libstdc++,然后再找到MATLAB的libstdc++。 - Amro
@Amro 你说得完全正确,我修改了我的答案。谢谢! - rubenvb
1
@Fere,你那里有个错别字(应该是.so.6而不是.do.6)。另外:似乎matlab不在你的PATH中。 - rubenvb
耶稣,你是对的!愚蠢的打字错误。非常感谢您这个解释得很清楚的答案。 - Jose Ramon
1
@FereRes,你也可以像@Amro的链接中所解释的那样创建一个bash别名,或者export环境变量。这将影响从那一点开始启动的所有内容(不仅仅是Matlab),这可能不是一个好主意。 - rubenvb
显示剩余4条评论

2
将其与类似以下内容关联起来,取决于版本。
sudo ln -s /usr/lib/libstdc++.so.6.0.9 libstdc++.so.6

libstdc++仅存在于gcc/i686-linux-gnu/4.6/libstdc++.so文件夹中。这是我要找的文件吗?我尝试了sudo ln -s /usr/lib/cc/i686-linux-gnu/4.6/libstdc++.so libstdc++.so.6,但是我得到了相同的错误。 - Jose Ramon
我该如何查看默认定义的libstdc++是哪个? - Jose Ramon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接