Files
cargoxx/flake.nix

188 lines
7.1 KiB
Nix

{
description = "cargoxx";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
bundlers.url = "github:NixOS/bundlers";
bundlers.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, flake-utils, bundlers }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
# exec::run shells out to these at runtime; wrap the binary so
# they're reachable even outside a nix develop shell.
cargoxxRuntimePath = pkgs.lib.makeBinPath [
pkgs.nix
pkgs.cmake
pkgs.ninja
pkgs.curl
pkgs.git
];
# Defaults applied to the bundled `nix` so it works on hosts
# that don't already have nix set up (Arch/Debian/Fedora users
# who install our .pkg.tar.zst / .deb / .rpm). Multi-user mode
# would expect a `nixbld` group and a running daemon
cargoxxNixConfig = ''
experimental-features = nix-command flakes
build-users-group =
'';
cargoxx-bin = pkgs.gcc15Stdenv.mkDerivation {
pname = "cargoxx";
version = "0.1.0";
src = ./.;
nativeBuildInputs = [ pkgs.cmake pkgs.ninja pkgs.makeWrapper ];
buildInputs = [ pkgs.sqlite pkgs.reproc pkgs.catch2_3 ];
configurePhase = ''
cmake -S build -B build/release -G Ninja \
-DCMAKE_BUILD_TYPE=Release
'';
buildPhase = ''
cmake --build build/release
'';
installPhase = ''
mkdir -p $out/bin
cp build/release/cargoxx $out/bin/
wrapProgram $out/bin/cargoxx \
--prefix PATH : ${cargoxxRuntimePath} \
--set-default NIX_CONFIG ${pkgs.lib.escapeShellArg cargoxxNixConfig}
'';
hardeningDisable = [ "all" ];
};
buildCppPackage = { src, name ? null, ... }@args:
let
lock = builtins.fromTOML (builtins.readFile (src + "/Cargoxx.lock"));
isDep = p: p ? linkdb_source;
isRoot = p: !(isDep p);
root = builtins.head (builtins.filter isRoot lock.package);
depPkgs = builtins.filter isDep lock.package;
pname = if name != null then name else root.name;
pkgsAt = rev:
(builtins.getFlake "github:NixOS/nixpkgs/${rev}")
.legacyPackages.${system};
evalDep = p:
let rev = if (p ? nixpkgs_rev) && (p.nixpkgs_rev != "")
then p.nixpkgs_rev
else lock.nixpkgs_rev;
in (pkgsAt rev).${p.nixpkgs_attr};
depInputs = map evalDep depPkgs;
usesPkgConfig = builtins.any
(p: (p.linkdb_source or "") == "pkg-config") depPkgs;
nixpkgsSource = (builtins.getFlake
"github:NixOS/nixpkgs/${lock.nixpkgs_rev}").outPath;
flakeUtilsSource = (builtins.getFlake
"github:numtide/flake-utils/${lock.flake_utils_rev}").outPath;
mkDepTomlEntry = p:
let
derivation = evalDep p;
rev = if (p ? nixpkgs_rev) && (p.nixpkgs_rev != "")
then p.nixpkgs_rev else lock.nixpkgs_rev;
in ''
[[dep]]
name = "${p.name}"
nixpkgs_attr = "${p.nixpkgs_attr}"
nixpkgs_rev = "${rev}"
store_path = "${derivation}"
'';
vendorToml = pkgs.writeText "vendor.toml" (''
schema = 1
[nixpkgs]
rev = "${lock.nixpkgs_rev}"
store_path = "${nixpkgsSource}"
[flake_utils]
rev = "${lock.flake_utils_rev}"
store_path = "${flakeUtilsSource}"
'' + builtins.concatStringsSep "\n" (map mkDepTomlEntry depPkgs));
in pkgs.gcc15Stdenv.mkDerivation {
inherit pname src;
version = root.version;
nativeBuildInputs =
[ cargoxx-bin pkgs.cmake pkgs.ninja ]
++ pkgs.lib.optional usesPkgConfig pkgs.pkg-config;
buildInputs = depInputs;
dontConfigure = true;
buildPhase = ''
export HOME=$(mktemp -d)
cargoxx build --release --offline --vendor ${vendorToml}
'';
installPhase = ''
mkdir -p $out/bin
cp build/release/${pname} $out/bin/ 2>/dev/null || \
cp build/release/${pname}_bin $out/bin/${pname}
'';
hardeningDisable = [ "all" ];
};
bundlers-sys = bundlers.bundlers.${system};
# Arch's pacman expects a tar.zst archive containing a
# `.PKGINFO` metadata file plus the file tree rooted at /.
# We ship the entire closure under /nix/store; /usr/bin/cargoxx
# is a symlink to the in-store wrapper.
toArchPkg = drv:
let
pname = drv.pname or drv.name;
version = drv.version or "0";
mainProgram = drv.meta.mainProgram or pname;
in pkgs.runCommand "${pname}-${version}-1-x86_64.pkg.tar.zst" {
nativeBuildInputs = [ pkgs.libarchive pkgs.coreutils ];
closureInfo = pkgs.closureInfo { rootPaths = [ drv ]; };
} ''
stage=$(mktemp -d)
mkdir -p $stage/nix/store $stage/usr/bin
for p in $(cat $closureInfo/store-paths); do
cp -a "$p" $stage/nix/store/
done
ln -s ${drv}/bin/${mainProgram} $stage/usr/bin/${mainProgram}
installed_size=$(du -sk $stage | cut -f1)
cat > $stage/.PKGINFO <<EOF
pkgname = ${pname}
pkgver = ${version}-1
pkgdesc = ${drv.meta.description or pname}
builddate = 0
packager = nix-build
size = $installed_size
arch = x86_64
EOF
( cd $stage && bsdtar --zstd -cf $out .PKGINFO nix usr )
'';
in {
packages.default = cargoxx-bin;
packages.appimage = bundlers-sys.toAppImage cargoxx-bin;
packages.dockerImage = bundlers-sys.toDockerImage cargoxx-bin;
packages.deb = bundlers-sys.toDEB cargoxx-bin;
packages.rpm = bundlers-sys.toRPM cargoxx-bin;
packages.archpkg = toArchPkg cargoxx-bin;
# Reusable packaging functions, all of the shape `drv -> drv`.
# Mirror the `to*` naming used by github:NixOS/bundlers.
lib.toAppImage = bundlers-sys.toAppImage;
lib.toDockerImage = bundlers-sys.toDockerImage;
lib.toDEB = bundlers-sys.toDEB;
lib.toRPM = bundlers-sys.toRPM;
lib.toArchPkg = toArchPkg;
lib.buildCppPackage = buildCppPackage;
devShells.default = pkgs.gcc15Stdenv.mkDerivation {
name = "cargoxx-dev";
version = "0.1.0";
nativeBuildInputs = [ pkgs.ninja pkgs.cmake ];
buildInputs = [ pkgs.reproc pkgs.sqlite pkgs.catch2_3 ];
hardeningDisable = [ "all" ];
};
});
}