Skip to content

Commit

Permalink
python: propagate makeWrapper arguments
Browse files Browse the repository at this point in the history
Python libraries that have runtime dependencies, like Qt and GTK
libraries, are currently not working. These are not included in
the interpreter wrapper and no mechanism exist to do so automatically.

This commit adds a `nix-support/make-wrapper-args` file that stores
the makeWrapper arguments of a python derivation (created with
buildPythonPackage). The arguments are loaded from python.buildEnv
when creating the Python environment and passed to the makeWrapper
invocation.
  • Loading branch information
rnhmjoj committed Sep 2, 2020
1 parent f90a11a commit af1c62d
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 6 deletions.
3 changes: 2 additions & 1 deletion pkgs/development/interpreters/python/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ with pkgs;
isPyPy = lib.hasInfix "pypy" interpreter;

buildEnv = callPackage ./wrapper.nix { python = self; inherit (pythonPackages) requiredPythonModules; };
withPackages = import ./with-packages.nix { inherit buildEnv pythonPackages;};
withPackages = import ./with-packages.nix { inherit buildEnv pythonPackages; };

pkgs = pythonPackages;
interpreter = "${self}/bin/${executable}";
inherit executable implementation libPrefix pythonVersion sitePackages;
Expand Down
6 changes: 6 additions & 0 deletions pkgs/development/interpreters/python/hooks/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ in rec {
};
} ./pip-install-hook.sh) {};

propagateWrapperArgsHook = callPackage ({ }:
makeSetupHook {
name = "propagate-wrapper-args";
deps = [ ];
} ./propagate-wrapper-args.sh) {};

pytestCheckHook = callPackage ({ pytest }:
makeSetupHook {
name = "pytest-check-hook";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Hook that propagates wrapper arguments up to the
# python interpreter buildEnv environment.
echo "Sourcing propagate-wrapper-args.sh"

storeWrapperArgsHook() {
# Store the arguments for use by other derivations
# and the python interpreter derivation.
echo "Executing propagateWrapperArgsHook"

mkdir -p "$out/nix-support"
if [ ${#qtWrapperArgs[@]} -ne 0 ]; then
printf '%s\n' "${qtWrapperArgs[@]}" >> "$out/nix-support/make-wrapper-args"
fi
if [ ${#gappsWrapperArgs[@]} -ne 0 ]; then
printf '%s\n' "${gappsWrapperArgs[@]}" >> "$out/nix-support/make-wrapper-args"
fi
if [ ${#makeWrapperArgs[@]} -ne 0 ]; then
printf '%s\n' "${makeWrapperArgs[@]}" >> "$out/nix-support/make-wrapper-args"
fi
}

loadWrapperArgsHook() {
# Load the arguments from all the dependencies.
# Note: this hook *must* run after storeWrapperArgsHook to
# avoid an exponential duplication of the wrapper arguments.
for path in $propagatedBuildInputs "$@"; do
if [ -f "$path/nix-support/make-wrapper-args" ]; then
makeWrapperArgs+=$(cat "$path/nix-support/make-wrapper-args")
fi
done
}

postFixupHooks+=(storeWrapperArgsHook loadWrapperArgsHook)
2 changes: 2 additions & 0 deletions pkgs/development/interpreters/python/mk-python-derivation.nix
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
, flitBuildHook
, pipBuildHook
, pipInstallHook
, propagateWrapperArgsHook
, pythonCatchConflictsHook
, pythonImportsCheckHook
, pythonNamespacesHook
Expand Down Expand Up @@ -113,6 +114,7 @@ let
ensureNewerSourcesForZipFilesHook # move to wheel installer (pip) or builder (setuptools, flit, ...)?
pythonRecompileBytecodeHook # Remove when solved https://github.com/NixOS/nixpkgs/issues/81441
pythonRemoveTestsDirHook
propagateWrapperArgsHook
] ++ lib.optionals catchConflicts [
setuptools pythonCatchConflictsHook
] ++ lib.optionals removeBinBytecode [
Expand Down
21 changes: 16 additions & 5 deletions pkgs/development/interpreters/python/wrapper.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# Create a python executable that knows about additional packages.
let
env = let
paths = requiredPythonModules (extraLibs ++ [ python ] ) ;
paths = requiredPythonModules (extraLibs ++ [ python ]);
pythonPath = "${placeholder "out"}/${python.sitePackages}";
pythonExecutable = "${placeholder "out"}/bin/${python.executable}";
in buildEnv {
Expand All @@ -22,29 +22,40 @@ let
inherit ignoreCollisions;
extraOutputsToInstall = [ "out" ] ++ extraOutputsToInstall;

postBuild = ''
buildInputs = [ python.pkgs.propagateWrapperArgsHook ];

postBuild = with stdenv.lib; ''
. "${makeWrapper}/nix-support/setup-hook"
# Load propagated wrapper arguments from each
# path in the environment.
loadWrapperArgsHook ${concatStringsSep " " paths}
if [ -L "$out/bin" ]; then
unlink "$out/bin"
fi
mkdir -p "$out/bin"
for path in ${stdenv.lib.concatStringsSep " " paths}; do
for path in ${concatStringsSep " " paths}; do
if [ -d "$path/bin" ]; then
cd "$path/bin"
for prg in *; do
if [ -f "$prg" ]; then
rm -f "$out/bin/$prg"
if [ -x "$prg" ]; then
makeWrapper "$path/bin/$prg" "$out/bin/$prg" --set NIX_PYTHONPREFIX "$out" --set NIX_PYTHONEXECUTABLE ${pythonExecutable} --set NIX_PYTHONPATH ${pythonPath} ${if permitUserSite then "" else ''--set PYTHONNOUSERSITE "true"''} ${stdenv.lib.concatStringsSep " " makeWrapperArgs}
makeWrapper "$path/bin/$prg" "$out/bin/$prg" \
--set NIX_PYTHONPREFIX "$out" \
--set NIX_PYTHONEXECUTABLE ${pythonExecutable} \
--set NIX_PYTHONPATH \
${pythonPath} \
${optionalString (!permitUserSite) ''--set PYTHONNOUSERSITE "true"''} \
''${makeWrapperArgs[@]}
fi
fi
done
fi
done
'' + postBuild;

inherit (python) meta;

passthru = python.passthru // {
Expand Down
1 change: 1 addition & 0 deletions pkgs/top-level/python-packages.nix
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ in {
flitBuildHook
pipBuildHook
pipInstallHook
propagateWrapperArgsHook
pytestCheckHook
pythonCatchConflictsHook
pythonImportsCheckHook
Expand Down

0 comments on commit af1c62d

Please sign in to comment.