【问题标题】:How to make Scons look for libstdc++ in nonstandard directory如何让 Scons 在非标准目录中查找 libstdc++
【发布时间】:2014-03-08 11:31:44
【问题描述】:

我正在尝试使用Scons 在我有权在特定位置(而不是/usr/)安装东西的服务器上构建一个简单的项目。由于我对服务器提供给我的默认编译器不满意,我安装了g++4.8 并验证它工作正常。但是当我尝试使用Scons 来构建一个简单的项目时,虽然它选择了正确的g++(我可以通过检查版本来得到它),它在/usr/ 目录中寻找libstdc++ 而不是所在的目录g++4.8 安装驻留。例如。代码编译,但执行失败:

./main: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./main)

再一次 - 当我自己从终端调用编译器时,这不会发生。 即使我使用 LIBPATH 选项添加包含 g++4.8 库的库路径,我也会收到相同的错误。 这是我的 SConscript 文件:

            Import('env')

    COMPILER_FLAGS = '-Wall -fopenmp -O3 -std=c++11'
    LINK_FLAGS = '-Wall -fopenmp -O3 -std=c++11'
    LIB_PATH = 'myfolder/gcc-4.8.2/lib64'

    PROGRAM = 'main'
    SRC = ['main.cpp', 'Foo.cpp']
    env.Append(CPPFLAGS = COMPILER_FLAGS)
                                                                                                                                                             env.Append(LINKFLAGS = LINK_FLAGS)
    env.Program(target = PROGRAM, source = SRC, LIBPATH = LIB_PATH)

而 SConstruct 只是

import os
env = Environment(ENV = os.environ)
SConscript('./SConscript', exports=['env'], duplicate=0)

编辑:

我确保编译器的位置位于默认编译器之前的路径中。但即使我用Environment(CXX=...) 明确设置它也是一样的。这是构建输出:

/mypath/gcc-4.8.2/bin/g++ -o Foo.o -c -Wall -fopenmp -O3 -std=c++11 Foo.cpp
/mypath/gcc-4.8.2/bin/g++ -o main.o -c -Wall -fopenmp -O3 -std=c++11 main.cpp
/mypath/gcc-4.8.2/bin/g++ -o main -Wall -fopenmp -O3 -std=c++11 main.o Foo.o -L/mypath/gcc-4.8.2/lib64
scons: done building targets.
-bash-3.2$ 
-bash-3.2$ 
-bash-3.2$ ./main 
./main: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by ./main)
./main: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by ./main)
-bash-3.2$ 

又一次修改:

手动和 scons 上的 ldd 编译显示:

linux-vdso.so.1 =>  (0x00007fff513fd000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6(0x0000003e7f600000)
libm.so.6 => /lib64/libm.so.6 (0x0000003e79600000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x0000003e7de00000)
libc.so.6 => /lib64/libc.so.6 (0x0000003e79200000)
/lib64/ld-linux-x86-64.so.2 (0x0000003e78e00000)

确实,即使手动编译也不会在正确的目录(或我安装编译器的位置)中查找库,问题不在于 scons 本身,但可能是我没有正确配置某些东西,但是那么我真的很困惑为什么可执行文件运行良好,而对于 scons 却没有。


好的,所以我的问题不在于 scons,而在于我没有给出指向 libstdc++ 和朋友的非标准位置的明确路径。 SO answer在这里更详细地解释了这一点: Linking g++ 4.8 to libstdc++

【问题讨论】:

    标签: linker g++ scons libstdc++


    【解决方案1】:

    您误解了错误。 GCC 总是知道如何找到自己的库,包括 libstdc++。问题是,在您编译完程序后,运行时链接器(它不是 GCC 的一部分,它是您的操作系统的一部分,来自 glibc)不知道如何找到较新的 libstdc++,因此它会找到默认系统之一,太旧了。

    Libstdc++ 常见问题解答"How do I insure that the dynamically linked library will be found?" 和手册"Finding Dynamic or Shared Libraries" 中描述了问题和解决方案

    【讨论】:

      【解决方案2】:

      这听起来不对。 你能告诉我们你做了什么来覆盖编译器吗? 如果您只执行上述操作,我认为您的编译器不会被新版本覆盖。

      你需要做类似的事情 env = 环境(CC='/path/to/gcc') 或者 Environment(CXX='/path/to/g++') 如果你想覆盖 c++ 编译器

      或者您的环境设置路径是否在标准编译器目录之前具有自定义编译器的目录?

      使用 --debug=presub 清理然后使用 scons 运行可能会有所帮助,这将向您显示用于构建每个目标的命令行。 此外,您的环境是一本字典,因此请尝试打印出不同的键以确保它们符合您的期望:

      print env['CC']
      print env['CXX']
      

      【讨论】:

      • 似乎 main.o 是使用较新的编译器显式“手动”编译的,而 scons 正在尝试与该版本的 main.o 链接。虽然,我认为 SCons 会检测到这种情况,但无论如何,所有对象都应该被清除。
      • 请看一下我的编辑,答案太长,无法放入 cmets。
      • 令我惊讶的是,你说从终端手动调用编译器时不会发生这种情况。
      • 过早进入那里。 ...我无法想象 scons 可能会做些什么来影响局势。我会做以下测试。从命令行手动编译二进制文件,然后运行 ​​ldd /path/to/your/binary 并保存结果。现在用 scons 编译二进制文件并再次运行 ldd /path/to/your/binary 现在检查并比较结果。如果结果相同,那么问题似乎不太可能与 scons 相关。另一方面,如果结果不同,那么仔细检查可能会发现问题。
      • Avatar33 - 一个很好的电话,请看看我的编辑。我想问题在于我如何配置编译器安装:/
      猜你喜欢
      • 2017-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-18
      • 2014-04-15
      • 2012-12-27
      • 1970-01-01
      相关资源
      最近更新 更多