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

Add support for cross compilation #524

Closed
10 tasks done
yorickpeterse opened this issue May 15, 2023 · 5 comments
Closed
10 tasks done

Add support for cross compilation #524

yorickpeterse opened this issue May 15, 2023 · 5 comments
Assignees
Labels
compiler Changes related to the compiler feature New things to add to Inko, such as a new standard library module
Milestone

Comments

@yorickpeterse
Copy link
Collaborator

yorickpeterse commented May 15, 2023

Description

#508 introduces a native code compiler uses LLVM, replacing the bytecode interpreter. The new setup involves a Rust based runtime library, and generated code statically links against this library.

While the generated code supports cross compilation (though we only support a limited number of known targets for now), we still need a runtime library for the target environment. Users of Inko might not have Rust and the necessary dependencies installed (e.g. when installing through a package manager that provides pre-built packages), so we need a way to make it easy to obtain the runtime library for a target environment.

One approach is that we provide pre-built runtime libraries for all supported targets, and extend the `inko executable to support downloading these. I don't want this to be a separate tool (e.g. ivm), as users should be able to cross compile without the need for even more tools.

The mentioned pull request includes some foundational work for this, as the compiler looks for the runtime library in a specific directory, but it only supports a single directory. In case of a system installation that will be something like /usr/lib/inko/..., and the user likely won't have write permissions to that directory. This means we'll need to extend it to either support multiple directories. This comes with the challenge of having to version that path somehow, as different versions of Inko might not be compatible with each other (e.g. they expect a different structure, or the runtime files need to be different).

Related work

Related issues

Tasks

  • Determine if/how to cross compile from e.g. amd64-linux to arm64-mac, and what dependencies are necessary for this
  • Extend CI to build runtime libraries for Linux and macOS, relying on Rust's cross-compilation support to do so. Do this when pushing a new release/tag.
    • amd64-linux-gnu
    • arm64-linux-gnu
    • amd64-mac-native
    • arm64-mac-native
  • Upload the resulting .a files to the S3 bucket releases.inko-lang.org/runtime. Make sure this doesn't mess up the release process (e.g. generating the manifest)
  • Add the command inko runtime add TARGET which downloads a runtime for the given target into the runtime directory
  • Add the command inko runtime remove TARGET which removes a given runtime
  • Add the command inko runtime list which simply lists all available runtimes
@yorickpeterse yorickpeterse added feature New things to add to Inko, such as a new standard library module compiler Changes related to the compiler labels May 15, 2023
@yorickpeterse yorickpeterse added this to the 0.12.0 milestone May 19, 2023
@yorickpeterse yorickpeterse moved this to Todo in NLnet tasks May 24, 2023
@yorickpeterse
Copy link
Collaborator Author

For the initial setup we'll only support a single directory containing runtime libraries. In the case of a system-wide installation, that means you'll have to use sudo inko ... to download the runtime file(s). This is a tad annoying, but it spares us having to version whatever user-local path we'd use otherwise.

@yorickpeterse yorickpeterse moved this from Planning to Ready in NLnet tasks May 24, 2023
@yorickpeterse yorickpeterse self-assigned this May 24, 2023
@yorickpeterse yorickpeterse modified the milestones: 0.12.0, 0.13.0 May 30, 2023
@yorickpeterse yorickpeterse modified the milestones: 0.13.0, 0.14.0 Jun 6, 2023
@yorickpeterse yorickpeterse moved this from Ready to Planning in NLnet tasks Jun 13, 2023
yorickpeterse added a commit that referenced this issue Jan 8, 2024
This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 9, 2024
This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 9, 2024
This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 9, 2024
This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 9, 2024
This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 10, 2024
This fixes #524.

Changelog: added
@yorickpeterse
Copy link
Collaborator Author

Instead of adding a inko target command, we'll start by just building the supported architectures as part of make install. Cross-compiling the runtimes is easy enough at least on Linux (I've yet to verify macOS). This way we don't need to include any HTTP logic in the inko executable, nor do we need to host anything. These runtimes are then installed in the system-wide directory, while custom runtimes can be placed in ~/.local/share/inko/runtimes/VERSION if needed. This means we do need to adjust ivm to also perform this.

The downside is that this increases the total installation size, as each .a file is somewhere between 20 and 30 MiB. This isn't going to be an actual problem for a long time though, so it should be good enough as a starting point.

@yorickpeterse
Copy link
Collaborator Author

We can simplify this even more: as you can't create a custom target name, there's not really a point to allowing custom target runtimes, so we can just get rid of the ~/.local/share directory.

@yorickpeterse
Copy link
Collaborator Author

I forgot to overlook an important detail: to cross-compile the runtimes, we'd need the Rust targets, which means we'd need a Rustup installation. Ignoring that, the more runtimes we'd compile ahead of time, the slower the installation process, which isn't ideal either.

yorickpeterse added a commit that referenced this issue Jan 10, 2024
This fixes #524.

Changelog: added
@yorickpeterse
Copy link
Collaborator Author

I played around a bit with trying to use a nightly build of Rust to build the runtime library using the unwinding crate. This turns out to be rather fragile. First, you need to find a nightly build close to the minimum release of Rust that Inko requires. Now you have to hope you don't run into any weird linker errors such as rust-lang/rust#111285, and potentially other issues. I'm not sure yet if this being stable enough is something we can rely upon.

yorickpeterse added a commit that referenced this issue Jan 11, 2024
This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 11, 2024
This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 11, 2024
This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 12, 2024
This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 12, 2024
This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 12, 2024
This adds proper support for cross-compiling Inko programs from one
target to another.

The Rust runtime is compiled ahead of time as part of the release
process. These runtimes are managed using the `inko runtime` command.
For musl we also include libunwind.a as this is needed to resolve linker
symbol errors. The library is taken from the rustup musl toolchain to
ensure it's the same version as Rust expects. This also saves us having
to compile it in the first place.

By default the compiler tries to detect what compiler/linker driver to
use based on the target you're compiling for. For example, when
targeting musl, the linker tries to use musl-gcc or musl-clang if it's
installed. A custom linker can be specified using the --linker option.
We also support linking using Zig, which makes it _much_ easier to
target macOS and potentially other targets, provided you have Zig
installed of course.

This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 12, 2024
This adds proper support for cross-compiling Inko programs from one
target to another.

The Rust runtime is compiled ahead of time as part of the release
process. These runtimes are managed using the `inko runtime` command.
For musl we also include libunwind.a as this is needed to resolve linker
symbol errors. The library is taken from the rustup musl toolchain to
ensure it's the same version as Rust expects. This also saves us having
to compile it in the first place.

By default the compiler tries to detect what compiler/linker driver to
use based on the target you're compiling for. For example, when
targeting musl, the linker tries to use musl-gcc or musl-clang if it's
installed. A custom linker can be specified using the --linker option.
We also support linking using Zig, which makes it _much_ easier to
target macOS and potentially other targets, provided you have Zig
installed of course.

This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 12, 2024
This adds proper support for cross-compiling Inko programs from one
target to another.

The Rust runtime is compiled ahead of time as part of the release
process. These runtimes are managed using the `inko runtime` command.
For musl we also include libunwind.a as this is needed to resolve linker
symbol errors. The library is taken from the rustup musl toolchain to
ensure it's the same version as Rust expects. This also saves us having
to compile it in the first place.

By default the compiler tries to detect what compiler/linker driver to
use based on the target you're compiling for. For example, when
targeting musl, the linker tries to use musl-gcc or musl-clang if it's
installed. A custom linker can be specified using the --linker option.
We also support linking using Zig, which makes it _much_ easier to
target macOS and potentially other targets, provided you have Zig
installed of course.

This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 13, 2024
This adds proper support for cross-compiling Inko programs from one
target to another.

The Rust runtime is compiled ahead of time as part of the release
process. These runtimes are managed using the `inko runtime` command.
For musl we also include libunwind.a as this is needed to resolve linker
symbol errors. The library is taken from the rustup musl toolchain to
ensure it's the same version as Rust expects. This also saves us having
to compile it in the first place.

By default the compiler tries to detect what compiler/linker driver to
use based on the target you're compiling for. For example, when
targeting musl, the linker tries to use musl-gcc or musl-clang if it's
installed. A custom linker can be specified using the --linker option.
We also support linking using Zig, which makes it _much_ easier to
target macOS and potentially other targets, provided you have Zig
installed of course.

This commit also contains some dependency version updates and the
necessary changes, in an effort to reduce the dependency tree size a bit
after the addition of the "ureq" crate.

Finally, this commit replaces the use of blake2 with blake3. The blake3
crate has a simple API and is supposed to perform much better than
blake2. Also, the blake2 crate relies on a pile of generics and
dependencies such that rust-analyzer isn't able to provide meaningful
help (i.e showing types on hover doesn't work), while this works fine
with blake3.

This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 13, 2024
This adds proper support for cross-compiling Inko programs from one
target to another.

The Rust runtime is compiled ahead of time as part of the release
process. These runtimes are managed using the `inko runtime` command.
For musl we also include libunwind.a as this is needed to resolve linker
symbol errors. The library is taken from the rustup musl toolchain to
ensure it's the same version as Rust expects. This also saves us having
to compile it in the first place.

By default the compiler tries to detect what compiler/linker driver to
use based on the target you're compiling for. For example, when
targeting musl, the linker tries to use musl-gcc or musl-clang if it's
installed. A custom linker can be specified using the --linker option.
We also support linking using Zig, which makes it _much_ easier to
target macOS and potentially other targets, provided you have Zig
installed of course.

This commit also contains some dependency version updates and the
necessary changes, in an effort to reduce the dependency tree size a bit
after the addition of the "ureq" crate.

Finally, this commit replaces the use of blake2 with blake3. The blake3
crate has a simple API and is supposed to perform much better than
blake2. Also, the blake2 crate relies on a pile of generics and
dependencies such that rust-analyzer isn't able to provide meaningful
help (i.e showing types on hover doesn't work), while this works fine
with blake3.

This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 13, 2024
This adds proper support for cross-compiling Inko programs from one
target to another.

The Rust runtime is compiled ahead of time as part of the release
process. These runtimes are managed using the `inko runtime` command.
For musl we also include libunwind.a as this is needed to resolve linker
symbol errors. The library is taken from the rustup musl toolchain to
ensure it's the same version as Rust expects. This also saves us having
to compile it in the first place.

By default the compiler tries to detect what compiler/linker driver to
use based on the target you're compiling for. For example, when
targeting musl, the linker tries to use musl-gcc or musl-clang if it's
installed. A custom linker can be specified using the --linker option.
We also support linking using Zig, which makes it _much_ easier to
target macOS and potentially other targets, provided you have Zig
installed of course.

This commit also contains some dependency version updates and the
necessary changes, in an effort to reduce the dependency tree size a bit
after the addition of the "ureq" crate.

Finally, this commit replaces the use of blake2 with blake3. The blake3
crate has a simple API and is supposed to perform much better than
blake2. Also, the blake2 crate relies on a pile of generics and
dependencies such that rust-analyzer isn't able to provide meaningful
help (i.e showing types on hover doesn't work), while this works fine
with blake3.

This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 13, 2024
This adds proper support for cross-compiling Inko programs from one
target to another.

The Rust runtime is compiled ahead of time as part of the release
process. These runtimes are managed using the `inko runtime` command.
For musl we also include libunwind.a as this is needed to resolve linker
symbol errors. The library is taken from the rustup musl toolchain to
ensure it's the same version as Rust expects. This also saves us having
to compile it in the first place.

By default the compiler tries to detect what compiler/linker driver to
use based on the target you're compiling for. For example, when
targeting musl, the linker tries to use musl-gcc or musl-clang if it's
installed. A custom linker can be specified using the --linker option.
We also support linking using Zig, which makes it _much_ easier to
target macOS and potentially other targets, provided you have Zig
installed of course.

This commit also contains some dependency version updates and the
necessary changes, in an effort to reduce the dependency tree size a bit
after the addition of the "ureq" crate.

Finally, this commit replaces the use of blake2 with blake3. The blake3
crate has a simple API and is supposed to perform much better than
blake2. Also, the blake2 crate relies on a pile of generics and
dependencies such that rust-analyzer isn't able to provide meaningful
help (i.e showing types on hover doesn't work), while this works fine
with blake3.

This fixes #524.

Changelog: added
yorickpeterse added a commit that referenced this issue Jan 13, 2024
This adds proper support for cross-compiling Inko programs from one
target to another.

The Rust runtime is compiled ahead of time as part of the release
process. These runtimes are managed using the `inko runtime` command.
For musl we also include libunwind.a as this is needed to resolve linker
symbol errors. The library is taken from the rustup musl toolchain to
ensure it's the same version as Rust expects. This also saves us having
to compile it in the first place.

By default the compiler tries to detect what compiler/linker driver to
use based on the target you're compiling for. For example, when
targeting musl, the linker tries to use musl-gcc or musl-clang if it's
installed. A custom linker can be specified using the --linker option.
We also support linking using Zig, which makes it _much_ easier to
target macOS and potentially other targets, provided you have Zig
installed of course.

This commit also contains some dependency version updates and the
necessary changes, in an effort to reduce the dependency tree size a bit
after the addition of the "ureq" crate.

Finally, this commit replaces the use of blake2 with blake3. The blake3
crate has a simple API and is supposed to perform much better than
blake2. Also, the blake2 crate relies on a pile of generics and
dependencies such that rust-analyzer isn't able to provide meaningful
help (i.e showing types on hover doesn't work), while this works fine
with blake3.

This fixes #524.

Changelog: added

These tests may sporadically fail due to reasons unknown. By not having
these tests panic in such a case, it should be easier to debug when/why
this happens.
yorickpeterse added a commit that referenced this issue Jan 13, 2024
This adds proper support for cross-compiling Inko programs from one
target to another.

The Rust runtime is compiled ahead of time as part of the release
process. These runtimes are managed using the `inko runtime` command.
For musl we also include libunwind.a as this is needed to resolve linker
symbol errors. The library is taken from the rustup musl toolchain to
ensure it's the same version as Rust expects. This also saves us having
to compile it in the first place.

By default the compiler tries to detect what compiler/linker driver to
use based on the target you're compiling for. For example, when
targeting musl, the linker tries to use musl-gcc or musl-clang if it's
installed. A custom linker can be specified using the --linker option.
We also support linking using Zig, which makes it _much_ easier to
target macOS and potentially other targets, provided you have Zig
installed of course.

This commit also contains some dependency version updates and the
necessary changes, in an effort to reduce the dependency tree size a bit
after the addition of the "ureq" crate.

Finally, this commit replaces the use of blake2 with blake3. The blake3
crate has a simple API and is supposed to perform much better than
blake2. Also, the blake2 crate relies on a pile of generics and
dependencies such that rust-analyzer isn't able to provide meaningful
help (i.e showing types on hover doesn't work), while this works fine
with blake3.

This fixes #524.

Changelog: added

These tests may sporadically fail due to reasons unknown. By not having
these tests panic in such a case, it should be easier to debug when/why
this happens.
@github-project-automation github-project-automation bot moved this from Pending to Done in NLnet tasks Jan 13, 2024
yorickpeterse added a commit that referenced this issue Jan 13, 2024
This adds proper support for cross-compiling Inko programs from one
target to another.

The Rust runtime is compiled ahead of time as part of the release
process. These runtimes are managed using the `inko runtime` command.
For musl we also include libunwind.a as this is needed to resolve linker
symbol errors. The library is taken from the rustup musl toolchain to
ensure it's the same version as Rust expects. This also saves us having
to compile it in the first place.

By default the compiler tries to detect what compiler/linker driver to
use based on the target you're compiling for. For example, when
targeting musl, the linker tries to use musl-gcc or musl-clang if it's
installed. A custom linker can be specified using the --linker option.
We also support linking using Zig, which makes it _much_ easier to
target macOS and potentially other targets, provided you have Zig
installed of course.

This commit also contains some dependency version updates and the
necessary changes, in an effort to reduce the dependency tree size a bit
after the addition of the "ureq" crate.

Finally, this commit replaces the use of blake2 with blake3. The blake3
crate has a simple API and is supposed to perform much better than
blake2. Also, the blake2 crate relies on a pile of generics and
dependencies such that rust-analyzer isn't able to provide meaningful
help (i.e showing types on hover doesn't work), while this works fine
with blake3.

This fixes #524.

Changelog: added
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler Changes related to the compiler feature New things to add to Inko, such as a new standard library module
Projects
No open projects
Status: Done
Development

No branches or pull requests

1 participant