Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build static executable for linux aarch64 #3866

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

wolfgangwalther
Copy link
Member

@wolfgangwalther wolfgangwalther commented Jan 19, 2025

This is based on #3865, so the first few commits are from there.

Right now, this is a POC: What happens when we remove all the Template Haskell, update to GHC 9.6/9.8, and then try building the static aarch64 executable again?

This happens:

% file /nix/store/[...]-postgrest-static-aarch64-unknown-linux-musl-12.3/bin/postgrest
/nix/store/[...]-postgrest-static-aarch64-unknown-linux-musl-12.3/bin/postgrest:
  ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, stripped

Once we have that, we could once more simplify our docker image and ship the minimal, single executable for both platforms. Drastically reduced size.

I also tried to build the static executable on aarch64-darwin and x86_64-freebsd. There's still a bit more work to do for those, but it looks much better than... a year ago. In any case, we need to do our part first.

In #3597 I introduced neat-interpolation as the quasi quoter, because it cross-compiles better. It does - but any project actually using it, will still have the same "external interpreter" problem that any Template Haskell causes. So the only way forward is to remove all use of Quasi Quoters. Yes - the change look a bit ugly, with all the quotes etc. - but that's the best we can do right now.

GHC 9.12 has native multiline strings, which could go a long way already. We're still a bit away from making 9.12 our minimum version, though. There's also a GHC proposal for native string interpolation, which would give us everything we need, once agreed on and implemented. But yeah - even further out in the future.

Let's see how long we need to replace OpenAPI - maybe native string interpolation is already widely supported by then ;).

This has been EOL since November and has been dropped from nixpkgs.
Instead of rolling our own, we can use some tooling from nix / nixpkgs.

We drop the "statically linked" check, because our goal is to compile
mostly-static executables to darwin, too. However, those will never be
fully static, because they always link to the platform's libc.
We have fixed the static build of PostgreSQL upstream, so we don't need
our separate overlay anymore. One more step towards building a static
executable on other platforms.
This way we benefit from NixOS' binary cache to deliver GHC for us and
don't need to cache it ourselves.

This will become relevant once we do that for more platforms.
While neat-interpolation builds fine in the static overlay, we still
can't actually *use* it for cross-compilation. Every quasi quotation
needs to execute Template Haskell during compilation, period.

Thus, get rid of it.

Currently, we keep heredoc for the test-suite. It would probably be a
**huge** pain to remove all quasi quotation from the spec tests, so we
don't even need to bother with that. As long as we can build the static
executable we should be good.
@steve-chavez
Copy link
Member

So the only way forward is to remove all use of Quasi Quoters. Yes - the change look a bit ugly, with all the quotes etc. - but that's the best we can do right now.

Completely fine with that too.

Let's see how long we need to replace OpenAPI - maybe native string interpolation is already widely supported by then ;)

Could we fork (or vendor) swagger2 and do the same process to get rid of the template haskell dependency? Looks like that would be the quickest way to unblock this.

@wolfgangwalther
Copy link
Member Author

Could we fork (or vendor) swagger2 and do the same process to get rid of the template haskell dependency? Looks like that would be the quickest way to unblock this.

I'm not sure whether that would be faster. They do actually use Template Haskell there for code generation, I think - at least for me it would take quite some time to actually understand what they're doing.

Plus, we'd end up with some dependencies which are not on hackage, again, which works against our goal of eventually having an up2date PostgREST available in nixpkgs itself as well.

@taimoorzaeem
Copy link
Collaborator

same "external interpreter" problem that any Template Haskell causes

@wolfgangwalther I would like to know more about the external interpreter problem. I am looking for external links or issue threads related to this.

@wolfgangwalther
Copy link
Member Author

I would like to know more about the external interpreter problem.

Be prepared to spend some time, if you really want to dig into that. And yes: There is no nice solution waiting for you at the end.

Some resources:

@taimoorzaeem
Copy link
Collaborator

@wolfgangwalther Some questions:

Could we fork (or vendor) swagger2 and do the same process to get rid of the template haskell dependency? Looks like that would be the quickest way to unblock this.

Does getting rid of the template haskell dependency mean that we only need to remove it as a direct dependency and not if the package is indirectly dependent on it?

Does our goal of cross-compilation mean that we eventually need to get rid of template haskell from all the packages that we depend on?

Plus, we'd end up with some dependencies which are not on hackage, again, which works against our goal of eventually having an up2date PostgREST available in nixpkgs itself as well.

How sustainable or worth it does this sound if I say that I can write a swagger2 like library (maybe patch it) which is not dependent on template haskell and I can also upload this on hackage and maintain it?

@wolfgangwalther
Copy link
Member Author

Does getting rid of the template haskell dependency mean that we only need to remove it as a direct dependency and not if the package is indirectly dependent on it?

No, all indirect dependencies need to be TH free as well.

Does our goal of cross-compilation mean that we eventually need to get rid of template haskell from all the packages that we depend on?

Yes, correct.

How sustainable or worth it does this sound if I say that I can write a swagger2 like library (maybe patch it) which is not dependent on template haskell and I can also upload this on hackage and maintain it?

I'd say it'd just be a waste of time. We do want to do #1698 anyway, so we just focus on that instead. Once that's done - there is no swagger dependency needed anymore. So writing our own swagger2 library now, would just derail us from our actual goal.

@taimoorzaeem
Copy link
Collaborator

Does our goal of cross-compilation mean that we eventually need to get rid of template haskell from all the packages that we depend on?

Yes, correct.

Hm, this does not seem very possible to me. Even the very basic packages like aeson and lens depend on TH. Infact, most workable packages on hackage directly or indirectly depend on TH.

@wolfgangwalther
Copy link
Member Author

Hm, this does not seem very possible to me. Even the very basic packages like aeson and lens depend on TH. Infact, most workable packages on hackage directly or indirectly depend on TH.

Well, this PR shows that it's possible - and what's needed to get there. I have already removed all TH here, otherwise the static builds on GHC 9.6+ wouldn't succeed, including the one for aarch64.

IIRC, aeson only uses TH for its test-suite. That can just be disabled for cross-compiling - done.

The path is clear, we just need to take it.

@taimoorzaeem
Copy link
Collaborator

taimoorzaeem commented Feb 1, 2025

IIRC, aeson only uses TH for its test-suite. That can just be disabled for cross-compiling - done

aeson uses TH for a QuasiQuoter for JSON in their library. Disabling test-suite makes sense, but can we disable this too?

@wolfgangwalther
Copy link
Member Author

aeson uses TH for a QuasiQuoter for JSON in their library. Disabling test-suite makes sense, but can we disable this too?

As I said... it is already working. So we don't need to disable more.

To be more precise: We need to get rid of all TH, which runs at build-time.

The quasi quoter for aeson doesn't run at build-time for aeson. It would only run at our build-time, if we were using it. But we are not.

@taimoorzaeem
Copy link
Collaborator

To be more precise: We need to get rid of all TH, which runs at build-time.

This explains everything. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants