diff --git a/flake.nix b/flake.nix index 8bb6806..110497b 100644 --- a/flake.nix +++ b/flake.nix @@ -5,39 +5,40 @@ nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11"; }; - outputs = { self, nixpkgs, naersk, fenix }: - let + outputs = { self, nixpkgs, naersk, fenix }: let + + newBuildTarget = { + nixPkgsSystem, + rustTarget ? nixPkgsSystem, + nativeBuildInputs ? pkgsCross: [], + rustFlags ? pkgsCross: [], + }: { + inherit nixPkgsSystem rustTarget nativeBuildInputs rustFlags; + }; + buildTargets = { - "x86_64-linux" = { - crossSystemConfig = "x86_64-unknown-linux-musl"; - rustTarget = "x86_64-unknown-linux-musl"; + "x86_64-linux" = newBuildTarget { + nixPkgsSystem = "x86_64-unknown-linux-musl"; }; - "i686-linux" = { - crossSystemConfig = "i686-unknown-linux-musl"; - rustTarget = "i686-unknown-linux-musl"; + "i686-linux" = newBuildTarget { + nixPkgsSystem = "i686-unknown-linux-musl"; }; - "aarch64-linux" = { - crossSystemConfig = "aarch64-unknown-linux-musl"; - rustTarget = "aarch64-unknown-linux-musl"; + "aarch64-linux" = newBuildTarget { + nixPkgsSystem = "aarch64-unknown-linux-musl"; }; # Old Raspberry Pi's - "armv6l-linux" = { - crossSystemConfig = "armv6l-unknown-linux-musleabihf"; + "armv6l-linux" = newBuildTarget { + nixPkgsSystem = "armv6l-unknown-linux-musleabihf"; rustTarget = "arm-unknown-linux-musleabihf"; }; - "x86_64-windows" = { - crossSystemConfig = "x86_64-w64-mingw32"; + "x86_64-windows" = newBuildTarget { + nixPkgsSystem = "x86_64-w64-mingw32"; rustTarget = "x86_64-pc-windows-gnu"; - makeBuildPackageAttrs = pkgsCross: { - depsBuildBuild = [ - pkgsCross.stdenv.cc - pkgsCross.windows.pthreads - ]; - }; + nativeBuildInputs = pkgsCross: [ pkgsCross.windows.pthreads ]; }; }; @@ -77,76 +78,105 @@ # build platform (and therefore it's not really cross-compiling). So we # only set up the cross-compiling config if the target platform is # different. - crossSystem.config = buildTargets.${targetSystem}.crossSystemConfig; + crossSystem.config = buildTargets.${targetSystem}.nixPkgsSystem; })); + mkToolchain = buildSystem: targetSystem: let + debug = v: builtins.trace v v; + buildTarget = buildTargets.${targetSystem}; + rustTarget = buildTarget.rustTarget; + #fenixPkgs = fenix.packages.${buildSystem}; + + # TODO prefer to use the nix flake fenix + fenixPkgs = import ((mkPkgs buildSystem null).fetchFromGitHub { + owner = "nix-community"; + repo = "fenix"; + rev = "81ab0b4f7ae9ebb57daa0edf119c4891806e4d3a"; + hash = "sha256-bZmI7ytPAYLpyFNgj5xirDkKuAniOkj1xHdv5aIJ5GM="; + }) { + system = buildSystem; + }; + + # TODO I'd prefer to use the toolchain file + # https://github.com/nix-community/fenix/issues/123 + fenixToolchain = fenixTarget: (builtins.getAttr "toolchainOf" fenixTarget) { + channel = "nightly"; + date = "2023-07-23"; + sha256 = "sha256-LU4C/i+maIOqBZagUaXpFyWZyOVfQ3Ah5/JTz7v6CG4="; + }; + in + fenixPkgs.combine [ + (fenixToolchain fenixPkgs).rustc + (fenixToolchain fenixPkgs).rustfmt + (fenixToolchain fenixPkgs).cargo + (fenixToolchain fenixPkgs).clippy + (fenixToolchain (fenixPkgs.targets).${rustTarget}).rust-std + ]; + + buildEnv = buildSystem: targetSystem: let + pkgs = mkPkgs buildSystem null; + pkgsCross = mkPkgs buildSystem targetSystem; + buildTarget = buildTargets.${targetSystem}; + in + rec { + nativeBuildInputs = (buildTarget.nativeBuildInputs pkgsCross) ++ [ + (mkToolchain buildSystem targetSystem) + + # Required for shell because of rust dependency build scripts which + # must run on the build system. + pkgs.stdenv.cc + ]; + + OPENSSL_STATIC = "1"; + OPENSSL_LIB_DIR = "${pkgsCross.pkgsStatic.openssl.out}/lib"; + OPENSSL_INCLUDE_DIR = "${pkgsCross.pkgsStatic.openssl.dev}/include"; + + # Required because ring crate is special. This also seems to have + # fixed some issues with the x86_64-windows cross-compile :shrug: + TARGET_CC = "${pkgsCross.stdenv.cc}/bin/${pkgsCross.stdenv.cc.targetPrefix}cc"; + + CARGO_BUILD_TARGET = buildTarget.rustTarget; + CARGO_BUILD_RUSTFLAGS = [ + "-C" "target-feature=+crt-static" + + # -latomic is required to build openssl-sys for armv6l-linux, but + # it doesn't seem to hurt any other builds. + "-C" "link-args=-static -latomic" + + # https://github.com/rust-lang/cargo/issues/4133 + "-C" "linker=${TARGET_CC}" + ]; + }; + in { + packages = eachCrossSystem (builtins.attrNames buildTargets) (buildSystem: targetSystem: let pkgs = mkPkgs buildSystem null; - pkgsCross = mkPkgs buildSystem targetSystem; - rustTarget = buildTargets.${targetSystem}.rustTarget; - - # TODO I'd prefer to use the toolchain file - # https://github.com/nix-community/fenix/issues/123 - #toolchain = fenix.packages.${buildSystem}.fromToolchainFile { - # file = ./rust-toolchain.toml; - # sha256 = "sha256-LU4C/i+maIOqBZagUaXpFyWZyOVfQ3Ah5/JTz7v6CG4="; - #}; - - fenixPkgs = fenix.packages.${buildSystem}; - - mkToolchain = fenixPkgs: fenixPkgs.toolchainOf { - channel = "nightly"; - date = "2023-07-23"; - sha256 = "sha256-LU4C/i+maIOqBZagUaXpFyWZyOVfQ3Ah5/JTz7v6CG4="; - }; - - toolchain = fenixPkgs.combine [ - (mkToolchain fenixPkgs).rustc - (mkToolchain fenixPkgs).cargo - (mkToolchain fenixPkgs.targets.${rustTarget}).rust-std - ]; - - buildPackageAttrs = if - builtins.hasAttr "makeBuildPackageAttrs" buildTargets.${targetSystem} - then - buildTargets.${targetSystem}.makeBuildPackageAttrs pkgsCross - else - {}; - + toolchain = mkToolchain buildSystem targetSystem; naersk-lib = pkgs.callPackage naersk { cargo = toolchain; rustc = toolchain; }; - in - naersk-lib.buildPackage (buildPackageAttrs // rec { + naersk-lib.buildPackage (rec { src = ./.; strictDeps = true; doCheck = false; + release = true; + } // (buildEnv buildSystem targetSystem)) + ); - OPENSSL_STATIC = "1"; - OPENSSL_LIB_DIR = "${pkgsCross.pkgsStatic.openssl.out}/lib"; - OPENSSL_INCLUDE_DIR = "${pkgsCross.pkgsStatic.openssl.dev}/include"; - - # Required because ring crate is special. This also seems to have - # fixed some issues with the x86_64-windows cross-compile :shrug: - TARGET_CC = "${pkgsCross.stdenv.cc}/bin/${pkgsCross.stdenv.cc.targetPrefix}cc"; - - CARGO_BUILD_TARGET = rustTarget; - CARGO_BUILD_RUSTFLAGS = [ - "-C" "target-feature=+crt-static" - - # -latomic is required to build openssl-sys for armv6l-linux, but - # it doesn't seem to hurt any other builds. - "-C" "link-args=-static -latomic" - - # https://github.com/rust-lang/cargo/issues/4133 - "-C" "linker=${TARGET_CC}" - ]; - }) + devShells = eachCrossSystem + (builtins.attrNames buildTargets) + (buildSystem: targetSystem: let + pkgs = mkPkgs buildSystem null; + toolchain = mkToolchain buildSystem targetSystem; + in + pkgs.mkShell ({ + inputsFrom = []; # extra packages for dev + } // (buildEnv buildSystem targetSystem)) ); }; }