Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: Tag and Publish release

# console is no longer cross-built here -- penguin-tools builds it for every
# guest arch from this source (github:rehosting/penguin-tools#console-*) and
# ships it in penguin-tools.tar.gz. This workflow only cuts a versioned release
# for tracking/provenance; it publishes no binary asset.
# This repo builds itself via its own flake (`nix build .#dist`, see tests.yml).
# penguin consumes it as a flake input pinned to the tag this workflow cuts,
# building the binaries from source at that tag -- so this release is a
# version/provenance marker and publishes no binary asset.

on:
push:
Expand Down
37 changes: 17 additions & 20 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
name: Check that the code compiles

# Build console for every guest arch through the penguin-tools Nix cross matrix
# (the same machinery that ships it in penguin-tools.tar.gz), compiling *this*
# checkout via --override-input. Replaces the old embedded-toolchains Docker build.
# Build console for every guest arch through this repo's OWN flake
# (`nix build .#dist` cross-builds all arches into the /igloo_static fragment
# penguin consumes). Self-contained -- no longer borrows penguin-tools' machinery.
# Replaces the old embedded-toolchains Docker build.

on:
pull_request:
Expand All @@ -25,27 +26,23 @@ jobs:
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install -y curl jq xz-utils

- uses: cachix/install-nix-action@v27
# Use the org-shared Nix setup (same as penguin's image build): pins a
# modern Nix whose hashing matches the flake.lock and disables the KVM
# setup that Arc pods lack a working udevd for.
- name: Set up Nix
uses: rehosting/ci/actions/nix-setup@v1
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}
extra_nix_config: |
github-token: ${{ secrets.GITHUB_TOKEN }}
install-url: https://releases.nixos.org/nix/nix-2.31.2/install
enable-kvm: false
extra-nix-config: |
max-jobs = 8
cores = 8

- name: Configure Cachix
uses: cachix/cachix-action@v16
with:
name: rehosting-tools
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
skipPush: ${{ github.event_name == 'pull_request' }}
cache-backend: cachix
cachix-name: rehosting-tools
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}

- name: Build console for all guest arches (this checkout)
run: |
set -eux
for a in x86_64 armel aarch64 mipsel mipseb mips64el mips64eb \
powerpc64 powerpc64le riscv64 loongarch64; do
nix build --accept-flake-config \
"github:rehosting/penguin-tools#console-$a" \
--override-input console "path:$PWD" \
--no-link --print-out-paths -L
done
nix build --accept-flake-config .#dist --no-link --print-out-paths -L
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

94 changes: 94 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
description = "console: guest console helper for penguin, cross-built for every guest arch";

nixConfig = {
extra-substituters = [ "https://rehosting-tools.cachix.org" ];
extra-trusted-public-keys = [
"rehosting-tools.cachix.org-1:iNKSaFwG7MfGn6Fk7oTmIcLHqfffQ+cQIE5gWc6MlY0="
];
};

# Pinned to the same nixpkgs commit as penguin / penguin-tools so the cross
# toolchains are byte-identical and shared through Cachix.
inputs.nixpkgs.url = "github:NixOS/nixpkgs/b6067cc0127d4db9c26c79e4de0513e58d0c40c9";

outputs = { self, nixpkgs }:
let
system = "x86_64-linux";
archMatrix = import ./src/archs.nix;

pkgs = import nixpkgs {
inherit system;
config.allowUnsupportedSystem = true;
};
lib = pkgs.lib;

mkMuslCrossPkgs = archKey:
import nixpkgs {
inherit system;
config.allowUnsupportedSystem = true;
crossSystem = archMatrix.${archKey}.muslCrossSystem;
};

# Built as static-musl binaries. console's Makefile hardcodes -march on
# MIPS, but archs.nix already pins gcc.arch per arch (mips32r2/mips64r2),
# so we let the cross stdenv set -march rather than fighting it.
mkConsole = archKey:
import ./src/mk-guest-c-tool.nix {
crossPkgs = mkMuslCrossPkgs archKey;
src = self;
pname = "console-${archMatrix.${archKey}.penguinName}";
sources = [ "console.c" ];
outName = "console";
defines = {
SHELL = "/igloo/utils/sh";
SERIAL = "/igloo/serial";
};
};
consoleBins = lib.mapAttrs (archKey: _: mkConsole archKey) archMatrix;

perArchPackages = builtins.listToAttrs (
lib.mapAttrsToList
(archKey: _: {
name = "console-${archMatrix.${archKey}.penguinName}";
value = consoleBins.${archKey};
})
archMatrix
);

# dist: the /igloo_static fragment this tool owns -- the per-arch console
# in the melting-pot dir penguin globs (penguin's staging loop then makes
# the flat console/console.<arch> links). Mirrors penguin-tools mk-dist-root.
dist = pkgs.runCommand "console-dist"
{
nativeBuildInputs = with pkgs.buildPackages; [ coreutils ];
}
''
set -euo pipefail
${lib.concatStringsSep "\n" (
lib.mapAttrsToList
(archKey: _:
let
pn = archMatrix.${archKey}.penguinName;
console = consoleBins.${archKey};
in
''
mkdir -p "$out/${pn}"
cp ${console}/bin/console "$out/${pn}/console"
'')
archMatrix
)}
chmod -R u+w "$out"
'';
in
{
packages.${system} = perArchPackages // {
inherit dist;
default = dist;
};

