diff --git a/packages/build-support/drv-parts/backends/buildPythonPackage/default.nix b/packages/build-support/drv-parts/backends/buildPythonPackage/default.nix new file mode 100644 index 0000000..2272cc4 --- /dev/null +++ b/packages/build-support/drv-parts/backends/buildPythonPackage/default.nix @@ -0,0 +1,9 @@ +{ drv-backends, ... }: + +{ + drv-backends.buildPythonPackage.imports = [ + drv-backends.mkDerivation + ./interface.nix + ./implementation.nix + ]; +} diff --git a/packages/build-support/drv-parts/backends/buildPythonPackage/implementation.nix b/packages/build-support/drv-parts/backends/buildPythonPackage/implementation.nix new file mode 100644 index 0000000..562a308 --- /dev/null +++ b/packages/build-support/drv-parts/backends/buildPythonPackage/implementation.nix @@ -0,0 +1,91 @@ +{ config, dependencySets, lib, ... }: + +let + inherit (config) deps; + + withDistOutput = lib.elem config.format [ + "pyproject" + "setuptools" + "flit" + "wheel" + ]; +in + +{ + deps = { pkgs, python3Packages, ... }: { + inherit (python3Packages) + python + wrapPython + pythonRemoveTestsDirHook + pythonCatchConflictsHook + pythonRemoveBinBytecodeHook + unzip + setuptoolsBuildHook + flitBuildHook + pipBuildHook + wheelUnpackHook + eggUnpackHook eggBuildHook eggInstallHook + pipInstallHook + pythonImportsCheckHook + pythonNamespacesHook + pythonOutputDistHook + ; + inherit (pkgs) + ensureNewerSourcesForZipFilesHook + ; + }; + + nativeBuildInputs = with deps; [ + python + wrapPython + ensureNewerSourcesForZipFilesHook + pythonRemoveTestsDirHook + ] ++ lib.optionals config.catchConflicts [ + pythonCatchConflictsHook + ] ++ lib.optionals config.removeBinByteCode [ + pythonRemoveBinBytecodeHook + ] ++ lib.optionals (lib.hasSuffix "zip" (config.src.name or "")) [ + unzip + ] ++ lib.optionals (config.format == "setuptools") [ + setuptoolsBuildHook + ] ++ lib.optionals (config.format == "flit") [ + flitBuildHook + ] ++ lib.optionals (config.format == "pyproject") [ + pipBuildHook + ] ++ lib.optionals (config.format == "wheel") [ + wheelUnpackHook + ] ++ lib.optionals (config.format == "egg") [ + eggUnpackHook eggBuildHook eggInstallHook + ] ++ lib.optionals (!(config.format == "other") || config.dontUsePipInstall) [ + pipInstallHook + ] ++ lib.optionals (python.stdenv.buildPlatform == python.stdenv.hostPlatform) [ + # This is a test, however, it should be ran independent of the checkPhase and checkInputs + pythonImportsCheckHook + ] ++ lib.optionals (python.pythonAtLeast "3.3") [ + # Optionally enforce PEP420 for python3 + pythonNamespacesHook + ] ++ lib.optionals withDistOutput [ + pythonOutputDistHook + ]; + + propagatedBuildInputs = with deps; [ + python + ]; + + env = { + strictDeps = if config.strictDeps == null then false else config.strictDeps; + LANG = "${if deps.python.stdenv.isDarwin then "en_US" else "C"}.UTF-8"; + }; + + doCheck = false; + doInstallCheck = lib.mkDefault true; + installCheckInputs = lib.optionals (config.format == "setuptools") [ + deps.setuptoolsCheckHook + ]; + + postFixup = lib.mkBefore (lib.optionalString (!config.dontWrapPythonPrograms) '' + wrapPythonPrograms + ''); + + outputs = [ "out" ] ++ lib.optional withDistOutput "dist"; +} diff --git a/packages/build-support/drv-parts/backends/buildPythonPackage/interface.nix b/packages/build-support/drv-parts/backends/buildPythonPackage/interface.nix new file mode 100644 index 0000000..8f31ddf --- /dev/null +++ b/packages/build-support/drv-parts/backends/buildPythonPackage/interface.nix @@ -0,0 +1,27 @@ +{ lib, ... }: +with lib; + +let + flag = default: description: mkOption { + inherit description default; + type = types.bool; + }; +in + +{ + options = { + format = mkOption { + description = "Python package source format"; + type = types.enum [ + "setuptools" + "pyproject" + "flit" + "wheel" + "other" + ]; + }; + catchConflicts = flag true "If true, abort package build if a package name appears more than once in dependency tree."; + dontWrapPythonPrograms = flag false "Skip wrapping of Python programs."; + removeBinByteCode = flag true "Remove bytecode from /bin. Bytecode is only created when the filenames end with .py."; + }; +} diff --git a/packages/build-support/drv-parts/backends/default.nix b/packages/build-support/drv-parts/backends/default.nix index 86e0060..7c5a71f 100644 --- a/packages/build-support/drv-parts/backends/default.nix +++ b/packages/build-support/drv-parts/backends/default.nix @@ -1,5 +1,7 @@ { imports = [ ./options.nix + + ./buildPythonPackage ]; }