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 <nixpkgs>) {} }: 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
This commit is contained in:
parent
abedfadd73
commit
2ba7926959
|
@ -30,7 +30,7 @@ opcache extension shipped with PHP is available at
|
||||||
`php.extensions.opcache` and the third-party ImageMagick extension at
|
`php.extensions.opcache` and the third-party ImageMagick extension at
|
||||||
`php.extensions.imagick`.
|
`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.,
|
attributes named based on major and minor version number; e.g.,
|
||||||
`php74` is PHP 7.4 with commonly used extensions installed,
|
`php74` is PHP 7.4 with commonly used extensions installed,
|
||||||
`php74base` is the same PHP runtime without extensions.
|
`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
|
A PHP package with specific extensions enabled can be built using
|
||||||
`php.withExtensions`. This is a function which accepts an anonymous
|
`php.withExtensions`. This is a function which accepts an anonymous
|
||||||
function as its only argument; the function should take one argument,
|
function as its only argument; the function should accept two named
|
||||||
the set of all extensions, and return a list of wanted extensions. For
|
parameters: `enabled` - a list of currently enabled extensions and
|
||||||
example, a PHP package with the opcache and ImageMagick extensions
|
`all` - the set of all extensions, and return a list of wanted
|
||||||
enabled:
|
extensions. For example, a PHP package with all default extensions and
|
||||||
|
ImageMagick enabled:
|
||||||
|
|
||||||
```nix
|
```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
|
To exclude some, but not all, of the default extensions, you can
|
||||||
ImageMagick, none of the other extensions which are enabled by default
|
filter the `enabled` list like this:
|
||||||
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:
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
php.withExtensions (e:
|
php.withExtensions ({ enabled, all }:
|
||||||
(lib.filter (e: e != php.extensions.opcache) php.enabledExtensions)
|
(lib.filter (e: e != php.extensions.opcache) enabled)
|
||||||
++ [ e.imagick ])
|
++ [ 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`
|
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
|
```nix
|
||||||
php.buildEnv {
|
php.buildEnv {
|
||||||
extensions = e: with e; [ imagick opcache ];
|
extensions = { all, ... }: with all; [ imagick opcache ];
|
||||||
extraConfig = "memory_limit=256M";
|
extraConfig = "memory_limit=256M";
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -85,7 +88,7 @@ follows:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
let
|
let
|
||||||
myPhp = php.withExtensions (e: with e; [ imagick opcache ]);
|
myPhp = php.withExtensions ({ all, ... }: with all; [ opcache imagick ]);
|
||||||
in {
|
in {
|
||||||
services.phpfpm.pools."foo".phpPackage = myPhp;
|
services.phpfpm.pools."foo".phpPackage = myPhp;
|
||||||
};
|
};
|
||||||
|
@ -94,7 +97,7 @@ in {
|
||||||
```nix
|
```nix
|
||||||
let
|
let
|
||||||
myPhp = php.buildEnv {
|
myPhp = php.buildEnv {
|
||||||
extensions = e: with e; [ imagick opcache ];
|
extensions = { all, ... }: with all; [ imagick opcache ];
|
||||||
extraConfig = "memory_limit=256M";
|
extraConfig = "memory_limit=256M";
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
|
@ -105,8 +108,8 @@ in {
|
||||||
##### Example usage with `nix-shell`
|
##### Example usage with `nix-shell`
|
||||||
|
|
||||||
This brings up a temporary environment that contains a PHP interpreter
|
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
|
```sh
|
||||||
nix-shell -p 'php.buildEnv { extensions = e: with e; [ imagick opcache ]; }'
|
nix-shell -p 'php.withExtensions ({ all, ... }: with all; [ imagick opcache ])'
|
||||||
```
|
```
|
||||||
|
|
|
@ -135,18 +135,23 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Since this release there's an easy way to customize your PHP install to get a much smaller
|
Since this release there's an easy way to customize your PHP
|
||||||
base PHP with only wanted extensions enabled. See the following snippet installing a smaller PHP
|
install to get a much smaller base PHP with only wanted
|
||||||
with the extensions <literal>imagick</literal>, <literal>opcache</literal> and
|
extensions enabled. See the following snippet installing a
|
||||||
|
smaller PHP with the extensions <literal>imagick</literal>,
|
||||||
|
<literal>opcache</literal>, <literal>pdo</literal> and
|
||||||
<literal>pdo_mysql</literal> loaded:
|
<literal>pdo_mysql</literal> loaded:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
environment.systemPackages = [
|
environment.systemPackages = [
|
||||||
(pkgs.php.buildEnv { extensions = pp: with pp; [
|
(pkgs.php.withExtensions
|
||||||
|
({ all, ... }: with all; [
|
||||||
imagick
|
imagick
|
||||||
opcache
|
opcache
|
||||||
|
pdo
|
||||||
pdo_mysql
|
pdo_mysql
|
||||||
]; })
|
])
|
||||||
|
)
|
||||||
];</programlisting>
|
];</programlisting>
|
||||||
|
|
||||||
The default <literal>php</literal> attribute hasn't lost any extensions -
|
The default <literal>php</literal> attribute hasn't lost any extensions -
|
||||||
|
|
|
@ -7,7 +7,7 @@ let
|
||||||
fpm = config.services.phpfpm.pools.roundcube;
|
fpm = config.services.phpfpm.pools.roundcube;
|
||||||
localDB = cfg.database.host == "localhost";
|
localDB = cfg.database.host == "localhost";
|
||||||
user = cfg.database.username;
|
user = cfg.database.username;
|
||||||
phpWithPspell = pkgs.php.withExtensions (e: [ e.pspell ] ++ pkgs.php.enabledExtensions);
|
phpWithPspell = pkgs.php.withExtensions ({ enabled, all }: [ all.pspell ] ++ enabled);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.services.roundcube = {
|
options.services.roundcube = {
|
||||||
|
|
|
@ -11,8 +11,8 @@ let
|
||||||
base = pkgs.php74;
|
base = pkgs.php74;
|
||||||
in
|
in
|
||||||
base.buildEnv {
|
base.buildEnv {
|
||||||
extensions = e: with e;
|
extensions = { enabled, all }: with all;
|
||||||
base.enabledExtensions ++ [
|
enabled ++ [
|
||||||
apcu redis memcached imagick
|
apcu redis memcached imagick
|
||||||
];
|
];
|
||||||
extraConfig = phpOptionsStr;
|
extraConfig = phpOptionsStr;
|
||||||
|
|
|
@ -43,8 +43,16 @@ let
|
||||||
phpWithExtensions = self.withExtensions defaultPhpExtensions;
|
phpWithExtensions = self.withExtensions defaultPhpExtensions;
|
||||||
});
|
});
|
||||||
|
|
||||||
mkBuildEnv = prevArgs: lib.makeOverridable (
|
# buildEnv wraps php to provide additional extensions and
|
||||||
{ extensions ? (_: []), extraConfig ? "", ... }@innerArgs:
|
# 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
|
let
|
||||||
allArgs = args // prevArgs // innerArgs;
|
allArgs = args // prevArgs // innerArgs;
|
||||||
filteredArgs = builtins.removeAttrs allArgs [ "extensions" "extraConfig" ];
|
filteredArgs = builtins.removeAttrs allArgs [ "extensions" "extraConfig" ];
|
||||||
|
@ -54,8 +62,15 @@ let
|
||||||
inherit php phpWithExtensions;
|
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;
|
getExtName = ext: lib.removePrefix "php-" (builtins.parseDrvName ext.name).name;
|
||||||
enabledExtensions = extensions php-packages.extensions;
|
|
||||||
|
|
||||||
# Generate extension load configuration snippets from the
|
# Generate extension load configuration snippets from the
|
||||||
# extension parameter. This is an attrset suitable for use
|
# extension parameter. This is an attrset suitable for use
|
||||||
|
@ -89,9 +104,8 @@ let
|
||||||
inherit (php) version;
|
inherit (php) version;
|
||||||
nativeBuildInputs = [ makeWrapper ];
|
nativeBuildInputs = [ makeWrapper ];
|
||||||
passthru = {
|
passthru = {
|
||||||
buildEnv = mkBuildEnv allArgs;
|
buildEnv = mkBuildEnv allArgs allExtensionFunctions;
|
||||||
withExtensions = mkWithExtensions allArgs;
|
withExtensions = mkWithExtensions allArgs allExtensionFunctions;
|
||||||
inherit enabledExtensions;
|
|
||||||
inherit (php-packages) packages extensions;
|
inherit (php-packages) packages extensions;
|
||||||
};
|
};
|
||||||
paths = [ php ];
|
paths = [ php ];
|
||||||
|
@ -108,8 +122,8 @@ let
|
||||||
in
|
in
|
||||||
phpWithExtensions);
|
phpWithExtensions);
|
||||||
|
|
||||||
mkWithExtensions = prevArgs: extensions:
|
mkWithExtensions = prevArgs: prevExtensionFunctions: extensions:
|
||||||
mkBuildEnv prevArgs { inherit extensions; };
|
mkBuildEnv prevArgs prevExtensionFunctions { inherit extensions; };
|
||||||
|
|
||||||
pcre' = if (lib.versionAtLeast version "7.3") then pcre2 else pcre;
|
pcre' = if (lib.versionAtLeast version "7.3") then pcre2 else pcre;
|
||||||
in
|
in
|
||||||
|
@ -218,9 +232,8 @@ let
|
||||||
outputs = [ "out" "dev" ];
|
outputs = [ "out" "dev" ];
|
||||||
|
|
||||||
passthru = {
|
passthru = {
|
||||||
enabledExtensions = [];
|
buildEnv = mkBuildEnv {} [];
|
||||||
buildEnv = mkBuildEnv {};
|
withExtensions = mkWithExtensions {} [];
|
||||||
withExtensions = mkWithExtensions {};
|
|
||||||
inherit (php-packages) packages extensions;
|
inherit (php-packages) packages extensions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -258,7 +271,7 @@ let
|
||||||
inherit defaultPhpExtensions;
|
inherit defaultPhpExtensions;
|
||||||
});
|
});
|
||||||
|
|
||||||
defaultPhpExtensions = extensions: with extensions; ([
|
defaultPhpExtensions = { all, ... }: with all; ([
|
||||||
bcmath calendar curl ctype dom exif fileinfo filter ftp gd
|
bcmath calendar curl ctype dom exif fileinfo filter ftp gd
|
||||||
gettext gmp iconv intl json ldap mbstring mysqli mysqlnd opcache
|
gettext gmp iconv intl json ldap mbstring mysqli mysqlnd opcache
|
||||||
openssl pcntl pdo pdo_mysql pdo_odbc pdo_pgsql pdo_sqlite pgsql
|
openssl pcntl pdo pdo_mysql pdo_odbc pdo_pgsql pdo_sqlite pgsql
|
||||||
|
@ -266,8 +279,8 @@ let
|
||||||
tokenizer xmlreader xmlwriter zip zlib
|
tokenizer xmlreader xmlwriter zip zlib
|
||||||
] ++ lib.optionals (!stdenv.isDarwin) [ imap ]);
|
] ++ lib.optionals (!stdenv.isDarwin) [ imap ]);
|
||||||
|
|
||||||
defaultPhpExtensionsWithHash = extensions:
|
defaultPhpExtensionsWithHash = { all, ... }:
|
||||||
(defaultPhpExtensions extensions) ++ [ extensions.hash ];
|
(defaultPhpExtensions { inherit all; }) ++ [ all.hash ];
|
||||||
|
|
||||||
php74 = php74base.withExtensions defaultPhpExtensions;
|
php74 = php74base.withExtensions defaultPhpExtensions;
|
||||||
php73 = php73base.withExtensions defaultPhpExtensionsWithHash;
|
php73 = php73base.withExtensions defaultPhpExtensionsWithHash;
|
||||||
|
|
Loading…
Reference in New Issue