mirror of
https://github.com/limine-bootloader/limine
synced 2024-11-22 00:21:21 +03:00
Merge pull request #340 from phip1611/more-nix
nix: build limine in Nix derivation + CI
This commit is contained in:
commit
95a48ebbfc
18
.github/workflows/check.yml
vendored
18
.github/workflows/check.yml
vendored
@ -29,3 +29,21 @@ jobs:
|
||||
|
||||
- name: Build the bootloader (GNU, riscv64)
|
||||
run: ./bootstrap && ./configure TOOLCHAIN_FOR_TARGET=riscv64-linux-gnu --enable-werror --enable-uefi-riscv64 && make all && make maintainer-clean
|
||||
|
||||
build_nix:
|
||||
name: Build with Nix
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: cachix/install-nix-action@v26
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
- run: nix build .#limine
|
||||
|
||||
build_nix_shell:
|
||||
name: Build with Nix shell toolchain
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: cachix/install-nix-action@v26
|
||||
- uses: DeterminateSystems/magic-nix-cache-action@main
|
||||
- run: nix develop --command bash -c "./bootstrap && ./configure --enable-all && make -j $(nproc)"
|
31
README.md
31
README.md
@ -82,7 +82,19 @@ Host utility binaries are provided for Windows.
|
||||
*The following steps are not necessary if cloning a binary release. If so, skip to*
|
||||
*"Installing Limine binaries".*
|
||||
|
||||
### Prerequisites
|
||||
### Building with Nix
|
||||
|
||||
This repository provides [Nix](https://nixos.org/)-based tooling for a convenient
|
||||
development environment and building Limine using Nix.
|
||||
|
||||
- `$ nix build .#\limine` (build with clang and `--enable-all`)
|
||||
|
||||
To use the regular build flow using a toolchain obtained by Nix, simply
|
||||
run `$ nix develop` to open a Nix shell. Then follow the guide below.
|
||||
|
||||
### Regular build
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
In order to build Limine, the following programs have to be installed:
|
||||
common UNIX tools (also known as `coreutils`),
|
||||
@ -91,7 +103,7 @@ common UNIX tools (also known as `coreutils`),
|
||||
Furthermore, `gcc` or `llvm/clang` must also be installed, alongside
|
||||
the respective binutils.
|
||||
|
||||
### Configure
|
||||
#### Configure
|
||||
|
||||
If using a release tarball (recommended, see https://github.com/limine-bootloader/limine/releases),
|
||||
run `./configure` directly.
|
||||
@ -109,7 +121,7 @@ Limine supports both in-tree and out-of-tree builds. Simply run the `configure`
|
||||
script from the directory you wish to execute the build in. The following `make`
|
||||
commands are supposed to be run inside the build directory.
|
||||
|
||||
### Building Limine
|
||||
#### Building Limine
|
||||
|
||||
To build Limine, run:
|
||||
```bash
|
||||
@ -132,6 +144,19 @@ make install # (or gmake where applicable)
|
||||
|
||||
## How to use
|
||||
|
||||
### Consume via Nix
|
||||
|
||||
Limine is not yet in `nixpkgs`.
|
||||
|
||||
You can consume this as Nix flake:
|
||||
|
||||
```nix
|
||||
{
|
||||
inputs.limine.url = "github:limine-bootloader/limine/<branch>";
|
||||
inputs.limine.inputs.nixpkgs.follows = "nixpkgs";
|
||||
}
|
||||
```
|
||||
|
||||
### UEFI
|
||||
The `BOOT*.EFI` files are valid EFI applications that can be simply copied to
|
||||
the `/EFI/BOOT` directory of a FAT formatted EFI system partition. These files can
|
||||
|
12
flake.lock
12
flake.lock
@ -7,11 +7,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709336216,
|
||||
"narHash": "sha256-Dt/wOWeW6Sqm11Yh+2+t0dfEWxoMxGBvv3JpIocFl9E=",
|
||||
"lastModified": 1712014858,
|
||||
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "f7b3c975cf067e56e7cda6cb098ebe3fb4d74ca2",
|
||||
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -22,11 +22,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1710695816,
|
||||
"narHash": "sha256-3Eh7fhEID17pv9ZxrPwCLfqXnYP006RKzSs0JptsN84=",
|
||||
"lastModified": 1711668574,
|
||||
"narHash": "sha256-u1dfs0ASQIEr1icTVrsKwg2xToIpn7ZXxW3RHfHxshg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "614b4613980a522ba49f0d194531beddbb7220d3",
|
||||
"rev": "219951b495fc2eac67b1456824cc1ec1fd2ee659",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
13
flake.nix
13
flake.nix
@ -5,7 +5,7 @@
|
||||
# regarding the packaging in nixpkgs.
|
||||
|
||||
{
|
||||
description = "limine";
|
||||
description = "Limine";
|
||||
|
||||
inputs = {
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
@ -20,6 +20,10 @@
|
||||
# will notice it soon enough.
|
||||
systems = nixpkgs.lib.systems.flakeExposed;
|
||||
perSystem = { config, pkgs, ... }:
|
||||
let
|
||||
keep-directory-diff = pkgs.callPackage ./nix/keep-directory-diff.nix { };
|
||||
limine = pkgs.callPackage ./nix/build.nix { inherit keep-directory-diff; };
|
||||
in
|
||||
{
|
||||
devShells = {
|
||||
default = pkgs.mkShell {
|
||||
@ -38,6 +42,7 @@
|
||||
# gcc toolchain (comes as default, here only for completness)
|
||||
binutils
|
||||
gcc
|
||||
gnumake
|
||||
|
||||
# llvm toolchain (with TOOLCHAIN_FOR_TARGET=llvm)
|
||||
llvmPackages.bintools
|
||||
@ -52,6 +57,12 @@
|
||||
|
||||
# `$ nix fmt`
|
||||
formatter = pkgs.nixpkgs-fmt;
|
||||
|
||||
# `$ nix build .#<attr>`
|
||||
packages = {
|
||||
inherit limine;
|
||||
default = limine;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
151
nix/build.nix
Normal file
151
nix/build.nix
Normal file
@ -0,0 +1,151 @@
|
||||
# Building Limine with all features in Nix.
|
||||
#
|
||||
# Independent of the packing in nixpkgs, This is convenient for prototyping and
|
||||
# local development.
|
||||
#
|
||||
# These derivations always builds Limine from the current src tree and not some
|
||||
# stable release. Further, unlike the nixpkgs derivation, this derivation runs
|
||||
# the ./bootstrap step which needs network access. Due to the nature of the
|
||||
# self-hacked Git submodules download approach, packaging this project in Nix
|
||||
# is especailly complicated. The complicated multi-derivation approach below
|
||||
# is the best I can get after multiple hours of trying. :).
|
||||
|
||||
{
|
||||
# Helpers
|
||||
fd
|
||||
, lib
|
||||
, keep-directory-diff
|
||||
, nix-gitignore
|
||||
, stdenv
|
||||
|
||||
# Actual derivation dependencies.
|
||||
, autoconf
|
||||
, automake
|
||||
, cacert
|
||||
, git
|
||||
, llvmPackages
|
||||
, mtools
|
||||
, nasm
|
||||
}:
|
||||
|
||||
let
|
||||
# The actual current source but close to the repo state, i.e., no files from
|
||||
# the bootstrap step.
|
||||
currentRepoSrc = nix-gitignore.gitignoreSource [
|
||||
# Additional git ignores:
|
||||
"flake.nix" # otherwise
|
||||
"flake.lock"
|
||||
"nix/"
|
||||
|
||||
# bootstrapped sources from ./bootstrap
|
||||
"/build-aux/freestanding-toolchain"
|
||||
"/freestanding-headers"
|
||||
"/decompressor/cc-runtime"
|
||||
"/limine-efi"
|
||||
"/tinf"
|
||||
"/common/flanterm"
|
||||
"/stb"
|
||||
] ../.;
|
||||
|
||||
# Contains the sources downloaded by the Git submodule-like initialation done
|
||||
# in ./bootstrap.
|
||||
#
|
||||
# ALWAYS update the hash when one of the network dependencies in ./bootstrap
|
||||
# changes.
|
||||
# bootstrappedSrcHash = lib.fakeHash;
|
||||
bootstrappedSrcHash = "sha256-uggy1cDftq0tPD777hS+rz2oBnP2Q2AQ9xHdM8QhBQQ=";
|
||||
|
||||
# The full accumulated source tree to build Limine from.
|
||||
bootstrappedSrc = stdenv.mkDerivation {
|
||||
pname = "limine-src-bootstrapped";
|
||||
version = "0.0.0";
|
||||
src = currentRepoSrc;
|
||||
nativeBuildInputs = [
|
||||
cacert
|
||||
fd
|
||||
git
|
||||
keep-directory-diff
|
||||
];
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
# `true` refers to the binary/bash-builtin to prevent any configuration
|
||||
# steps apart from downloading sources.
|
||||
AUTOMAKE=true AUTORECONF=true ./bootstrap
|
||||
|
||||
keep-directory-diff ${currentRepoSrc} .
|
||||
|
||||
# When cloning, Git automatically creates hooks. Unfortunately, in a Nix
|
||||
# environment / on a NixOS system, this includes Nix store paths.
|
||||
# However, me must prevent to have any Nix store path inside the final
|
||||
# directory, as otherwise we get the error
|
||||
# "illegal path references in fixed-output derivation"! Further, we must
|
||||
# remove all git artifacts (.git dirs) as they affect the hash of the
|
||||
# derivation in a non-deterministic way.
|
||||
fd -u --type=d "^.git$" --min-depth=2 . --exec rm -rf {}
|
||||
|
||||
# This should report nothing. Othewise, the Nix build will fail.
|
||||
# grep -r /nix/store .
|
||||
|
||||
runHook postBuild
|
||||
'';
|
||||
dontPatchShebangs = true;
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
mkdir $out
|
||||
|
||||
cp -r . $out
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
doCheck = false;
|
||||
dontFixup = true;
|
||||
# See "fixed output derivation".
|
||||
outputHashAlgo = "sha256";
|
||||
outputHashMode = "recursive";
|
||||
outputHash = bootstrappedSrcHash;
|
||||
};
|
||||
|
||||
# Common build dependencies apart from the compiler toolchain.
|
||||
commonBuildDeps = [
|
||||
autoconf
|
||||
automake
|
||||
|
||||
mtools
|
||||
nasm
|
||||
];
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
pname = "limine-dev";
|
||||
version = "0.0.0";
|
||||
src = bootstrappedSrc;
|
||||
nativeBuildInputs = commonBuildDeps ++ [
|
||||
# gcc is used to build the host tools and clang to (cross)compile all
|
||||
# the bootloader files
|
||||
llvmPackages.bintools
|
||||
llvmPackages.clang
|
||||
llvmPackages.lld
|
||||
];
|
||||
enableParallelBuilding = true;
|
||||
preConfigure = ''
|
||||
# The default input source of this derivation is what we aggregated
|
||||
# from `./bootstrap`. As this derivation holds all files but we are only
|
||||
# interested in the ones that are not in `currentRepoSrc`, we just
|
||||
# override all.
|
||||
#
|
||||
# This way we can use the actual current repo sources but still use the
|
||||
# populated sources from the ./bootstrap script.
|
||||
#
|
||||
# It's very complicated, I know. But that way we can make it work, at
|
||||
# least.
|
||||
cp -RTf ${currentRepoSrc} .
|
||||
|
||||
# Extracted from ./bootstrap. To see why, check the `bootstrapedSrc`
|
||||
# derivation.
|
||||
#
|
||||
# TODO, we could also do this in ./bootstrap but add a special flag.
|
||||
autoreconf -fvi -Wall
|
||||
'';
|
||||
configureFlags = [ "--enable-all" ];
|
||||
outputs = [ "out" "doc" "dev" "man" ];
|
||||
}
|
55
nix/keep-directory-diff.nix
Normal file
55
nix/keep-directory-diff.nix
Normal file
@ -0,0 +1,55 @@
|
||||
{ ansi
|
||||
, argc
|
||||
, fd
|
||||
, lib
|
||||
, writeShellScriptBin
|
||||
}:
|
||||
|
||||
writeShellScriptBin "keep-directory-diff" ''
|
||||
# The following @-annotations belong to https://github.com/sigoden/argc
|
||||
#
|
||||
# @describe
|
||||
# This script takes two directories. The first directory is the base source.
|
||||
# The second is the base source plus potentially additional or modified
|
||||
# sources. It removes all files from the second directory that are unchanged
|
||||
# in the first directory. The use case is to get the actual difference that
|
||||
# preparation scripts of a source tree cause, such as through downloading
|
||||
# certain resources into the tree.
|
||||
#
|
||||
# Only file content is checked, not file attributes. Symlinks are ignored.
|
||||
#
|
||||
# @arg base! Base directory
|
||||
# Path to source directory
|
||||
# @arg target! Target directory
|
||||
# Path to target directory. This directory is modified.
|
||||
|
||||
# Bash strict mode.
|
||||
set -eou pipefail
|
||||
|
||||
export PATH="${lib.makeBinPath([
|
||||
ansi
|
||||
argc
|
||||
fd
|
||||
])
|
||||
}:$PATH"
|
||||
|
||||
# Do the "argc" magic. Reference: https://github.com/sigoden/argc
|
||||
eval "$(argc --argc-eval "$0" "$@")"
|
||||
|
||||
# Find directories and regular files, don't follow symlinks.
|
||||
readarray -d "" BASE_FILES < <(cd "$argc_base" && fd --unrestricted --print0 --type file)
|
||||
|
||||
for FILE in "''${BASE_FILES[@]}"; do
|
||||
# Check if the content of the file was changed.
|
||||
TARGET_FILE=$(realpath "$argc_target/$FILE" --relative-to=$PWD)
|
||||
FILE=$(realpath "$argc_base/$FILE" --relative-to=$PWD)
|
||||
echo -e "base file : $(ansi bold)$FILE$(ansi reset)"
|
||||
echo -e "target file: $(ansi bold)$TARGET_FILE$(ansi reset)"
|
||||
if cmp -s "$FILE" "$TARGET_FILE"; then
|
||||
echo -e "Removing $(ansi bold)$TARGET_FILE$(ansi reset) as it hasn't changed."
|
||||
rm -f "$TARGET_FILE"
|
||||
else
|
||||
echo -e "Keeping $(ansi bold)$TARGET_FILE$(ansi reset) as it was modified"
|
||||
fi
|
||||
done
|
||||
''
|
Loading…
Reference in New Issue
Block a user