checks.${system} = {
inherit dist;
};
};
}
134 changes: 134 additions & 0 deletions src/archs.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Per-arch build matrix (copied from penguin-tools/src/archs.nix so this repo
# builds itself standalone -- no penguin-tools dependency).
#
# crossSystem -- glibc cross system (unused here; kept for parity with the
# shared matrix so arch additions stay in sync).
# muslCrossSystem -- musl cross system used to build the fully-static guest
# binary (rustPlatform cross + crt-static).
{
x86_64 = {
penguinName = "x86_64";
compatNames = [ "intel64" ];
crossSystem = {
config = "x86_64-unknown-linux-gnu";
};
muslCrossSystem = {
config = "x86_64-linux-musl";
};
};

armel = {
penguinName = "armel";
crossSystem = {
config = "armv7l-unknown-linux-gnueabihf";
};
muslCrossSystem = {
config = "armv7l-linux-musleabi";
};
};

arm64 = {
penguinName = "aarch64";
crossSystem = {
config = "aarch64-unknown-linux-gnu";
};
muslCrossSystem = {
config = "aarch64-linux-musl";
};
};

mipsel = {
penguinName = "mipsel";
crossSystem = {
config = "mipsel-unknown-linux-gnu";
gcc.arch = "mips32r2";
};
muslCrossSystem = {
config = "mipsel-linux-musl";
gcc.arch = "mips32r2";
};
};

mipseb = {
penguinName = "mipseb";
crossSystem = {
config = "mips-unknown-linux-gnu";
gcc.arch = "mips32r2";
};
muslCrossSystem = {
config = "mips-linux-musl";
gcc.arch = "mips32r2";
};
};

mips64el = {
penguinName = "mips64el";
crossSystem = {
config = "mips64el-unknown-linux-gnuabi64";
gcc.arch = "mips64r2";
gcc.abi = "64";
};
muslCrossSystem = {
config = "mips64el-linux-musl";
gcc.arch = "mips64r2";
gcc.abi = "64";
};
};

mips64eb = {
penguinName = "mips64eb";
crossSystem = {
config = "mips64-unknown-linux-gnuabi64";
gcc.arch = "mips64r2";
gcc.abi = "64";
};
muslCrossSystem = {
config = "mips64-linux-musl";
gcc.arch = "mips64r2";
gcc.abi = "64";
};
};

ppc64 = {
penguinName = "powerpc64";
crossSystem = {
config = "powerpc64-unknown-linux-gnuabielfv2";
gcc.abi = "elfv2";
};
muslCrossSystem = {
config = "powerpc64-linux-musl";
gcc.abi = "elfv2";
};
};

ppc64el = {
penguinName = "powerpc64le";
compatNames = [ "powerpc64el" ];
crossSystem = {
config = "powerpc64le-unknown-linux-gnu";
};
muslCrossSystem = {
config = "powerpc64le-linux-musl";
};
};

riscv64 = {
penguinName = "riscv64";
crossSystem = {
config = "riscv64-unknown-linux-gnu";
};
muslCrossSystem = {
config = "riscv64-linux-musl";
};
};

loongarch = {
penguinName = "loongarch64";
crossSystem = {
config = "loongarch64-unknown-linux-gnu";
};
muslCrossSystem = {
config = "loongarch64-linux-musl";
};
};
}
60 changes: 60 additions & 0 deletions src/mk-guest-c-tool.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Build a small, self-contained C guest utility (e.g. console) as a static
# binary cross-compiled for one target arch.
#
# These tools have no runtime closure -- they are statically linked against
# musl and drop into the guest as a single file -- so unlike the debugging
# tools (mk-arch-closure.nix) there is nothing to bind-mount; the output is
# just $out/bin/<outName>.
#
# crossPkgs -- a musl cross nixpkgs (archs.nix muslCrossSystem) so the binary
# is fully static and freestanding in the guest.
# src -- the (forked) source tree of the utility.
# pname -- derivation name.
# sources -- list of .c files to compile (relative to src).
# outName -- installed binary name (what penguin expects in the tarball).
# defines -- attrset of -D macros (string values are quoted for C).
# extraCFlags-- arch-specific flags (e.g. [ "-mips32r3" ]).
{ crossPkgs
, src
, pname
, sources ? [ ]
, outName
, defines ? { }
, extraCFlags ? [ ]
}:

let
lib = crossPkgs.lib;
# Single-quote the value so bash preserves the inner double quotes and the
# compiler sees a C string literal (-DSERIAL='"/igloo/serial"'), matching
# console's Makefile (-DSERIAL=\"/igloo/serial\").
defineFlags =
lib.mapAttrsToList (k: v: "-D${k}='\"${toString v}\"'") defines;
cflags = lib.concatStringsSep " " ([ "-static" "-O2" "-Wall" ] ++ extraCFlags ++ defineFlags);
in
crossPkgs.stdenv.mkDerivation {
inherit pname src;
version = "0";

dontConfigure = true;

# Use the cross stdenv's $CC directly rather than the upstream Makefile: the
# Makefile keys its per-arch flags off bespoke triple names (mipsel-linux-musl
# etc.) that don't match nixpkgs' config strings, and nix already selects the
# correct cross-gcc. The flags here mirror console's Makefile verbatim.
buildPhase = ''
runHook preBuild
$CC ${cflags} ${lib.concatStringsSep " " sources} -o ${outName}
runHook postBuild
'';

installPhase = ''
runHook preInstall
install -Dm755 ${outName} "$out/bin/${outName}"
runHook postInstall
'';

# Static musl binaries have no dynamic deps; skip the (cross-hostile) checks.
dontStrip = true;
dontPatchELF = true;
}
Loading