-
Most software is not designed for cross-compilation. ~All spec files are not designed for cross-compilation. The procedure must appear to be native compilation as much as possible.
-
Most software which is used during build procedures is not actually a compiler and does not need detailed knowledge of the current arch.
-
Breaking build-dep cycles is very labor intensive. We would like to not do it.
-
riscv64 and x86_64 are both little endian 64-bit ASCII with IEEE floating point. They cannot share solibs but can share nearly everything else.
-
We want to verify that the final system can build itself without hacks. Scaffolding until we have the final system is A-OK.
-
Final RPMs are built in system emulation using unmodified (or all modifications upstreamed) spec files and only riscv64 RPMs. Nonfinal RPMs may be built in user emulation with a mix of riscv64 and x86_64 RPMs, but we would still prefer to not modify the spec files.
-
Build environments for nonfinal RPMs are divided into an "old world" and a "new world". The old world contains x86_64 RPMs; the new world contains riscv64 RPMs (which may be final or nonfinal); the whole thing is run under user emulation x86_64 (reverse user emulation would be possible if we had fast RV64G hardware).
-
Old world and new world are defined by ABI/ISA and which shared libraries are visible. /old and /new are visible globally, each process has bind mounts to make the correct libraries visible. A statically linked program can live in either world regardless of ABI/ISA.
-
If a binary is installed in the old world or the new world, a statically linked shadow is installed in the other world which switches the mount namespace. (This requires setuid root)
-
A LD_PRELOAD shim is installed in the old world to ensure uname(2) consistency. Other hacks will be added as needed.
-
Toolchain must live in the new world because it must see the new-architecture libraries. It could be statically linked or cross-compiled.