30

I am trying to implement backtrace functionality for a large framework, which is used for different platforms and OS'es. In some of them, it is linked against glibc, while in the other, something different (eg. uclibc) is used. backtrace() function exists only in the former.

Is there any way to tell whether glibc is used? Any #define? I was unable to find an answer in glibc manual. I know I can't have linking-time information during compilation, but I guess include files have to differ. At least backtrace have to be declared somewhere. I would like to check it without being forced to pass explicit flags to the compiler.

Fred Nurk
  • 13,952
  • 4
  • 37
  • 63
x13n
  • 4,103
  • 2
  • 21
  • 28

5 Answers5

38

Include features.h, it contains the macros you need, e.g.

#define __GNU_LIBRARY__ 6

/* Major and minor version number of the GNU C library package.  Use
   these macros to test for features in specific releases.  */
#define __GLIBC__       2
#define __GLIBC_MINOR__ 4
Erich Kitzmueller
  • 36,381
  • 5
  • 80
  • 102
30

There are the #defines __GNU_LIBRARY__, __GLIBC__ and __GLIBC_MINOR__ (6, 2 and 11 on my system with glibc-2.11) in features.h.

Gunther Piez
  • 29,760
  • 6
  • 71
  • 103
6

Checking for preprocessor macros is not a good solution. uClibc and possibly other libc implementations define macros to mimic glibc (without providing all of its bloated functionality) for much the same reasons that all browsers include "Mozilla" in their User-Agent strings: broken programs that expect to see glibc and turn off lots of features if they don't see it.

Instead you should write a configure script to probe for backtrace and use it only if it's available.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 2
    Configure scripts are not a useful solution for a project that needs to build on Windows and iPhone as well as Linux targets. – Logan Pickup Sep 17 '14 at 21:03
  • @LoganPickup: I don't see why not. But if you insist on using a build system that's not amenable to configure on those targets, you can just have hard-coded configure results (`config.h`, etc.) for them since they're essentially single, tightly-controlled environments. – R.. GitHub STOP HELPING ICE Sep 17 '14 at 23:20
  • 1
    Use CMake for multi platform projects. What you want is system introspection, not configure scripts per se. CMake does multi platform system introspection – Joakim Jan 14 '16 at 15:19
  • 2
    @Joakim - CMake is probably one of the worse choices. If he uses CMake he will have to write his own test that configure would perform for him. We just removed CMake as an alternative because it was so anemic, created so much extra work and caused so many problems. For a detailed list of problems see [CMake Removal](https://www.cryptopp.com/wiki/CMake#CMake_Removal). – jww Sep 17 '17 at 03:40
2

Empirically, both of the following compile and run fine on GCC 6.4:

#include <stdio.h>

int main(void) {
#ifdef __GLIBC__
    puts("__GLIBC__");
#endif
    return 0;
}

and:

int main(void) {
#ifdef __GLIBC__
    puts("__GLIBC__");
#endif
    return 0;
}

but only the first produces output of course.

This must mean that __GLIBC__ comes from stdio.h which must include features.h, see also: What is the purpose of features.h header?

Therefore, strictly speaking, __GLIBC__ by itself is not a clear indication that glibc is used, since even without headers, GCC already embeds runtime objects such as crt1.o in the finale executable, and those come from glibc.

So the main missing question is: does glibc guarantee that features.h gets included by every header? I could not find a clear documentation quote. TODO.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
1
#if defined(__GLIBC__) && !defined(__UCLIBC__) && !defined(__MUSL__)

This is getting a bit ugly and syntactically ambiguous, but useful.

Jagger Yu
  • 577
  • 4
  • 5
  • 1
    To future readers, there is no `__MUSL__` define, see the musl faq for the reasoning behind this. You're left with probing for functionality at runtime instead. – troglobit Feb 14 '21 at 04:06