-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
icedragon is a tool for easy cross (but also native) builds using LLVM (clang, Rust). It consists of: - Container images which provide the toolchains for each target. - A CLI tool, which is a wrapper about a container engine (Docker, podman) and allows easy execution of the toolchain.
- Loading branch information
1 parent
a6cf419
commit b93068d
Showing
18 changed files
with
864 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
branches: | ||
- main | ||
schedule: | ||
- cron: 00 4 * * * | ||
|
||
env: | ||
CARGO_TERM_COLOR: always | ||
|
||
jobs: | ||
lint-stable: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- uses: dtolnay/rust-toolchain@master | ||
with: | ||
toolchain: stable | ||
components: clippy, rust-src | ||
|
||
- name: Run clippy | ||
run: cargo clippy --all-targets --workspace -- --deny warnings | ||
|
||
lint-nightly: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- uses: dtolnay/rust-toolchain@master | ||
with: | ||
toolchain: nightly | ||
components: rustfmt, rust-src | ||
|
||
- name: Check formatting | ||
run: cargo fmt --all -- --check | ||
|
||
build-container-image: | ||
runs-on: ubuntu-22.04 | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
include: | ||
- target: aarch64-unknown-linux-musl | ||
type: cross | ||
- target: x86_64-unknown-linux-musl | ||
type: native | ||
name: container ${{ matrix.type }} ${{ matrix.target }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: dtolnay/rust-toolchain@stable | ||
|
||
- name: Log in to GitHub Container Registry | ||
run: | | ||
set -euxo pipefail | ||
echo "${{ secrets.GITHUB_TOKEN }}" | \ | ||
docker login ghcr.io -u ${{ github.actor }} --password-stdin | ||
- name: Build container image | ||
if: github.ref == 'refs/heads/main' | ||
run: | | ||
cargo run build-container-image \ | ||
--tag ghcr.io/${{ github.repository }}/${{ matrix.type }}-${{ matrix.target }}:latest \ | ||
--target ${{ matrix.target }} \ | ||
--push | ||
- name: Build container image | ||
if: github.ref != 'refs/heads/main' | ||
run: | | ||
cargo run build-container-image \ | ||
--tag ghcr.io/${{ github.repository }}/${{ matrix.type }}-${{ matrix.target }}:${{ github.head_ref }} \ | ||
--target ${{ matrix.target }} \ | ||
--push |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "icedragon" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
anyhow = "1.0.89" | ||
chrono = "0.4" | ||
clap = { version = "4.5", features = ["derive"] } | ||
env_logger = "0.11" | ||
log = "0.4" | ||
target-lexicon = "0.12" | ||
thiserror = { version = "1.0.64" } | ||
uuid = { version = "1.10", features = ["v4"] } | ||
which = "6.0" | ||
|
||
[[bin]] | ||
name = "icedragon" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,97 @@ | ||
# cross-llvm | ||
Containerized (cross) LLVM toolchains | ||
# icedragon | ||
|
||
Linux cross-compilation suite for building portable, statically linked | ||
software. | ||
|
||
Currently supports the following languages: | ||
|
||
* C | ||
* C++ | ||
* Rust | ||
|
||
Icedragon comes in two forms: | ||
|
||
* Container images, with a "zero-setup" set of toolchains and essential | ||
libraries. | ||
* CLI, which leverages the container images, but feels like using a regular | ||
compiler on your host. | ||
|
||
It's based on: | ||
|
||
* [Gentoo Linux][gentoo] ([musl-llvm][gentoo-musl-llvm] flavor), which is used | ||
as the base system for the containers. | ||
* [crossdev][crossdev], which manages Gentoo sysroots for different | ||
architectures. | ||
* [musl][musl] libc, which, unlike [glibc][glibc], can be statically linked | ||
without imposing any runtime dependencies. | ||
* [LLVM][llvm] compiler infrastructer. | ||
* [Rustup][rustup], which is used for managing [Rust][rust] toolchains. | ||
|
||
## How is icedragon different from Alpine Linux? | ||
|
||
Let's start with similarities. Both icedragon and [Alpine][alpine] are using | ||
[musl][musl] as the C standard library. Both can be used to build portable, | ||
statically linked binaries. | ||
|
||
The first difference is that [Alpine][alpine] uses [GCC][gcc] | ||
and [GNU C++ library][libstdc++]. Icedragon uses [LLVM][llvm] and | ||
[LLVM C++ library][libcxx] and doesn't come with [GCC][gcc]. | ||
|
||
The second difference is strong focus on cross-compilation in icedragon. | ||
Ability to build for different targets without manual setup of a cross | ||
sysroot is one of the most important goals. | ||
|
||
## Featured libraries | ||
|
||
Icedragon comes with a set of static libraries which can be considered "build | ||
essentials" for the most of C/C++ software on Linux, as well as for Rust | ||
crates, which don't vendor C dependencies and expect them to be present in the | ||
system. | ||
|
||
* Compression libraries: | ||
* brotli | ||
* zstd | ||
* zlib | ||
* Cryptography libraries: | ||
* gpgme | ||
* OpenSSL | ||
* JSON | ||
* json-c | ||
* Key-value stores | ||
* rocksdb | ||
* Linux-specific libraries and utilities: | ||
* util-linux | ||
* Network libraries: | ||
* c-ares | ||
* libcurl | ||
* Regular expressions: | ||
* libpcre2 | ||
|
||
## GNU extensions | ||
|
||
Icedragon doesn't use glibc, but it also doesn't require rigurous POSIX | ||
compatibility. It makes use of various projects, which provide ports of GNU | ||
extensions, while still being compatible with a musl/LLVM toolchain: | ||
|
||
* [argp-standalone][argp-standalone] | ||
* [error-standalone][error-standalone] | ||
* [llvm-libgcc][llvm-libgcc] | ||
* [musl-fts][musl-tfs] | ||
|
||
At the same time, these ports can be linked statically and don't issue any | ||
`dlopen` calls. | ||
|
||
[gentoo]: https://www.gentoo.org | ||
[crossdev]: https://wiki.gentoo.org/wiki/Crossdev | ||
[musl]: https://musl.libc.org | ||
[glibc]: https://www.gnu.org/software/libc | ||
[llvm]: https://llvm.org | ||
[rustup]: https://rustup.rs | ||
[rust]: https://www.rust-lang.org | ||
[alpine]: https://www.alpinelinux.org | ||
[gcc]: https://gcc.gnu.org | ||
[libstdc++]: https://gcc.gnu.org/onlinedocs/libstdc++ | ||
[libcxx]: https://libcxx.llvm.org | ||
[argp-standalone]: https://github.com/ericonr/argp-standalone | ||
[error-standalone]: https://hacktivis.me/git/error-standalone | ||
[musl-fts]: https://github.com/void-linux/musl-fts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
FROM docker.io/gentoo/stage3:musl-llvm | ||
|
||
ARG LLVM_VERSION=19 | ||
|
||
ENV PATH="/root/.cargo/bin:/usr/lib/llvm/${LLVM_VERSION}/bin:${PATH}" | ||
# Install only aarch64 user-space wrapper when installing app-emulation/qemu. | ||
ENV QEMU_USER_TARGETS="aarch64" | ||
# Enable static libraries for installed packages (zstd, zlib etc.). | ||
ENV USE="static-libs" | ||
|
||
COPY package.accept_keywords/* /etc/portage/package.accept_keywords/ | ||
COPY package.use/* /etc/portage/package.use/ | ||
|
||
# Install QEMU, which can be used for running foreign binaries and therefore is | ||
# useful for running `cargo test` for foreign targets. | ||
# | ||
# Install the following dependencies, which can be considered "build essentials" | ||
# for the most of C/C++ software on Linux, as well as for Rust crates, which | ||
# don't vendor C dependencies and expect them to be present in the system. All of | ||
# these dependencies provide static libraries. | ||
# | ||
# * Ports of GNU, non-POSIX functionality: | ||
# * llvm-libgcc[0] - LLVM's runtime library with GNU symbols. Many | ||
# third-party binaries, including Rust toolchains from rustup, rely on them | ||
# and wouldn't work with vanilla LLVM compiler runtime[1][2]. | ||
# * musl-compatible ports of glibc's GNU extensions: | ||
# * argp-standalone | ||
# * error-standalone | ||
# * musl-fts (packaged as fts-standalone in Gentoo) | ||
# * Compression libraries: | ||
# * brotli | ||
# * zstd | ||
# * zlib | ||
# * Cryptography libraries: | ||
# * gpgme | ||
# * OpenSSL | ||
# * JSON | ||
# * json-c | ||
# * Key-value stores | ||
# * rocksdb | ||
# * Linux-specific libraries and utilities: | ||
# * util-linux | ||
# * Network libraries: | ||
# * c-ares | ||
# * libcurl | ||
# * Regular expressions: | ||
# * libpcre2 | ||
# | ||
# Create a cross sysroot using crossdev[3], which also creates wrappers for: | ||
# * clang, which can be used for compiling C/C++ projects without doing the | ||
# whole dance with `--target` and `--sysroot` arguments. | ||
# * emerge, which let you install packages in the cross sysroot. | ||
# | ||
# Unpack the stage3 tarball into that sysroot to avoiding compilation of the | ||
# whole base system from scratch. Otherwise, bootstraping the base sysroot with | ||
# `emerge-aarch64-unknown-linux-musl @system` would take an eternity to run on | ||
# free GitHub runners. | ||
# | ||
# [0] https://github.com/llvm/llvm-project/tree/main/llvm-libgcc | ||
# [1] https://github.com/rust-lang/rust/issues/119504 | ||
# [2] https://github.com/rust-lang/rustup/issues/2213#issuecomment-1888615413 | ||
# [3] https://wiki.gentoo.org/wiki/Crossdev | ||
RUN emerge-webrsync \ | ||
&& emerge \ | ||
app-arch/brotli \ | ||
app-arch/zstd \ | ||
app-crypt/gpgme \ | ||
app-emulation/qemu \ | ||
app-eselect/eselect-repository \ | ||
dev-libs/json-c \ | ||
dev-libs/libpcre2 \ | ||
dev-libs/openssl \ | ||
dev-libs/rocksdb \ | ||
llvm-runtimes/libgcc \ | ||
net-dns/c-ares \ | ||
net-misc/curl \ | ||
sys-apps/util-linux \ | ||
sys-devel/crossdev \ | ||
sys-libs/argp-standalone \ | ||
sys-libs/error-standalone \ | ||
sys-libs/fts-standalone \ | ||
sys-libs/zlib \ | ||
&& eselect repository create crossdev \ | ||
&& crossdev --llvm --target aarch64-unknown-linux-musl --c ${LLVM_VERSION} \ | ||
&& curl -L "https://ftp-osl.osuosl.org/pub/gentoo/releases/arm64/autobuilds/current-stage3-arm64-musl-llvm/$(\ | ||
curl -L "https://ftp-osl.osuosl.org/pub/gentoo/releases/arm64/autobuilds/current-stage3-arm64-musl-llvm/latest-stage3-arm64-musl-llvm.txt" | \ | ||
grep tar.xz | cut -d ' ' -f 1)" | \ | ||
tar -xJpf - -C /usr/aarch64-unknown-linux-musl --exclude=dev --skip-old-files \ | ||
&& ln -s \ | ||
/etc/portage/repos.conf \ | ||
/usr/aarch64-unknown-linux-musl/etc/portage/repos.conf \ | ||
&& ln -s \ | ||
/etc/portage/package.accept_keywords \ | ||
/usr/aarch64-unknown-linux-musl/etc/portage/package.accept_keywords \ | ||
&& PORTAGE_CONFIGROOT=/usr/aarch64-unknown-linux-musl eselect profile set \ | ||
default/linux/arm64/23.0/musl/llvm \ | ||
&& aarch64-unknown-linux-musl-emerge --sync --quiet \ | ||
&& aarch64-unknown-linux-musl-emerge \ | ||
app-arch/brotli \ | ||
app-arch/zstd \ | ||
app-crypt/gpgme \ | ||
dev-libs/json-c \ | ||
dev-libs/libpcre2 \ | ||
dev-libs/openssl \ | ||
dev-libs/rocksdb \ | ||
llvm-runtimes/libgcc \ | ||
net-dns/c-ares \ | ||
net-misc/curl \ | ||
sys-apps/util-linux \ | ||
sys-libs/argp-standalone \ | ||
sys-libs/error-standalone \ | ||
sys-libs/fts-standalone \ | ||
sys-libs/zlib \ | ||
&& curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \ | ||
&& rustup toolchain install stable --component rust-src \ | ||
&& rustup toolchain install beta --component rust-src \ | ||
&& rustup toolchain install nightly --component rust-src \ | ||
&& rustup target add aarch64-unknown-linux-musl \ | ||
&& rustup +beta target add aarch64-unknown-linux-musl \ | ||
&& rustup +nightly target add aarch64-unknown-linux-musl \ | ||
&& cargo install btfdump \ | ||
&& rm -rf \ | ||
/var/cache/binpkgs/* \ | ||
/var/cache/distfiles/* \ | ||
/var/tmp/portage/* |
Oops, something went wrong.