Building a package from a .deb

Hi all

Can anyone help please? I am trying to build a package for my printer as when using the generic printer options, the colour is wrong and I can’t choose the paper type (photo/glossy). I am able to use the .rpm fine on OpenSUSE and I have tried to follow the instructions in the wiki for creating a package with a .deb file but I’ve had mutiple different errors and I’ve not been able to get any part of it to work properly.
Can someone please explain how I download, extract and then build this .deb file - https://download.brother.com/welcome/dlf105455/mfcj5340dwpdrv-3.5.0-1.i386.deb
I’ve had various errors about src not being defined and many others.

Thanks in advance

In the nixpkgs source look for unpackCmd = "dpkg and you will find plenty of inspiration

1 Like

How to install deb or rpm - #5 by bme has the minimal code to unpack a deb (you’ll need to substitute url / hash). You will need to adapt the contents to work as a cups driver. You should look at other drivers for brother printers to gain an intuition of what derivation output needs to look like to function. See also this thread for another example of patching a brother driver.

I’ve been able to build via nix-build but that just gives me a directory called ‘result’, I’ve no idea what to do next

If you look inside ./result you’ll see the contents of the .deb.

I have no idea how to do that, do I make it into a package and install it from the local package or do I add it to the nixos repo somehow?

This is all I have at the moment:

default.nix

let
  pkgs = import <nixpkgs> { };
  package =
    {
      dpkg,
      fetchurl,
      stdenv,
    }:
    stdenv.mkDerivation {
      pname = "mfcj5340dwp";
      version = "3.5.0-1";
      src = fetchurl {
        url = "https://download.brother.com/welcome/dlf105455/mfcj5340dwpdrv-3.5.0-1.i386.deb";
        hash = "sha256-VVq5Urcdaag3rAfsWDtr8/HhLSxOiXScawhxmyS4GEM=";
      };
      nativeBuildInputs = [ dpkg ];

      installPhase = ''
        mkdir $out
        cp -r . $out
      '';
    };
in
pkgs.callPackage package { }

Also, I’ve rewritten the example package:
default.nix

{
  pkgsi686Linux,
  stdenv,
  fetchurl,
  dpkg,
  makeWrapper,
  coreutils,
  ghostscript,
  gnugrep,
  gnused,
  which,
  perl,
  lib,
}:

let
  model = "mfcj5340dw";
  version = "3.5.0-1";
  src = fetchurl {
    url = "https://download.brother.com/welcome/dlf105455/${model}pdrv-${version}.i386.deb";
    sha256 = "sha256-VVq5Urcdaag3rAfsWDtr8/HhLSxOiXScawhxmyS4GEM=";
  };
  reldir = "opt/brother/Printers/${model}/";

in
rec {
  driver = pkgsi686Linux.stdenv.mkDerivation rec {
    inherit src version;
    name = "${model}drv-${version}";

    nativeBuildInputs = [
      dpkg
      makeWrapper
    ];

    unpackPhase = "dpkg-deb -x $src $out";

    installPhase = ''
        dir="$out/${reldir}"
        substituteInPlace $dir/lpd/filter_${model} \
          --replace /usr/bin/perl ${perl}/bin/perl \
          --replace "BR_PRT_PATH =~" "BR_PRT_PATH = \"$dir\"; #" \
          --replace "PRINTER =~" "PRINTER = \"${model}\"; #"
        wrapProgram $dir/lpd/filter_${model} \
          --prefix PATH : ${
            lib.makeBinPath [
              coreutils
              ghostscript
              gnugrep
              gnused
              which
            ]
          }
      # need to use i686 glibc here, these are 32bit proprietary binaries
      patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
        $dir/lpd/brmfcl3770cdwfilter
    '';

    meta = {
      description = "Brother ${lib.strings.toUpper model} driver";
      homepage = "http://www.brother.com/";
      sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
      license = lib.licenses.unfree;
      platforms = [
        "x86_64-linux"
        "i686-linux"
      ];
      maintainers = [ lib.maintainers.steveej ];
    };
  };

  cupswrapper = stdenv.mkDerivation rec {
    inherit version src;
    name = "${model}cupswrapper-${version}";

    nativeBuildInputs = [
      dpkg
      makeWrapper
    ];

    unpackPhase = "dpkg-deb -x $src $out";

    installPhase = ''
      basedir=${driver}/${reldir}
      dir=$out/${reldir}
      substituteInPlace $dir/cupswrapper/brother_lpdwrapper_${model} \
        --replace /usr/bin/perl ${perl}/bin/perl \
        --replace "basedir =~" "basedir = \"$basedir\"; #" \
        --replace "PRINTER =~" "PRINTER = \"${model}\"; #"
      wrapProgram $dir/cupswrapper/brother_lpdwrapper_${model} \
        --prefix PATH : ${
          lib.makeBinPath [
            coreutils
            gnugrep
            gnused
          ]
        }
      mkdir -p $out/lib/cups/filter
      mkdir -p $out/share/cups/model
      ln $dir/cupswrapper/brother_lpdwrapper_${model} $out/lib/cups/filter
      ln $dir/cupswrapper/brother_${model}_printer_en.ppd $out/share/cups/model
    '';

    meta = {
      description = "Brother ${lib.strings.toUpper model} CUPS wrapper driver";
      homepage = "http://www.brother.com/";
      sourceProvenance = with lib.sourceTypes; [ binaryNativeCode ];
      license = lib.licenses.gpl2Plus;
      platforms = [
        "x86_64-linux"
        "i686-linux"
      ];
      maintainers = [ lib.maintainers.squarepeg ];
    };
  };
}

1 Like

can anyone confirm if this will work or advise how to test/package?