How to package a Rust application with python bindings

Hi,

I need help in building a Rust package that contains python bindings. Currently, I’ve listed in the nativeBuildInputs all the Python packages that the bindings require and only the installPhase fails. Here’s the relevant part from the log:

TEST FAILED: /nix/store/2xg4lc4bxxsw80w194wvbhp2pyj62haa-sequoia-0.8.0/lib/python3.7/site-packages/ does NOT support .pth files
error: bad install directory or PYTHONPATH

You are attempting to install a package to a directory that is not
on PYTHONPATH and which Python does not read ".pth" files from.  The
installation directory you specified (via --install-dir, --prefix, or
the distutils default setting) was:

    /nix/store/2xg4lc4bxxsw80w194wvbhp2pyj62haa-sequoia-0.8.0/lib/python3.7/site-packages/

and your PYTHONPATH environment variable currently contains:

    '/nix/store/4c4ajgdnhlqk994hilagk5cgv7vw9yzg-python3-3.7.3/lib/python3.7/site-packages:/nix/store/4x78gsi5bv90fyy2s0mzbvdqqh9r5s4l-python3.7-pycparser-2.19/lib/python3.7/site-packages:/nix/store/vrz3m340f1gd5rd51dgyjfxs9xlw7ns1-python3.7-setuptools-41.0.1/lib/python3.7/site-packages:/nix/store/bsj9vi3rv9rrc5753hrm90rbxscchwjr-python3.7-cffi-1.12.3/lib/python3.7/site-packages:/nix/store/6d9yhxbfigsdn0yx2930s6fkfcb1nrlm-python3.7-pytest-4.2.1/lib/python3.7/site-packages:/nix/store/mxp6vn80iijxc29zygp31xvvwisxjjf3-python3.7-attrs-18.2.0/lib/python3.7/site-packages:/nix/store/6dr7kw0sh4ddic5ax1qx3b3bb1kmap98-python3.7-py-1.7.0/lib/python3.7/site-packages:/nix/store/dp69kvb1ba1f3y401f47hk2zz8mr86mh-python3.7-six-1.12.0/lib/python3.7/site-packages:/nix/store/wp024fspqw8brw8n1kn9q9xmmz624x6d-python3.7-pluggy-0.8.1/lib/python3.7/site-packages:/nix/store/h0wizcpxiws9px4sx0pqb8qwvakmf4m6-python3.7-more-itertools-6.0.0/lib/python3.7/site-packages:/nix/store/m3xi0x1micjdcpkgk5gv6r3ydnjh6pa4-python3.7-atomicwrites-1.3.0/lib/python3.7/site-packages:/nix/store/abz6jpl55ia132c98hr1i74k330p7fh9-python3.7-pytest-runner-4.2/lib/python3.7/site-packages:/nix/store/4c4ajgdnhlqk994hilagk5cgv7vw9yzg-python3-3.7.3/lib/python3.7/site-packages:/nix/store/4x78gsi5bv90fyy2s0mzbvdqqh9r5s4l-python3.7-pycparser-2.19/lib/python3.7/site-packages:/nix/store/vrz3m340f1gd5rd51dgyjfxs9xlw7ns1-python3.7-setuptools-41.0.1/lib/python3.7/site-packages:/nix/store/bsj9vi3rv9rrc5753hrm90rbxscchwjr-python3.7-cffi-1.12.3/lib/python3.7/site-packages:/nix/store/6d9yhxbfigsdn0yx2930s6fkfcb1nrlm-python3.7-pytest-4.2.1/lib/python3.7/site-packages:/nix/store/mxp6vn80iijxc29zygp31xvvwisxjjf3-python3.7-attrs-18.2.0/lib/python3.7/site-packages:/nix/store/6dr7kw0sh4ddic5ax1qx3b3bb1kmap98-python3.7-py-1.7.0/lib/python3.7/site-packages:/nix/store/dp69kvb1ba1f3y401f47hk2zz8mr86mh-python3.7-six-1.12.0/lib/python3.7/site-packages:/nix/store/wp024fspqw8brw8n1kn9q9xmmz624x6d-python3.7-pluggy-0.8.1/lib/python3.7/site-packages:/nix/store/h0wizcpxiws9px4sx0pqb8qwvakmf4m6-python3.7-more-itertools-6.0.0/lib/python3.7/site-packages:/nix/store/m3xi0x1micjdcpkgk5gv6r3ydnjh6pa4-python3.7-atomicwrites-1.3.0/lib/python3.7/site-packages:/nix/store/abz6jpl55ia132c98hr1i74k330p7fh9-python3.7-pytest-runner-4.2/lib/python3.7/site-packages:/nix/store/4c4ajgdnhlqk994hilagk5cgv7vw9yzg-python3-3.7.3/lib/python3.7/site-packages:/nix/store/4x78gsi5bv90fyy2s0mzbvdqqh9r5s4l-python3.7-pycparser-2.19/lib/python3.7/site-packages:/nix/store/vrz3m340f1gd5rd51dgyjfxs9xlw7ns1-python3.7-setuptools-41.0.1/lib/python3.7/site-packages:/nix/store/bsj9vi3rv9rrc5753hrm90rbxscchwjr-python3.7-cffi-1.12.3/lib/python3.7/site-packages:/nix/store/6d9yhxbfigsdn0yx2930s6fkfcb1nrlm-python3.7-pytest-4.2.1/lib/python3.7/site-packages:/nix/store/mxp6vn80iijxc29zygp31xvvwisxjjf3-python3.7-attrs-18.2.0/lib/python3.7/site-packages:/nix/store/6dr7kw0sh4ddic5ax1qx3b3bb1kmap98-python3.7-py-1.7.0/lib/python3.7/site-packages:/nix/store/dp69kvb1ba1f3y401f47hk2zz8mr86mh-python3.7-six-1.12.0/lib/python3.7/site-packages:/nix/store/wp024fspqw8brw8n1kn9q9xmmz624x6d-python3.7-pluggy-0.8.1/lib/python3.7/site-packages:/nix/store/h0wizcpxiws9px4sx0pqb8qwvakmf4m6-python3.7-more-itertools-6.0.0/lib/python3.7/site-packages:/nix/store/m3xi0x1micjdcpkgk5gv6r3ydnjh6pa4-python3.7-atomicwrites-1.3.0/lib/python3.7/site-packages:/nix/store/abz6jpl55ia132c98hr1i74k330p7fh9-python3.7-pytest-runner-4.2/lib/python3.7/site-packages'

Here are some of your options for correcting the problem:

* You can choose a different installation directory, i.e., one that is
  on PYTHONPATH or supports .pth files

* You can add the installation directory to the PYTHONPATH environment
  variable.  (It must then also be on PYTHONPATH whenever you run
  Python and want to use the package(s) you are installing.)

* You can set up the installation directory to support ".pth" files by
  using one of the approaches described here:

  https://setuptools.readthedocs.io/en/latest/easy_install.html#custom-installation-locations

It seems the most natural way is to set PYTHONPATH as an attribute to the rustPlatform.buildRustPackage so it will be used as an environmental variable.

I tried adding:

  PYTHONPATH = "${out}/lib/python3.7/site-packages

But I got this error from nix-build:

error: undefined variable 'out' at /var/src/nixpkgs/pkgs/tools/security/sequoia/default.nix:34:19

Since the project uses a Makefile for the installation of other various support files, my installPhase is:

make PREFIX=$out install

I guess I could just use:

env PYTHONPATH=$PYTHONPATH:$out/lib/python3.7/site-packages make PREFIX=$out install

But I’m not sure this is the best way to go.

I’ve also learned about the toPythonModule function from stdlib which is supposed to be used for Python bindings of non Python packages. It seems to me, from reading the examples that it just overrides a package with the necessary changed flags to make it install the bindings as well.

If I’ll use it, Would that mean that every user of my package will have to rebuild it from the ground up just because he wants the python bindings? I think that would be rather insane considering the fact that as a Rust package, it takes hours for it to build and test so a modified derivation of it by toPythonModule will require a rebuild although it shouldn’t be necessary.

Thanks for any help in advance.

I’ve found various workarounds here thanks to @volth’s comment.

I wish that suggestion would have been considered… It would have saved me a lot of time / frustration around this package addition…