Jump to page: 1 24  
Page
Thread overview
Cross-compiling a static binary from GitHub Actions
Sep 25, 2021
Vladimir Panteleev
Sep 25, 2021
kinke
Sep 25, 2021
Vladimir Panteleev
Sep 25, 2021
kinke
Sep 25, 2021
kinke
Sep 25, 2021
Vladimir Panteleev
Sep 25, 2021
kinke
Sep 26, 2021
Vladimir Panteleev
Sep 26, 2021
Vladimir Panteleev
Sep 26, 2021
Vladimir Panteleev
Sep 26, 2021
Vladimir Panteleev
Sep 26, 2021
kinke
Sep 26, 2021
Vladimir Panteleev
Sep 27, 2021
kinke
Sep 27, 2021
Vladimir Panteleev
Oct 01, 2021
Vladimir Panteleev
Oct 01, 2021
Vladimir Panteleev
Oct 01, 2021
kinke
Oct 01, 2021
Vladimir Panteleev
Oct 01, 2021
kinke
Oct 01, 2021
Vladimir Panteleev
Oct 01, 2021
kinke
Oct 01, 2021
kinke
Oct 01, 2021
Vladimir Panteleev
Sep 25, 2021
Vladimir Panteleev
Sep 25, 2021
Vladimir Panteleev
Sep 25, 2021
kinke
Sep 26, 2021
Jacob Carlborg
Sep 27, 2021
Vladimir Panteleev
Sep 27, 2021
Paolo Invernizzi
Sep 28, 2021
Kagamin
September 25, 2021

Hi,

The problem: I made a tool written in D, but some people are having trouble building/running it on non-x86_64 architectures across various distributions. (I managed to build a static binary for x86_64.)

My goal: build a static binary of a D program for Linux-AArch64 from GitHub Actions (as an artifact).

Does anyone have any advice in this direction?

I found https://wiki.dlang.org/Cross-compiling_with_LDC , which is a good resource, but leaves open the question for how better to set up the toolchain, dependency pinning, as well as obtaining / building the static libraries for C dependencies (such as glibc).

Maybe someone has a Dockerfile on Nix script which demonstrates cross-compiling static binaries of D programs?

Thanks!

September 25, 2021

On Saturday, 25 September 2021 at 07:59:08 UTC, Vladimir Panteleev wrote:

>

(I managed to build a static binary for x86_64.)

Linked statically against glibc? I thought that's not really possible, and one would need to resort to another libc like musl for fully statically linked binaries. Could you link to the repo of the tool?

That said, linking dynamically against a rather old glibc seems to work in many cases. The official LDC binaries do that and are built on Ubuntu 18.04 for that reason; they seem to work on most distros, excl. musl-only Alpine. So I'd expect cross-compiling on Ubuntu 18 and using its cross-gcc toolchain to work for most people.

Another (potentially more flexible) option could be using Travis for native AArch64 compilation - again, that's what LDC does (https://github.com/ldc-developers/ldc/blob/master/.travis.yml). They have a Ubuntu 18.04 image, and the D integration still works, on AArch64 too. Their AArch64 service is sponsored by ARM and doesn't cost any credits for public open-source projects.

September 25, 2021

On Saturday, 25 September 2021 at 16:12:52 UTC, kinke wrote:

>

On Saturday, 25 September 2021 at 07:59:08 UTC, Vladimir Panteleev wrote:

>

(I managed to build a static binary for x86_64.)

Linked statically against glibc? I thought that's not really possible, and one would need to resort to another libc like musl for fully statically linked binaries. Could you link to the repo of the tool?

Sure:

https://github.com/CyberShadow/btdu

And here is the script I use to link the x86_64 binary:

https://gist.github.com/CyberShadow/df49946888ad1ea683729f57c5e59d8a

During linking I see warnings such as:

warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

but I haven't paid them mind because the application is not using networking (or at least name resolution).

ldd says "not a dynamic executable", so I guess that makes it fully static?

>

That said, linking dynamically against a rather old glibc seems to work in many cases. The official LDC binaries do that and are built on Ubuntu 18.04 for that reason; they seem to work on most distros, excl. musl-only Alpine. So I'd expect cross-compiling on Ubuntu 18 and using its cross-gcc toolchain to work for most people.

My understanding is that you can't really pick-and-choose which libraries you want to link statically vs. dynamically (or at least, the toolchain didn't let me). I also depend on libncurses, which has broken its ABI in the past, so I would like to avoid that dependency if possible for the stand-alone binary.

>

Another (potentially more flexible) option could be using Travis for native AArch64 compilation - again, that's what LDC does (https://github.com/ldc-developers/ldc/blob/master/.travis.yml). They have a Ubuntu 18.04 image, and the D integration still works, on AArch64 too. Their AArch64 service is sponsored by ARM and doesn't cost any credits for public open-source projects.

That's interesting, thanks - though I'm not sure why it would be considered more flexible, as it would create a rather strong dependency on a third-party service with a tumultuous track record :)

September 25, 2021

On Saturday, 25 September 2021 at 16:23:09 UTC, Vladimir Panteleev wrote:

>

That's interesting, thanks - though I'm not sure why it would be considered more flexible, as it would create a rather strong dependency on a third-party service with a tumultuous track record :)

Flexible as in being able to run any unittests, install a native musl toolchain etc., plus I'd expect stuff like -L-l:libtermcap.a to work there as well (i.e., static libs being available just like on an x64 image).

September 25, 2021

On Saturday, 25 September 2021 at 16:28:16 UTC, kinke wrote:

>

plus I'd expect stuff like -L-l:libtermcap.a to work there as well (i.e., static libs being available just like on an x64 image).

According to https://packages.ubuntu.com/bionic/arm64/libtinfo-dev/filelist, the static libs are probably generally available. So something like

dpkg --add-architecture arm64
apt-get update
apt-get install libtinfo-dev:arm64

might be sufficient to make them available for the gcc-aarch64-linux-gnu toolchain as well.

September 25, 2021

On Saturday, 25 September 2021 at 16:35:33 UTC, kinke wrote:

>

According to https://packages.ubuntu.com/bionic/arm64/libtinfo-dev/filelist, the static libs are probably generally available. So something like

dpkg --add-architecture arm64
apt-get update
apt-get install libtinfo-dev:arm64

might be sufficient to make them available for the gcc-aarch64-linux-gnu toolchain as well.

That looked promising so I tried it out.

Ubuntu seems to require some non-trivial edits to /etc/apt/sources.list in order to add arm64, so I proceeded with Debian.

On Bullseye, I got linking errors with undefined references to 'deflateInit2_', and no matter how I tried to add libz they wouldn't go away, so I proceeded with Buster.

The Dub version packaged in Buster is too old and doesn't work any more, so I used the installation script from the website to install ldc+dub.

This gets me to a point where I can build the x86_64 binary. But, if I try "-mtriple arm64-linux-gnu", I get "/usr/bin/ld.gold: fatal error: btdu-static-arm64.o: unsupported ELF machine number 183". Not sure how to proceed from here, fiddled with --linker but couldn't get anything to work.

Say, shouldn't it be using lld anyway? I tried installing lld, but that didn't work because it didn't match the LLVM version in ldc.

Here is what I have:
https://github.com/CyberShadow/btdu/tree/next/release

September 25, 2021

On Saturday, 25 September 2021 at 16:28:16 UTC, kinke wrote:

>

On Saturday, 25 September 2021 at 16:23:09 UTC, Vladimir Panteleev wrote:

>

That's interesting, thanks - though I'm not sure why it would be considered more flexible, as it would create a rather strong dependency on a third-party service with a tumultuous track record :)

Flexible as in being able to run any unittests, install a native musl toolchain etc., plus I'd expect stuff like -L-l:libtermcap.a to work there as well (i.e., static libs being available just like on an x64 image).

Got it. I guess some qemu-based setup would achieve the same thing (with a LOT more fiddling up front).

Speaking of, I found this crazy wizardry which looks quite interesting:

https://github.com/multiarch/qemu-user-static

September 25, 2021

On Saturday, 25 September 2021 at 18:31:27 UTC, Vladimir Panteleev wrote:

>

Speaking of, I found this crazy wizardry which looks quite interesting:

https://github.com/multiarch/qemu-user-static

I played around with it.

  1. It works. It's amazing. I guess it's a bit like Rosetta for Linux.

  2. It's slow (about 8x). Probably don't try to build LLVM inside it.

  3. There seems to be some problem with creating processes using std.process. Everything just segfaults. This prevents D tools like Dub from doing pretty much anything.

September 25, 2021

On Saturday, 25 September 2021 at 19:31:40 UTC, Vladimir Panteleev wrote:

>
  1. It's slow (about 8x). Probably don't try to build LLVM inside it.

Lol yeah - I used to build LLVM in qemu for armhf, that took like 3 full days. Later qemu versions seemed to be able to use 3 host CPU cores for emulating 3 virtual cores => down to 'only' 24 hours. ;)

September 25, 2021

On Saturday, 25 September 2021 at 18:08:44 UTC, Vladimir Panteleev wrote:

>

This gets me to a point where I can build the x86_64 binary. But, if I try "-mtriple arm64-linux-gnu", I get "/usr/bin/ld.gold: fatal error: btdu-static-arm64.o: unsupported ELF machine number 183". Not sure how to proceed from here, fiddled with --linker but couldn't get anything to work.

I assume you've skipped the https://wiki.dlang.org/Cross-compiling_with_LDC#Tweaking_the_LDC_configuration_file part and expect passing -mtriple to be sufficient for linking as well. In that case, read that section again - you'll need to pass -gcc=aarch64-linux-gnu-gcc for LDC to invoke the cross-gcc as linker driver. And specify the AArch64 druntime/Phobos dir via -L (but the linker might still complain about the x64 libs dir specified in the default ldc2.conf section). [ldc2 -v shows the linker cmdline for troubleshooting.]

« First   ‹ Prev
1 2 3 4