Background:
While setting up YouCompleteMe compile arguments for a standalone GCC + sysroot for aarch64, I went spelunking in the standard C++ system includes and found this little gem:
[sysroot]/usr/include/c++/11.2.0/cstdarg
#include <stdarg.h>
Which points at
[sysroot]/usr/include/c++/11.2.0/tr1/stdarg.h
#include <tr1/cstdarg>
Which, itself, points at
[sysroot]/usr/include/c++/11.2.0/tr1/cstdarg
#include <cstdarg>
Thereby looping us back to the beginning. The loop is ultimately broken by some #ifdef
's but, ultimately, none of these files really defines anything substantial.
Since these three files all really just include other files, this is causing clangd (YCM's back-end compile server) to eventually parse
namespace std
{
using ::va_list;
} // namespace std
from [sysroot]/usr/include/c++/11.2.0/cstdarg
and then emit:
No member named 'va_list' in the global namespace
I double checked my standard system headers and they are essentially identical so this isn't just limited to my cross toolchain.
Questions:
- Where is
va_list
ultimately defined for C++? - What arguments would I need to feed to clangd to resolve this?
- What is the purpose of defining system headers like this?
Reference:
The relevant compile arguments are:
'-xc++',
'-std=gnu++17',
'-stdlib=libc++',
'-nostdinc',
'-isystem', SYSROOT_AARCH64 + '/usr/include',
'-isystem', SYSROOT_AARCH64 + '/usr/include/linux',
'-isystem', SYSROOT_AARCH64 + '/usr/include/c++/11.2.0',
'-isystem', SYSROOT_AARCH64 + '/usr/include/c++/11.2.0/tr1',
'-isystem', SYSROOT_AARCH64 + '/usr/include/c++/11.2.0/aarch64-poky-linux',
Comment Responses:
@PasserBy: Where are you seeing that? The only stdarg.h
I have is under c++/11.2.0/tr1
(see comment response to teapot418 below) and this does not have any typedefs in it. The total content of this file (minus comments) is:
#ifndef _TR1_STDARG_H
#define _TR1_STDARG_H 1
#include <tr1/cstdarg>
#endif
This matches my host system's stdarg.h
so I don't think this is a failing of the toolchain.
@Lundin: I am not using this but it looks like <string>
eventually includes <cstdarg>
which causes clangd errors.
@teapot418: I had considered this when I noticed that other headers were included as <tr1/foo>
. The problem, though, is that removing tr1
as an include directory causes stdarg.h
to not be found at all. A simple find reveals:
$ find /path/to/sysroot/ -name stdarg.h
/path/to/sysroot/usr/include/c++/11.2.0/tr1/stdarg.h
This is strange to me as I would have expected to find the C version of stdarg.h
somewhere like [sysroot]/usr/include
. I would be wrong, though, as comparing to my host system yields the same result:
$ find /usr/include/ -name stdarg.h
/usr/include/c++/12/tr1/stdarg.h
Is there some other shenanigans going on here that I am missing?
@KamilCuk: See below. One thing I notice is that the pats are being included from .../sysroots/x86_64-pokysdk-linux/...
while I was primarily using paths from .../sysroots/aarch64-poky-linux/...
. Yocto generates both of these as part of the SDK and, I admit, I don't fully appreciate the difference between the two. I would have expected all relevant headers to be in the aarch64-poky-linux
but, clearly, this assumption is false.
aarch64-poky-linux-gcc -E -xc - <<<'#include <stdarg.h>'
# 0 "<stdin>"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "<stdin>"
# 1 "/opt/lmc/sdk/remus/0.31.7/sysroots/x86_64-pokysdk-linux/usr/lib/aarch64-poky-linux/gcc/aarch64-poky-linux/11.2.0/include/stdarg.h" 1 3 4
# 40 "/opt/lmc/sdk/remus/0.31.7/sysroots/x86_64-pokysdk-linux/usr/lib/aarch64-poky-linux/gcc/aarch64-poky-linux/11.2.0/include/stdarg.h" 3 4
# 40 "/opt/lmc/sdk/remus/0.31.7/sysroots/x86_64-pokysdk-linux/usr/lib/aarch64-poky-linux/gcc/aarch64-poky-linux/11.2.0/include/stdarg.h" 3 4
typedef __builtin_va_list __gnuc_va_list;
# 99 "/opt/lmc/sdk/remus/0.31.7/sysroots/x86_64-pokysdk-linux/usr/lib/aarch64-poky-linux/gcc/aarch64-poky-linux/11.2.0/include/stdarg.h" 3 4
typedef __gnuc_va_list va_list;
# 2 "<stdin>" 2