Simon Wright
Simon Wright

Reputation: 25511

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

I am building for arm-eabi (alias for arm-none-eabi) using GCC hosted on OS X and on Debian. The code concerned doesn’t use C++. However, the link fails on Debian with

/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

This surprises me because the reported link line (with -Wl,-v) doesn’t mention libstdc++ either (see at end).

The Debian build doesn’t have a cross-libstdc++.a, while the OS X build does (I don’t know how that happened; it only contains empty_arm_object.o). If I copy this libstdc++.a to the Debian side, the build works OK; but I would like to understand why it’s needed in the first place.

The link command line (edited for clarity, I hope) is

/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

The end of the linker script contains

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

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

and the first is clearly where arm-eabi-ld is finding a reference to libstdc++.a. I’m afraid that these sections were copied blindly from somewhere on the web, and I don’t know what the first is in fact for. Is it “anything from libstdc++.a that you haven’t already allocated”?

Upvotes: 4

Views: 1867

Answers (1)

Simon Wright
Simon Wright

Reputation: 25511

The reason that the linker was looking for libstdc++.a was that the library was mentioned in the linker script in a /DISCARD/ section.

It seems odd to include a whole file in a /DISCARD/ section, the purpose of which is to omit some sections of the input. If you don’t want to include the file, leave it out of the link command line!

Investigation revealed that ld has an unexpected behaviour in this case, in that including libc.a in a /DISCARD/ section has a very similar (if not identical) effect to including -lc in the link command line; and the link command line in use in this case ended -nostdlib -lgcc. It should have been -nostdlib -lgcc -lc. This, together with removing the peculiar /DISCARD/ section, resolved the problem.

Upvotes: 3

Related Questions