
#12169: libraries/base/dist-install/build/HSbase-4.9.0.0.o: unknown symbol `stat' -------------------------------------+------------------------------------- Reporter: thomie | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Runtime System | Version: 8.0.1 (Linker) | Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by rwbarton): https://www.redhat.com/archives/pam-list/1999-February/msg00082.html has the answer. Apparently little has changed in 17 years. What's happening is * `libc.so.6` defines only `__xstat`, not `stat`. * `sys/stat.h` defines `stat` as an extern inline function that calls `__xstat`. With optimizations enabled, gcc expands the inline function call to its definition, so it generates a reference to `__xstat` and that's that. * `libc.so` is a linker script that pulls in `libc.so.6` and `libc_nonshared.a`. The latter library contains the standalone definition of the function `stat` that a C program compiled without optimizations will be linked against. * If you link something with gcc then it will automatically link in `-lc`, because gcc is a C compiler. However if you link a shared library manually using `ld -shared` then ld will not add `-lc`, because ld is not a "C linker". This usually works okay in practice anyways, because you are linking or `dlopen()`ing the shared library into a C program. In the `dlopen()` case, the shared library can see the parts of the C library that are in `libc.so.6`, but not the parts that are in `libc_nonshared.a`. This is the problem in that email thread. In our case we use `ld -r` to combine all the object files for the `base` library into one `.o` file for faster loading into the RTS linker. I don't know whether there is an equivalent to `-lc` here that will also link in just the needed bits of `libc_nonshared.a`. Even the entirety of `libc_nonshared.a` is quite small (22K), but in my attempts I could only get ld to link against the entire static `libc.a`, which is unacceptable. One thing that would work is to load `libc_nonshared.a` into the RTS linker at startup time, but that's probably glibc-specific. Trying to parse the linker script `libc.so` sounds like a rabbit hole. As a hack, we could also just add `stat` and whatever else we need to `RtsSymbols.c`. (Or ideally, just deprecate the RTS linker...) -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/12169#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler