2

There's a TL;DR at the end if the context is too much!

Context

I am trying to update the version of glibc a project uses to 2.23 (I know it's old, that's another issue). In order to do this, I need to swap out the libraries and use the associated interpreter.

I encountered some issues when swapping out the interpreter that looked like an ABI change, so I figured it was probably because the header files had changed somehow and started working on getting those included into the project.

At first I tried using -I to include the headers, but got an error (see below). Later I tried setting --sysroot, but this quickly felt like the wrong way of doing things since I was essentially reinventing what g++ already did with system headers. I later found another mechanism that looked more promising (see Problem section).

Could this be an XY issue? Absolutely, but either way, the problem I'm seeing seems odd to me.

Problem

I looked into whether there was a different mechanism to include headers for system libraries, such as glibc, in gcc and g++. I found the flag -isystem:

   -isystem dir
      Search dir for header files, after all directories specified by -I but before the standard system directories.  Mark it as a system directory, so that it gets the same special treatment as is applied to the standard system directories.  If dir begins with "=", then the "="
      will be replaced by the sysroot prefix; see --sysroot and -isysroot.

I figured that this was probably wanted and set about intergrating this flag into the build system for the project. The resulting g++ command looks like this (simplified and broken onto multiple lines):

> /path/to/gcc-6.3.0/bin/g++
  -c
  -Wl,--dynamic-linker=/path/to/glibc-2.23/build/install/lib/ld-linux-x86-64.so.2
  -Wl,--rpath=/path/to/glibc-2.23/build/install/lib
  -isystem /path/to/glibc-2.23/build/install/include
  -I.
  -I/project-foo/include
  -I/project-bar/include
  -o example.o 
  example.cpp

This leads to the following error, followed by many similar ones:

In file included from /usr/include/math.h:71:0,
                 from /path/to/gcc-6.3.0/include/c++/6.3.0/cmath:45,
                 from example.cpp:42:
/path/to/glibc-2.23/build/install/include/bits/mathcalls.h:63:16: error: expected constructor, destructor, or type conversion before '(' token
 __MATHCALL_VEC (cos,, (_Mdouble_ __x));

Looking into this, it appears that this particular math.h is incompatible with this version of glibc. The fact it tries to use it surprises me, because the math.h file exists in the glibc directory I specified; why didn't it use that? Here's how I verified that file exists:

> ls /path/to/glibc-2.23/build/install/include/math.h 
/path/to/glibc-2.23/build/install/include/math.h

Research

I searched around on the internet for people with a similar issue and came across the following relevant things:

The last of these is the most promising; it talks about why -isystem won't work here stating that the special #include_next traverses the include path in a different way. Here, the solution appears to be "don't use -isystem where you can help it", but since I've tried using -I only get get the same problem again, I'm not sure how I'd apply that here.

Original issue

When compiling with the new glibc, I get the following error (our build process ends up running some of the programs it compiles to generate further source to be compiled, hence this runtime error whilst compiling):

Inconsistency detected by ld.so: get-dynamic-info.h: 143: elf_get_dynamic_info: Assertion `info[DT_RPATH] == NULL' failed!

I found a couple of relevant things about this:

The only solution I see there is completely recompiling gcc to use the new glibc. I'd like to avoid that if possible, which is what lead me down the include route.

Eliminating the complex build system

To try and eliminate the complex build system on the "real" project, I reproduced the problem using the following test.cpp file:

#include <cmath>

int main() {

}

Compiled using:

> /path/to/gcc-6.3.0/bin/g++ test.cpp -Wl,--dynamic-linker=/path/to/glibc-2.23/build/install/lib/ld-linux-x86-64.so.2 -Wl,--rpath=/path/to/glibc-2.23/build/install/lib

Running yields the same original issue:

> ./a.out 
Inconsistency detected by ld.so: get-dynamic-info.h: 143: elf_get_dynamic_info: Assertion `info[DT_RPATH] == NULL' failed!

Trying to use the newer headers yields the same include issue:

> /path/to/gcc-6.3.0/bin/g++ test.cpp -Wl,--dynamic-linker=/path/to/glibc-2.23/build/install/lib/ld-linux-x86-64.so.2 -Wl,--rpath=/path/to/glibc-2.23/build/install/lib -isystem /path/to/glibc-2.23/build/install/include
In file included from /usr/include/math.h:71:0,
                 from /path/to/gcc-6.3.0/include/c++/6.3.0/cmath:45,
                 from test.cpp:1:
/path/to/glibc-2.23/build/install/include/bits/mathcalls.h:63:16: error: expected constructor, destructor, or type conversion before '(' token
 __MATHCALL_VEC (cos,, (_Mdouble_ __x));

TL;DR

How can I get g++ to include the headers from my glibc build correctly, without it accidentally including incompatible files from /usr/include?

OMGtechy
  • 7,935
  • 8
  • 48
  • 83
  • Did you read the documentation of [GCC](http://gcc.gnu.org/) ? And of [GNU cpp](https://gcc.gnu.org/onlinedocs/cpp/) ? GCC being free software, you can recompile it and improve it – Basile Starynkevitch Jul 08 '20 at 13:15
  • @BasileStarynkevitch some parts that looked relevant, but not all. There's a lot to go through! Specifically I took a look at the FAQ and grepped the complete PDF manual for glibc and headers, which is what lead me to isystem. I also took a look here: https://www.gnu.org/software/libc/manual/html_mono/libc.html#Installation Modifying gcc and/or rebuilding it is a last resort, I'm hoping to avoid it if possible as it would add even more "specialness" to our build process. – OMGtechy Jul 08 '20 at 13:23
  • You probably have to look inside the documentation of [GNU binutils](https://www.gnu.org/software/binutils/) since it is (or may be) invoked by `gcc` or `g++` – Basile Starynkevitch Jul 10 '20 at 05:23

1 Answers1

1

In your GCC version,<cmath> uses #include_next, which means that you need to make sure that the directory which contains the cmath file comes before (on the include search path) the directory with the proper math.h for the version of glibc you are building against.

You can use g++ -v to view the search path. In your case, it probably looks like this:

#include "..." search starts here:
#include <...> search starts here:
 .
 /project-foo/include
 /project-bar/include
 /path/to/glibc-2.23/build/install/include
 /usr/include/c++/6
 /usr/include/x86_64-linux-gnu/c++/6
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include

If you configure glibc with --prefix=/usr and install it with DESTDIR=/path/to/glibc-2.23/build/install, its header files will be installed into the directory /path/to/glibc-2.23/build/install/usr/include. This means you should be able to use the -isysroot option, which rewrites the default /usr/include directory, resulting in the right ordering of the search path:

#include "..." search starts here:
#include <...> search starts here:
 .
 /project-foo/include
 /project-bar/include
 /usr/include/c++/6
 /usr/include/x86_64-linux-gnu/c++/6
 /usr/include/c++/6/backward
 /usr/lib/gcc/x86_64-linux-gnu/6/include
 /usr/lib/gcc/x86_64-linux-gnu/6/include-fixed
 /path/to/glibc-2.23/build/install/usr/include

Florian Weimer
  • 32,022
  • 3
  • 48
  • 92
  • I just tried this and it compiled, but when running I still get the `Assertion `info[DT_RPATH] == NULL'` problem. Since it answers the question, I'll still accept this, but if you have any other info regarding the assertion problem in an off-comment, that would be appreciated. If it's too complex an answer, then I'll just need to post a new question. The most obvious thing of using --sysroot instead created new problems that should go in their own question. Thank you! – OMGtechy Jul 13 '20 at 10:57
  • You likely built glibc with `-Wl,--rpath`, that doesn't work. – Florian Weimer Jul 13 '20 at 18:29
  • Indeed I did, tried removing it, still no joy. I will ask another question :) – OMGtechy Jul 14 '20 at 09:54