[Bug]: ABSL_HAVE_ELF_MEM_IMAGE assumes every ELF target ships <link.h>
Describe the issue
ABSL_HAVE_ELF_MEM_IMAGE is switched on for every __ELF__ target except an explicit deny-list, and the header then unconditionally includes <link.h>:
__ELF__ says the object format is ELF. It does not say a dynamic loader exists, and <link.h> is a glibc/dynamic-linker header, not part of the ELF format. Bare-metal ELF toolchains produce ELF objects and ship no <link.h> at all — arm-none-eabi-g++ with newlib is the common one. There ABSL_HAVE_ELF_MEM_IMAGE is defined, #include <link.h> is reached, and the build stops with a fatal error.
The deny-list is the symptom: __QNX__, __asmjs__, __wasm__, __HAIKU__, __VXWORKS__, __hexagon__, __XTENSA__ are, for the most part, ELF targets that were added one at a time as each one hit this. Every further bare-metal ELF target has to send another PR to add itself.
I would expect the guard to test for what the code actually needs — the availability of <link.h> — rather than enumerating the platforms that lack it.
Steps to reproduce the problem
Reproduces on unmodified master with a stock arm-none-eabi toolchain. No FreeRTOS, RTOS or other platform code is involved — a plain -fsyntax-only on Abseil's own sources is enough:
$ git rev-parse HEAD
71330b939f8b6b92d7f1b0a83e04c1288583737b
$ arm-none-eabi-g++ -std=c++17 -I. -fsyntax-only absl/debugging/internal/elf_mem_image.cc
In file included from absl/debugging/internal/elf_mem_image.cc:18:
./absl/debugging/internal/elf_mem_image.h:45:10: fatal error: link.h: No such file or directory
45 | #include <link.h> // for ElfW
| ^~~~~~~~
compilation terminated.
$ arm-none-eabi-g++ -std=c++17 -I. -fsyntax-only absl/debugging/internal/vdso_support.cc
In file included from ./absl/debugging/internal/vdso_support.h:45,
from absl/debugging/internal/vdso_support.cc:19:
./absl/debugging/internal/elf_mem_image.h:45:10: fatal error: link.h: No such file or directory
45 | #include <link.h> // for ElfW
| ^~~~~~~~
compilation terminated.
$ g++ -std=c++17 -I. -fsyntax-only absl/debugging/internal/elf_mem_image.cc # host, for contrast: compiles The two preconditions can be confirmed separately — the target is ELF, and it has no <link.h>:
#if !defined(__ELF__)
#error NOT_ELF
#endif
#if __has_include(<link.h>)
#error HAS_LINK_H
#else
#error NO_LINK_H
#endif$ arm-none-eabi-g++ -std=c++17 -fsyntax-only t.cc
t.cc:7:2: error: #error NO_LINK_H
$ g++ -std=c++17 -fsyntax-only t.cc
t.cc:5:2: error: #error HAS_LINK_HWhat version of Abseil are you using?
71330b939f8b6b92d7f1b0a83e04c1288583737b (master)
What operating system and version are you using?
Ubuntu 24.04.4 LTS, x86-64 (kernel 6.8.0-138-generic).
The failure is compile-time and host-independent; it depends only on the target toolchain being ELF without a <link.h>.
What compiler and version are you using?
arm-none-eabi-g++ (15:13.2.rel1-2) 13.2.1 20231009 -- the toolchain that fails.
g++ (Ubuntu 13.3.0-6ubuntu2~24.04.1) 13.3.0 -- host compiler, shown above for contrast.
What build system are you using?
None -- the errors above come from a direct -fsyntax-only compiler invocation on Abseil's own sources.
Additional context
The one-line fix is to add the header check to the existing condition, keeping the deny-list untouched:
!defined(__XTENSA__) && __has_include(<link.h>) absl/debugging/internal/stacktrace_config.h already guards this way in the same directory (#if __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL)), and __has_include is used unconditionally across Abseil since "Use __has_include unconditionally as it is supported by C++17" (2fb25663).
Verified on 71330b93: with this line, elf_mem_image.cc and vdso_support.cc both compile under arm-none-eabi-g++, and on the host ABSL_HAVE_ELF_MEM_IMAGE is still defined and both files still compile — so no supported platform changes behaviour.
Source: abseil/abseil-cpp