3

This question is related to Why does pclose return prematurely?. I'd like to find out what version of libc is used for a cross-compiled executable. There are limitations, described below, that make the answers at Check glibc version for a particular gcc compiler not apply.

  • One proposed way to check the libc version is to use the gnu_get_libc_version() function declared in gnu/libc-version.h. My cross-toolchain does not include libc-version.h.

  • Another proposed solution is to use the -print-file-name gcc option. This answer in the linked question just flat-out didn't work for me:

$ /path/to/toolchains/ARM-cortex-m3-4.4/bin/arm-uclinuxeabi-gcc -print-file-name=libc.so
libc.so
$
$ /path/to/toolchains/ARM-cortex-m3-4.4/bin/arm-uclinuxeabi-gcc -print-file-name=foo.bar
foo.bar
$ # I really do not have a foo.bar file in existence
  • Another proposed solution is to just do ldd --version. My target platform doesn't have ldd:
$ ldd
sh: can't execute 'ldd': No such file or directory
  • Another proposed solution is to look at __GLIBC__ and __GLIBC_MINOR__ -- but these also appear to come from libc-version.h, which doesn't exist in my cross-toolchain, as described above.

My cross-toolchain seems to only provide libc.a, not libc.so.
I tried running that libc.a through /path/to/toolchains/ARM-cortex-m3-4.4/bin/arm-uclinuxeabi-nm and strings grepping (case-insensitive) for "version" and "libc" but did not find anything that looked like an identifying version.

The last thing I tried was strings /path/to/toolchains/ARM-cortex-m3-4.4/bin/arm-uclinuxeabi-gcc | grep GLIBC, which gave me:

GLIBC_2.3
GLIBC_2.2
GLIBC_2.1
GLIBC_2.0
EGLIBC configuration specifier, serves multilib purposes.

But that solution wasn't highly upvoted, and it also has a comment suggesting that it doesn't really give you the version. I don't really understand this answer or its responding comment, so I don't know what to make of its validity.

Question: given all the above, is there any definitive way to determine the libc version used for cross-compiling for this cross-platform?

StoneThrow
  • 5,314
  • 4
  • 44
  • 86
  • The `strings` thing is most likely just telling you that the compiler executable itself is linked against the (host) glibc. That wouldn't tell you anything about what the executables it produces do. – Nate Eldredge Jul 04 '20 at 17:48
  • 2
    It sounds like maybe your target platform doesn't use glibc at all, but perhaps some entirely unrelated C library, so glibc stuff may not be of any use. Each implementation of a C library gets to decide for itself how to report its version numbering (if at all); there's no standard interface as far as I know. So you're going to need to find out what C library you installed and read its documentation. – Nate Eldredge Jul 04 '20 at 17:50
  • 1
    Wow, thank you for the effort put into researching this question. A comment on the other question suggests you might be dealing with uclibc. Can you try [this answer](https://stackoverflow.com/a/50471325/530160) and check if it gives you the correct version? – Nick ODell Jul 04 '20 at 17:52
  • @NateEldredge - is the compiler/toolchain completely independent of the `libc`? I thought that because the compiler was (a cross-compiling flavor of) `gcc`, that implied it was a `gnu` toolchain, thereby also including `gnu` `libc`...? – StoneThrow Jul 04 '20 at 17:53
  • @StoneThrow: No, the compiler and C library are generally agnostic of one another. As long as they both obey the correct ABI, any combination is supposed to work. – Nate Eldredge Jul 04 '20 at 17:54
  • You can't "portably" check the version or origin of C implementation. My guess is you use newlib. But why not just navigate to the directory with the system headers and inspect them? – KamilCuk Jul 04 '20 at 18:06
  • @KamilCuk - that sounds similar to the suggestion at my other linked question: a commenter there suggested I "look at the files in the cross toolchain's sysroot" -- I think I don't really understand what that means...do you mean literally just look around at various files in that directory-tree and look for a string that has the libc version? – StoneThrow Jul 04 '20 at 18:10
  • @NateEldredge - is there a way to determine the "flavor" of `libc`? I.e. if I knew which variant of `libc` it was, perhaps I could look up its documentation on how to get its version. Fwiw, as far as I can tell, the only thing I have to work with is `libc.a`. – StoneThrow Jul 04 '20 at 18:12
  • I like the suggestion made on the other question - find the header files and look for identifying comments or macros. Surely you have those in addition to libc.a, otherwise you can't compile anything anyway. – Nate Eldredge Jul 04 '20 at 18:13
  • To answer your direct question, there is no universal way - every implementation decides for itself what to do. It's assumed that you are able to remember what software you installed, or that you did it in a way that keeps logs or records (e.g. via your OS package manager). – Nate Eldredge Jul 04 '20 at 18:15
  • In `/path/to/toolchains/ARM-cortex-m3-4.4/` there is most probably an `include` or `usr/include` directory. In that directory there are standard headres `stdef.h` `stdint.h` etc. See at the top of these files - maybe there is a "copyright" section, maybe author information. Research that, browse those files. – KamilCuk Jul 04 '20 at 18:35
  • @KamilCuk - I find a variety of copyright references, so it's hard to say which one is "right." One example is `/path/to/toolchains/ARM-cortex-m3-4.4/sysroot/include/stdlib.h` which says copyright "1991-2007, 2009). It sounds like this method - i.e. browsing the header files - is the best approach under the circumstances, thank you. – StoneThrow Jul 04 '20 at 20:07
  • @NateEldredge - I'll need to check with the engineers responsible for this toolchain; I think you're right - they ought to have record of what software and versions are used to comprise this toolchain. – StoneThrow Jul 04 '20 at 20:08
  • @KamilCuk - in case you have any insight on the problem that spawned this question, please visit https://chat.stackoverflow.com/rooms/217220/why-does-pclose-return-prematurely and feel free to comment - my most recent post in that chat-room ties both questions together. – StoneThrow Jul 04 '20 at 20:15
  • @NateEldredge - in case you have any insight on the problem that spawned this question, please visit https://chat.stackoverflow.com/rooms/217220/why-does-pclose-return-prematurely and feel free to comment - my most recent post in that chat-room ties both questions together. – StoneThrow Jul 04 '20 at 20:15
  • Well, from the text `EGLIBC configuration specifier` you may be curious to take a look at [EGLIBC](https://github.com/Xilinx/eglibc). – KamilCuk Jul 04 '20 at 20:31
  • @NickODell - that seems to have generated an interesting lead! The script does end up identifying `uClibc`, and version major.minor.sublevel 0.9.30. I'll need to ponder and research this a little more in the context of the other linked question. Are you pretty confident in this script's validity to identify `uClibc`? I'm new to this concept of there being different "variants" of l`ibc`. – StoneThrow Jul 06 '20 at 01:52

1 Answers1

3

You might be dealing with a variant of libc other than glibc. There are multiple different implementations of libc, such as musl or uclibc.

Here's a Bash script which can detect whether your compiler is using glibc or uclibc, and tells you the version if it detects either.

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

(Source.)

If you're using musl, unfortunately this script will report "something else." There's no way to detect musl with a preprocessor macro, and this is intentional.

Nick ODell
  • 15,465
  • 3
  • 32
  • 66