probonopd / static-tools

Building static binaries of some tools using an Alpine chroot with musl
MIT License
28 stars 13 forks source link

Can we get rid of chroot and containers? #18

Open probonopd opened 2 years ago

probonopd commented 2 years ago

@Tachi107 could we go back to using chroot instead of premade Docker containers, i.e., run chroot inside qemu-static?

Similar to https://github.com/probonopd/static-tools/blob/f167a798cb35e5f4d0721c468e727def26306e2a/build.sh

This way we could use everything provided by Alpine Linux, not just what happens to be available from https://github.com/uraimo?tab=packages&repo_name=run-on-arch-action.

For example, we need alpine_edge but that is not available in https://github.com/uraimo/run-on-arch-action.

Also, by using chroot, we can easily run it on our local developer machines without having to set up Docker.

Tachi107 commented 2 years ago

For example, we need alpine_edge but that is not available in https://github.com/uraimo/run-on-arch-action.

I wouldn't use Alpine Edge, because as the name implies it could break stuff. If you need a static library that's not provided by the repos you can simply build it from source and install it (like I did with liblmdb)

Also, by using chroot, we can easily run it on our local developer machines without having to set up Docker.

You can use a chroot locally if you want to, the end result should be the same

Edit: I made this repo work with a couple of PRs, but as I already said it is not a robust and well made solution. As you can see, every time you add something to the build process everything breaks.

If this were my project, I would:

Tachi107 commented 2 years ago

Quick info: as https://github.com/mesonbuild/meson/pull/9603 has been merged, you'll no longer need modify upstream files with sed to insert static: true in dependency() calls; Meson 0.63.0 will make this as simple as passing --prefer-static when invoking meson setup build :D

Edit: by the way, the sed expression is incomplete and won't work in all cases. I've been able to write a more complete regex using perl, here: https://github.com/Tachi107/static-bin/blob/546401adcebeba2ac4241980a3e8b20c7d3a0714/.github/workflows/static.yaml#L73 - there are a few comments describing why and when sed doesn't work, but unfortunately are in Italian and you would probably need to translate them :/

probonopd commented 2 years ago

I think I found a really exciting new way to cross-compile things using zig as a cc substitute to statically link executables using musl libc. Doing it this way has the advantage that no Docker container or chroots are needed for building multiple architectures.

With the help of @kristoff-it and @andrewrk I was able to use this in go-appimage for Go programs that need Cgo. Which I think is quite awesome!

For this repository, the task is a bit more challenging because unlike go-appimage the executables we are building in this repository have C dependencies outside of what comes with musl libc. We are currently getting most of these dependencies from Alpine Linux, which comes for *-static packages.

The question is whether we can somehow continue to use dependencies downloaded from Alpine Linux but using zig in x86_64 to do the actual compiling for all architectures. Otherwise we would have to build all libraries ourselves, which I imagine would increase build times quite a bit.

Tachi107 commented 2 years ago

I think I found a really exciting new way to cross-compile things using zig as a cc substitute to statically link executables using musl libc. Doing it this way has the advantage that no Docker container or chroots are needed for building multiple architectures.

How is cross compiling with zig different than cross compiling with GCC / Meson?

If what zig does is simply statically link musl libc into the executable I don't see how it could help here - you already accomplish this with CFLAGS=-no-pie LDFLAGS=-static or CFLAGS=-static-pie LDFLAGS=-static.

One thing that could really help though is cross compilation. With it, no emulators would be required, and the build process would be significantly simplified.

I don't know how well Alpine handles cross-compilation, but a quick web search suggested me that it doesn't support it well. Again, I suggest you to look into Debian and its Multiarch support- Alpine is best suited for containers.

probonopd commented 2 years ago

How is cross compiling with zig different than cross compiling with GCC / Meson?

I don't know, as I have never tried cross-compiling with GCC and Meson.

One thing that could really help though is cross compilation. With it, no emulators would be required, and the build process would be significantly simplified.

That's what I meant!

eli-schwartz commented 2 years ago

Using ccache is also an excellent way to decrease build times in repetition... and Meson already defaults to ccache if it is installed and you don't specify your own $CC. :D

Alternatively, it may make sense to build dependencies and cache them (for example as distro packages to quickly install). I'm reminded that Meson's CI runners regularly build and publish docker containers that install various packages and build+install other things from source, so that all that needs to be done is pull down the fedora/arch/opensuse image and be all set to go.

probonopd commented 2 years ago

Actually, I want to get away from complicated build systems like Meson and from containers like Docker and make things simpler, not more complicated...

azubieta commented 2 years ago

yes you can, check: https://github.com/azubieta/appimage-runtime you just need to translate the cmake code to your scripts.