Brother DCP-572DW wrapper

I’d like to install the aforementioned printer with a custom nix expression:

{ stdenv, fetchurl, cups, dpkg, ghostscript, a2ps, coreutils, gnused, gawk, file, makeWrapper }:

stdenv.mkDerivation rec {
  pname = "dcp-j572dw-cupswrapper";
  version = "1.0.5-0";

  src = fetchurl {
    url = "https://download.brother.com/welcome/dlf103777/dcpj572dwpdrv-${version}.i386.deb";
    sha256 = "7166e4c46e42c24dc9342eccf014547dda61580c91be4293e821a196343a8fa7";
  };

  nativeBuildInputs = [ makeWrapper ];
  buildInputs = [ cups ghostscript dpkg a2ps ];

  dontUnpack = true;

  installPhase = ''
    dpkg-deb -x $src $out

    patchelf --set-interpreter ${stdenv.glibc.out}/lib/ld-linux.so.2 $out/opt/brother/Printers/dcpj572dw/lpd/brdcpj572dwfilter

    mkdir -p $out/lib/cups/filter/
    ln -s $out/opt/brother/Printers/dcp572dw/lpd/filter_dcpj572dw $out/lib/cups/filter/brother_lpdwrapper_dcpj572dw

    substituteInPlace $out/opt/brother/Printers/dcpj572dw/cupswrapper/brother_lpdwrapper_dcpj572dw \
    --replace /opt "$out/opt" 

    substituteInPlace $out/opt/brother/Printers/dcpj572dw/cupswrapper/cupswrapperdcpj572dw \
    --replace /opt "$out/opt" 
    '';

  meta = {
    homepage = "http://www.brother.com/";
    description = "Brother DCP-J572DW LPR driver";
    license = stdenv.lib.licenses.unfree;
    platforms = stdenv.lib.platforms.linux;
    downloadPage = "http://support.brother.com/g/b/downloadlist.aspx?c=us&lang=en&prod=mfcj470dw_us_eu_as&os=128";
  };
}

It is modelled after: https://github.com/NixOS/nixpkgs/blob/a3389443b3d6c6857554721dd1b1f61367878bcc/pkgs/misc/cups/drivers/mfcj470dwlpr/default.nix

I’m probably doing all kinds of things wrong, even though: this way it a least installs something :smiley:

Any pointers on how to proceed?


On another note: can anyone recommend a networked printer/scanner combination that works out of the box with NixOS?

Ok, so my current setup is the following:

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

let
  model = "dcpj572dw";
  version = "1.0.5-0";
  src = fetchurl {
    url = "https://download.brother.com/welcome/dlf103777/dcpj572dwpdrv-${version}.i386.deb";
    sha256 = "7166e4c46e42c24dc9342eccf014547dda61580c91be4293e821a196343a8fa7";
  };
  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 : ${stdenv.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/br${model}filter
    '';

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

  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 : ${stdenv.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/";
      license = stdenv.lib.licenses.gpl2;
      platforms = [ "x86_64-linux" "i686-linux" ];
    };
  };
}

This makes it at least possible to install the driver (as in: it is selectable in the CUPS web gui) but it won’t print. It simply does nothing.

I already tried to follow the advice given here: Gentoo Forums :: View topic - How to install an Brother (DCP-J572) Printer correctly? and configure it via lpd.

I was able to configure my Brother MFC-J4620DW with CUPS GUI over WIFI by choosing:
Internet Printing Protocol (ipp)
For the connection type and then entering the details as:
lpd://[IP_ADDRESS]/queue
Then just continue setup & choose the correct driver, defaults, etc.

While this looks really promising (you can see many options in the gui that look sensible) it still doesn’t print the test page at all.

Any pointers on how to debug this?

So this is slightly off-topic, but I’m hoping it can help you.

I have a Brother printer too, and it turns out that it supports “IPP Everywhere” which was completely new to me.

So this is the only config I use to get mine working:

hardware =
  let
    brother = "Brother_HL-3170CDW_NixOS";
    hostName = "printer.home.hoeg.com";
  in
  {
    printers = {
      ensureDefaultPrinter = brother;
      ensurePrinters = [
        {
          name = brother;
          deviceUri = "ipp://${hostName}/ipp";
          model = "everywhere";
          description = lib.replaceStrings [ "_" ] [ " " ] brother;
          location = "Study";
        }
      ];
    };
  };

No fiddling with strange wrappers or drivers - IPP Everywhere just works.

7 Likes

Ha. Incredible… that really works :smiley:
Thank you so much.

I don’t recall how I stumbled over IPP Everywhere but it definitely should be getting more attention.

3 Likes

I added the code to the config but there is no printer shown. (21.11)
What else needs to be in the configuration?

Probably this:

services.printing.enable = true;

1 Like