10

cross compiling a library with buildroot using the external toolchain alias code sourcery lite 2011 resulting in

output/host/opt/ext-toolchain/bin/../lib/gcc/arm-none-linux-gnueabi/4.6.1/../../../../arm-none-linux-gnueabi/bin/ld: cannot find -lgcc_s
collect2: ld returned 1 exit status

due to an obviously missing libgcc_s.a

# find . -iname "libgcc*"        
./output/host/usr/arm-buildroot-linux-gnueabi/sysroot/lib/libgcc_s.so
./output/host/usr/arm-buildroot-linux-gnueabi/sysroot/lib/libgcc_s.so.1
./output/host/opt/ext-toolchain/arm-none-linux-gnueabi/libc/armv4t/lib/libgcc_s.so.1
./output/host/opt/ext-toolchain/arm-none-linux-gnueabi/libc/armv4t/lib/libgcc_s.so
./output/host/opt/ext-toolchain/arm-none-linux-gnueabi/libc/thumb2/lib/libgcc_s.so.1
./output/host/opt/ext-toolchain/arm-none-linux-gnueabi/libc/thumb2/lib/libgcc_s.so
./output/host/opt/ext-toolchain/arm-none-linux-gnueabi/libc/lib/libgcc_s.so.1
./output/host/opt/ext-toolchain/arm-none-linux-gnueabi/libc/lib/libgcc_s.so
./output/host/opt/ext-toolchain/lib/gcc/arm-none-linux-gnueabi/4.6.1/armv4t/libgcc.a
./output/host/opt/ext-toolchain/lib/gcc/arm-none-linux-gnueabi/4.6.1/armv4t/libgcc_eh.a
./output/host/opt/ext-toolchain/lib/gcc/arm-none-linux-gnueabi/4.6.1/plugin/libgcc
./output/host/opt/ext-toolchain/lib/gcc/arm-none-linux-gnueabi/4.6.1/thumb2/libgcc.a
./output/host/opt/ext-toolchain/lib/gcc/arm-none-linux-gnueabi/4.6.1/thumb2/libgcc_eh.a
./output/host/opt/ext-toolchain/lib/gcc/arm-none-linux-gnueabi/4.6.1/libgcc.a
./output/host/opt/ext-toolchain/lib/gcc/arm-none-linux-gnueabi/4.6.1/libgcc_eh.a

Is there any way to circumvent this issue but still linking statically? Is there a CLFAGS or LDFLAGS option that does link everything statically except libgcc_s?

Stuff tried so far (beyond reading applicable parts of ld and gcc man pages):

CFLAGS="-static -static-libgcc"
CFLAGS="-static -shared-libgcc"
CFLAGS="-static -static-libgcc -Wl,-Bstatic"
CFLAGS="-static -shared-libgcc -Wl,-Bstatic"

After adding -Wl,-lgcc_s,-Bstatic I get a huge load of undefined/unknown symbols... (-Bshared is not a valid options says ld)

/home/bernhard/buildroot-2013.08/output/target/usr/lib/libgio-2.0.a(libgio_2_0_la-glocalfileinfo.o): In function `_g_local_file_info_get':
glocalfileinfo.c:(.text+0x2d90): warning: Using 'getgrgid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bernhard/buildroot-2013.08/output/target/usr/lib/libgio-2.0.a(libgio_2_0_la-glocalvfs.o): In function `g_local_vfs_parse_name':
glocalvfs.c:(.text+0x174): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bernhard/buildroot-2013.08/output/target/usr/lib/libglib-2.0.a(libglib_2_0_la-gutils.o): In function `g_get_user_database_entry':
gutils.c:(.text+0x254): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
gutils.c:(.text+0x24c): warning: Using 'setpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
gutils.c:(.text+0x25c): warning: Using 'endpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
gutils.c:(.text+0xa0): warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
gutils.c:(.text+0xe0): warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/bernhard/buildroot-2013.08/output/target/usr/lib/libgio-2.0.a(libgio_2_0_la-gnetworkaddress.o): In function `g_network_address_parse_sockaddr':
gnetworkaddress.c:(.text+0x1ac): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
<<<< SNIP >>>>
/home/bernhard/buildroot-2013.08/output/target/usr/lib/libxml2.a(xmlschemastypes.o): In function `xmlSchemaGetCanonValue':
xmlschemastypes.c:(.text+0x7680): undefined reference to `trunc'
xmlschemastypes.c:(.text+0x76bc): undefined reference to `trunc'
xmlschemastypes.c:(.text+0x7710): undefined reference to `floor'
xmlschemastypes.c:(.text+0x7760): undefined reference to `floor'
collect2: ld returned 1 exit status
drahnr
  • 6,782
  • 5
  • 48
  • 75

1 Answers1

13

It may be possible to eliminate the use of libgcc_s.a with flags that prevent gcc from using internal built-in functions (such as it's built-in memcpy), but you are probably best served by locating and using it.

Looks like this option should prevent the use of built-ins -fno-builtin. See here for more details: http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

Linking with the Shared libgcc_s.so

If the libgcc_s.a is missing, or it's desirable to use a shared libgcc_s with an otherwise static executable, this should do the job:

CFLAGS="-static -Wl,-Bdynamic,-lgcc_s,-Bstatic"
Paweł Szczur
  • 5,484
  • 3
  • 29
  • 32
ash
  • 4,867
  • 1
  • 23
  • 33
  • the above is the output of find looking for the libgcc_s in the install path of the cross compiler (yes it is installed within the buildroot directory which is the current working directory `.`) and thus it simply seems to not exist... – drahnr Sep 14 '13 at 16:05
  • hmm, somehow it's skipping that one. I would try `gcc -v` or `strace` to verify it's trying to use that specific path then. – ash Sep 14 '13 at 16:10
  • ah, looking carefully at the find output - there is no `libgccc_s.a` in there, so statically linking won't work. You could try linking it dynamically - I'll update the answer to show how. – ash Sep 14 '13 at 16:13
  • Sorry don't get it, the `libgcc_s.a` simply does not exist as show in the find results. There are plenty other `libgcc.a` `libgcc_eh.a` but not a single instance of `libgcc.a`. I checked the paths anyways and they seem to be totally fine (Updated question) – drahnr Sep 14 '13 at 16:13
  • The update in the answer should cover it. It stinks that the gcc_s.a is missing - if you want a truly static executable, you'll either need that lib, or to use the `-fno-builtin` to exclude its use (if that's sufficient). – ash Sep 14 '13 at 16:16
  • Suboptimal - I am glued to that toolchain... and -fno-builtin seems to fail/be not sufficient but I am currently my builtscript has some other issues I have to get rid of first - will comment back on as soon as it works/I am sure not working – drahnr Sep 14 '13 at 16:20
  • I understand. Perhaps you can go back to the source of the toolchain and try to get the libgcc_s.a from there. It might be possible to grab one from somewhere else and use it, but that could lead to painful bugs. It is possible to stop using libgcc_s.a, but it's been a long time since doing it. – ash Sep 14 '13 at 16:23
  • I am still a cross compiling novice so I'd rather not burn my hands that bad (also see updated question) – drahnr Sep 14 '13 at 16:31
  • Also -Bshared does not seem to be supported, but it rather being the default so I tried `-static -Wl,-lgcc_s,-Bstatic` instead which should yield the same – drahnr Sep 14 '13 at 16:36
  • 1
    Ah, looks like it should be `-Bdynamic` not shared. – ash Sep 14 '13 at 22:32
  • output does not change with additional `-Bdynamic` – drahnr Sep 14 '13 at 22:44
  • guess that is due to ordering of lib includes - anyways initial problem solved – drahnr Sep 14 '13 at 22:58
  • 2
    the first time a lib is pulled-in by it's placement on the command-line determines how it's included. If static is set, it must be static, if dynamic it can be either dynamic or static. So, `-Bstatic -lx -Bdynamic -ly` takes x as static only, and y as either. Typically, to force one lib to be static, we do `-Bstatic -lx -Bdynamic` so it can be added with other arguments before and after without breaking anything. – ash Sep 15 '13 at 06:56