cross-ld找不到libstdc++.a,不过应该一直在找

Cross-ld can’t find libstdc++.a, but shouldn’t have been looking

我正在使用托管在 OS X 和 Debian 上的 GCC 构建 arm-eabi(arm-none-eabi 的别名)。相关代码未使用 C++。但是,link 在 Debian 上失败

/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/../../../../arm-eabi/bin/ld: cannot find libstdc++.a
collect2: error: ld returned 1 exit status

这让我感到惊讶,因为报告的 link 行(带有 -Wl,-v)也没有提到 libstdc++(见末尾)。

Debian 构建没有交叉 libstdc++.a,而 OS X 构建有(我不知道那是怎么发生的;它只包含 empty_arm_object.o) .如果我将此 libstdc++.a 复制到 Debian 端,构建工作正常;但我想首先了解为什么需要它。

link 命令行(我希望为清楚起见进行了编辑)是

/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/../../../../arm-eabi/bin/ld                            \
-plugin                                                                                                 \
/opt/gnat-gpl-2015/bin/../libexec/gcc/arm-eabi/4.9.3/liblto_plugin.so                                   \
-plugin-opt=/opt/gnat-gpl-2015/bin/../libexec/gcc/arm-eabi/4.9.3/lto-wrapper                            \
-plugin-opt=-fresolution=/tmp/cctcp4CP.res                                                              \
-EL                                                                                                     \
-X                                                                                                      \
-o                                                                                                      \
/home/simon/cortex-gnat-rts/test-stm32f4//testbed                                                       \
-L/home/simon/cortex-gnat-rts/test-stm32f4/.build/                                                      \
-L/home/simon/cortex-gnat-rts/test-stm32f4/.build/                                                      \
-L/home/simon/cortex-gnat-rts/test-stm32f4/../stm32f429i-disco-rtos/adalib/                             \
-L/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/fpu                                                  \
-L/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/../../../../arm-eabi/lib/fpu                         \
-L/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3                                                      \
-L/opt/gnat-gpl-2015/bin/../lib/gcc                                                                     \
-L/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/../../../../arm-eabi/lib                             \
testbed.o                                                                                               \
b__testbed.o                                                                                            \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/last_chance_handler.o                                   \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/memory_streams.o                                        \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/containing.o                                            \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/dispatching.o                                           \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/iteration.o                                             \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/so.o                                                    \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/streams.o                                               \
/home/simon/cortex-gnat-rts/test-stm32f4/.build/strings.o                                               \
/home/simon/cortex-gnat-rts/test-stm32f4/../stm32f429i-disco-rtos//adalib/libgnat.a                     \
/home/simon/cortex-gnat-rts/test-stm32f4/../stm32f429i-disco-rtos//adalib/libbsp-rtos.a                 \
-lgcc                                                                                                   \
-Map /home/simon/cortex-gnat-rts/test-stm32f4/testbed.map                                               \
-T /home/simon/cortex-gnat-rts/test-stm32f4/../stm32f429i-disco-rtos//adalib/stm32f429i-flash.ld
/opt/gnat-gpl-2015/bin/../lib/gcc/arm-eabi/4.9.3/../../../../arm-eabi/bin/ld: cannot find libstdc++.a
collect2: error: ld returned 1 exit status

linker 脚本的末尾包含

/DISCARD/ :
{
    libc.a ( * )
    libm.a ( * )
    libgcc.a ( * )
    libstdc++.a ( * )
}

/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }

第一个显然是 arm-eabi-ld 找到对 libstdc++.a 的引用。恐怕这些部分是从网络上的某个地方盲目复制的,我不知道第一个实际上是什么。是“libstdc++.a 中您尚未分配的任何东西”吗?

linker 寻找 libstdc++.a 的原因是 linker 脚本中的 /DISCARD/ 部分提到了该库。

将整个文件包含在 /DISCARD/ 部分似乎很奇怪,其目的是省略输入的某些部分。如果您不想包含该文件,请将其从 link 命令行中删除!

调查显示 ld 在这种情况下有一个意想不到的行为,在 /DISCARD/ 部分中包含 libc.a 与包含 -lc 在 link 命令行中;并且在这种情况下使用的 link 命令行结束 -nostdlib -lgcc。应该是-nostdlib -lgcc -lc。这与删除特殊的 /DISCARD/ 部分一起解决了问题。