oasislinux / oasis

a small statically-linked linux system
Other
2.75k stars 84 forks source link

Oasis (swc, vis, xz) not compiling under cproc (use of volatiles & flexible array members) #62

Open xphung opened 1 year ago

xphung commented 1 year ago

Hi, I'd like to help where I can with getting oasis to compile with cproc, as it preserves the traditions of "original" unix which otherwise have been lost in modern linux (excessive use of dynamic linking, excessive focus on optimising machine code to the zillionth degree, excessive use of c++, excessive use of binary distribution as source code for complex packages are no easily longer comprehensible).

I get the following cproc compiler errors for xz, vis & swc, which I understand are meant to compile with cproc:

pkg/swc/src/cursor/convert_font.c:109:15: struct member contains flexible array member pkg/xz/src/src/xz/message.c:97:31: volatile store not yet supported pkg/vis/src/vis.c:832:24: volatile store not yet supported

(There might be more errors but I stopped there).

My cproc version is 995d5b48b1, swc is 32905f16ca, xz is 5.2.5

Also, I don't fully understand the oasis build system yet (not sure where $cc is being set), so at the moment I am activating cproc by replacing the rules.ninja cc rule (line 7 in rules.ninja) to directly execute cproc. Is there a better way to configure the oasis build system to use cproc instead of gcc and do I need to make any changes to CFLAGS (at present set to -Os -pipe)?

michaelforney commented 1 year ago

Hi, I'd like to help where I can with getting oasis to compile with cproc, as it preserves the traditions of "original" unix which otherwise have been lost in modern linux (excessive use of dynamic linking, excessive focus on optimising machine code to the zillionth degree, excessive use of c++, excessive use of binary distribution as source code for complex packages are no easily longer comprehensible).

I get the following cproc compiler errors for xz, vis & swc, which I understand are meant to compile with cproc:

pkg/swc/src/cursor/convert_font.c:109:15: struct member contains flexible array member

This is a tool used to generate sources, so is typically compiled for the system building oasis rather than the target system. I typically leave host.cc at the default of just cc (i.e. gcc), so I hadn't hit that error.

The problem is that the convert_font program uses a union of two structs with flexible array members, which is not allowed in standard C. Fixing it would be a little involved, but is doable. It looks like the program is reading files directly into C structs, which is problematic in several ways (portability, endianness, etc). The program is pretty short, so maybe the best option would be to just rewrite it.

pkg/xz/src/src/xz/message.c:97:31: volatile store not yet supported pkg/vis/src/vis.c:832:24: volatile store not yet supported

The volatile error can be worked around by adding -D volatile= to target.cflags.

qbe doesn't yet support volatile loads and stores, but it is pretty safe to work around it this way since I don't think qbe will optimize out non-stack loads/stores (which is where volatile is typically used, and is indeed the case for the above uses).

Also, I don't fully understand the oasis build system yet (not sure where $cc is being set), so at the moment I am activating cproc by replacing the rules.ninja cc rule (line 7 in rules.ninja) to directly execute cproc. Is there a better way to configure the oasis build system to use cproc instead of gcc and do I need to make any changes to CFLAGS (at present set to -Os -pipe)?

The best way to test with cproc is to modify the target table in config.lua and add an entry cc='cproc'.

cc is set in the toolchain function defined in ninja.lua as follows:

set('cc', tc.cc or (tc.platform and tc.platform..'-cc') or 'cc')

So if you don't set cc or platform, it is cc. If you set platform='x86_64-linux-musl', but not cc, it is x86_64-linux-musl-cc, and if you set cc, then it uses the value you set it to.

xphung commented 1 year ago

Thanks! I now managed to get the cproc toolchain to compile itself, and (sort of) self-host. I haven't done anything further swc/velox/wayland yet. (At this stage I'm doing more testing of toolchain itself)

I have also managed to get the musl-gcc wrapper to bootstrap the 1st cproc executable, so I avoided the need to build/use the musl cross compiler.

A few of the patches I needed to make to get the cproc-based toolchain to compile were:

  1. atomics and SSE intrinsics needed to be disabled in various pkg level config.h's (no suprise here, these omissions well documented in cproc README).

  2. cproc is very strict in forbidding semicolons after function declarations - this tripped up python numerous times and then even when I fixed that aspect of the python code, the fact long double isn't supported has made me put python into the "too hard" basket (for now). (Python also uses computed goto's but this is configurable out of the build),

  3. binutils v2.39 onwards has introduced a dependence on GCC C language extensions, I had to rewrite this line in the function print_insn(), located in the file opcodes/i386-dis.c:

    
    instr_info ins = {
     .op_index[0 ... MAX_OPERANDS - 1] = -1,
     ...
    }

I replaced the above with a loop to initialise the -1 value across the 0...MAX_OPERANDS range instead of relying on the GNU extension.  This is new to v2.39, it's not present in v2.38 and seems to be the only GNU C extension used in binutils.

I don't know if it is worthwhile contacting the binutils (and gcc!) team to alert them to this?  It seems to go against the rest of the binutils code base, which doesn't rely on GNU extensions (maybe it was something that slipped in accidentally?).

In theory gcc -std=c17 should be reporting an error for this code, but when I use gcc -std=c17, the gcc compiler *doesn't* complain.  This seems to be a bug in gcc, unless I have missed the introduction of array range initializers in the C standard spec?