Bug #12430
openOur Headers break clang
0%
Description
While compiling newest firefox I stumbled upon the following error
In file included from <built-in>:2:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil_visibility.h:26:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil/log.h:25:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil/avutil.h:296:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil/common.h:36:
/usr/clang/9.0/lib/clang/9.0.1/include/stdint.h:217:25: error: typedef redefinition with different types ('int16_t' (aka 'short') vs 'int')
typedef __int_least16_t int_fast16_t;
^
/usr/include/sys/int_types.h:136:15: note: previous definition is here
typedef int int_fast16_t;
^
In file included from <built-in>:2:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil_visibility.h:26:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil/log.h:25:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil/avutil.h:296:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil/common.h:36:
/usr/clang/9.0/lib/clang/9.0.1/include/stdint.h:218:26: error: typedef redefinition with different types ('uint16_t' (aka 'unsigned short') vs 'unsigned int')
typedef __uint_least16_t uint_fast16_t;
^
/usr/include/sys/int_types.h:147:23: note: previous definition is here
typedef unsigned int uint_fast16_t;
^
In file included from <built-in>:2:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil_visibility.h:26:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil/log.h:25:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil/avutil.h:296:
In file included from /vagrant/components/web/firefox/firefox-68.6.0/media/ffvpx/libavutil/common.h:36:
/usr/clang/9.0/lib/clang/9.0.1/include/stdint.h:224:23: error: typedef redefinition with different types ('signed char' vs 'char')
typedef __INT8_TYPE__ int8_t;
^
/usr/include/sys/int_types.h:75:16: note: previous definition is here
typedef char int8_t;
^
3 errors generated.
Turns out glibc has type guards in place which are respected by clang. The following snippet from stdint.h show this in practice.
#ifdef __INT8_TYPE__
#ifndef __int8_t_defined /* glibc sys/types.h also defines int8_t*/
typedef __INT8_TYPE__ int8_t;
#endif /* __int8_t_defined */
However our headers do not have the same defines. Thus compilation of programs that build with clang i.e. rust and Firefox which include C code which in turn includes stdint.h fails.
To solve this we will need at least these defines:
_int8_t_defined
_uint32_t_defined
__intptr_t_defined
Clang seems to also use the same safeguard to stop glibc from defining the same types if clang headers are included first. See this example from stdint.h
/* prevent glibc sys/types.h from defining conflicting types */
#ifndef __int8_t_defined
# define __int8_t_defined
#endif /* __int8_t_defined */
We will need to be compatible with this or make clang be compatible with us.
Updated by Till Wegmüller over 3 years ago
There seems to be a similar problem with /usr/clang/9.0/lib/clang/9.0.1/include/mm_malloc.h where clang redefines system headers in it's own way!!! No wonder Firefox's memory allocator is broken.
Updated by Carsten Grzemba almost 3 years ago
It seems it is only related to the (FF)/media/ffvpx/libavutil code. So, perhaps patch this code is also an option.
Updated by Joshua M. Clulow almost 3 years ago
I would say that anywhere there is a relatively simple pre-existing guard that a common implementation (e.g., glibc, FreeBSD libc, etc) is already using, and which Clang respects, we should probably just adopt in our headers. Things like __int8_t_defined
seem pretty low-maintenance.
Updated by Rich Lowe almost 3 years ago
Is this another case where the compiler tries to "fix" our headers, like GCC's fixincludes/include-fixed? If so, do we want to go through and fix any real problems it's trying to work around, as well as perhaps introduce guards as Joshua suggested?
Updated by Jason King almost 3 years ago
Is the clang build being used defining __STDC_HOSTED__
as part of it's default set of macros? IIUC, that's used to tell clang (or gcc) that the build system has a full functional libc (which should also make clang avoid redefining those macros)?