Subject: Alpine for riscv64

From: Roman Shaposhnik <[email-masked]>
Date: Fri, 23 Apr 2021 20:14:55 -0700

Hi!

long time lurker (and user of Alpine in Linux Foundation's Project EVE)
first time poster here!

Over at Project EVE we're now embarking on a riscv64 port
and it would be super helpful if Alpine had that architecture supported.

Since that's not that case, I started looking into it by using
aports/scripts/bootstrap.sh
and I have few things to report back.

First good news -- after some small amount of patching of aports
I was able to run the script and get myself a riscv64 build environment.
I'm attaching the changes I had to make to accomplish this. These
are mostly workaround and I'd love to collaborate with folks interested
in riscv64 to at least clean these things up.

The workarounds are roughly in the following categories:
   0. stale config.sub (what's an Alpine way of dealing with this?)
   1. nghttp2 binary that is generated with TEXT relocations (not sure
what to do here)
   2. failing to recognize a proper riscv64-alpine-linux-musl so I
have to force riscv64-linux-musl

And finally, here's the most interesting part in all of this -- it turns out
that an initial gcc is lacking libatomic.so and thus a few packages fail.
In order to workaround it I had to:
    1. restructure bootstrap.sh slightly so that a proper gcc gets built
    2. once #1 happens we add gcc and libatomic to build deps
Not sure what's up with this and would love to know if there's a simpler way.

In general, as I said -- I'd love to know if anyone else is also interested
in riscv64 port and what's the best way to collaborate on that.

Thanks,
Roman.

P.S. If you're curious what my next steps are - for EVE I need these
packages:
     https://github.com/lf-edge/eve/blob/master/pkg/alpine/mirrors/3.13/main
diff --git a/main/gcc/APKBUILD b/main/gcc/APKBUILD
index b58d970f24..3762cf5092 100644
--- a/main/gcc/APKBUILD
+++ b/main/gcc/APKBUILD
@@ -23,15 +23,15 @@ replaces="libstdc++ binutils"
 
 : "${LANG_CXX:=true}"
 : "${LANG_D:=true}"
-: "${LANG_OBJC:=true}"
+: "${LANG_OBJC:=false}"
 : "${LANG_GO:=true}"
-: "${LANG_FORTRAN:=true}"
-: "${LANG_ADA:=true}"
+: "${LANG_FORTRAN:=false}"
+: "${LANG_ADA:=false}"
 
 _libgomp=true
 _libgcc=true
 _libatomic=true
-_libitm=true
+_libitm=false
 
 if [ "$CHOST" != "$CTARGET" ]; then
 	if [ "$BOOTSTRAP" = nolibc ]; then
diff --git a/main/pkgconf/APKBUILD b/main/pkgconf/APKBUILD
index 4f39b28d4e..a9db575172 100644
--- a/main/pkgconf/APKBUILD
+++ b/main/pkgconf/APKBUILD
@@ -15,7 +15,7 @@ checkdepends="kyua atf"
 build() {
 	./configure \
 		--build=$CBUILD \
-		--host=$CHOST \
+		--host=riscv64-linux-musl \
 		--prefix=/usr \
 		--sysconfdir=/etc \
 		--mandir=/usr/share/man \
diff --git a/main/isl22/APKBUILD b/main/isl22/APKBUILD
index 31ffbb3cf9..67b01d117c 100644
--- a/main/isl22/APKBUILD
+++ b/main/isl22/APKBUILD
@@ -24,7 +24,7 @@ builddir="$srcdir"/isl-$pkgver
 build() {
 	./configure \
 		--build=$CBUILD \
-		--host=$CHOST \
+		--host=riscv64-linux-musl \
 		--prefix=/usr \
 		--mandir=/usr/share/man \
 		--infodir=/usr/share/info \
diff --git a/main/openssl/APKBUILD b/main/openssl/APKBUILD
index fcc4b6fa5d..b8bcc6e6bf 100644
--- a/main/openssl/APKBUILD
+++ b/main/openssl/APKBUILD
@@ -63,6 +63,7 @@ build() {
 		x86)		_target="linux-elf" ;;
 		x86_64)		_target="linux-x86_64"; _optflags="enable-ec_nistp_64_gcc_128" ;;
 		s390x) 		_target="linux64-s390x";;
+		riscv64) 	_target="linux-generic64";;
 		*)		msg "Unable to determine architecture from (CARCH=$CARCH)" ; return 1 ;;
 	esac
 
@@ -74,7 +75,7 @@ build() {
 		--libdir=lib \
 		--openssldir=/etc/ssl \
 		shared no-zlib $_optflags \
-		no-async no-comp no-idea no-mdc2 no-rc5 no-ec2m \
+		no-asm no-threads no-async no-comp no-idea no-mdc2 no-rc5 no-ec2m \
 		no-sm2 no-sm4 no-ssl2 no-ssl3 no-seed \
 		no-weak-ssl-ciphers \
 		$CPPFLAGS $CFLAGS $LDFLAGS -Wa,--noexecstack
 
diff --git a/main/lvm2/APKBUILD b/main/lvm2/APKBUILD
index 6c78d0cd58..b3f231be23 100644
--- a/main/lvm2/APKBUILD
+++ b/main/lvm2/APKBUILD
@@ -11,7 +11,7 @@ license="GPL-2.0-only LGPL-2.1-only"
 # lvm2 will dlopen libs so we need to add explicit depend
 depends="lvm2-libs=$pkgver-r$pkgrel"
 depends_dev="linux-headers"
-makedepends_build="coreutils"
+makedepends_build="coreutils automake"
 makedepends_host="$depends_dev libaio-dev util-linux-dev"
 makedepends="$makedepends_build $makedepends_host"
 source="https://mirrors.kernel.org/sourceware/lvm2/LVM2.$pkgver.tgz
@@ -46,6 +46,7 @@ build() {
 	export ac_cv_func_malloc_0_nonnull=yes
 	export ac_cv_func_realloc_0_nonnull=yes
 
+	cp /usr/share/abuild/config.sub autoconf/
 	./configure \
 		--build=$CBUILD \
 		--host=$CHOST \
diff --git a/main/cunit/APKBUILD b/main/cunit/APKBUILD
index ef44d83068..3ccd298d82 100644
--- a/main/cunit/APKBUILD
+++ b/main/cunit/APKBUILD
@@ -28,6 +28,7 @@ prepare() {
 
 build() {
 	cd "$builddir"
+	cp /usr/share/abuild/config.sub .
 	./configure \
 		--build=$CBUILD \
 		--host=$CHOST \
diff --git a/main/nghttp2/APKBUILD b/main/nghttp2/APKBUILD
index fd1e637302..c60dcb42aa 100644
--- a/main/nghttp2/APKBUILD
+++ b/main/nghttp2/APKBUILD
@@ -50,6 +50,7 @@ build() {
 		--enable-static \
 		--enable-app
 	make
+	printf "#!/bin/sh\ntrue\n" > src/.libs/nghttpx
 }
 
 package() {
diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh
index 8f305a4eaf..641237041f 100755
--- a/scripts/bootstrap.sh
+++ b/scripts/bootstrap.sh
@@ -60,7 +60,7 @@ fi
 if [ ! -d "$CBUILDROOT" ]; then
 	msg "Creating sysroot in $CBUILDROOT"
 	mkdir -p "$CBUILDROOT/etc/apk/keys"
-	cp -a /etc/apk/keys/* "$CBUILDROOT/etc/apk/keys"
+	cp -a /etc/apk/keys/* ~/.abuild/*.pub "$CBUILDROOT/etc/apk/keys"
 	${SUDO_APK} add --quiet --initdb --arch $TARGET_ARCH --root $CBUILDROOT
 fi
 
@@ -88,11 +88,12 @@ CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname gcc) abuild -r
 
 # Cross build-base
 CTARGET=$TARGET_ARCH BOOTSTRAP=nobase APKBUILD=$(apkbuildname build-base) abuild -r
+exit 0
 
 msg "Cross building base system"
 
 # Implicit dependencies for early targets
 EXTRADEPENDS_TARGET="libgcc libstdc++ musl-dev"
 
 # ordered cross-build
 for PKG in fortify-headers linux-headers musl libc-dev pkgconf zlib \
@@ -96,9 +96,10 @@ EXTRADEPENDS_TARGET="libgcc libstdc++ musl-dev"
 
 # ordered cross-build
 for PKG in fortify-headers linux-headers musl libc-dev pkgconf zlib \
-	   openssl ca-certificates libmd libbsd libtls-standalone busybox busybox-initscripts binutils make \
+	   openssl ca-certificates libmd \
+	   gmp mpfr4 mpc1 isl22 cloog libucontext binutils gcc \
+	   libbsd libtls-standalone busybox busybox-initscripts make \
 	   apk-tools file \
-	   gmp mpfr4 mpc1 isl22 cloog libucontext gcc \
 	   openrc alpine-conf alpine-baselayout alpine-keys alpine-base patch build-base \
 	   attr libcap acl fakeroot tar \
 	   lzip abuild ncurses libedit openssh \
@@ -110,7 +111,7 @@ for PKG in fortify-headers linux-headers musl libc-dev pkgconf zlib \
 	   libxml2 llvm10 community/rust \
 	   $KERNEL_PKG ; do
 
-	EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET" \
+	EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET"  EXTRADEPENDS_BUILD="libatomic gcc-$TARGET_ARCH g++-$TARGET_ARCH" \
 	CHOST=$TARGET_ARCH BOOTSTRAP=bootimage APKBUILD=$(apkbuildname $PKG) abuild -r
 
 	case "$PKG" in
@@ -118,6 +119,11 @@ for PKG in fortify-headers linux-headers musl libc-dev pkgconf zlib \
 		# Additional implicit dependencies once built
 		EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET $PKG"
 		;;
+	gcc)
+		# After gcc full build, we get to have libatomic that a low of packages require
+		# The reason we need gcc as well is because .so is there, not in libatomic
+		EXTRADEPENDS_TARGET="libatomic gcc $EXTRADEPENDS_TARGET"
+		;;
 	build-base)
 		# After build-base, that alone is sufficient dependency in the target
 		EXTRADEPENDS_TARGET="busybox $PKG"

---

From: Ariadne Conill <[email-masked]>
Date: Fri, 23 Apr 2021 22:25:38 -0600 (MDT)

Hello,

>   0. stale config.sub (what's an Alpine way of dealing with this?)

Something like:

prepare() {
   default_prepare
   update_config_sub
}

>   1. nghttp2 binary that is generated with TEXT relocations (not sure

I'm not sure.  Do you have a build log?

> have to force riscv64-linux-musl

What is failing to recogize that triplet?  LLVM?  We might need to add it 
there still.

> Not sure what's up with this and would love to know if there's a simpler way.

bootstrap.sh is intended to get a runtime environment up on a host, so you 
can build the rest of the distribution.  Accordingly, we don't presently 
build libatomic when crosscompiling, as we don't need it.

But I think we can change that if it would be helpful.

> in riscv64 port and what's the best way to collaborate on that.

Drew DeVault was working on riscv64, but I'm not sure if he still is 
working on it.  We found that running on physical hardware would be too 
slow (the builder would have issues keeping up with the other ones).

So an option might be to do something with qemu.  The Alpine community has 
some experience with that via postmarketOS and the initial mips64 port.

Ariadne

---

From: Roman Shaposhnik <[email-masked]>
Date: Fri, 23 Apr 2021 22:06:21 -0700

Somehow I have a feeling that the mailing list ate my attachment --
can someone please confirm/deny?

More comments inline:

> >   0. stale config.sub (what's an Alpine way of dealing with this?)

Awesome! Let me try it.

> I'm not sure.  Do you have a build log?

I am thinking that it actually would be helpful to build this on my GitHub
via GitHub actions so we can all have access to the logs (and missing
attachments ;-))

> What is failing to recogize that triplet?  LLVM?  We might need to add it

configure (but I haven't dug into why and what could be stale)

> But I think we can change that if it would be helpful.

I get that -- but the problem is -- without libatomic in the initial gcc or the
trick that I play with the patch below -- it doesn't build. In fact, I
think patching
bootstrap.sh like that would be helpful anyway -- I can submit a PR.

What do you all think?

> some experience with that via postmarketOS and the initial mips64 port.

Got it!

Thanks,
Roman.

And here's the bootstrap.sh patch:

 # ordered cross-build
 for PKG in fortify-headers linux-headers musl libc-dev pkgconf zlib \
-          openssl ca-certificates libmd libbsd libtls-standalone
busybox busybox-initscripts binutils make \
+          openssl ca-certificates libmd \
+          gmp mpfr4 mpc1 isl22 cloog libucontext binutils gcc \
+          libbsd libtls-standalone busybox busybox-initscripts make \
           apk-tools file \
-          gmp mpfr4 mpc1 isl22 cloog libucontext gcc \
           openrc alpine-conf alpine-baselayout alpine-keys
alpine-base patch build-base \
           attr libcap acl fakeroot tar \
           lzip abuild ncurses libedit openssh \
@@ -110,7 +111,7 @@ for PKG in fortify-headers linux-headers musl
libc-dev pkgconf zlib \
           libxml2 llvm10 community/rust \
           $KERNEL_PKG ; do

-       EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET" \
+       EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET"
EXTRADEPENDS_BUILD="libatomic gcc-$TARGET_ARCH g++-$TARGET_ARCH" \
        CHOST=$TARGET_ARCH BOOTSTRAP=bootimage APKBUILD=$(apkbuildname
$PKG) abuild -r

        case "$PKG" in
@@ -118,6 +119,11 @@ for PKG in fortify-headers linux-headers musl
libc-dev pkgconf zlib \
                # Additional implicit dependencies once built
                EXTRADEPENDS_TARGET="$EXTRADEPENDS_TARGET $PKG"
                ;;
+       gcc)
+               # After gcc full build, we get to have libatomic that
a low of packages require
+               # The reason we need gcc as well is because .so is
there, not in libatomic
+               EXTRADEPENDS_TARGET="libatomic gcc $EXTRADEPENDS_TARGET"
+               ;;
        build-base)
                # After build-base, that alone is sufficient
dependency in the target
                EXTRADEPENDS_TARGET="busybox $PKG"

---

From: Ariadne Conill <[email-masked]>
Date: Fri, 23 Apr 2021 23:54:33 -0600 (MDT)

Hi,

> can someone please confirm/deny?

No, it was present.

> configure (but I haven't dug into why and what could be stale)

I think based on your patch, update_config_sub is what is needed there 
too.  I'll be sure to update the bundled config.guess/config.sub when I 
cut another release of pkgconf.

> bootstrap.sh like that would be helpful anyway -- I can submit a PR.

To clarify, are you using bootstrap.sh from v3.13 or from edge?  We only 
support bootstrap.sh on edge, as it's mainly intended to be an internal 
development tool.

Ariadne

---

From: Roman Shaposhnik <[email-masked]>
Date: Mon, 26 Apr 2021 15:04:24 -0700

> support bootstrap.sh on edge, as it's mainly intended to be an internal

Yes I am. Btw, I've pushed all my build steps into a single Dockerfile
    https://github.com/rvs/alpine-riscv64
so that:
  1. we can all be sure what we're talking about
  2. I actually end up with a container that I can use as riscv64
build environment

Btw, there's a GitHub action that is running the build so that build logs are
alway available:
    https://github.com/rvs/alpine-riscv64/actions/runs/787052838

Thanks,
Roman.