【问题标题】:Link with an older version of libstdc++与旧版本的 libstdc++ 链接
【发布时间】:2011-01-06 07:48:06
【问题描述】:

安装新的构建机器后,我发现它带有标准 C++ 库的 6.0.10

-rw-r--r--  1 root root 1019216 2009-01-02 12:15 libstdc++.so.6.0.10

但是,我们的许多目标机器仍然使用旧版本的 libstdc++,例如:

-rwxr-xr-x 1 root root  985888 Aug 19 21:14 libstdc++.so.6.0.8

显然 ABI 在最后两个 0.0.1 中发生了变化,因为尝试运行程序会导致

/usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found

我尝试显式安装旧版本的 gcc,但没有帮助。 升级目标机器是我无法控制的,所以不是一个选择。让我的构建在具有较旧 libstdc++ 的机器上运行的最佳方法是什么?

我在 apt-cache 中搜索了要安装的旧 libstdc++ 版本,但显然没有旧版本 6 可用?

【问题讨论】:

    标签: c++ linux linker


    【解决方案1】:

    您不需要链接到不同的库,您需要使用旧版本的编译器。

    看看the GNU ABI policy。 libstdc++ 共享库被设计为向前兼容。 IE。如果需要 6.0.8,可以使用 6.0.10 版本。在政策中,您可以从 gcc-4.2.0 开始阅读,需要 6.0.9,因此您需要 gcc-4.1.x。

    简而言之,这就是为什么您的系统上只有一个 libstdc++.so.6.0.x,您只需要最新的。

    至于将构建系统设置为仅使用特定版本的编译器:确保不能使用标准 g++(重命名链接,删除提供它的包,将其从 PATH 中取出),然后开始挖掘。为我工作。

    【讨论】:

    • 你的意思是我们必须安装旧版本的g++?
    • @Peter 是的,使用旧版本的 g++ 链接到旧版本的 libstdc++.so
    • 我认为,为了使用旧版本的 C++ 库,您必须使用可能存在错误和缺少优化的编译器,这很蹩脚——尤其是因为反过来(使用旧的带有新库版本的编译器)似乎只是设置LD_LIBRARY_PATH的问题。
    【解决方案2】:

    您可以使用自己的代码(例如在子目录中)提供所需的共享库,并将 LD_LIBRARY_PATH 作为运行应用程序的前导设置为首先在该目录中搜索。

    提供您需要的特定版本意味着用户安装的版本无关紧要。你只需要确保你也发布了所有依赖项。

    【讨论】:

      【解决方案3】:

      另一种方法,对我不起作用,但也许其他人会发现它有用,是静态链接 libgcc 和 libstdc++。

      gcc 有一个选项-static-libgcc,但简单地使用这个选项没有任何效果,因为 libstdc++ 仍然是动态链接的。但是通过确保 gcc 只能找到 libstdc++ 的静态版本,就可以实现静态链接。

      ln -s `g++ -print-file-name=libstdc++.a`
      g++ -static-libgcc -L. source.cpp
      

      问题是,boost 库是针对较新的 libstdc++ 构建的,因此当程序正确编译时,它会产生运行时错误...

      如果我也重建 boost,也许这可以解决,还没有尝试过。

      (为了记录,如果您使用任何动态加载库的代码,例如dlopen,静态链接是不可能的)

      【讨论】:

      • 你只需要使用 -static-libstdc++ 而不需要符号链接魔法。
      【解决方案4】:

      已经遇到过这种情况。我没有想到比安装一个与目标机器具有相同配置的系统(虚拟化?)来构建可分发的二进制文件更好。

      【讨论】:

      • 虽然这当然是一个选项,但对于简单地与较旧的库链接来说,这似乎工作量很大......老实说,我希望发布一些更好的选项:)
      • 另一种选择是安装与目标系统上存在的完全相同版本的 stdc++ 库。但由于默认情况下它不存在于您的发行版中,因此您必须手动执行此操作。这不会是微不足道的,并且您会真正头疼使 2 版本在您的系统上共存。设置旧发行版并在其上编译需要几个小时(如果您不使用那么多外来库),与手动安装第二版库相比,这确实值得。
      • 您不需要安装整个系统 - 只需设置第二个工具链,就像您进行交叉编译一样,但针对您自己的平台。
      【解决方案5】:

      您可以将较新的 libstdc++“走私”到客户端系统(进入私人区域)并将程序与适当的-rpath 链接,或者您可以将旧版本的 libstdc++ 安装到您的计算机上。看起来您需要更新,并且无论如何可能由于其他原因而没有问题。

      注意:在 FreeBSD 上,libstdc++ 与编译器相结合(我安装了 gcc4.2、4.4 和 4.5,每个都有自己的 libstc++)。尝试安装较旧(匹配客户端系统)版本的 gcc,它可能带有您正在寻找的较旧的 libstdc++。

      【讨论】:

        【解决方案6】:

        为我工作:设置此标志:

        -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic -Wl,-Bstatic -lgcc -Wl,-B动态 -静态

        如果只放 -static-libstdc++ -static 对我不起作用。

        【讨论】:

          【解决方案7】:

          您是否尝试过将其与来源列表一起放入?这假设您实际上已经安装了库!

          g++ /usr/lib/libstdc++.so.6.0.8 source1.cpp source2.cpp
          

          【讨论】:

          • libstdc++ 不能以这种方式包含在内。有一个 static-libc++ 选项,但通常不是你想要的。
          猜你喜欢
          • 2016-12-19
          • 1970-01-01
          • 2013-05-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多