Cross Build Progress
2021-02-08
The sysroot/cross-compile build tree is nearly able to build all of HitchHiker now, with only a few packages left to tweak.
- pkg-config: This is messy in general. There is a circular dependency with Glib, satisfied by the pkg-config maintainers incorporating a recent version of Glib directly into the distribution. However, Glib requires extra work to cross compile. I've looked into it but not yet implemented the fixes.
- XML::Parser: Perl was actually able to cross compile successfully to both aarch64 and riscv64 using perl-cross. XML::Parser is a perl module, uses perl during it's build and perl modules in general have their own home baked build system which does not play well with cross compiling. I'm investigating whether it really needs to be in the base system or can be moved to ports.
- Ninja and Meson: may not actually be needed in the base system?
- zstd: Uses a Makefile or Meson for it's build system. I've already dealt with a few projects that built with a plain Makefile and was just putting this off to be honest, as a few of the others required significant reworking to get a functional build.
- iproute2: Another one using it's own home grown configure script which will likely require much manual intervention.
- mandoc: This builds after a fair amount of manual intervention. However, it segfaults on riscv64. Unknown whether this is due to qemu or if it will segfault on real hardware, but not a great sign. I'm looking at porting an earlier man utility from 4.4BSD-lite. Man should be a simple program.
- file: Our file utility, descended from the relatively recent OpenBSD sandboxed file, built fine on intel and Arm architectures, but the original author pulled in some SECCOMP defs that are architecture dependent and failed to account for any architectures besides Intel and Arm. I've hacked the source so that it compiles on Riscv64. However, there appears to be more work to be done to get it fully working on that arch. There were, of course, numerous hiccups along the way. I'll elaborate on a few.
Bzip2 has it's own Makefile based build. It also has a separate Makefile to build the shared version of the library, and even when you do build the shared version it uses the static version for bzip2recover. In true hitchhiker fashion after mucking about with what was already there for a while I wound up just discarding it and imported the source directly into the build tree, substitution our own infrastructure. This required creating hhl.sharedlib.mk, which was overdue anyway. At the moment we're building both shared and static versions of libbz2, and linking the bzip2 and bzip2recover binaries against the shared library.
Recent versions of util-linux include a new utility, hardlink, which links against pcre2 if available. However, the build system detects pcre2 on the host system, not in the sysroot, and there is no provision to manually disable linking against pcre2. Interestingly, there are two competing implementations of the hardlink program, and the one currently in util-linux is potentially going to be replaced as it is not the more fully featured one. There is some interesting discussion of the issue on the mailing list. In the meantime, since it is a potentially useful utility, I just imported the source of the preferred version and am building it using our build infrustructure.
And now, gettext. This one really pissed me off. Recent versions of gettext include libtextstyle, a library for formatting text for display. The included gettext utilities link against libtextstyle. However, the headers don't yet exist at the time the utilities are built, so the only reason the build is not failing for everyone is that they are building against the headers already present on the host system. The libtextstyle subdirectory is not even in the library search path on the command line.
Now, this is just bad practice. It means that if those headers are updated for a new release, then distro packagers will be building against the old headers, potentially causing undefined behavior and random bugs. I only caught it because the build utterly fails in a sysroot environment.
Furthermore, one of the missing headers, included by textstyle.h, is stdbool.h, because for some reason they're worried about building on systems that don't have a working boolean implementation. This is just crazy at this point. It's no wonder GNU projects get bloated.
In the end, I pulled the headers out of the host system, put them in the appropriate directory inside the source directory, compiled, then did a chroot into the sysroot and did a native compile just to be sure that the headers matched. Those headers are now imported into the build tree and are placed into the source directory after running configure, and the Makefile is patched to search the build directory before the system header directory. It's not a full fix that I would push upstream but it works. A full fix would build the headers first, before building the utilities, then link against them. I didn't feel like going that in depth fixing their build.
In a general sense, even though I feel that autotools based builds are often extremely bloated and inefficient, based on the mistakes that I keep fixing in other project's home brewed Makefiles to enable cross compilation (as well as simple things like installing into a DESTDIR) I can really see some of the strengths of autotools. Most of the time, all that is needed to cross compile is setting --host and either passing --sysroot in the CFLAGS or, if supported the the specific package, passing --with-sysroot to configure. That isn't to say that autotools is perfect. Frequently the package maintainers compile tests against the host system or check for library support by looking in /usr/include. After a while you begin to realize that you're literally fixing the same mistake repeatedly, and start to feel despair for the human race. And then it works, and everything is all right again.
Tags for this post:
Programming Milestones Porting RiscV