Re: devel/arm-none-eabi-newlib headers inconsistencies (not functional) or am I misusing something?

From: José_Pérez <fbl_at_aoek.com>
Date: Sat, 27 May 2023 09:13:22 UTC
El 2023-05-26 18:53, José Pérez escribió:
> Hi,
> a source as simple as this does not compile with
> devel/arm-none-eabi-newlib installed
> 
> #include <stdio.h>
> 
> int main(int argc, char *argv[]) {
>   return 0;
> }

I elaborate a little more with the hope to understand how to wire things
up the proper way.

devel/arm-none-eabi-newlib is not a dependency of 
devel/arm-none-eabi-gcc
(but it should?). When only devel/arm-none-eabi-gcc is installed
(which btw correctly installs arm-none-eabi-binutils as a dependency)
the compiler is unusable:

% arm-none-eabi-gcc break_arm.c
/usr/local/bin/arm-none-eabi-ld: cannot find crt0.o: No such file or 
directory
/lib/libc.so.7: file not recognized: file format not recognized
collect2: error: ld returned 1 exit status

Do you think this missing port dependency should be fixed or is it ok
to leave it as it is now?


Looking at the missing types more closely, arm-none-eabi-gcc header
search path defaults as follows:
  /usr/local/lib/gcc/arm-none-eabi/11.3.0/include
  /usr/local/lib/gcc/arm-none-eabi/11.3.0/include-fixed
  /usr/local/arm-none-eabi/include
  /usr/include

devel/arm-none-eabi-gcc populates the former two and
devel/arm-none-eabi-newlib populates the third.

Both ports relay on a number of types defined in /usr/include
and those files are opaqued out by files by the same name, but
significantly different content, located in directories appearing
earlier in the search path.

__off_t, __ssize_t, __off64_t, __mbstate_t and __va_list are
defined in the system default header:
/usr/include/sys/_types.h:94:typedef       __int64_t       __ssize_t;    
   /* byte count or error */
/usr/include/sys/_types.h:97:typedef       __int32_t       __ssize_t;    
   /* byte count or error */
/usr/include/sys/_types.h:133:typedef      __int64_t       __off_t;      
   /* file offset */
/usr/include/sys/_types.h:134:typedef      __int64_t       __off64_t;    
   /* file offset (alias) */
/usr/include/sys/_types.h:203:} __mbstate_t;
/usr/include/sys/_types.h:211:typedef      __builtin_va_list       
__va_list;      /* internally known to gcc */

Which is never included because 
/usr/local/arm-none-eabi/include/sys/_types.h
exists and appears earlier in the search path.

Note that newlib's /usr/local/arm-none-eabi/include/sys/_types.h seems
to be partially aware of the problem and does something, but it's not a
full fix:
15:#ifndef __off_t_defined
16:typedef long _off_t;
17:#endif

Note how it checks for __off_defined (two underscores at the beginning 
of
the type name) and defines _off_t (one underscore only).

The file also does similar fixes for a bunch of other types including
__ssize_t, __off64_t and __mbstate_t that pop up while trying to
compile my test .c file: i.e.
it checks for __foo_t and, if not found, defines _foo_t but not __foo_t

Shall I patch newlib's sys/type.h to define also __foo_t, not only 
_foo_t
or is there a bettere way to handle this?


There is an exception: __va_list is not mentioned in newlib's headers
but only system default sys/_types.h, so I suspect this is not an 
isolated
case, and maybe a different approach shall be used? I.e. manually bring 
in
all that is typedef'd in system defaults sys/_types.h and make sure 
there is
a corresponding entry in newlib's version of the same file? Furthermore,
how shall the missing types be defined? The types are defined 
differently
by the system default and newlib.

E.g. __off_t (two underscores) in system default is:
/usr/include/sys/_types.h:133:typedef      __int64_t       __off_t;      
   /* file offset */
and _off_t (one underscore) in newlibs lingo is:
/usr/local/arm-none-eabi/include/sys/_types.h:16-typedef long _off_t;

which might or might not be the same thing.

In any case, this solution smells bad to me, that's why I ask before I 
do anything.

BR,

-- 
José Pérez