From 03eaa480bd7a649e0cfc4f8479fc6deba279eb48 Mon Sep 17 00:00:00 2001 From: volth Date: Tue, 9 Apr 2019 14:49:47 +0000 Subject: [PATCH] perl: add .withPackages --- .../development/interpreters/perl/default.nix | 21 ++++++- .../development/interpreters/perl/wrapper.nix | 55 +++++++++++++++++++ .../perl-modules/generic/default.nix | 6 +- pkgs/top-level/all-packages.nix | 19 ++----- pkgs/top-level/perl-packages.nix | 23 +++++++- 5 files changed, 103 insertions(+), 21 deletions(-) create mode 100644 pkgs/development/interpreters/perl/wrapper.nix diff --git a/pkgs/development/interpreters/perl/default.nix b/pkgs/development/interpreters/perl/default.nix index 9adc72f941a2..e03777b0fb35 100644 --- a/pkgs/development/interpreters/perl/default.nix +++ b/pkgs/development/interpreters/perl/default.nix @@ -1,4 +1,4 @@ -{ lib, stdenv, fetchurl, buildPackages +{ config, lib, stdenv, fetchurl, buildPackages, callPackage , enableThreading ? stdenv ? glibc, makeWrapper }: @@ -22,7 +22,8 @@ let libcInc = lib.getDev libc; libcLib = lib.getLib libc; crossCompiling = stdenv.buildPlatform != stdenv.hostPlatform; - common = { version, sha256 }: stdenv.mkDerivation (rec { + + common = { self, version, sha256 }: stdenv.mkDerivation (rec { inherit version; name = "perl-${version}"; @@ -104,7 +105,19 @@ let setupHook = ./setup-hook.sh; - passthru.libPrefix = "lib/perl5/site_perl"; + passthru = rec { + interpreter = "${self}/bin/perl"; + libPrefix = "lib/perl5/site_perl"; + pkgs = callPackage ../../../top-level/perl-packages.nix { + perl = self; + overrides = config.perlPackageOverrides or (p: {}); # TODO: (self: super: {}) like in python + }; + buildEnv = callPackage ./wrapper.nix { + perl = self; + inherit (pkgs) requiredPerlModules; + }; + withPackages = f: buildEnv.override { extraLibs = f pkgs; }; + }; doCheck = false; # some tests fail, expensive @@ -179,12 +192,14 @@ let in rec { # the latest Maint version perl528 = common { + self = perl528; version = "5.28.1"; sha256 = "0iy3as4hnbjfyws4in3j9d6zhhjxgl5m95i5n9jy2bnzcpz8bgry"; }; # the latest Devel version perldevel = common { + self = perldevel; version = "5.29.9"; sha256 = "017x3nghyc5m8q1yqnrdma96b3d5rlfx87vv5mi64jq0r8k6zppm"; }; diff --git a/pkgs/development/interpreters/perl/wrapper.nix b/pkgs/development/interpreters/perl/wrapper.nix new file mode 100644 index 000000000000..9142a1f4fc36 --- /dev/null +++ b/pkgs/development/interpreters/perl/wrapper.nix @@ -0,0 +1,55 @@ +{ stdenv, perl, buildEnv, makeWrapper +, extraLibs ? [] +, extraOutputsToInstall ? [] +, postBuild ? "" +, ignoreCollisions ? false +, lib +, requiredPerlModules +, makeWrapperArgs ? [] +}: + +# Create a perl executable that knows about additional packages. +let + env = let + paths = requiredPerlModules (extraLibs ++ [ perl ] ); + in buildEnv { + name = "${perl.name}-env"; + + inherit paths; + inherit ignoreCollisions; + extraOutputsToInstall = [ "out" ] ++ extraOutputsToInstall; + + # we create wrapper for the binaries in the different packages + postBuild = '' + + . "${makeWrapper}/nix-support/setup-hook" + + if [ -L "$out/bin" ]; then + unlink "$out/bin" + fi + mkdir -p "$out/bin" + + # take every binary from perl packages and put them into the env + for path in ${stdenv.lib.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 PERL5LIB "$out/${perl.libPrefix}" + fi + fi + done + fi + done + '' + postBuild; + + meta = perl.meta // { outputsToInstall = ["out"]; }; # remove "man" from meta.outputsToInstall. pkgs.buildEnv produces no "man", it puts everything to "out" + + passthru = perl.passthru // { + interpreter = "${env}/bin/perl"; + inherit perl; + }; + }; +in env diff --git a/pkgs/development/perl-modules/generic/default.nix b/pkgs/development/perl-modules/generic/default.nix index 5b4d9ffa15c4..20947b1dc335 100644 --- a/pkgs/development/perl-modules/generic/default.nix +++ b/pkgs/development/perl-modules/generic/default.nix @@ -1,8 +1,8 @@ -{ lib, stdenv, perl, buildPackages }: +{ lib, stdenv, perl, buildPackages, toPerlModule }: { nativeBuildInputs ? [], name, ... } @ attrs: -stdenv.mkDerivation ( +toPerlModule(stdenv.mkDerivation ( ( lib.recursiveUpdate { @@ -39,4 +39,4 @@ stdenv.mkDerivation ( nativeBuildInputs = nativeBuildInputs ++ [ (perl.dev or perl) ]; perl = buildPackages.perl; } -) +)) diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index bc6801b563a5..16fd41b15967 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -8107,8 +8107,6 @@ in ocropus = callPackage ../applications/misc/ocropus { }; - inherit (callPackages ../development/interpreters/perl {}) perl528 perldevel; - pachyderm = callPackage ../applications/networking/cluster/pachyderm { }; php = php72; @@ -13624,19 +13622,14 @@ in ### DEVELOPMENT / PERL MODULES - # the latest Maint version - perl528Packages = recurseIntoAttrs (callPackage ./perl-packages.nix { - perl = perl528; - overrides = (config.perlPackageOverrides or (p: {})) pkgs; - }); - # the latest Devel version - perldevelPackages = recurseIntoAttrs (callPackage ./perl-packages.nix { - perl = perldevel; - overrides = (config.perlPackageOverrides or (p: {})) pkgs; - }); + perlInterpreters = callPackages ../development/interpreters/perl {}; + inherit (perlInterpreters) perl528 perldevel; + perl528Packages = recurseIntoAttrs perl528.pkgs; + perldevelPackages = perldevel.pkgs; + + perl = perl528; perlPackages = perl528Packages; - inherit (perlPackages) perl; ack = perlPackages.ack; diff --git a/pkgs/top-level/perl-packages.nix b/pkgs/top-level/perl-packages.nix index 0d6e1c7bfc6e..cc5b22c0c1b3 100644 --- a/pkgs/top-level/perl-packages.nix +++ b/pkgs/top-level/perl-packages.nix @@ -12,14 +12,33 @@ assert stdenv.lib.versionAtLeast perl.version "5.28.1"; let inherit (stdenv.lib) maintainers; - self = _self // overrides; + self = _self // (overrides pkgs); _self = with self; { inherit perl; callPackage = pkgs.newScope self; - buildPerlPackage = callPackage ../development/perl-modules/generic { }; + # Check whether a derivation provides a perl module. + hasPerlModule = drv: drv ? perlModule ; + + requiredPerlModules = drvs: let + modules = stdenv.lib.filter hasPerlModule drvs; + in stdenv.lib.unique ([perl] ++ modules ++ stdenv.lib.concatLists (stdenv.lib.catAttrs "requiredPerlModules" modules)); + + # Convert derivation to a perl module. + toPerlModule = drv: + drv.overrideAttrs( oldAttrs: { + # Use passthru in order to prevent rebuilds when possible. + passthru = (oldAttrs.passthru or {}) // { + perlModule = perl; + requiredPerlModules = requiredPerlModules drv.propagatedBuildInputs; + }; + }); + + buildPerlPackage = callPackage ../development/perl-modules/generic { + inherit toPerlModule; + }; # Helper functions for packages that use Module::Build to build. buildPerlModule = { buildInputs ? [], ... } @ args: