techknowlogick / xgo

Go CGO cross compiler
MIT License
478 stars 79 forks source link

Newest xgo fails for arm builds #256

Closed kolaente closed 2 weeks ago

kolaente commented 3 weeks ago

Using the techknowlogick/xgo:latest docker image to build fails with this issue:

cgo: C compiler "arm-linux-gnueabihf-gcc" not found: exec: "arm-linux-gnueabihf-gcc": executable file not found in $PATH
2024/11/02 08:47:57 Failed to cross compile package: exit status 1.

Full run here: https://drone.kolaente.de/vikunja/vikunja/8996/3/10

Tag 1.21.x seems to work, now checking with 1.22.x.

kolaente commented 3 weeks ago

Looks like 1.22.x does not work either https://drone.kolaente.de/vikunja/vikunja/9008/3/10

kolaente commented 3 weeks ago

I wonder if this is related to https://github.com/techknowlogick/xgo/pull/255 ?

pat-s commented 3 weeks ago

Likely yes. I can try to take a stab tomorrow, the library per se should be installed, if not it should be a quick fix.

(you can of course also have a look yourself by checking the libs and paths in the image)

pat-s commented 2 weeks ago

So arm-linux-gnueabihf-gcc is only missing in the amd64 variant.

The following is happening:

when install gcc-arm-linux-gnueabihf on amd64, gcc-multilib is being removed:

The following additional packages will be installed:
  gcc-13-arm-linux-gnueabihf
Suggested packages:
  gcc-13-doc gcc-13-locales flex bison gdb-arm-linux-gnueabihf gcc-doc
The following packages will be REMOVED:
  gcc-multilib
The following NEW packages will be installed:
  gcc-13-arm-linux-gnueabihf gcc-arm-linux-gnueabihf

When removing gcc-multilib, we likely need to install the arch-specific multilib packages individually.

The conflict of gcc-multilib and the aarch64 compilers on amd64 is actually a known bug.

In addition, we should probably use aarch64-linux-gnu-gcc (64 bit) instead of arm-linux-gnueabi-gcc (32 bit) as discussed here.

techknowlogick commented 2 weeks ago

@kolaente did the recent merges work for you?

kolaente commented 2 weeks ago

Seems like now the linux/386 builds are failing:

In file included from _cgo_export.c:3:

/usr/include/stdlib.h:26:10: fatal error: bits/libc-header-start.h: No such file or directory

   26 | #include <bits/libc-header-start.h>

      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~

compilation terminated.

https://drone.kolaente.de/vikunja/vikunja/9040/3/10

kolaente commented 2 weeks ago

Looks like the xgo version was not the latest in my go.mod file - I've now updated this, but it still fails with the same error: https://drone.kolaente.de/vikunja/vikunja/9048/3/10

It seems to work locally though, not sure what the issue is here.

pat-s commented 2 weeks ago

Can you provide a snippet to test locally? Makes life a bit easier for me :)

Did you by chance search for the error message? It often yields the library which provides the missing headers.

kolaente commented 2 weeks ago

Seems to happen only when starting xgo from its own docker image. Here's what I found to be working to reproduce the error:

(you need to clone Vikunja (from https://kolaente.dev/vikunja/vikunja.git) and have mage installed)

cd vikunja
mage -compile mage-static
docker run -v $PWD:/app -it --entrypoint bash techknowlogick/xgo:go-1.23.x

# inside the docker container
cd /app
./mage-static release:linux

Interestingly, when I run the command that mage generates manually, in the docker container, I get a different error:

$ /usr/bin/xgo -dest /app/dist/binaries -tags netgo  -ldflags -linkmode external -extldflags "-static" -X "code.vikunja.io/api/pkg/version.Version=v0.^C.1-422-d6194b8f10" -X "main.Tags=" -targets linux/* -out vikunja-unstable /app

Cross compiling external...
Fetching main repository external...
go: -d flag is deprecated. -d=true is a no-op
go: modules disabled by GO111MODULE=off; see 'go help modules'
/build.sh: line 114: cd: /go/src/external: No such file or directory
2024/11/05 18:11:36 Failed to cross compile package: exit status 1.
kolaente commented 2 weeks ago

It seems to work when I install gcc-multilib in the container. That will then uninstall a bunch of other libraries and install gcc-13-multilib gcc-multilib lib32asan8 lib32atomic1 lib32gcc-13-dev lib32gomp1 lib32itm1 lib32quadmath0 lib32ubsan1 libc6-dev-i386 libc6-dev-x32 libc6-x32 libx32asan8 libx32atomic1 libx32gcc-13-dev libx32gcc-s1 libx32gomp1 libx32itm1 libx32quadmath0 libx32stdc++6 libx32ubsan1 (based on this stackoverflow response). Will do a few more checks and then send a PR.

pat-s commented 2 weeks ago

This won't work, see my previous comment

The conflict of gcc-multilib and the aarch64 compilers on amd64 is actually a known bug.

Essentially, there are arch-specific versions of all gcc-multilib-* packages besides one for lib32*. I don't know why but it seems there won't be any in the future and the conflict mentioned above won't be solved either (given the many years this issue exists and 32-bit being practically dead).

I wonder: is 32-bit support still needed? I see you built them but are they actually used by anyone? AFAIK even Raspberry PIs are meanwhile 64 bit (for a while).

It looks like that we can't achieve both arm64 build and amd64 32-bit builds.

kolaente commented 2 weeks ago

Yeah I also thought about just not releasing 32 bit builds. I think this is a reasonable way to go, and then seeing if someone even needs 32 bit builds. If that's the case, (and they can't reasonably compile from source themselves) I think the only way to support both is with a different image which only contains the 32 bit libs. That would of course complicate things more, better avoid it.

Removing the 32 bit builds and building everything else, I noticed all mips variants and riscv64 now failing. It seems like these packages must be installed in the docker image in order for them to work:

gcc-9-mipsel-linux-gnu
gcc-9-mips-linux-gnu
gcc-9-mips64-linux-gnuabi64
gcc-9-mips64el-linux-gnuabi64
gcc-9-riscv64-linux-gnu

With these installed, everything builds fine. Including the arm builds. I'll send a PR.

kolaente commented 2 weeks ago

PR: https://github.com/techknowlogick/xgo/pull/262

pat-s commented 2 weeks ago

It seems like these packages must be installed in the docker image in order for them to work:

Yes, this can very well be as due to the amount of arch-specific libs I likely didn't catch all of them. Thanks for checking and applying an immediate fix!

As said, I think to move forward it is reasonable to drop 32-bit to include arm64 as this reflects much more current user needs.