base16-schemes: unstable-2024-06-21 -> unstable-2024-11-12 (#356361)
[NixPkgs.git] / pkgs / top-level / php-packages.nix
blobc02e9f8ed0686fc0293124217ee7e97f17fce883
1 { stdenv
2 , config
3 , callPackages
4 , lib
5 , pkgs
6 , phpPackage
7 , autoconf
8 , pkg-config
9 , bzip2
10 , curl
11 , cyrus_sasl
12 , enchant2
13 , freetds
14 , gd
15 , gettext
16 , gmp
17 , html-tidy
18 , icu73
19 , libffi
20 , libiconv
21 , libkrb5
22 , libsodium
23 , libxml2
24 , libxslt
25 , libzip
26 , net-snmp
27 , nix-update-script
28 , oniguruma
29 , openldap
30 , openssl_1_1
31 , openssl
32 , overrideSDK
33 , pam
34 , pcre2
35 , postgresql
36 , bison
37 , re2c
38 , readline
39 , rsync
40 , sqlite
41 , unixODBC
42 , uwimap
43 , valgrind
44 , zlib
45 , fetchpatch
48 lib.makeScope pkgs.newScope (self: let
49   inherit (self) buildPecl callPackage mkExtension php;
51   builders = import ../build-support/php/builders {
52     inherit callPackages callPackage buildPecl;
53   };
54 in {
55   buildPecl = callPackage ../build-support/php/build-pecl.nix {
56     php = php.unwrapped;
57   };
59   inherit (builders.v1) buildComposerProject buildComposerWithPlugin composerHooks mkComposerRepository;
61   # Next version of the builder
62   buildComposerProject2 = builders.v2.buildComposerProject;
63   composerHooks2 = builders.v2.composerHooks;
64   mkComposerVendor = builders.v2.mkComposerVendor;
66   # Wrap mkDerivation to prepend pname with "php-" to make names consistent
67   # with how buildPecl does it and make the file easier to overview.
68   mkDerivation = origArgs:
69     let
70       args = lib.fix (lib.extends
71         (_: previousAttrs: {
72           pname = "php-${previousAttrs.pname}";
73           passthru = (previousAttrs.passthru or { }) // {
74             updateScript = nix-update-script { };
75           };
76           meta = (previousAttrs.meta or { }) // {
77             mainProgram = previousAttrs.meta.mainProgram or previousAttrs.pname;
78           };
79         })
80         (if lib.isFunction origArgs then origArgs else (_: origArgs))
81       );
82     in
83     pkgs.stdenv.mkDerivation args;
85   # Function to build an extension which is shipped as part of the php
86   # source, based on the php version.
87   #
88   # Name passed is the name of the extension and is automatically used
89   # to add the configureFlag "--enable-${name}", which can be overridden.
90   #
91   # Build inputs is used for extra deps that may be needed. And zendExtension
92   # will mark the extension as a zend extension or not.
93   mkExtension = lib.makeOverridable
94     ({ name
95      , configureFlags ? [ "--enable-${extName}" ]
96      , internalDeps ? [ ]
97      , postPhpize ? ""
98      , buildInputs ? [ ]
99      , zendExtension ? false
100      , doCheck ? true
101      , extName ? name
102      , ...
103      }@args: stdenv.mkDerivation ((builtins.removeAttrs args [ "name" ]) // {
104       pname = "php-${name}";
105       extensionName = extName;
107       outputs = [ "out" "dev" ];
109       inherit (php.unwrapped) version src;
111       enableParallelBuilding = true;
113       nativeBuildInputs = [
114         php.unwrapped
115         autoconf
116         pkg-config
117         re2c
118         bison
119       ];
121       inherit configureFlags internalDeps buildInputs zendExtension doCheck;
123       preConfigurePhases = [
124         "genfiles"
125         "cdToExtensionRootPhase"
126       ];
128       genfiles = ''
129         if [ -f "scripts/dev/genfiles" ]; then
130           ./scripts/dev/genfiles
131         fi
132       '';
134       cdToExtensionRootPhase = ''
135         # Go to extension source root.
136         cd "ext/${extName}"
137       '';
139       preConfigure = ''
140         nullglobRestore=$(shopt -p nullglob)
141         shopt -u nullglob   # To make ?-globbing work
143         # Some extensions have a config0.m4 or config9.m4
144         if [ -f config?.m4 ]; then
145           mv config?.m4 config.m4
146         fi
148         $nullglobRestore
150         phpize
151         ${postPhpize}
153         ${lib.concatMapStringsSep
154           "\n"
155           (dep: "mkdir -p ext; ln -s ${dep.dev}/include ext/${dep.extensionName}")
156           internalDeps
157         }
158       '';
160       checkPhase = ''
161         runHook preCheck
163         NO_INTERACTION=yes SKIP_PERF_SENSITIVE=yes SKIP_ONLINE_TESTS=yes make test
164         runHook postCheck
165       '';
167       installPhase = ''
168         runHook preInstall
170         mkdir -p $out/lib/php/extensions
171         cp modules/${extName}.so $out/lib/php/extensions/${extName}.so
172         mkdir -p $dev/include
173         ${rsync}/bin/rsync -r --filter="+ */" \
174                               --filter="+ *.h" \
175                               --filter="- *" \
176                               --prune-empty-dirs \
177                               . $dev/include/
179         runHook postInstall
180       '';
182       meta = {
183         description = "PHP upstream extension: ${name}";
184         inherit (php.meta) maintainers homepage license platforms;
185       } // args.meta or { };
186     }));
188   php = phpPackage;
190   # This is a set of interactive tools based on PHP.
191   tools = {
192     box = callPackage ../development/php-packages/box { };
194     castor = callPackage ../development/php-packages/castor { };
196     composer = callPackage ../development/php-packages/composer { };
198     composer-local-repo-plugin = callPackage ../development/php-packages/composer-local-repo-plugin { };
200     cyclonedx-php-composer = callPackage ../development/php-packages/cyclonedx-php-composer { };
202     deployer = callPackage ../development/php-packages/deployer { };
204     grumphp = callPackage ../development/php-packages/grumphp { };
206     phan = callPackage ../development/php-packages/phan { };
208     phing = callPackage ../development/php-packages/phing { };
210     phive = callPackage ../development/php-packages/phive { };
212     php-codesniffer = callPackage ../development/php-packages/php-codesniffer { };
214     php-cs-fixer = callPackage ../development/php-packages/php-cs-fixer { };
216     php-parallel-lint = callPackage ../development/php-packages/php-parallel-lint { };
218     phpinsights = callPackage ../development/php-packages/phpinsights { };
220     phpmd = callPackage ../development/php-packages/phpmd { };
222     phpspy = callPackage ../development/php-packages/phpspy { };
224     phpstan = callPackage ../development/php-packages/phpstan { };
226     psalm = callPackage ../development/php-packages/psalm { };
228     psysh = callPackage ../development/php-packages/psysh { };
229   } // lib.optionalAttrs config.allowAliases {
230     phpcbf = throw "`phpcbf` is now deprecated, use `php-codesniffer` instead which contains both `phpcs` and `phpcbf`.";
231     phpcs = throw "`phpcs` is now deprecated, use `php-codesniffer` instead which contains both `phpcs` and `phpcbf`.";
232   };
234   # This is a set of PHP extensions meant to be used in php.buildEnv
235   # or php.withExtensions to extend the functionality of the PHP
236   # interpreter.
237   # The extensions attributes is composed of three sections:
238   # 1. The contrib conditional extensions, which are only available on specific PHP versions
239   # 2. The contrib extensions available
240   # 3. The core extensions
241   extensions =
242   # Contrib extensions
243   {
244     amqp = callPackage ../development/php-packages/amqp { };
246     apcu = callPackage ../development/php-packages/apcu { };
248     ast = callPackage ../development/php-packages/ast { };
250     blackfire = callPackage ../development/tools/misc/blackfire/php-probe.nix { };
252     couchbase = callPackage ../development/php-packages/couchbase { };
254     datadog_trace = callPackage ../development/php-packages/datadog_trace {
255       buildPecl = buildPecl.override {
256         stdenv = if stdenv.hostPlatform.isDarwin then overrideSDK stdenv "11.0" else stdenv;
257       };
258       inherit (pkgs) darwin;
259     };
261     ds = callPackage ../development/php-packages/ds { };
263     event = callPackage ../development/php-packages/event { };
265     gnupg = callPackage ../development/php-packages/gnupg { };
267     grpc = callPackage ../development/php-packages/grpc { };
269     igbinary = callPackage ../development/php-packages/igbinary { };
271     imagick = callPackage ../development/php-packages/imagick { };
273     # Shadowed by built-in version on PHP < 8.3.
274     imap = callPackage ../development/php-packages/imap { };
276     inotify = callPackage ../development/php-packages/inotify { };
278     ioncube-loader = callPackage ../development/php-packages/ioncube-loader { };
280     mailparse = callPackage ../development/php-packages/mailparse { };
282     maxminddb = callPackage ../development/php-packages/maxminddb { };
284     memcache = callPackage ../development/php-packages/memcache { };
286     memcached = callPackage ../development/php-packages/memcached { };
288     meminfo = callPackage ../development/php-packages/meminfo { };
290     memprof = callPackage ../development/php-packages/memprof { };
292     mongodb = callPackage ../development/php-packages/mongodb {
293       inherit (pkgs) darwin;
294     };
296     msgpack = callPackage ../development/php-packages/msgpack { };
298     oci8 = callPackage ../development/php-packages/oci8 { };
300     opentelemetry = callPackage ../development/php-packages/opentelemetry { };
302     openswoole = callPackage ../development/php-packages/openswoole { };
304     parallel = callPackage ../development/php-packages/parallel { };
306     pdlib = callPackage ../development/php-packages/pdlib { };
308     pcov = callPackage ../development/php-packages/pcov { };
310     pdo_oci = buildPecl rec {
311       inherit (php.unwrapped) src version;
313       pname = "pdo_oci";
314       sourceRoot = "php-${version}/ext/pdo_oci";
316       buildInputs = [ pkgs.oracle-instantclient ];
317       configureFlags = [ "--with-pdo-oci=instantclient,${pkgs.oracle-instantclient.lib}/lib" ];
319       internalDeps = [ php.extensions.pdo ];
321       postPatch = ''
322         sed -i -e 's|OCISDKMANINC=`.*$|OCISDKMANINC="${pkgs.oracle-instantclient.dev}/include"|' config.m4
323       '';
325       meta.maintainers = lib.teams.php.members;
326     };
328     pdo_sqlsrv = callPackage ../development/php-packages/pdo_sqlsrv { };
330     phalcon = callPackage ../development/php-packages/phalcon { };
332     pinba = callPackage ../development/php-packages/pinba { };
334     protobuf = callPackage ../development/php-packages/protobuf { };
336     pspell = callPackage ../development/php-packages/pspell { };
338     rdkafka = callPackage ../development/php-packages/rdkafka { };
340     redis = callPackage ../development/php-packages/redis { };
342     relay = callPackage ../development/php-packages/relay { };
344     rrd = callPackage ../development/php-packages/rrd { };
346     smbclient = callPackage ../development/php-packages/smbclient { };
348     snuffleupagus = callPackage ../development/php-packages/snuffleupagus {
349       inherit (pkgs) darwin;
350     };
352     spx = callPackage ../development/php-packages/spx { };
354     sqlsrv = callPackage ../development/php-packages/sqlsrv { };
356     ssh2 = callPackage ../development/php-packages/ssh2 { };
358     swoole = callPackage ../development/php-packages/swoole { };
360     uv = callPackage ../development/php-packages/uv { };
362     vld = callPackage ../development/php-packages/vld { };
364     xdebug = callPackage ../development/php-packages/xdebug { };
366     yaml = callPackage ../development/php-packages/yaml { };
368     zstd = callPackage ../development/php-packages/zstd { };
369   } // lib.optionalAttrs config.allowAliases {
370     php-spx = throw "php-spx is deprecated, use spx instead";
371   } // (
372     # Core extensions
373     let
374       # This list contains build instructions for different modules that one may
375       # want to build.
376       #
377       # These will be passed as arguments to mkExtension above.
378       extensionData = [
379         { name = "bcmath"; }
380         { name = "bz2"; buildInputs = [ bzip2 ]; configureFlags = [ "--with-bz2=${bzip2.dev}" ]; }
381         { name = "calendar"; }
382         { name = "ctype"; }
383         {
384           name = "curl";
385           buildInputs = [ curl ];
386           configureFlags = [ "--with-curl=${curl.dev}" ];
387           doCheck = false;
388         }
389         { name = "dba"; }
390         {
391           name = "dom";
392           buildInputs = [ libxml2 ];
393           configureFlags = [
394             "--enable-dom"
395           ];
396           # Add a PHP lower version bound constraint to avoid applying the patch on older PHP versions.
397           patches = lib.optionals (lib.versions.majorMinor php.version == "8.1") [
398             # Fix tests with libxml 2.12
399             # Part of 8.3.1RC1+, 8.2.14RC1+
400             (fetchpatch {
401               url = "https://github.com/php/php-src/commit/061058a9b1bbd90d27d97d79aebcf2b5029767b0.patch";
402               hash = "sha256-0hOlAG+pOYp/gUU0MUMZvzWpgr0ncJi5GB8IeNxxyEU=";
403               excludes = [
404                 "NEWS"
405               ];
406             })
407           ] ++ lib.optionals (lib.versions.majorMinor php.version == "8.1") [
408             # Backport of PHP_LIBXML_IGNORE_DEPRECATIONS_START and PHP_LIBXML_IGNORE_DEPRECATIONS_END
409             (fetchpatch {
410               url = "https://github.com/php/php-src/commit/e2d97314ab342d434e778cd00a2f34e4bdb07664.patch";
411               hash = "sha256-w0hyYUgbRGpvIBfWeDTSEUGpiJdyrtNjKy+Fn1vyAO0=";
412             })
413             # Fix build with libxml2 2.13+. Has to be applied after libxml2 2.12 patch.
414             (fetchpatch {
415               url = "https://github.com/php/php-src/commit/4fe821311cafb18ca8bdf20b9d796c48a13ba552.patch";
416               hash = "sha256-YC3I0BQi3o3+VmRu/UqpqPpaSC+ekPqzbORTHftbPvY=";
417             })
418           ];
419         }
420         {
421           name = "enchant";
422           buildInputs = [ enchant2 ];
423           configureFlags = [ "--with-enchant" ];
424           doCheck = false;
425         }
426         { name = "exif"; doCheck = false; }
427         { name = "ffi"; buildInputs = [ libffi ]; }
428         {
429           name = "fileinfo";
430           buildInputs = [ pcre2 ];
431         }
432         { name = "filter"; buildInputs = [ pcre2 ]; }
433         { name = "ftp"; buildInputs = [ openssl ]; }
434         {
435           name = "gd";
436           buildInputs = [ zlib gd ];
437           configureFlags = [
438             "--enable-gd"
439             "--with-external-gd=${gd.dev}"
440             "--enable-gd-jis-conv"
441           ];
442           doCheck = false;
443         }
444         {
445           name = "gettext";
446           buildInputs = [ gettext ];
447           postPhpize = ''substituteInPlace configure --replace-fail 'as_fn_error $? "Cannot locate header file libintl.h" "$LINENO" 5' ':' '';
448           configureFlags = [ "--with-gettext=${gettext}" ];
449         }
450         {
451           name = "gmp";
452           buildInputs = [ gmp ];
453           configureFlags = [ "--with-gmp=${gmp.dev}" ];
454         }
455         {
456           name = "iconv";
457           buildInputs = [ libiconv ];
458           configureFlags = [ "--with-iconv" ];
459           # Some other extensions support separate libdirs, but iconv does not. This causes problems with detecting
460           # Darwin’s libiconv because it has separate outputs. Adding `-liconv` works around the issue.
461           env = lib.optionalAttrs stdenv.hostPlatform.isDarwin { NIX_LDFLAGS = "-liconv"; };
462           doCheck = stdenv.hostPlatform.isLinux;
463         }
464         {
465           name = "intl";
466           buildInputs = [ icu73 ];
467         }
468         {
469           name = "ldap";
470           buildInputs = [ openldap cyrus_sasl ];
471           configureFlags = [
472             "--with-ldap"
473             "LDAP_DIR=${openldap.dev}"
474             "LDAP_INCDIR=${openldap.dev}/include"
475             "LDAP_LIBDIR=${openldap.out}/lib"
476           ] ++ lib.optionals stdenv.hostPlatform.isLinux [
477             "--with-ldap-sasl=${cyrus_sasl.dev}"
478           ];
479           doCheck = false;
480         }
481         {
482           name = "mbstring";
483           buildInputs = [ oniguruma pcre2 ];
484           doCheck = false;
485         }
486         {
487           name = "mysqli";
488           internalDeps = [ php.extensions.mysqlnd ];
489           configureFlags = [ "--with-mysqli=mysqlnd" "--with-mysql-sock=/run/mysqld/mysqld.sock" ];
490           doCheck = false;
491         }
492         {
493           name = "mysqlnd";
494           buildInputs = [ zlib openssl ];
495           # The configure script doesn't correctly add library link
496           # flags, so we add them to the variable used by the Makefile
497           # when linking.
498           MYSQLND_SHARED_LIBADD = "-lz -lssl -lcrypto";
499           # The configure script builds a config.h which is never
500           # included. Let's include it in the main header file
501           # included by all .c-files.
502           patches = [
503             (pkgs.writeText "mysqlnd_config.patch" ''
504               --- a/ext/mysqlnd/mysqlnd.h
505               +++ b/ext/mysqlnd/mysqlnd.h
506               @@ -1,3 +1,6 @@
507               +#ifdef HAVE_CONFIG_H
508               +#include "config.h"
509               +#endif
510                /*
511                  +----------------------------------------------------------------------+
512                  | Copyright (c) The PHP Group                                          |
513             '')
514           ];
515         }
516         {
517           name = "opcache";
518           buildInputs = [ pcre2 ] ++
519             lib.optional
520               (!stdenv.hostPlatform.isDarwin && lib.meta.availableOn stdenv.hostPlatform valgrind)
521               valgrind.dev;
522           configureFlags = lib.optional php.ztsSupport "--disable-opcache-jit";
523           zendExtension = true;
524           postPatch = lib.optionalString stdenv.hostPlatform.isDarwin ''
525             # Tests are flaky on darwin
526             rm ext/opcache/tests/blacklist.phpt
527             rm ext/opcache/tests/bug66338.phpt
528             rm ext/opcache/tests/bug78106.phpt
529             rm ext/opcache/tests/issue0115.phpt
530             rm ext/opcache/tests/issue0149.phpt
531             rm ext/opcache/tests/revalidate_path_01.phpt
532           '';
533           # Tests launch the builtin webserver.
534           __darwinAllowLocalNetworking = true;
535         }
536         {
537           name = "openssl";
538           buildInputs = [ openssl ];
539           configureFlags = [ "--with-openssl" ];
540           doCheck = false;
541         }
542         # This provides a legacy OpenSSL PHP extension
543         # For situations where OpenSSL 3 do not support a set of features
544         # without a specific openssl.cnf file
545         {
546           name = "openssl-legacy";
547           extName = "openssl";
548           buildInputs = [ openssl_1_1 ];
549           configureFlags = [ "--with-openssl" ];
550           doCheck = false;
551         }
552         { name = "pcntl"; }
553         { name = "pdo"; doCheck = false; }
554         {
555           name = "pdo_dblib";
556           internalDeps = [ php.extensions.pdo ];
557           configureFlags = [ "--with-pdo-dblib=${freetds}" ];
558           meta.broken = stdenv.hostPlatform.isDarwin;
559           doCheck = false;
560         }
561         {
562           name = "pdo_mysql";
563           internalDeps = with php.extensions; [ pdo mysqlnd ];
564           configureFlags = [ "--with-pdo-mysql=mysqlnd" "PHP_MYSQL_SOCK=/run/mysqld/mysqld.sock" ];
565           doCheck = false;
566         }
567         {
568           name = "pdo_odbc";
569           internalDeps = [ php.extensions.pdo ];
570           buildInputs = [ unixODBC ];
571           configureFlags = [ "--with-pdo-odbc=unixODBC,${unixODBC}" ];
572           doCheck = false;
573         }
574         {
575           name = "pdo_pgsql";
576           internalDeps = [ php.extensions.pdo ];
577           configureFlags = [ "--with-pdo-pgsql=${lib.getDev postgresql}" ];
578           doCheck = false;
579         }
580         {
581           name = "pdo_sqlite";
582           internalDeps = [ php.extensions.pdo ];
583           buildInputs = [ sqlite ];
584           configureFlags = [ "--with-pdo-sqlite=${sqlite.dev}" ];
585           doCheck = false;
586         }
587         {
588           name = "pgsql";
589           buildInputs = [ pcre2 ];
590           configureFlags = [ "--with-pgsql=${lib.getDev postgresql}" ];
591           doCheck = false;
592         }
593         { name = "posix"; doCheck = false; }
594         {
595           name = "readline";
596           buildInputs = [
597             readline
598           ];
599           configureFlags = [
600             "--with-readline=${readline.dev}"
601           ];
602           postPatch = ''
603             # Fix `--with-readline` option not being available.
604             # `PHP_ALWAYS_SHARED` generated by phpize enables all options
605             # without the possibility to override them. But when `--with-libedit`
606             # is enabled, `--with-readline` is not registered.
607             echo '
608             AC_DEFUN([PHP_ALWAYS_SHARED],[
609               test "[$]$1" != "no" && ext_shared=yes
610             ])dnl
611             ' | cat - ext/readline/config.m4 > ext/readline/config.m4.tmp
612             mv ext/readline/config.m4{.tmp,}
613           '';
614           doCheck = false;
615         }
616         { name = "session";
617           doCheck = false;
618         }
619         { name = "shmop"; }
620         {
621           name = "simplexml";
622           buildInputs = [ libxml2 pcre2 ];
623           configureFlags = [
624             "--enable-simplexml"
625           ];
626           patches = lib.optionals (lib.versions.majorMinor php.version == "8.1") [
627             # Fix tests with libxml2 2.12
628             (fetchpatch {
629               url = "https://github.com/php/php-src/commit/061058a9b1bbd90d27d97d79aebcf2b5029767b0.patch";
630               hash = "sha256-0hOlAG+pOYp/gUU0MUMZvzWpgr0ncJi5GB8IeNxxyEU=";
631               excludes = [
632                 "NEWS"
633               ];
634             })
635             # Backport of PHP_LIBXML_IGNORE_DEPRECATIONS_START and PHP_LIBXML_IGNORE_DEPRECATIONS_END
636             # Required for libxml2 2.13 compatibility patch.
637             (fetchpatch {
638               url = "https://github.com/php/php-src/commit/e2d97314ab342d434e778cd00a2f34e4bdb07664.patch";
639               hash = "sha256-w0hyYUgbRGpvIBfWeDTSEUGpiJdyrtNjKy+Fn1vyAO0=";
640             })
641             # Fix build with libxml2 2.13+. Has to be applied after libxml2 2.12 patch.
642             (fetchpatch {
643               url = "https://github.com/php/php-src/commit/4fe821311cafb18ca8bdf20b9d796c48a13ba552.patch";
644               hash = "sha256-YC3I0BQi3o3+VmRu/UqpqPpaSC+ekPqzbORTHftbPvY=";
645             })
646           ];
647         }
648         {
649           name = "snmp";
650           buildInputs = [ net-snmp openssl ];
651           configureFlags = [ "--with-snmp" ];
652           doCheck = false;
653         }
654         {
655           name = "soap";
656           buildInputs = [ libxml2 ];
657           configureFlags = [
658             "--enable-soap"
659           ];
660           # Some tests are causing issues in the Darwin sandbox with issues
661           # such as
662           #   Unknown: php_network_getaddresses: getaddrinfo for localhost failed: nodename nor servname provided
663           doCheck = !stdenv.hostPlatform.isDarwin && lib.versionOlder php.version "8.4";
664           internalDeps = [ php.extensions.session ];
665           patches = lib.optionals (lib.versions.majorMinor php.version == "8.1") [
666             # Fix tests with libxml2 2.12
667             (fetchpatch {
668               url = "https://github.com/php/php-src/commit/061058a9b1bbd90d27d97d79aebcf2b5029767b0.patch";
669               hash = "sha256-0hOlAG+pOYp/gUU0MUMZvzWpgr0ncJi5GB8IeNxxyEU=";
670               excludes = [
671                 "NEWS"
672               ];
673             })
674             # Backport of PHP_LIBXML_IGNORE_DEPRECATIONS_START and PHP_LIBXML_IGNORE_DEPRECATIONS_END
675             # Required for libxml2 2.13 compatibility patch.
676             (fetchpatch {
677               url = "https://github.com/php/php-src/commit/e2d97314ab342d434e778cd00a2f34e4bdb07664.patch";
678               hash = "sha256-w0hyYUgbRGpvIBfWeDTSEUGpiJdyrtNjKy+Fn1vyAO0=";
679             })
680             # Fix build with libxml2 2.13+. Has to be applied after libxml2 2.12 patch.
681             (fetchpatch {
682               url = "https://github.com/php/php-src/commit/4fe821311cafb18ca8bdf20b9d796c48a13ba552.patch";
683               hash = "sha256-YC3I0BQi3o3+VmRu/UqpqPpaSC+ekPqzbORTHftbPvY=";
684             })
685           ]
686           ++ lib.optionals (lib.versionAtLeast php.version "8.3") [
687             # https://github.com/php/php-src/pull/16733 (fix soap test)
688             (fetchpatch {
689               url = "https://github.com/php/php-src/commit/5c308d61db104854e4ff84ab123e3ea56e1b4046.patch";
690               hash = "sha256-xQ4Sg4kL0cgHYauRW2AzGgFXfcqtxeRVhI9zNh7CsoM=";
691             })
692           ];
693         }
694         {
695           name = "sockets";
696           doCheck = false;
697         }
698         { name = "sodium"; buildInputs = [ libsodium ]; }
699         {
700           name = "sqlite3";
701           buildInputs = [ sqlite ];
703           # The `sqlite3_bind_bug68849.phpt` test is currently broken for i686 Linux systems since sqlite 3.43, cf.:
704           # - https://github.com/php/php-src/issues/12076
705           # - https://www.sqlite.org/forum/forumpost/abbb95376ec6cd5f
706           patches = lib.optionals (stdenv.hostPlatform.isi686 && stdenv.hostPlatform.isLinux) [
707             ../development/interpreters/php/skip-sqlite3_bind_bug68849.phpt.patch
708           ];
709         }
710         { name = "sysvmsg"; }
711         { name = "sysvsem"; }
712         { name = "sysvshm"; }
713         { name = "tidy"; configureFlags = [ "--with-tidy=${html-tidy}" ]; doCheck = false; }
714         {
715           name = "tokenizer";
716           patches = [ ../development/interpreters/php/fix-tokenizer-php81.patch ];
717         }
718         {
719           name = "xml";
720           buildInputs = [ libxml2 ];
721           configureFlags = [
722             "--enable-xml"
723           ];
724           doCheck = false;
725           patches = lib.optionals (lib.versions.majorMinor php.version == "8.1") [
726             # Fix tests with libxml2 2.12
727             (fetchpatch {
728               url = "https://github.com/php/php-src/commit/061058a9b1bbd90d27d97d79aebcf2b5029767b0.patch";
729               hash = "sha256-0hOlAG+pOYp/gUU0MUMZvzWpgr0ncJi5GB8IeNxxyEU=";
730               excludes = [
731                 "NEWS"
732               ];
733             })
734             # Backport of PHP_LIBXML_IGNORE_DEPRECATIONS_START and PHP_LIBXML_IGNORE_DEPRECATIONS_END
735             # Required for libxml2 2.13 compatibility patch.
736             (fetchpatch {
737               url = "https://github.com/php/php-src/commit/e2d97314ab342d434e778cd00a2f34e4bdb07664.patch";
738               hash = "sha256-w0hyYUgbRGpvIBfWeDTSEUGpiJdyrtNjKy+Fn1vyAO0=";
739             })
740             # Fix build with libxml2 2.13+. Has to be applied after libxml2 2.12 patch.
741             (fetchpatch {
742               url = "https://github.com/php/php-src/commit/4fe821311cafb18ca8bdf20b9d796c48a13ba552.patch";
743               hash = "sha256-YC3I0BQi3o3+VmRu/UqpqPpaSC+ekPqzbORTHftbPvY=";
744             })
745           ];
746         }
747         {
748           name = "xmlreader";
749           buildInputs = [ libxml2 ];
750           internalDeps = [ php.extensions.dom ];
751           env.NIX_CFLAGS_COMPILE = toString [ "-I../.." "-DHAVE_DOM" ];
752           doCheck = false;
753           configureFlags = [
754             "--enable-xmlreader"
755           ];
756         }
757         {
758           name = "xmlwriter";
759           buildInputs = [ libxml2 ];
760           configureFlags = [
761             "--enable-xmlwriter"
762           ];
763           patches = lib.optionals (lib.versions.majorMinor php.version == "8.1") [
764             # Fix tests with libxml2 2.12
765             (fetchpatch {
766               url = "https://github.com/php/php-src/commit/061058a9b1bbd90d27d97d79aebcf2b5029767b0.patch";
767               hash = "sha256-0hOlAG+pOYp/gUU0MUMZvzWpgr0ncJi5GB8IeNxxyEU=";
768               excludes = [
769                 "NEWS"
770               ];
771             })
772             # Backport of PHP_LIBXML_IGNORE_DEPRECATIONS_START and PHP_LIBXML_IGNORE_DEPRECATIONS_END
773             # Required for libxml2 2.13 compatibility patch.
774             (fetchpatch {
775               url = "https://github.com/php/php-src/commit/e2d97314ab342d434e778cd00a2f34e4bdb07664.patch";
776               hash = "sha256-w0hyYUgbRGpvIBfWeDTSEUGpiJdyrtNjKy+Fn1vyAO0=";
777             })
778             # Fix build with libxml2 2.13+. Has to be applied after libxml2 2.12 patch.
779             (fetchpatch {
780               url = "https://github.com/php/php-src/commit/4fe821311cafb18ca8bdf20b9d796c48a13ba552.patch";
781               hash = "sha256-YC3I0BQi3o3+VmRu/UqpqPpaSC+ekPqzbORTHftbPvY=";
782             })
783           ];
784         }
785         {
786           name = "xsl";
787           buildInputs = [ libxslt libxml2 ];
788           internalDeps = [ php.extensions.dom ];
789           doCheck = false;
790           env.NIX_CFLAGS_COMPILE = toString [ "-I../.." "-DHAVE_DOM" ];
791           configureFlags = [ "--with-xsl=${libxslt.dev}" ];
792         }
793         {
794           name = "zend_test";
795           internalDeps = [ php.extensions.dom ];
796           env.NIX_CFLAGS_COMPILE = "-I${libxml2.dev}/include/libxml2";
797         }
798         {
799           name = "zip";
800           buildInputs = [ libzip pcre2 ];
801           configureFlags = [
802             "--with-zip"
803           ];
804           doCheck = false;
805         }
806         {
807           name = "zlib";
808           buildInputs = [ zlib ];
809           configureFlags = [
810             "--with-zlib"
811           ];
812         }
813       ] ++ lib.optionals (lib.versionOlder php.version "8.3") [
814         # Using version from PECL on new PHP versions.
815         {
816           name = "imap";
817           buildInputs = [ uwimap openssl pam pcre2 libkrb5 ];
818           configureFlags = [ "--with-imap=${uwimap}" "--with-imap-ssl" "--with-kerberos" ];
819         }
820       ];
822       # Convert the list of attrs:
823       # [ { name = <name>; ... } ... ]
824       # to a list of
825       # [ { name = <name>; value = <extension drv>; } ... ]
826       #
827       # which we later use listToAttrs to make all attrs available by name.
828       namedExtensions = builtins.map
829         (drv: {
830           name = drv.name;
831           value = mkExtension drv;
832         })
833         extensionData;
835       # Produce the final attribute set of all extensions defined.
836     in
837     builtins.listToAttrs namedExtensions
838   );