Skip to content

lm4flash Binaries

Rahul Butani edited this page May 30, 2022 · 1 revision

Binaries

(built on macOS arm64 using the nix expression below)

Nix Expression

{ altSystem ? null
# Until https://github.com/NixOS/nixpkgs/pull/175052 gets merged:
, lm4toolsPkg ? null
, nixpkgsSrc ? <nixpkgs>
}: let
  dbg = x: builtins.trace x x;
  np = import nixpkgsSrc {};

  overlays = if lm4toolsPkg != null then
    [(final: prev: {
      lm4tools = final.callPackage lm4toolsPkg { testers = {}; };

      libusb1 = prev.libusb1.overrideAttrs (old: {
        # Not providing the deps dir breaks the build on Windows.
        dontAddDisableDepTrack = true;
      });
    })]
  else
    [];

  getLm4toolsForCrossSys =
    { crossSys ? null
    , system ? altSystem
    , extraArgs ? _: {}
    }:
    let
      sys = if system != null
        then { inherit system; }
        else { };
      cross = if crossSys != null
        # Note that we're asking for configurations that produce static binaries.
        then { crossSystem = np.lib.systems.examples.${crossSys} // { isStatic = true; }; }
        else { };

      args = { inherit overlays; } // sys // cross;
      nixpkgs = import nixpkgsSrc (args // (extraArgs args));
    in
      nixpkgs.lm4tools
    ;

  # Cross compiled binaries:
  crossSystems = {
    win-amd64 = "mingwW64";
    linux-amd64 = "musl64";
    linux-arm64 = "aarch64-multiplatform-musl";

    # !!! see `nativeSystems` below:
    # macOS-amd64 = "x86_64-darwin";
    # macOS-arm64 = "aarch64-darwin";
  };

  crossBinaries = builtins.mapAttrs (
    _: crossName: getLm4toolsForCrossSys { crossSys = crossName; }
  ) crossSystems;

  # Cross compiling for darwin is broken: https://github.com/NixOS/nixpkgs/issues/107241#issuecomment-826404272
  #
  # So we build these "natively" with Rosetta for the AMD64 binary.
  nativeSystems = {
    macOS-amd64 = "x86_64-darwin";
    macOS-arm64 = "aarch64-darwin";
  };

  nativeBinaries = builtins.mapAttrs (
    _: sysName: getLm4toolsForCrossSys {
      system = sysName;
      extraArgs = args: {
        # Because Darwin does not support cross-compiling, the `pkgsStatic` package set
        # does not apply `makeStatic` to the stdenv on darwin:
        # https://github.com/NixOS/nixpkgs/blob/200175a7011c0602c0a8e6d4c6583d9d577a03d1/pkgs/top-level/stage.nix#L256
        #
        # So, we apply it manually.
        #
        # !!! compiling all of the macOS stdenv with `makeStatic` breaks things, so:
        # instead we simply just make `libusb1` and `lm4tools`'s stdenv static.
        # config.replaceStdenv = { pkgs }: pkgs.stdenvAdapters.makeStatic pkgs.stdenv;
        overlays = args.overlays ++ [
          (f: p: let
            makePkgStdEnvStatic = pkgName:
              let
                base = p.${pkgName};
              in {
                ${pkgName} = base.override { stdenv = f.stdenvAdapters.makeStatic p.stdenv; };
              };
          in
            (makePkgStdEnvStatic "lm4tools") //
            (makePkgStdEnvStatic "libusb1")
          )
        ];
      };
    }
  ) nativeSystems;

  # Altogether:
  binaries = crossBinaries // nativeBinaries;

  # Make a Univeral macOS binary:
  macOSUniversal = np.stdenv.mkDerivation {
    name = "lm4flash-universal";
    unpackPhase = "true";
    nativeBuildInputs = with np; [ llvm ];
    installPhase = ''
      mkdir -p $out/bin
      llvm-lipo \
        --create \
        --output $out/bin/lm4flash \
        ${binaries.macOS-amd64}/bin/lm4flash \
        ${binaries.macOS-arm64}/bin/lm4flash
    '';
  };

  final = np.stdenvNoCC.mkDerivation {
    name = "lm4flash-binaries";
    unpackPhase = "true";
    installPhase = with binaries; ''
      mkdir $out
      copy() { cp $1/bin/lm4flash$3 $out/$2; }

      copy ${win-amd64} lm4flash.exe .exe
      copy ${linux-amd64} lm4flash-linux-amd64
      copy ${linux-arm64} lm4flash-linux-arm64
      copy ${macOSUniversal} lm4flash-macos
    '';
  };
in final

# Assuming on ARM macOS.
# Run as: `nix build -f build.nix --arg lm4toolsPkg ./default.nix --arg altSystem "aarch64-linux"`
Clone this wiki locally