3

I have a few cross-compilers on my linux desktop. Some use glibc and some use uclibc (and in future there could be other libcs too).

Currently, I can go into their sysroot directories and search for libc.so and try to find which file name it points to (for eg. libc.so -> libuClibc-1.0.12.so) and I fetch their names. But this won't last long if naming changes or if cross-compiler itself changes.

Is there a better/reliable programmatic way of detecting the name and version of the libc being used by a target cross compiler? Or are there any introspection tools available to get details about the target ceros

Note: There are a few similar questions here which normally point to #include <features.h> file or similar. That works fine if the generated code can also run on the host. But not suitable for cross-compile environments.

So has anyone been able to detect much more reliably?

EDIT: On the off chance someone comes here looking for detecting musl libc specifically, I've answered another question on SO that is related to this question.

Unmanned Player
  • 1,109
  • 9
  • 30
  • 1
    You could check for preprocessor macros. For instance, `gcc -dM -E - <<< "#include " | grep -iE "(uclibc|glibc)"`. – DaBler May 21 '18 at 07:27
  • @DaBler The only tiny troubles with that solution are: 1) It shows both `glibc` and `uclibc` for a MIPS32-uclibc cross compiler and 2) I have to parse the output. – Unmanned Player May 21 '18 at 22:05

1 Answers1

5

To detect the libc name and version at compile time, you can check for preprocessor macros. The following script is just a proof of concept:

GCC_FEATURES=$(gcc -dM -E - <<< "#include <features.h>")

if grep -q __UCLIBC__ <<< "${GCC_FEATURES}"; then
    echo "uClibc"
    grep "#define __UCLIBC_MAJOR__" <<< "${GCC_FEATURES}"
    grep "#define __UCLIBC_MINOR__" <<< "${GCC_FEATURES}"
    grep "#define __UCLIBC_SUBLEVEL__" <<< "${GCC_FEATURES}"
elif grep -q __GLIBC__ <<< "${GCC_FEATURES}"; then
    echo "glibc"
    grep "#define __GLIBC__" <<< "${GCC_FEATURES}"
    grep "#define __GLIBC_MINOR__" <<< "${GCC_FEATURES}"
else
    echo "something else"
fi

The uClibc test must be done first, since uClibc defines macros to mimic glibc.

Another possibility could be calling ldd --version in your cross-compiler environment (the glibc version is in parentheses). But I'm not sure if this works with libraries other than glibc.

DaBler
  • 2,695
  • 2
  • 26
  • 46
  • This is roughly what I was looking for. But this trick won't work for musl (https://wiki.musl-libc.org/faq.html). For most parts this is excellent. Thanks. – Unmanned Player May 22 '18 at 20:28
  • Just to add to this, you can test for musl libc by including features.h with _GNU_SOURCE defined and checking if __USE_GNU is defined, as musl libc uses _GNU_SOURCE directly to protect exposing GNU extensions unlike most the other major Linux libc's – nfries88 May 18 '22 at 06:20