From a46326141570098adc676cd66dc8030fa36d4998 Mon Sep 17 00:00:00 2001 From: talyz Date: Sat, 11 Apr 2020 21:48:37 +0200 Subject: [PATCH 01/11] php.buildEnv: Make the exported php package overridable This implements the override pattern for builds done with buildEnv, so that we can, for example, write php.override { fpmSupport = false; } and get a PHP package with the default extensions enabled, but PHP compiled without fpm support. --- pkgs/development/interpreters/php/default.nix | 82 ++++++++++--------- pkgs/top-level/all-packages.nix | 2 +- 2 files changed, 45 insertions(+), 39 deletions(-) diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index 1d6576b383c..4a80f79deeb 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -148,55 +148,61 @@ let generic' = { version, sha256, self, selfWithExtensions, ... }@args: let - php = generic (builtins.removeAttrs args [ "self" "selfWithExtensions" ]); + filteredArgs = builtins.removeAttrs args [ "self" "selfWithExtensions" ]; + php = generic filteredArgs; php-packages = (callPackage ../../../top-level/php-packages.nix { php = self; phpWithExtensions = selfWithExtensions; }); - buildEnv = { extensions ? (_: []), extraConfig ? "" }: - let - getExtName = ext: lib.removePrefix "php-" (builtins.parseDrvName ext.name).name; - enabledExtensions = extensions php-packages.extensions; + buildEnv = lib.makeOverridable ( + { extensions ? (_: []), extraConfig ? "", ... }@innerArgs: + let + filteredInnerArgs = builtins.removeAttrs innerArgs [ "extensions" "extraConfig" ]; + allArgs = filteredArgs // filteredInnerArgs; + php = generic allArgs; - # Generate extension load configuration snippets from the - # extension parameter. This is an attrset suitable for use - # with textClosureList, which is used to put the strings in - # the right order - if a plugin which is dependent on - # another plugin is placed before its dependency, it will - # fail to load. - extensionTexts = - lib.listToAttrs - (map (ext: - let - extName = getExtName ext; - type = "${lib.optionalString (ext.zendExtension or false) "zend_"}extension"; - in - lib.nameValuePair extName { - text = "${type}=${ext}/lib/php/extensions/${extName}.so"; - deps = lib.optionals (ext ? internalDeps) - (map getExtName ext.internalDeps); - }) - enabledExtensions); + getExtName = ext: lib.removePrefix "php-" (builtins.parseDrvName ext.name).name; + enabledExtensions = extensions php-packages.extensions; - extNames = map getExtName enabledExtensions; - extraInit = writeText "custom-php.ini" '' + # Generate extension load configuration snippets from the + # extension parameter. This is an attrset suitable for use + # with textClosureList, which is used to put the strings in + # the right order - if a plugin which is dependent on + # another plugin is placed before its dependency, it will + # fail to load. + extensionTexts = + lib.listToAttrs + (map (ext: + let + extName = getExtName ext; + type = "${lib.optionalString (ext.zendExtension or false) "zend_"}extension"; + in + lib.nameValuePair extName { + text = "${type}=${ext}/lib/php/extensions/${extName}.so"; + deps = lib.optionals (ext ? internalDeps) + (map getExtName ext.internalDeps); + }) + enabledExtensions); + + extNames = map getExtName enabledExtensions; + extraInit = writeText "custom-php.ini" '' ${lib.concatStringsSep "\n" (lib.textClosureList extensionTexts extNames)} ${extraConfig} ''; - in - symlinkJoin { - name = "php-with-extensions-${version}"; - inherit (php) version; - nativeBuildInputs = [ makeWrapper ]; - passthru = { - inherit buildEnv withExtensions enabledExtensions; - inherit (php-packages) packages extensions; - }; - paths = [ php ]; - postBuild = '' + in + symlinkJoin { + name = "php-with-extensions-${version}"; + inherit (php) version; + nativeBuildInputs = [ makeWrapper ]; + passthru = { + inherit buildEnv withExtensions enabledExtensions; + inherit (php-packages) packages extensions; + }; + paths = [ php ]; + postBuild = '' cp ${extraInit} $out/lib/custom-php.ini wrapProgram $out/bin/php --set PHP_INI_SCAN_DIR $out/lib @@ -205,7 +211,7 @@ let wrapProgram $out/bin/php-fpm --set PHP_INI_SCAN_DIR $out/lib fi ''; - }; + }); withExtensions = extensions: buildEnv { inherit extensions; }; in diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 78f07dc3c16..7f2c34039b4 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -9494,7 +9494,7 @@ in php73Extensions = recurseIntoAttrs php73.extensions; php74Extensions = recurseIntoAttrs php74.extensions; - inherit (callPackages ../development/interpreters/php { + inherit (callPackage ../development/interpreters/php { stdenv = if stdenv.cc.isClang then llvmPackages_6.stdenv else stdenv; }) php74 php73 php72 php74base php73base php72base; From dde5f5f899acc34407b604cbca4d4070e3111f13 Mon Sep 17 00:00:00 2001 From: talyz Date: Sun, 12 Apr 2020 13:55:57 +0200 Subject: [PATCH 02/11] php: Make all arguments to a PHP build overridable Make all arguments to a PHP build overridable; i.e, both configuration flags, such as valgrindSupport, and packages, such as valgrind: php.override { valgrindSupport = false; valgrind = valgrind-light; } This applies to packages built by generic and buildEnv/withExtensions; i.e, it works with both phpXX and phpXXBase packages. The following changes were also made to facilitate this: - generic and generic' are merged into one function - generic now takes all required arguments for a complete build and is meant to be called by callPackage - The main function called from all-packages.nix no longer takes all required arguments for a complete build - all arguments passed to it are however forwarded to the individual builds, thus default arguments can still be overridden from all-packages.nix --- pkgs/development/interpreters/php/default.nix | 430 +++++++++--------- 1 file changed, 217 insertions(+), 213 deletions(-) diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index 4a80f79deeb..7c6cb87dfb3 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -1,254 +1,258 @@ # We have tests for PCRE and PHP-FPM in nixos/tests/php/ or # both in the same attribute named nixosTests.php -{ callPackage, config, fetchurl, lib, makeWrapper, stdenv, symlinkJoin -, writeText , autoconf, automake, bison, flex, libtool, pkgconfig, re2c -, apacheHttpd, libargon2, libxml2, pcre, pcre2 , systemd, valgrind -}: +{ callPackage, lib, stdenv }@_args: let generic = - { version - , sha256 - , extraPatches ? [] + { callPackage, lib, stdenv, config, fetchurl, makeWrapper + , symlinkJoin, writeText, autoconf, automake, bison, flex, libtool + , pkgconfig, re2c, apacheHttpd, libargon2, libxml2, pcre, pcre2 + , systemd, valgrind - # Sapi flags - , cgiSupport ? config.php.cgi or true - , cliSupport ? config.php.cli or true - , fpmSupport ? config.php.fpm or true - , pearSupport ? config.php.pear or true - , pharSupport ? config.php.phar or true - , phpdbgSupport ? config.php.phpdbg or true + , version + , sha256 + , extraPatches ? [] + + , defaultPhpExtensions + + # Sapi flags + , cgiSupport ? config.php.cgi or true + , cliSupport ? config.php.cli or true + , fpmSupport ? config.php.fpm or true + , pearSupport ? config.php.pear or true + , pharSupport ? config.php.phar or true + , phpdbgSupport ? config.php.phpdbg or true - # Misc flags - , apxs2Support ? config.php.apxs2 or (!stdenv.isDarwin) - , argon2Support ? config.php.argon2 or true - , cgotoSupport ? config.php.cgoto or false - , embedSupport ? config.php.embed or false - , ipv6Support ? config.php.ipv6 or true - , systemdSupport ? config.php.systemd or stdenv.isLinux - , valgrindSupport ? config.php.valgrind or true - , ztsSupport ? (config.php.zts or false) || (apxs2Support) - }: let - pcre' = if (lib.versionAtLeast version "7.3") then pcre2 else pcre; - in stdenv.mkDerivation { - pname = "php"; + # Misc flags + , apxs2Support ? config.php.apxs2 or (!stdenv.isDarwin) + , argon2Support ? config.php.argon2 or true + , cgotoSupport ? config.php.cgoto or false + , embedSupport ? config.php.embed or false + , ipv6Support ? config.php.ipv6 or true + , systemdSupport ? config.php.systemd or stdenv.isLinux + , valgrindSupport ? config.php.valgrind or true + , ztsSupport ? (config.php.zts or false) || (apxs2Support) + }@args: + let + self = generic args; - inherit version; + php-packages = (callPackage ../../../top-level/php-packages.nix { + php = self; + phpWithExtensions = self.withExtensions defaultPhpExtensions; + }); - enableParallelBuilding = true; + buildEnv = lib.makeOverridable ( + { extensions ? (_: []), extraConfig ? "", ... }@innerArgs: + let + filteredInnerArgs = builtins.removeAttrs innerArgs [ "extensions" "extraConfig" ]; + allArgs = args // filteredInnerArgs; + php = generic allArgs; - nativeBuildInputs = [ autoconf automake bison flex libtool pkgconfig re2c ]; + php-packages = (callPackage ../../../top-level/php-packages.nix { + inherit php phpWithExtensions; + }); - buildInputs = - # PCRE extension - [ pcre' ] + getExtName = ext: lib.removePrefix "php-" (builtins.parseDrvName ext.name).name; + enabledExtensions = extensions php-packages.extensions; - # Enable sapis - ++ lib.optional pearSupport [ libxml2.dev ] + # Generate extension load configuration snippets from the + # extension parameter. This is an attrset suitable for use + # with textClosureList, which is used to put the strings in + # the right order - if a plugin which is dependent on + # another plugin is placed before its dependency, it will + # fail to load. + extensionTexts = + lib.listToAttrs + (map (ext: + let + extName = getExtName ext; + type = "${lib.optionalString (ext.zendExtension or false) "zend_"}extension"; + in + lib.nameValuePair extName { + text = "${type}=${ext}/lib/php/extensions/${extName}.so"; + deps = lib.optionals (ext ? internalDeps) + (map getExtName ext.internalDeps); + }) + enabledExtensions); - # Misc deps - ++ lib.optional apxs2Support apacheHttpd - ++ lib.optional argon2Support libargon2 - ++ lib.optional systemdSupport systemd - ++ lib.optional valgrindSupport valgrind - ; + extNames = map getExtName enabledExtensions; + extraInit = writeText "custom-php.ini" '' + ${lib.concatStringsSep "\n" + (lib.textClosureList extensionTexts extNames)} + ${extraConfig} + ''; - CXXFLAGS = lib.optionalString stdenv.cc.isClang "-std=c++11"; + phpWithExtensions = symlinkJoin rec { + name = "php-with-extensions-${version}"; + inherit (php) version; + nativeBuildInputs = [ makeWrapper ]; + passthru = { + inherit buildEnv withExtensions enabledExtensions; + inherit (php-packages) packages extensions; + }; + paths = [ php ]; + postBuild = '' + cp ${extraInit} $out/lib/custom-php.ini - configureFlags = - # Disable all extensions - [ "--disable-all" ] + wrapProgram $out/bin/php --set PHP_INI_SCAN_DIR $out/lib - # PCRE - ++ lib.optionals (lib.versionAtLeast version "7.4") [ "--with-external-pcre=${pcre'.dev}" ] - ++ lib.optionals (lib.versions.majorMinor version == "7.3") [ "--with-pcre-regex=${pcre'.dev}" ] - ++ lib.optionals (lib.versionOlder version "7.3") [ "--with-pcre-regex=${pcre'.dev}" ] - ++ [ "PCRE_LIBDIR=${pcre'}" ] - - - # Enable sapis - ++ lib.optional (!cgiSupport) "--disable-cgi" - ++ lib.optional (!cliSupport) "--disable-cli" - ++ lib.optional fpmSupport "--enable-fpm" - ++ lib.optional pearSupport [ "--with-pear=$(out)/lib/php/pear" "--enable-xml" "--with-libxml" ] - ++ lib.optional (pearSupport && (lib.versionOlder version "7.4")) "--enable-libxml" - ++ lib.optional pharSupport "--enable-phar" - ++ lib.optional phpdbgSupport "--enable-phpdbg" - - - # Misc flags - ++ lib.optional apxs2Support "--with-apxs2=${apacheHttpd.dev}/bin/apxs" - ++ lib.optional argon2Support "--with-password-argon2=${libargon2}" - ++ lib.optional cgotoSupport "--enable-re2c-cgoto" - ++ lib.optional embedSupport "--enable-embed" - ++ lib.optional (!ipv6Support) "--disable-ipv6" - ++ lib.optional systemdSupport "--with-fpm-systemd" - ++ lib.optional valgrindSupport "--with-valgrind=${valgrind.dev}" - ++ lib.optional ztsSupport "--enable-maintainer-zts" - ; - - hardeningDisable = [ "bindnow" ]; - - preConfigure = '' - # Don't record the configure flags since this causes unnecessary - # runtime dependencies - for i in main/build-defs.h.in scripts/php-config.in; do - substituteInPlace $i \ - --replace '@CONFIGURE_COMMAND@' '(omitted)' \ - --replace '@CONFIGURE_OPTIONS@' "" \ - --replace '@PHP_LDFLAGS@' "" - done - - export EXTENSION_DIR=$out/lib/php/extensions - - ./buildconf --copy --force - - if test -f $src/genfiles; then - ./genfiles - fi - '' + lib.optionalString stdenv.isDarwin '' - substituteInPlace configure --replace "-lstdc++" "-lc++" - ''; - - postInstall = '' - test -d $out/etc || mkdir $out/etc - cp php.ini-production $out/etc/php.ini - ''; - - postFixup = '' - mkdir -p $dev/bin $dev/share/man/man1 - mv $out/bin/phpize $out/bin/php-config $dev/bin/ - mv $out/share/man/man1/phpize.1.gz \ - $out/share/man/man1/php-config.1.gz \ - $dev/share/man/man1/ - ''; - - src = fetchurl { - url = "https://www.php.net/distributions/php-${version}.tar.bz2"; - inherit sha256; - }; - - patches = [ ./fix-paths-php7.patch ] ++ extraPatches; - - separateDebugInfo = true; - - outputs = [ "out" "dev" ]; - - meta = with stdenv.lib; { - description = "An HTML-embedded scripting language"; - homepage = "https://www.php.net/"; - license = licenses.php301; - maintainers = with maintainers; [ globin etu ma27 ]; - platforms = platforms.all; - outputsToInstall = [ "out" "dev" ]; - }; - }; - - generic' = { version, sha256, self, selfWithExtensions, ... }@args: - let - filteredArgs = builtins.removeAttrs args [ "self" "selfWithExtensions" ]; - php = generic filteredArgs; - - php-packages = (callPackage ../../../top-level/php-packages.nix { - php = self; - phpWithExtensions = selfWithExtensions; - }); - - buildEnv = lib.makeOverridable ( - { extensions ? (_: []), extraConfig ? "", ... }@innerArgs: - let - filteredInnerArgs = builtins.removeAttrs innerArgs [ "extensions" "extraConfig" ]; - allArgs = filteredArgs // filteredInnerArgs; - php = generic allArgs; - - getExtName = ext: lib.removePrefix "php-" (builtins.parseDrvName ext.name).name; - enabledExtensions = extensions php-packages.extensions; - - # Generate extension load configuration snippets from the - # extension parameter. This is an attrset suitable for use - # with textClosureList, which is used to put the strings in - # the right order - if a plugin which is dependent on - # another plugin is placed before its dependency, it will - # fail to load. - extensionTexts = - lib.listToAttrs - (map (ext: - let - extName = getExtName ext; - type = "${lib.optionalString (ext.zendExtension or false) "zend_"}extension"; - in - lib.nameValuePair extName { - text = "${type}=${ext}/lib/php/extensions/${extName}.so"; - deps = lib.optionals (ext ? internalDeps) - (map getExtName ext.internalDeps); - }) - enabledExtensions); - - extNames = map getExtName enabledExtensions; - extraInit = writeText "custom-php.ini" '' - ${lib.concatStringsSep "\n" - (lib.textClosureList extensionTexts extNames)} - ${extraConfig} - ''; - in - symlinkJoin { - name = "php-with-extensions-${version}"; - inherit (php) version; - nativeBuildInputs = [ makeWrapper ]; - passthru = { - inherit buildEnv withExtensions enabledExtensions; - inherit (php-packages) packages extensions; + if test -e $out/bin/php-fpm; then + wrapProgram $out/bin/php-fpm --set PHP_INI_SCAN_DIR $out/lib + fi + ''; }; - paths = [ php ]; - postBuild = '' - cp ${extraInit} $out/lib/custom-php.ini + in + phpWithExtensions); - wrapProgram $out/bin/php --set PHP_INI_SCAN_DIR $out/lib + withExtensions = extensions: buildEnv { inherit extensions; }; - if test -e $out/bin/php-fpm; then - wrapProgram $out/bin/php-fpm --set PHP_INI_SCAN_DIR $out/lib - fi - ''; - }); + pcre' = if (lib.versionAtLeast version "7.3") then pcre2 else pcre; + in + stdenv.mkDerivation { + pname = "php"; - withExtensions = extensions: buildEnv { inherit extensions; }; - in - php.overrideAttrs (_: { - passthru = { - enabledExtensions = []; - inherit buildEnv withExtensions; - inherit (php-packages) packages extensions; + inherit version; + + enableParallelBuilding = true; + + nativeBuildInputs = [ autoconf automake bison flex libtool pkgconfig re2c ]; + + buildInputs = + # PCRE extension + [ pcre' ] + + # Enable sapis + ++ lib.optional pearSupport [ libxml2.dev ] + + # Misc deps + ++ lib.optional apxs2Support apacheHttpd + ++ lib.optional argon2Support libargon2 + ++ lib.optional systemdSupport systemd + ++ lib.optional valgrindSupport valgrind + ; + + CXXFLAGS = lib.optionalString stdenv.cc.isClang "-std=c++11"; + + configureFlags = + # Disable all extensions + [ "--disable-all" ] + + # PCRE + ++ lib.optionals (lib.versionAtLeast version "7.4") [ "--with-external-pcre=${pcre'.dev}" ] + ++ lib.optionals (lib.versions.majorMinor version == "7.3") [ "--with-pcre-regex=${pcre'.dev}" ] + ++ lib.optionals (lib.versionOlder version "7.3") [ "--with-pcre-regex=${pcre'.dev}" ] + ++ [ "PCRE_LIBDIR=${pcre'}" ] + + + # Enable sapis + ++ lib.optional (!cgiSupport) "--disable-cgi" + ++ lib.optional (!cliSupport) "--disable-cli" + ++ lib.optional fpmSupport "--enable-fpm" + ++ lib.optional pearSupport [ "--with-pear=$(out)/lib/php/pear" "--enable-xml" "--with-libxml" ] + ++ lib.optional (pearSupport && (lib.versionOlder version "7.4")) "--enable-libxml" + ++ lib.optional pharSupport "--enable-phar" + ++ lib.optional phpdbgSupport "--enable-phpdbg" + + + # Misc flags + ++ lib.optional apxs2Support "--with-apxs2=${apacheHttpd.dev}/bin/apxs" + ++ lib.optional argon2Support "--with-password-argon2=${libargon2}" + ++ lib.optional cgotoSupport "--enable-re2c-cgoto" + ++ lib.optional embedSupport "--enable-embed" + ++ lib.optional (!ipv6Support) "--disable-ipv6" + ++ lib.optional systemdSupport "--with-fpm-systemd" + ++ lib.optional valgrindSupport "--with-valgrind=${valgrind.dev}" + ++ lib.optional ztsSupport "--enable-maintainer-zts" + ; + + hardeningDisable = [ "bindnow" ]; + + preConfigure = '' + # Don't record the configure flags since this causes unnecessary + # runtime dependencies + for i in main/build-defs.h.in scripts/php-config.in; do + substituteInPlace $i \ + --replace '@CONFIGURE_COMMAND@' '(omitted)' \ + --replace '@CONFIGURE_OPTIONS@' "" \ + --replace '@PHP_LDFLAGS@' "" + done + + export EXTENSION_DIR=$out/lib/php/extensions + + ./buildconf --copy --force + + if test -f $src/genfiles; then + ./genfiles + fi + '' + lib.optionalString stdenv.isDarwin '' + substituteInPlace configure --replace "-lstdc++" "-lc++" + ''; + + postInstall = '' + test -d $out/etc || mkdir $out/etc + cp php.ini-production $out/etc/php.ini + ''; + + postFixup = '' + mkdir -p $dev/bin $dev/share/man/man1 + mv $out/bin/phpize $out/bin/php-config $dev/bin/ + mv $out/share/man/man1/phpize.1.gz \ + $out/share/man/man1/php-config.1.gz \ + $dev/share/man/man1/ + ''; + + src = fetchurl { + url = "https://www.php.net/distributions/php-${version}.tar.bz2"; + inherit sha256; + }; + + patches = [ ./fix-paths-php7.patch ] ++ extraPatches; + + separateDebugInfo = true; + + outputs = [ "out" "dev" ]; + + passthru = { + enabledExtensions = []; + inherit buildEnv withExtensions; + inherit (php-packages) packages extensions; + }; + + meta = with stdenv.lib; { + description = "An HTML-embedded scripting language"; + homepage = "https://www.php.net/"; + license = licenses.php301; + maintainers = with maintainers; [ globin etu ma27 ]; + platforms = platforms.all; + outputsToInstall = [ "out" "dev" ]; + }; }; - }); - php72base = generic' { + php72base = callPackage generic (_args // { version = "7.2.29"; sha256 = "08xry2fgqgg8s0ym1hh11wkbr36av3zq1bn4krbciw1b7x8gb8ga"; - self = php72base; - selfWithExtensions = php72; + defaultPhpExtensions = defaultPhpExtensionsWithHash; # https://bugs.php.net/bug.php?id=76826 extraPatches = lib.optional stdenv.isDarwin ./php72-darwin-isfinite.patch; - }; + }); - php73base = generic' { + php73base = callPackage generic (_args // { version = "7.3.16"; sha256 = "0bh499v9dfgh9k51w4rird1slb9rh9whp5h37fb84c98d992s1xq"; - self = php73base; - selfWithExtensions = php73; + defaultPhpExtensions = defaultPhpExtensionsWithHash; # https://bugs.php.net/bug.php?id=76826 extraPatches = lib.optional stdenv.isDarwin ./php73-darwin-isfinite.patch; - }; + }); - php74base = generic' { + php74base = callPackage generic (_args // { version = "7.4.4"; sha256 = "17w2m4phhpj76x5fx67vgjrlkcczqvky3f5in1kjg2pch90qz3ih"; - self = php74base; - selfWithExtensions = php74; - }; + inherit defaultPhpExtensions; + }); defaultPhpExtensions = extensions: with extensions; ([ bcmath calendar curl ctype dom exif fileinfo filter ftp gd From abedfadd7376a2edf59bbfaa7ab101411d042529 Mon Sep 17 00:00:00 2001 From: talyz Date: Sun, 12 Apr 2020 22:52:51 +0200 Subject: [PATCH 03/11] php.buildEnv: Respect override Make buildEnv take earlier overridden values into account by forwarding all arguments (a merge of generic's arguments, all previous arguments and the current arguments) to the next invocation of buildEnv. --- pkgs/development/interpreters/php/default.nix | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index 7c6cb87dfb3..c1a7cdd11c4 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -43,12 +43,12 @@ let phpWithExtensions = self.withExtensions defaultPhpExtensions; }); - buildEnv = lib.makeOverridable ( + mkBuildEnv = prevArgs: lib.makeOverridable ( { extensions ? (_: []), extraConfig ? "", ... }@innerArgs: let - filteredInnerArgs = builtins.removeAttrs innerArgs [ "extensions" "extraConfig" ]; - allArgs = args // filteredInnerArgs; - php = generic allArgs; + allArgs = args // prevArgs // innerArgs; + filteredArgs = builtins.removeAttrs allArgs [ "extensions" "extraConfig" ]; + php = generic filteredArgs; php-packages = (callPackage ../../../top-level/php-packages.nix { inherit php phpWithExtensions; @@ -89,7 +89,9 @@ let inherit (php) version; nativeBuildInputs = [ makeWrapper ]; passthru = { - inherit buildEnv withExtensions enabledExtensions; + buildEnv = mkBuildEnv allArgs; + withExtensions = mkWithExtensions allArgs; + inherit enabledExtensions; inherit (php-packages) packages extensions; }; paths = [ php ]; @@ -106,7 +108,8 @@ let in phpWithExtensions); - withExtensions = extensions: buildEnv { inherit extensions; }; + mkWithExtensions = prevArgs: extensions: + mkBuildEnv prevArgs { inherit extensions; }; pcre' = if (lib.versionAtLeast version "7.3") then pcre2 else pcre; in @@ -216,7 +219,8 @@ let passthru = { enabledExtensions = []; - inherit buildEnv withExtensions; + buildEnv = mkBuildEnv {}; + withExtensions = mkWithExtensions {}; inherit (php-packages) packages extensions; }; From 2ba79269590cd186c3ad6e5226c4322de8984d87 Mon Sep 17 00:00:00 2001 From: talyz Date: Sun, 12 Apr 2020 23:31:56 +0200 Subject: [PATCH 04/11] php.buildEnv: Provide a list of currently enabled extensions Rework withExtensions / buildEnv to handle currently enabled extensions better and make them compatible with override. They now accept a function with the named arguments enabled and all, where enabled is a list of currently enabled extensions and all is the set of all extensions. This gives us several nice properties: - You always get the right version of the list of currently enabled extensions - Invocations chain - It works well with overridden PHP packages - you always get the correct versions of extensions As a contrived example of what's possible, you can add ImageMagick, then override the version and disable fpm, then disable cgi, and lastly remove the zip extension like this: { pkgs ? (import ) {} }: with pkgs; let phpWithImagick = php74.withExtensions ({ all, enabled }: enabled ++ [ all.imagick ]); phpWithImagickWithoutFpm743 = phpWithImagick.override { version = "7.4.3"; sha256 = "wVF7pJV4+y3MZMc6Ptx21PxQfEp6xjmYFYTMfTtMbRQ="; fpmSupport = false; }; phpWithImagickWithoutFpmZip743 = phpWithImagickWithoutFpm743.withExtensions ( { enabled, all }: lib.filter (e: e != all.zip) enabled); phpWithImagickWithoutFpmZipCgi743 = phpWithImagickWithoutFpmZip743.override { cgiSupport = false; }; in phpWithImagickWithoutFpmZipCgi743 --- doc/languages-frameworks/php.section.md | 47 ++++++++++--------- nixos/doc/manual/release-notes/rl-2009.xml | 21 +++++---- nixos/modules/services/mail/roundcube.nix | 2 +- nixos/modules/services/web-apps/nextcloud.nix | 4 +- pkgs/development/interpreters/php/default.nix | 41 ++++++++++------ 5 files changed, 68 insertions(+), 47 deletions(-) diff --git a/doc/languages-frameworks/php.section.md b/doc/languages-frameworks/php.section.md index a302a9a7f87..31190f3b51a 100644 --- a/doc/languages-frameworks/php.section.md +++ b/doc/languages-frameworks/php.section.md @@ -30,7 +30,7 @@ opcache extension shipped with PHP is available at `php.extensions.opcache` and the third-party ImageMagick extension at `php.extensions.imagick`. -The different versions of PHP that nixpkgs provides is located under +The different versions of PHP that nixpkgs provides are located under attributes named based on major and minor version number; e.g., `php74` is PHP 7.4 with commonly used extensions installed, `php74base` is the same PHP runtime without extensions. @@ -39,28 +39,31 @@ attributes named based on major and minor version number; e.g., A PHP package with specific extensions enabled can be built using `php.withExtensions`. This is a function which accepts an anonymous -function as its only argument; the function should take one argument, -the set of all extensions, and return a list of wanted extensions. For -example, a PHP package with the opcache and ImageMagick extensions -enabled: +function as its only argument; the function should accept two named +parameters: `enabled` - a list of currently enabled extensions and +`all` - the set of all extensions, and return a list of wanted +extensions. For example, a PHP package with all default extensions and +ImageMagick enabled: ```nix -php.withExtensions (e: with e; [ imagick opcache ]) +php.withExtensions ({ enabled, all }: + enabled ++ [ all.imagick ]) ``` -Note that this will give you a package with _only_ opcache and -ImageMagick, none of the other extensions which are enabled by default -in the `php` package will be available. - -To enable building on a previous PHP package, the currently enabled -extensions are made available in its `enabledExtensions` -attribute. For example, to generate a package with all default -extensions enabled, except opcache, but with ImageMagick: +To exclude some, but not all, of the default extensions, you can +filter the `enabled` list like this: ```nix -php.withExtensions (e: - (lib.filter (e: e != php.extensions.opcache) php.enabledExtensions) - ++ [ e.imagick ]) +php.withExtensions ({ enabled, all }: + (lib.filter (e: e != php.extensions.opcache) enabled) + ++ [ all.imagick ]) +``` + +To build your list of extensions from the ground up, you can simply +ignore `enabled`: + +```nix +php.withExtensions ({ all, ... }: with all; [ opcache imagick ]) ``` If you want a PHP build with extra configuration in the `php.ini` @@ -73,7 +76,7 @@ and ImageMagick extensions enabled, and `memory_limit` set to `256M`: ```nix php.buildEnv { - extensions = e: with e; [ imagick opcache ]; + extensions = { all, ... }: with all; [ imagick opcache ]; extraConfig = "memory_limit=256M"; } ``` @@ -85,7 +88,7 @@ follows: ```nix let - myPhp = php.withExtensions (e: with e; [ imagick opcache ]); + myPhp = php.withExtensions ({ all, ... }: with all; [ opcache imagick ]); in { services.phpfpm.pools."foo".phpPackage = myPhp; }; @@ -94,7 +97,7 @@ in { ```nix let myPhp = php.buildEnv { - extensions = e: with e; [ imagick opcache ]; + extensions = { all, ... }: with all; [ imagick opcache ]; extraConfig = "memory_limit=256M"; }; in { @@ -105,8 +108,8 @@ in { ##### Example usage with `nix-shell` This brings up a temporary environment that contains a PHP interpreter -with the extensions `imagick` and `opcache` enabled. +with the extensions `imagick` and `opcache` enabled: ```sh -nix-shell -p 'php.buildEnv { extensions = e: with e; [ imagick opcache ]; }' +nix-shell -p 'php.withExtensions ({ all, ... }: with all; [ imagick opcache ])' ``` diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml index 3e29c19af8f..e4e44c8405f 100644 --- a/nixos/doc/manual/release-notes/rl-2009.xml +++ b/nixos/doc/manual/release-notes/rl-2009.xml @@ -135,18 +135,23 @@ - Since this release there's an easy way to customize your PHP install to get a much smaller - base PHP with only wanted extensions enabled. See the following snippet installing a smaller PHP - with the extensions imagick, opcache and + Since this release there's an easy way to customize your PHP + install to get a much smaller base PHP with only wanted + extensions enabled. See the following snippet installing a + smaller PHP with the extensions imagick, + opcache, pdo and pdo_mysql loaded: environment.systemPackages = [ -(pkgs.php.buildEnv { extensions = pp: with pp; [ - imagick - opcache - pdo_mysql - ]; }) + (pkgs.php.withExtensions + ({ all, ... }: with all; [ + imagick + opcache + pdo + pdo_mysql + ]) + ) ]; The default php attribute hasn't lost any extensions - diff --git a/nixos/modules/services/mail/roundcube.nix b/nixos/modules/services/mail/roundcube.nix index 21e92cfee01..ed1439745ac 100644 --- a/nixos/modules/services/mail/roundcube.nix +++ b/nixos/modules/services/mail/roundcube.nix @@ -7,7 +7,7 @@ let fpm = config.services.phpfpm.pools.roundcube; localDB = cfg.database.host == "localhost"; user = cfg.database.username; - phpWithPspell = pkgs.php.withExtensions (e: [ e.pspell ] ++ pkgs.php.enabledExtensions); + phpWithPspell = pkgs.php.withExtensions ({ enabled, all }: [ all.pspell ] ++ enabled); in { options.services.roundcube = { diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix index 5f6f2bc7a16..f826096bf60 100644 --- a/nixos/modules/services/web-apps/nextcloud.nix +++ b/nixos/modules/services/web-apps/nextcloud.nix @@ -11,8 +11,8 @@ let base = pkgs.php74; in base.buildEnv { - extensions = e: with e; - base.enabledExtensions ++ [ + extensions = { enabled, all }: with all; + enabled ++ [ apcu redis memcached imagick ]; extraConfig = phpOptionsStr; diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index c1a7cdd11c4..2313f9fbcc4 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -43,8 +43,16 @@ let phpWithExtensions = self.withExtensions defaultPhpExtensions; }); - mkBuildEnv = prevArgs: lib.makeOverridable ( - { extensions ? (_: []), extraConfig ? "", ... }@innerArgs: + # buildEnv wraps php to provide additional extensions and + # configuration. Its usage is documented in + # doc/languages-frameworks/php.section.md. + # + # Create a buildEnv with earlier overridden values and + # extensions functions in its closure. This is necessary for + # consecutive calls to buildEnv and overrides to work as + # expected. + mkBuildEnv = prevArgs: prevExtensionFunctions: lib.makeOverridable ( + { extensions ? ({...}: []), extraConfig ? "", ... }@innerArgs: let allArgs = args // prevArgs // innerArgs; filteredArgs = builtins.removeAttrs allArgs [ "extensions" "extraConfig" ]; @@ -54,8 +62,15 @@ let inherit php phpWithExtensions; }); + allExtensionFunctions = prevExtensionFunctions ++ [ extensions ]; + enabledExtensions = + builtins.foldl' + (state: f: + f { enabled = state; all = php-packages.extensions; }) + [] + allExtensionFunctions; + getExtName = ext: lib.removePrefix "php-" (builtins.parseDrvName ext.name).name; - enabledExtensions = extensions php-packages.extensions; # Generate extension load configuration snippets from the # extension parameter. This is an attrset suitable for use @@ -89,9 +104,8 @@ let inherit (php) version; nativeBuildInputs = [ makeWrapper ]; passthru = { - buildEnv = mkBuildEnv allArgs; - withExtensions = mkWithExtensions allArgs; - inherit enabledExtensions; + buildEnv = mkBuildEnv allArgs allExtensionFunctions; + withExtensions = mkWithExtensions allArgs allExtensionFunctions; inherit (php-packages) packages extensions; }; paths = [ php ]; @@ -108,8 +122,8 @@ let in phpWithExtensions); - mkWithExtensions = prevArgs: extensions: - mkBuildEnv prevArgs { inherit extensions; }; + mkWithExtensions = prevArgs: prevExtensionFunctions: extensions: + mkBuildEnv prevArgs prevExtensionFunctions { inherit extensions; }; pcre' = if (lib.versionAtLeast version "7.3") then pcre2 else pcre; in @@ -218,9 +232,8 @@ let outputs = [ "out" "dev" ]; passthru = { - enabledExtensions = []; - buildEnv = mkBuildEnv {}; - withExtensions = mkWithExtensions {}; + buildEnv = mkBuildEnv {} []; + withExtensions = mkWithExtensions {} []; inherit (php-packages) packages extensions; }; @@ -258,7 +271,7 @@ let inherit defaultPhpExtensions; }); - defaultPhpExtensions = extensions: with extensions; ([ + defaultPhpExtensions = { all, ... }: with all; ([ bcmath calendar curl ctype dom exif fileinfo filter ftp gd gettext gmp iconv intl json ldap mbstring mysqli mysqlnd opcache openssl pcntl pdo pdo_mysql pdo_odbc pdo_pgsql pdo_sqlite pgsql @@ -266,8 +279,8 @@ let tokenizer xmlreader xmlwriter zip zlib ] ++ lib.optionals (!stdenv.isDarwin) [ imap ]); - defaultPhpExtensionsWithHash = extensions: - (defaultPhpExtensions extensions) ++ [ extensions.hash ]; + defaultPhpExtensionsWithHash = { all, ... }: + (defaultPhpExtensions { inherit all; }) ++ [ all.hash ]; php74 = php74base.withExtensions defaultPhpExtensions; php73 = php73base.withExtensions defaultPhpExtensionsWithHash; From 72636bc2f6321e5e25414904685ba9fbabbbfb56 Mon Sep 17 00:00:00 2001 From: talyz Date: Fri, 24 Apr 2020 13:29:46 +0200 Subject: [PATCH 05/11] php: Get rid of all config.php parameters Since all options controlled by the config.php parameters can now be overridden directly, there's no reason to keep them around. --- nixos/doc/manual/release-notes/rl-2009.xml | 79 +++++++++---------- pkgs/development/interpreters/php/default.nix | 29 ++++--- pkgs/servers/http/unit/default.nix | 12 +-- pkgs/servers/uwsgi/default.nix | 4 +- pkgs/top-level/aliases.nix | 48 +++++------ 5 files changed, 84 insertions(+), 88 deletions(-) diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml index e4e44c8405f..8231bf9842f 100644 --- a/nixos/doc/manual/release-notes/rl-2009.xml +++ b/nixos/doc/manual/release-notes/rl-2009.xml @@ -154,55 +154,50 @@ environment.systemPackages = [ ) ]; - The default php attribute hasn't lost any extensions - - the opcache extension was added there. + The default php attribute hasn't lost any + extensions. The opcache extension has been + added. All upstream PHP extensions are available under ]]>. - The updated php attribute is now easily customizable to your liking - by using extensions instead of writing config files or changing configure flags. - - Therefore we have removed the following configure flags: + All PHP config flags have been removed for + the following reasons: - PHP <literal>config</literal> flags that we don't read anymore: - config.php.argon2 - config.php.bcmath - config.php.bz2 - config.php.calendar - config.php.curl - config.php.exif - config.php.ftp - config.php.gd - config.php.gettext - config.php.gmp - config.php.imap - config.php.intl - config.php.ldap - config.php.libxml2 - config.php.libzip - config.php.mbstring - config.php.mysqli - config.php.mysqlnd - config.php.openssl - config.php.pcntl - config.php.pdo_mysql - config.php.pdo_odbc - config.php.pdo_pgsql - config.php.phpdbg - config.php.postgresql - config.php.readline - config.php.soap - config.php.sockets - config.php.sodium - config.php.sqlite - config.php.tidy - config.php.xmlrpc - config.php.xsl - config.php.zip - config.php.zlib + + + The updated php attribute is now easily + customizable to your liking by using + php.withExtensions or + php.buildEnv instead of writing config files + or changing configure flags. + + + + + The remaining configuration flags can now be set directly on + the php attribute. For example, instead of + + +php.override { + config.php.embed = true; + config.php.apxs2 = false; +} + + + you should now write + + +php.override { + embedSupport = true; + apxs2Support = false; +} + + + + diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index 2313f9fbcc4..33071b06d95 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -17,23 +17,22 @@ let , defaultPhpExtensions # Sapi flags - , cgiSupport ? config.php.cgi or true - , cliSupport ? config.php.cli or true - , fpmSupport ? config.php.fpm or true - , pearSupport ? config.php.pear or true - , pharSupport ? config.php.phar or true - , phpdbgSupport ? config.php.phpdbg or true - + , cgiSupport ? true + , cliSupport ? true + , fpmSupport ? true + , pearSupport ? true + , pharSupport ? true + , phpdbgSupport ? true # Misc flags - , apxs2Support ? config.php.apxs2 or (!stdenv.isDarwin) - , argon2Support ? config.php.argon2 or true - , cgotoSupport ? config.php.cgoto or false - , embedSupport ? config.php.embed or false - , ipv6Support ? config.php.ipv6 or true - , systemdSupport ? config.php.systemd or stdenv.isLinux - , valgrindSupport ? config.php.valgrind or true - , ztsSupport ? (config.php.zts or false) || (apxs2Support) + , apxs2Support ? !stdenv.isDarwin + , argon2Support ? true + , cgotoSupport ? false + , embedSupport ? false + , ipv6Support ? true + , systemdSupport ? stdenv.isLinux + , valgrindSupport ? true + , ztsSupport ? apxs2Support }@args: let self = generic args; diff --git a/pkgs/servers/http/unit/default.nix b/pkgs/servers/http/unit/default.nix index 1e3ddb4ad8f..f8992bf166b 100644 --- a/pkgs/servers/http/unit/default.nix +++ b/pkgs/servers/http/unit/default.nix @@ -18,12 +18,12 @@ with stdenv.lib; let phpConfig = { - config.php.embed = true; - config.php.apxs2 = false; - config.php.systemd = false; - config.php.phpdbg = false; - config.php.cgi = false; - config.php.fpm = false; + embedSupport = true; + apxs2Support = false; + systemdSupport = false; + phpdbgSupport = false; + cgiSupport = false; + fpmSupport = false; }; php72-unit = php72base.override phpConfig; diff --git a/pkgs/servers/uwsgi/default.nix b/pkgs/servers/uwsgi/default.nix index 29b807f1792..0f0d2c23e4c 100644 --- a/pkgs/servers/uwsgi/default.nix +++ b/pkgs/servers/uwsgi/default.nix @@ -8,8 +8,8 @@ }: let php-embed = php.override { - config.php.embed = true; - config.php.apxs2 = false; + embedSupport = true; + apxs2Support = false; }; pythonPlugin = pkg : lib.nameValuePair "python${if pkg.isPy2 then "2" else "3"}" { diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 9ad282149aa..678cb0d983a 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -332,48 +332,50 @@ mapAliases ({ pg_tmp = ephemeralpg; # added 2018-01-16 php-embed = throw '' - php*-embed has been dropped, you can build the same package by using - something similar with this following snippet: - (php74.override { config.php.embed = true; config.php.apxs2 = false; }) + php*-embed has been dropped, you can build something similar + with the following snippet: + php74.override { embedSupport = true; apxs2Support = false; } ''; # added 2020-04-01 php72-embed = php-embed; # added 2020-04-01 php73-embed = php-embed; # added 2020-04-01 php74-embed = php-embed; # added 2020-04-01 phpPackages-embed = throw '' - php*Packages-embed has been dropped, you can build the same package by using - something similar with this following snippet: - (php74.override { config.php.embed = true; config.php.apxs2 = false; }).packages + php*Packages-embed has been dropped, you can build something + similar with the following snippet: + (php74.override { embedSupport = true; apxs2Support = false; }).packages ''; # added 2020-04-01 php74Packages-embed = phpPackages-embed; php73Packages-embed = phpPackages-embed; php72Packages-embed = phpPackages-embed; php-unit = throw '' - php*-unit has been dropped, you can build the same package by using - something similar with this following snippet: - (php74.override { - config.php.embed = true; - config.php.apxs2 = false; - config.php.systemd = false; - config.php.phpdbg = false; - config.php.cgi = false; - config.php.fpm = false; }) + php*-unit has been dropped, you can build something similar with + the following snippet: + php74.override { + embedSupport = true; + apxs2Support = false; + systemdSupport = false; + phpdbgSupport = false; + cgiSupport = false; + fpmSupport = false; + } ''; # added 2020-04-01 php72-unit = php-unit; # added 2020-04-01 php73-unit = php-unit; # added 2020-04-01 php74-unit = php-unit; # added 2020-04-01 phpPackages-unit = throw '' - php*Packages-unit has been dropped, you can build the same package by using - something similar with this following snippet: + php*Packages-unit has been dropped, you can build something + similar with this following snippet: (php74.override { - config.php.embed = true; - config.php.apxs2 = false; - config.php.systemd = false; - config.php.phpdbg = false; - config.php.cgi = false; - config.php.fpm = false; }).packages + embedSupport = true; + apxs2Support = false; + systemdSupport = false; + phpdbgSupport = false; + cgiSupport = false; + fpmSupport = false; + }).packages ''; # added 2020-04-01 php74Packages-unit = phpPackages-unit; php73Packages-unit = phpPackages-unit; From d61040716e4e7266f36e523f8ba5fa11f387548e Mon Sep 17 00:00:00 2001 From: talyz Date: Fri, 24 Apr 2020 18:11:40 +0200 Subject: [PATCH 06/11] php.buildEnv: Automatically include extension dependencies Some extensions depend on other extensions. Previously, these had to be added manually to the list of included extensions, or we got a cryptic error message pointing to strings-with-deps.nix, which wasn't very helpful. This makes sure all required extensions are included in the set from which textClosureList chooses its snippets. --- pkgs/development/interpreters/php/default.nix | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index 33071b06d95..2eda206ef2e 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -71,6 +71,19 @@ let getExtName = ext: lib.removePrefix "php-" (builtins.parseDrvName ext.name).name; + # Recursively get a list of all internal dependencies + # for a list of extensions. + getDepsRecursively = extensions: + let + deps = lib.concatMap + (ext: ext.internalDeps or []) + extensions; + in + if ! (deps == []) then + deps ++ (getDepsRecursively deps) + else + deps; + # Generate extension load configuration snippets from the # extension parameter. This is an attrset suitable for use # with textClosureList, which is used to put the strings in @@ -89,7 +102,7 @@ let deps = lib.optionals (ext ? internalDeps) (map getExtName ext.internalDeps); }) - enabledExtensions); + (enabledExtensions ++ (getDepsRecursively enabledExtensions))); extNames = map getExtName enabledExtensions; extraInit = writeText "custom-php.ini" '' From c3d5d92f4a9b78357b803d0591bc9adf0e17f584 Mon Sep 17 00:00:00 2001 From: talyz Date: Fri, 24 Apr 2020 19:34:34 +0200 Subject: [PATCH 07/11] php.buildEnv: Add phpIni attribute for easy access to the php.ini --- nixos/modules/services/web-servers/apache-httpd/default.nix | 2 +- pkgs/development/interpreters/php/default.nix | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/nixos/modules/services/web-servers/apache-httpd/default.nix b/nixos/modules/services/web-servers/apache-httpd/default.nix index 5e55baa203a..b72b249220d 100644 --- a/nixos/modules/services/web-servers/apache-httpd/default.nix +++ b/nixos/modules/services/web-servers/apache-httpd/default.nix @@ -338,7 +338,7 @@ let } '' cat ${php}/etc/php.ini > $out - cat ${php}/lib/custom-php.ini > $out + cat ${php.phpIni} > $out echo "$options" >> $out ''; diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index 2eda206ef2e..4256e34980d 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -105,7 +105,7 @@ let (enabledExtensions ++ (getDepsRecursively enabledExtensions))); extNames = map getExtName enabledExtensions; - extraInit = writeText "custom-php.ini" '' + extraInit = writeText "php.ini" '' ${lib.concatStringsSep "\n" (lib.textClosureList extensionTexts extNames)} ${extraConfig} @@ -118,11 +118,12 @@ let passthru = { buildEnv = mkBuildEnv allArgs allExtensionFunctions; withExtensions = mkWithExtensions allArgs allExtensionFunctions; + phpIni = "${phpWithExtensions}/lib/php.ini"; inherit (php-packages) packages extensions; }; paths = [ php ]; postBuild = '' - cp ${extraInit} $out/lib/custom-php.ini + cp ${extraInit} $out/lib/php.ini wrapProgram $out/bin/php --set PHP_INI_SCAN_DIR $out/lib From ef990961bc98e6b8dbad47b0ea0da2b302df5476 Mon Sep 17 00:00:00 2001 From: talyz Date: Fri, 24 Apr 2020 21:28:33 +0200 Subject: [PATCH 08/11] php.buildEnv: Provide the unwrapped php package in php.unwrapped This is useful if you need to access the dev output of the unwrapped derivation. --- doc/languages-frameworks/php.section.md | 7 +++++++ pkgs/development/interpreters/php/default.nix | 1 + 2 files changed, 8 insertions(+) diff --git a/doc/languages-frameworks/php.section.md b/doc/languages-frameworks/php.section.md index 31190f3b51a..abf91a31769 100644 --- a/doc/languages-frameworks/php.section.md +++ b/doc/languages-frameworks/php.section.md @@ -66,6 +66,13 @@ ignore `enabled`: php.withExtensions ({ all, ... }: with all; [ opcache imagick ]) ``` +`php.withExtensions` provides extensions by wrapping a minimal php +base package, providing a `php.ini` file listing all extensions to be +loaded. You can access this package through the `php.unwrappedPhp` +attribute; useful if you, for example, need access to the `dev` +output. The generated `php.ini` file can be accessed through the +`php.phpIni` attribute. + If you want a PHP build with extra configuration in the `php.ini` file, you can use `php.buildEnv`. This function takes two named and optional parameters: `extensions` and `extraConfig`. `extensions` diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index 4256e34980d..78dc5d2e98a 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -119,6 +119,7 @@ let buildEnv = mkBuildEnv allArgs allExtensionFunctions; withExtensions = mkWithExtensions allArgs allExtensionFunctions; phpIni = "${phpWithExtensions}/lib/php.ini"; + unwrapped = php; inherit (php-packages) packages extensions; }; paths = [ php ]; From 3bfd4e864f6c97c47efb1a353566e4fe4402b611 Mon Sep 17 00:00:00 2001 From: talyz Date: Sun, 26 Apr 2020 16:41:39 +0200 Subject: [PATCH 09/11] php: Add passthru.tests --- pkgs/development/interpreters/php/default.nix | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index 78dc5d2e98a..57a0b716979 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -1,11 +1,11 @@ # We have tests for PCRE and PHP-FPM in nixos/tests/php/ or # both in the same attribute named nixosTests.php -{ callPackage, lib, stdenv }@_args: +{ callPackage, lib, stdenv, nixosTests }@_args: let generic = - { callPackage, lib, stdenv, config, fetchurl, makeWrapper + { callPackage, lib, stdenv, nixosTests, config, fetchurl, makeWrapper , symlinkJoin, writeText, autoconf, automake, bison, flex, libtool , pkgconfig, re2c, apacheHttpd, libargon2, libxml2, pcre, pcre2 , systemd, valgrind @@ -120,6 +120,7 @@ let withExtensions = mkWithExtensions allArgs allExtensionFunctions; phpIni = "${phpWithExtensions}/lib/php.ini"; unwrapped = php; + tests = nixosTests.php; inherit (php-packages) packages extensions; }; paths = [ php ]; From 5cad1b4aff3054b9c3ab97c420cce7b09b342dc8 Mon Sep 17 00:00:00 2001 From: talyz Date: Wed, 29 Apr 2020 12:46:26 +0200 Subject: [PATCH 10/11] php: Get rid of the phpXXbase attributes, update docs Since the introduction of php.unwrapped there's no real need for the phpXXbase attributes, so let's remove them to lessen potential confusion and clutter. Also update the docs to make it clear how to get hold of an unwrapped PHP if needed. --- doc/languages-frameworks/php.section.md | 27 ++++++++++--------- pkgs/development/interpreters/php/default.nix | 2 +- pkgs/servers/http/unit/default.nix | 12 ++++----- pkgs/top-level/all-packages.nix | 2 +- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/doc/languages-frameworks/php.section.md b/doc/languages-frameworks/php.section.md index abf91a31769..101f7b043ff 100644 --- a/doc/languages-frameworks/php.section.md +++ b/doc/languages-frameworks/php.section.md @@ -9,18 +9,24 @@ Several versions of PHP are available on Nix, each of which having a wide variety of extensions and libraries available. -The attribute `php` refers to the version of PHP considered most -stable and thoroughly tested in nixpkgs for any given release of -NixOS. Note that while this version of PHP may not be the latest major -release from upstream, any version of PHP supported in nixpkgs may be -utilized by specifying the desired attribute by version, such as -`php74`. +The different versions of PHP that nixpkgs provides are located under +attributes named based on major and minor version number; e.g., +`php74` is PHP 7.4. Only versions of PHP that are supported by upstream for the entirety of a given NixOS release will be included in that release of NixOS. See [PHP Supported Versions](https://www.php.net/supported-versions.php). +The attribute `php` refers to the version of PHP considered most +stable and thoroughly tested in nixpkgs for any given release of +NixOS - not necessarily the latest major release from upstream. + +All available PHP attributes are wrappers around their respective +binary PHP package and provide commonly used extensions this way. The +real PHP 7.4 package, i.e. the unwrapped one, is available as +`php74.unwrapped`; see the next section for more details. + Interactive tools built on PHP are put in `php.packages`; composer is for example available at `php.packages.composer`. @@ -30,12 +36,7 @@ opcache extension shipped with PHP is available at `php.extensions.opcache` and the third-party ImageMagick extension at `php.extensions.imagick`. -The different versions of PHP that nixpkgs provides are located under -attributes named based on major and minor version number; e.g., -`php74` is PHP 7.4 with commonly used extensions installed, -`php74base` is the same PHP runtime without extensions. - -#### Installing PHP with packages +#### Installing PHP with extensions A PHP package with specific extensions enabled can be built using `php.withExtensions`. This is a function which accepts an anonymous @@ -68,7 +69,7 @@ php.withExtensions ({ all, ... }: with all; [ opcache imagick ]) `php.withExtensions` provides extensions by wrapping a minimal php base package, providing a `php.ini` file listing all extensions to be -loaded. You can access this package through the `php.unwrappedPhp` +loaded. You can access this package through the `php.unwrapped` attribute; useful if you, for example, need access to the `dev` output. The generated `php.ini` file can be accessed through the `php.phpIni` attribute. diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index 57a0b716979..a67a26f083b 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -302,5 +302,5 @@ let php72 = php72base.withExtensions defaultPhpExtensionsWithHash; in { - inherit php72base php73base php74base php72 php73 php74; + inherit php72 php73 php74; } diff --git a/pkgs/servers/http/unit/default.nix b/pkgs/servers/http/unit/default.nix index f8992bf166b..0779a31f106 100644 --- a/pkgs/servers/http/unit/default.nix +++ b/pkgs/servers/http/unit/default.nix @@ -1,8 +1,8 @@ { stdenv, fetchFromGitHub, which , withPython2 ? false, python2 , withPython3 ? true, python3, ncurses -, withPHP72 ? false, php72base -, withPHP73 ? true, php73base +, withPHP72 ? false, php72 +, withPHP73 ? true, php73 , withPerl528 ? false, perl528 , withPerl530 ? true, perl530 , withPerldevel ? false, perldevel @@ -26,8 +26,8 @@ let fpmSupport = false; }; - php72-unit = php72base.override phpConfig; - php73-unit = php73base.override phpConfig; + php72-unit = php72.override phpConfig; + php73-unit = php73.override phpConfig; in stdenv.mkDerivation rec { version = "1.16.0"; pname = "unit"; @@ -71,8 +71,8 @@ in stdenv.mkDerivation rec { postConfigure = '' ${optionalString withPython2 "./configure python --module=python2 --config=${python2}/bin/python2-config --lib-path=${python2}/lib"} ${optionalString withPython3 "./configure python --module=python3 --config=${python3}/bin/python3-config --lib-path=${python3}/lib"} - ${optionalString withPHP72 "./configure php --module=php72 --config=${php72-unit.dev}/bin/php-config --lib-path=${php72-unit}/lib"} - ${optionalString withPHP73 "./configure php --module=php73 --config=${php73-unit.dev}/bin/php-config --lib-path=${php73-unit}/lib"} + ${optionalString withPHP72 "./configure php --module=php72 --config=${php72-unit.unwrapped.dev}/bin/php-config --lib-path=${php72-unit}/lib"} + ${optionalString withPHP73 "./configure php --module=php73 --config=${php73-unit.unwrapped.dev}/bin/php-config --lib-path=${php73-unit}/lib"} ${optionalString withPerl528 "./configure perl --module=perl528 --perl=${perl528}/bin/perl"} ${optionalString withPerl530 "./configure perl --module=perl530 --perl=${perl530}/bin/perl"} ${optionalString withPerldevel "./configure perl --module=perldev --perl=${perldevel}/bin/perl"} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 7f2c34039b4..c960ebcf7c3 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -9496,7 +9496,7 @@ in inherit (callPackage ../development/interpreters/php { stdenv = if stdenv.cc.isClang then llvmPackages_6.stdenv else stdenv; - }) php74 php73 php72 php74base php73base php72base; + }) php74 php73 php72; picoc = callPackage ../development/interpreters/picoc {}; From 2535cdfe91b9e0100a2950a128648c2ba509eb8c Mon Sep 17 00:00:00 2001 From: talyz Date: Wed, 29 Apr 2020 12:52:39 +0200 Subject: [PATCH 11/11] php: Unify the usage of the php package in php-packages.nix Instead of using two different php packages in php-packages.nix, one wrapper and one unwrapped, simply use the wrapper and use its "unwrapped" attribute when necessary. Also, get rid of the packages and extensions attributes from the base package, since they're no longer needed. --- pkgs/development/interpreters/php/default.nix | 15 +---------- pkgs/top-level/php-packages.nix | 25 ++++++++++--------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/pkgs/development/interpreters/php/default.nix b/pkgs/development/interpreters/php/default.nix index a67a26f083b..4c79691f504 100644 --- a/pkgs/development/interpreters/php/default.nix +++ b/pkgs/development/interpreters/php/default.nix @@ -14,8 +14,6 @@ let , sha256 , extraPatches ? [] - , defaultPhpExtensions - # Sapi flags , cgiSupport ? true , cliSupport ? true @@ -35,13 +33,6 @@ let , ztsSupport ? apxs2Support }@args: let - self = generic args; - - php-packages = (callPackage ../../../top-level/php-packages.nix { - php = self; - phpWithExtensions = self.withExtensions defaultPhpExtensions; - }); - # buildEnv wraps php to provide additional extensions and # configuration. Its usage is documented in # doc/languages-frameworks/php.section.md. @@ -58,7 +49,7 @@ let php = generic filteredArgs; php-packages = (callPackage ../../../top-level/php-packages.nix { - inherit php phpWithExtensions; + php = phpWithExtensions; }); allExtensionFunctions = prevExtensionFunctions ++ [ extensions ]; @@ -249,7 +240,6 @@ let passthru = { buildEnv = mkBuildEnv {} []; withExtensions = mkWithExtensions {} []; - inherit (php-packages) packages extensions; }; meta = with stdenv.lib; { @@ -265,7 +255,6 @@ let php72base = callPackage generic (_args // { version = "7.2.29"; sha256 = "08xry2fgqgg8s0ym1hh11wkbr36av3zq1bn4krbciw1b7x8gb8ga"; - defaultPhpExtensions = defaultPhpExtensionsWithHash; # https://bugs.php.net/bug.php?id=76826 extraPatches = lib.optional stdenv.isDarwin ./php72-darwin-isfinite.patch; @@ -274,7 +263,6 @@ let php73base = callPackage generic (_args // { version = "7.3.16"; sha256 = "0bh499v9dfgh9k51w4rird1slb9rh9whp5h37fb84c98d992s1xq"; - defaultPhpExtensions = defaultPhpExtensionsWithHash; # https://bugs.php.net/bug.php?id=76826 extraPatches = lib.optional stdenv.isDarwin ./php73-darwin-isfinite.patch; @@ -283,7 +271,6 @@ let php74base = callPackage generic (_args // { version = "7.4.4"; sha256 = "17w2m4phhpj76x5fx67vgjrlkcczqvky3f5in1kjg2pch90qz3ih"; - inherit defaultPhpExtensions; }); defaultPhpExtensions = { all, ... }: with all; ([ diff --git a/pkgs/top-level/php-packages.nix b/pkgs/top-level/php-packages.nix index 0cda058459d..b9247cf0a17 100644 --- a/pkgs/top-level/php-packages.nix +++ b/pkgs/top-level/php-packages.nix @@ -1,4 +1,4 @@ -{ stdenv, lib, pkgs, fetchgit, php, phpWithExtensions, autoconf, pkgconfig, re2c +{ stdenv, lib, pkgs, fetchgit, php, autoconf, pkgconfig, re2c , gettext, bzip2, curl, libxml2, openssl, gmp, icu, oniguruma, libsodium , html-tidy, libzip, zlib, pcre, pcre2, libxslt, aspell, openldap, cyrus_sasl , uwimap, pam, libiconv, enchant1, libXpm, gd, libwebp, libjpeg, libpng @@ -8,7 +8,8 @@ let buildPecl = import ../build-support/build-pecl.nix { - inherit php lib; + php = php.unwrapped; + inherit lib; inherit (pkgs) stdenv autoreconfHook fetchurl re2c; }; @@ -43,7 +44,7 @@ in installPhase = '' mkdir -p $out/bin install -D $src $out/libexec/box/box.phar - makeWrapper ${phpWithExtensions}/bin/php $out/bin/box \ + makeWrapper ${php}/bin/php $out/bin/box \ --add-flags "-d phar.readonly=0 $out/libexec/box/box.phar" ''; @@ -71,7 +72,7 @@ in installPhase = '' mkdir -p $out/bin install -D $src $out/libexec/composer/composer.phar - makeWrapper ${phpWithExtensions}/bin/php $out/bin/composer \ + makeWrapper ${php}/bin/php $out/bin/composer \ --add-flags "$out/libexec/composer/composer.phar" \ --prefix PATH : ${pkgs.lib.makeBinPath [ pkgs.unzip ]} ''; @@ -163,7 +164,7 @@ in installPhase = '' mkdir -p $out/bin install -D $src $out/libexec/phpcbf/phpcbf.phar - makeWrapper ${phpWithExtensions}/bin/php $out/bin/phpcbf \ + makeWrapper ${php}/bin/php $out/bin/phpcbf \ --add-flags "$out/libexec/phpcbf/phpcbf.phar" ''; @@ -190,7 +191,7 @@ in installPhase = '' mkdir -p $out/bin install -D $src $out/libexec/phpcs/phpcs.phar - makeWrapper ${phpWithExtensions}/bin/php $out/bin/phpcs \ + makeWrapper ${php}/bin/php $out/bin/phpcs \ --add-flags "$out/libexec/phpcs/phpcs.phar" ''; @@ -217,7 +218,7 @@ in installPhase = '' mkdir -p $out/bin install -D $src $out/libexec/phpstan/phpstan.phar - makeWrapper ${phpWithExtensions}/bin/php $out/bin/phpstan \ + makeWrapper ${php}/bin/php $out/bin/phpstan \ --add-flags "$out/libexec/phpstan/phpstan.phar" ''; @@ -537,7 +538,7 @@ in }; pdo_oci = buildPecl rec { - inherit (php) src version; + inherit (php.unwrapped) src version; pname = "pdo_oci"; sourceRoot = "php-${version}/ext/pdo_oci"; @@ -548,8 +549,8 @@ in internalDeps = [ php.extensions.pdo ]; postPatch = '' - sed -i -e 's|OCISDKMANINC=`.*$|OCISDKMANINC="${pkgs.oracle-instantclient.dev}/include"|' config.m4 - ''; + sed -i -e 's|OCISDKMANINC=`.*$|OCISDKMANINC="${pkgs.oracle-instantclient.dev}/include"|' config.m4 + ''; }; pdo_sqlsrv = buildPecl { @@ -746,11 +747,11 @@ in pname = "php-${name}"; extensionName = name; - inherit (php) version src; + inherit (php.unwrapped) version src; sourceRoot = "php-${php.version}/ext/${name}"; enableParallelBuilding = true; - nativeBuildInputs = [ php autoconf pkgconfig re2c ]; + nativeBuildInputs = [ php.unwrapped autoconf pkgconfig re2c ]; inherit configureFlags internalDeps buildInputs zendExtension doCheck;