nix-community / dream2nix

Simplified nix packaging for various programming language ecosystems [maintainer=@DavHau]
https://nix-community.github.io/dream2nix
MIT License
921 stars 121 forks source link

How to build pip package from source that requires rust toolchain #982

Open rupurt opened 3 weeks ago

rupurt commented 3 weeks ago

Howdy :wave:

I'm trying to add object-store-python as a dependency that will build from source as they haven't released a new pypi version. Is this possible with the current pip module? I've tried adding an override with cargo but it doesn't seem to get picked up.

Collecting object-store-python@ https://github.com/roeap/object-store-python/archive/6144879f3061f298122b28318bcad0a7d4001d09.zip#subdirectory=object-store
  Using cached https://github.com/roeap/object-store-python/archive/6144879f3061f298122b28318bcad0a7d4001d09.zip
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error

  × Preparing metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [6 lines of output]

      Cargo, the Rust package manager, is not installed or is not on PATH.
      This package requires Rust and Cargo to compile extensions. Install it through
      the system's package manager or via https://rustup.rs/

      Checking for Rust toolchain....
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed
  deps = {
    nixpkgs,
    self,
    ...
  }: {
    stdenv = nixpkgs.stdenv;
    python = nixpkgs.python312;
    cargo = nixpkgs.cargo;
  };

  pip = {
    requirementsList =
      pyproject.build-system.requires
      or []
      ++ pyproject.project.dependencies
      ++ lib.optionals (config.flags.groupDev) pyproject.project.optional-dependencies.dev;
    flattenDependencies = true;
    overrideAll.deps.python = lib.mkForce config.deps.python;
    overrides = {
      object-store-python.mkDerivation = {
        buildInputs = [
          config.deps.cargo
        ];
      };
  };
rupurt commented 3 weeks ago

I managed to get past the lock step by setting the module nativeBuildInputs

   nativeBuildInputs = [
      config.deps.cargo
      config.deps.rustc
    ];

However now I'm getting an error that the maturin backend is not available

error: builder for '/nix/store/5iyp7bl10msjnyhma16yzhr4v3jc89xi-python3.12-object-store-python-0.1.10.drv' failed with exit code 1;
       last 25 log lines:
       > Running phase: patchPhase
       > Running phase: updateAutotoolsGnuConfigScriptsPhase
       > Running phase: configurePhase
       > no configure script, doing nothing
       > Running phase: buildPhase
       > Executing pypaBuildPhase
       > Creating a wheel...
       > * Getting build dependencies for wheel...
       >
       > Traceback (most recent call last):
       >   File "/nix/store/94h0xf60fkvmz4gvwbp9xbaf5wiqy8hf-python3.12-pyproject-hooks-1.0.0/lib/python3.12/site-packages/pyproject_hooks/_impl.py", line 321, in _call_hook
       >     raise BackendUnavailable(data.get('traceback', ''))
       > pyproject_hooks._impl.BackendUnavailable: Traceback (most recent call last):
       >   File "/nix/store/94h0xf60fkvmz4gvwbp9xbaf5wiqy8hf-python3.12-pyproject-hooks-1.0.0/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 77, in _build_backend
       >     obj = import_module(mod_path)
       >           ^^^^^^^^^^^^^^^^^^^^^^^
       >   File "/nix/store/c7ycrgwv039nqglbif98yggx211sdbcl-python3-3.12.3/lib/python3.12/importlib/__init__.py", line 90, in import_module
       >     return _bootstrap._gcd_import(name[level:], package, level)
       >            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       >   File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
       >   File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
       >   File "<frozen importlib._bootstrap>", line 1324, in _find_and_load_unlocked
       > ModuleNotFoundError: No module named 'maturin'
       >
       > ERROR Backend 'maturin' is not available.
       For full logs, run 'nix log /nix/store/5iyp7bl10msjnyhma16yzhr4v3jc89xi-python3.12-object-store-python-0.1.10.drv'.
rupurt commented 3 weeks ago

Made some more progress by using the maturinBuildHook from rustPlatform in the pip override

      object-store-python = {
        mkDerivation = {
          sourceRoot = "object-store-python-6144879f3061f298122b28318bcad0a7d4001d09/object-store";
        };

        buildPythonPackage = {
          build-system = [
            config.deps.rustPlatform.maturinBuildHook
          ];
        };
      };

It's now failing because the Cargo.lock file is in the source root directory but the pip package I want to build in the object-store subdirectory. I think I'll need to remove the sourceRoot and figure out how to pick the correct subdirectory with pyproject.toml to build.