at 23.11-beta 680 lines 20 kB view raw
1{ stdenv 2, config 3, callPackages 4, lib 5, pkgs 6, phpPackage 7, autoconf 8, pkg-config 9, aspell 10, bzip2 11, curl 12, cyrus_sasl 13, enchant2 14, freetds 15, gd 16, gettext 17, gmp 18, html-tidy 19, icu64 20, libffi 21, libiconv 22, libkrb5 23, libsodium 24, libxml2 25, libxslt 26, libzip 27, net-snmp 28, nix-update-script 29, oniguruma 30, openldap 31, openssl_1_1 32, openssl 33, overrideSDK 34, pam 35, pcre2 36, postgresql 37, bison 38, re2c 39, readline 40, rsync 41, sqlite 42, unixODBC 43, uwimap 44, valgrind 45, zlib 46, fetchpatch 47}: 48 49lib.makeScope pkgs.newScope (self: with self; { 50 buildPecl = callPackage ../build-support/php/build-pecl.nix { 51 php = php.unwrapped; 52 }; 53 54 composerHooks = callPackages ../build-support/php/hooks { }; 55 56 mkComposerRepository = callPackage ../build-support/php/build-composer-repository.nix { }; 57 buildComposerProject = callPackage ../build-support/php/build-composer-project.nix { }; 58 59 # Wrap mkDerivation to prepend pname with "php-" to make names consistent 60 # with how buildPecl does it and make the file easier to overview. 61 mkDerivation = origArgs: 62 let 63 args = lib.fix (lib.extends 64 (_: previousAttrs: { 65 pname = "php-${previousAttrs.pname}"; 66 passthru = (previousAttrs.passthru or { }) // { 67 updateScript = nix-update-script { }; 68 }; 69 meta = (previousAttrs.meta or { }) // { 70 mainProgram = previousAttrs.meta.mainProgram or previousAttrs.pname; 71 }; 72 }) 73 (if lib.isFunction origArgs then origArgs else (_: origArgs)) 74 ); 75 in 76 pkgs.stdenv.mkDerivation args; 77 78 # Function to build an extension which is shipped as part of the php 79 # source, based on the php version. 80 # 81 # Name passed is the name of the extension and is automatically used 82 # to add the configureFlag "--enable-${name}", which can be overridden. 83 # 84 # Build inputs is used for extra deps that may be needed. And zendExtension 85 # will mark the extension as a zend extension or not. 86 mkExtension = lib.makeOverridable 87 ({ name 88 , configureFlags ? [ "--enable-${extName}" ] 89 , internalDeps ? [ ] 90 , postPhpize ? "" 91 , buildInputs ? [ ] 92 , zendExtension ? false 93 , doCheck ? true 94 , extName ? name 95 , ... 96 }@args: stdenv.mkDerivation ((builtins.removeAttrs args [ "name" ]) // { 97 pname = "php-${name}"; 98 extensionName = extName; 99 100 outputs = [ "out" "dev" ]; 101 102 inherit (php.unwrapped) version src; 103 104 enableParallelBuilding = true; 105 106 nativeBuildInputs = [ 107 php.unwrapped 108 autoconf 109 pkg-config 110 re2c 111 bison 112 ]; 113 114 inherit configureFlags internalDeps buildInputs zendExtension doCheck; 115 116 preConfigurePhases = [ 117 "genfiles" 118 "cdToExtensionRootPhase" 119 ]; 120 121 genfiles = '' 122 if [ -f "scripts/dev/genfiles" ]; then 123 ./scripts/dev/genfiles 124 fi 125 ''; 126 127 cdToExtensionRootPhase = '' 128 # Go to extension source root. 129 cd "ext/${extName}" 130 ''; 131 132 preConfigure = '' 133 nullglobRestore=$(shopt -p nullglob) 134 shopt -u nullglob # To make ?-globbing work 135 136 # Some extensions have a config0.m4 or config9.m4 137 if [ -f config?.m4 ]; then 138 mv config?.m4 config.m4 139 fi 140 141 $nullglobRestore 142 143 phpize 144 ${postPhpize} 145 146 ${lib.concatMapStringsSep 147 "\n" 148 (dep: "mkdir -p ext; ln -s ${dep.dev}/include ext/${dep.extensionName}") 149 internalDeps 150 } 151 ''; 152 153 checkPhase = '' 154 runHook preCheck 155 156 NO_INTERACTION=yes SKIP_PERF_SENSITIVE=yes make test 157 runHook postCheck 158 ''; 159 160 installPhase = '' 161 runHook preInstall 162 163 mkdir -p $out/lib/php/extensions 164 cp modules/${extName}.so $out/lib/php/extensions/${extName}.so 165 mkdir -p $dev/include 166 ${rsync}/bin/rsync -r --filter="+ */" \ 167 --filter="+ *.h" \ 168 --filter="- *" \ 169 --prune-empty-dirs \ 170 . $dev/include/ 171 172 runHook postInstall 173 ''; 174 175 meta = { 176 description = "PHP upstream extension: ${name}"; 177 inherit (php.meta) maintainers homepage license; 178 }; 179 })); 180 181 php = phpPackage; 182 183 # This is a set of interactive tools based on PHP. 184 tools = { 185 box = callPackage ../development/php-packages/box { }; 186 187 castor = callPackage ../development/php-packages/castor { }; 188 189 composer = callPackage ../development/php-packages/composer { }; 190 191 deployer = callPackage ../development/php-packages/deployer { }; 192 193 grumphp = callPackage ../development/php-packages/grumphp { }; 194 195 phan = callPackage ../development/php-packages/phan { }; 196 197 phing = callPackage ../development/php-packages/phing { }; 198 199 phive = callPackage ../development/php-packages/phive { }; 200 201 php-cs-fixer = callPackage ../development/php-packages/php-cs-fixer { }; 202 203 php-parallel-lint = callPackage ../development/php-packages/php-parallel-lint { }; 204 205 phpcbf = callPackage ../development/php-packages/phpcbf { }; 206 207 phpcs = callPackage ../development/php-packages/phpcs { }; 208 209 phpmd = callPackage ../development/php-packages/phpmd { }; 210 211 phpstan = callPackage ../development/php-packages/phpstan { }; 212 213 psalm = callPackage ../development/php-packages/psalm { }; 214 215 psysh = callPackage ../development/php-packages/psysh { }; 216 }; 217 218 219 220 # This is a set of PHP extensions meant to be used in php.buildEnv 221 # or php.withExtensions to extend the functionality of the PHP 222 # interpreter. 223 # The extensions attributes is composed of three sections: 224 # 1. The contrib conditional extensions, which are only available on specific PHP versions 225 # 2. The contrib extensions available 226 # 3. The core extensions 227 extensions = 228 # Contrib conditional extensions 229 lib.optionalAttrs (!(lib.versionAtLeast php.version "8.3")) { 230 blackfire = callPackage ../development/tools/misc/blackfire/php-probe.nix { inherit php; }; 231 } // 232 # Contrib extensions 233 { 234 amqp = callPackage ../development/php-packages/amqp { }; 235 236 apcu = callPackage ../development/php-packages/apcu { }; 237 238 ast = callPackage ../development/php-packages/ast { }; 239 240 couchbase = callPackage ../development/php-packages/couchbase { }; 241 242 datadog_trace = callPackage ../development/php-packages/datadog_trace { 243 buildPecl = buildPecl.override { 244 stdenv = if stdenv.isDarwin then overrideSDK stdenv "11.0" else stdenv; 245 }; 246 inherit (pkgs) darwin; 247 }; 248 249 ds = callPackage ../development/php-packages/ds { }; 250 251 event = callPackage ../development/php-packages/event { }; 252 253 gnupg = callPackage ../development/php-packages/gnupg { }; 254 255 grpc = callPackage ../development/php-packages/grpc { }; 256 257 igbinary = callPackage ../development/php-packages/igbinary { }; 258 259 imagick = callPackage ../development/php-packages/imagick { }; 260 261 inotify = callPackage ../development/php-packages/inotify { }; 262 263 mailparse = callPackage ../development/php-packages/mailparse { }; 264 265 maxminddb = callPackage ../development/php-packages/maxminddb { }; 266 267 memcache = callPackage ../development/php-packages/memcache { }; 268 269 memcached = callPackage ../development/php-packages/memcached { }; 270 271 meminfo = callPackage ../development/php-packages/meminfo { }; 272 273 memprof = callPackage ../development/php-packages/memprof { }; 274 275 mongodb = callPackage ../development/php-packages/mongodb { 276 inherit (pkgs) darwin; 277 }; 278 279 msgpack = callPackage ../development/php-packages/msgpack { }; 280 281 oci8 = callPackage ../development/php-packages/oci8 { }; 282 283 opentelemetry = callPackage ../development/php-packages/opentelemetry { }; 284 285 openswoole = callPackage ../development/php-packages/openswoole { }; 286 287 pdlib = callPackage ../development/php-packages/pdlib { }; 288 289 pcov = callPackage ../development/php-packages/pcov { }; 290 291 pdo_oci = buildPecl rec { 292 inherit (php.unwrapped) src version; 293 294 pname = "pdo_oci"; 295 sourceRoot = "php-${version}/ext/pdo_oci"; 296 297 buildInputs = [ pkgs.oracle-instantclient ]; 298 configureFlags = [ "--with-pdo-oci=instantclient,${pkgs.oracle-instantclient.lib}/lib" ]; 299 300 internalDeps = [ php.extensions.pdo ]; 301 302 postPatch = '' 303 sed -i -e 's|OCISDKMANINC=`.*$|OCISDKMANINC="${pkgs.oracle-instantclient.dev}/include"|' config.m4 304 ''; 305 306 meta.maintainers = lib.teams.php.members; 307 }; 308 309 pdo_sqlsrv = callPackage ../development/php-packages/pdo_sqlsrv { }; 310 311 phalcon = callPackage ../development/php-packages/phalcon { }; 312 313 php-spx = callPackage ../development/php-packages/php-spx { }; 314 315 pinba = callPackage ../development/php-packages/pinba { }; 316 317 protobuf = callPackage ../development/php-packages/protobuf { }; 318 319 rdkafka = callPackage ../development/php-packages/rdkafka { }; 320 321 redis = callPackage ../development/php-packages/redis { }; 322 323 relay = callPackage ../development/php-packages/relay { inherit php; }; 324 325 rrd = callPackage ../development/php-packages/rrd { }; 326 327 smbclient = callPackage ../development/php-packages/smbclient { }; 328 329 snuffleupagus = callPackage ../development/php-packages/snuffleupagus { 330 inherit (pkgs) darwin; 331 }; 332 333 sqlsrv = callPackage ../development/php-packages/sqlsrv { }; 334 335 ssh2 = callPackage ../development/php-packages/ssh2 { }; 336 337 swoole = callPackage ../development/php-packages/swoole { }; 338 339 uv = callPackage ../development/php-packages/uv { }; 340 341 vld = callPackage ../development/php-packages/vld { }; 342 343 xdebug = callPackage ../development/php-packages/xdebug { }; 344 345 yaml = callPackage ../development/php-packages/yaml { }; 346 } // ( 347 # Core extensions 348 let 349 # This list contains build instructions for different modules that one may 350 # want to build. 351 # 352 # These will be passed as arguments to mkExtension above. 353 extensionData = [ 354 { name = "bcmath"; } 355 { name = "bz2"; buildInputs = [ bzip2 ]; configureFlags = [ "--with-bz2=${bzip2.dev}" ]; } 356 { name = "calendar"; } 357 { name = "ctype"; } 358 { 359 name = "curl"; 360 buildInputs = [ curl ]; 361 configureFlags = [ "--with-curl=${curl.dev}" ]; 362 doCheck = false; 363 } 364 { name = "dba"; } 365 { 366 name = "dom"; 367 buildInputs = [ libxml2 ]; 368 configureFlags = [ 369 "--enable-dom" 370 ]; 371 } 372 { 373 name = "enchant"; 374 buildInputs = [ enchant2 ]; 375 configureFlags = [ "--with-enchant" ]; 376 doCheck = false; 377 } 378 { name = "exif"; doCheck = false; } 379 { name = "ffi"; buildInputs = [ libffi ]; } 380 { 381 name = "fileinfo"; 382 buildInputs = [ pcre2 ]; 383 } 384 { name = "filter"; buildInputs = [ pcre2 ]; } 385 { name = "ftp"; buildInputs = [ openssl ]; } 386 { 387 name = "gd"; 388 buildInputs = [ zlib gd ]; 389 configureFlags = [ 390 "--enable-gd" 391 "--with-external-gd=${gd.dev}" 392 "--enable-gd-jis-conv" 393 ]; 394 doCheck = false; 395 } 396 { 397 name = "gettext"; 398 buildInputs = [ gettext ]; 399 postPhpize = ''substituteInPlace configure --replace 'as_fn_error $? "Cannot locate header file libintl.h" "$LINENO" 5' ':' ''; 400 configureFlags = [ "--with-gettext=${gettext}" ]; 401 } 402 { 403 name = "gmp"; 404 buildInputs = [ gmp ]; 405 configureFlags = [ "--with-gmp=${gmp.dev}" ]; 406 } 407 { 408 name = "iconv"; 409 configureFlags = [ 410 "--with-iconv${lib.optionalString stdenv.isDarwin "=${libiconv}"}" 411 ]; 412 doCheck = false; 413 } 414 { 415 name = "imap"; 416 buildInputs = [ uwimap openssl pam pcre2 libkrb5 ]; 417 configureFlags = [ "--with-imap=${uwimap}" "--with-imap-ssl" "--with-kerberos" ]; 418 } 419 { 420 name = "intl"; 421 buildInputs = [ icu64 ]; 422 } 423 { 424 name = "ldap"; 425 buildInputs = [ openldap cyrus_sasl ]; 426 configureFlags = [ 427 "--with-ldap" 428 "LDAP_DIR=${openldap.dev}" 429 "LDAP_INCDIR=${openldap.dev}/include" 430 "LDAP_LIBDIR=${openldap.out}/lib" 431 ] ++ lib.optionals stdenv.isLinux [ 432 "--with-ldap-sasl=${cyrus_sasl.dev}" 433 ]; 434 doCheck = false; 435 } 436 { 437 name = "mbstring"; 438 buildInputs = [ oniguruma pcre2 ]; 439 doCheck = false; 440 } 441 { 442 name = "mysqli"; 443 internalDeps = [ php.extensions.mysqlnd ]; 444 configureFlags = [ "--with-mysqli=mysqlnd" "--with-mysql-sock=/run/mysqld/mysqld.sock" ]; 445 doCheck = false; 446 } 447 { 448 name = "mysqlnd"; 449 buildInputs = [ zlib openssl ]; 450 # The configure script doesn't correctly add library link 451 # flags, so we add them to the variable used by the Makefile 452 # when linking. 453 MYSQLND_SHARED_LIBADD = "-lssl -lcrypto"; 454 # The configure script builds a config.h which is never 455 # included. Let's include it in the main header file 456 # included by all .c-files. 457 patches = [ 458 (pkgs.writeText "mysqlnd_config.patch" '' 459 --- a/ext/mysqlnd/mysqlnd.h 460 +++ b/ext/mysqlnd/mysqlnd.h 461 @@ -1,3 +1,6 @@ 462 +#ifdef HAVE_CONFIG_H 463 +#include "config.h" 464 +#endif 465 /* 466 +----------------------------------------------------------------------+ 467 | Copyright (c) The PHP Group | 468 '') 469 ]; 470 } 471 { 472 name = "opcache"; 473 buildInputs = [ pcre2 ] ++ 474 lib.optional 475 (!stdenv.isDarwin && lib.meta.availableOn stdenv.hostPlatform valgrind) 476 valgrind.dev; 477 zendExtension = true; 478 postPatch = lib.optionalString stdenv.isDarwin '' 479 # Tests are flaky on darwin 480 rm ext/opcache/tests/blacklist.phpt 481 rm ext/opcache/tests/bug66338.phpt 482 rm ext/opcache/tests/bug78106.phpt 483 rm ext/opcache/tests/issue0115.phpt 484 rm ext/opcache/tests/issue0149.phpt 485 rm ext/opcache/tests/revalidate_path_01.phpt 486 ''; 487 # Tests launch the builtin webserver. 488 __darwinAllowLocalNetworking = true; 489 } 490 { 491 name = "openssl"; 492 buildInputs = [ openssl ]; 493 configureFlags = [ "--with-openssl" ]; 494 doCheck = false; 495 } 496 # This provides a legacy OpenSSL PHP extension 497 # For situations where OpenSSL 3 do not support a set of features 498 # without a specific openssl.cnf file 499 { 500 name = "openssl-legacy"; 501 extName = "openssl"; 502 buildInputs = [ openssl_1_1 ]; 503 configureFlags = [ "--with-openssl" ]; 504 doCheck = false; 505 } 506 { name = "pcntl"; } 507 { name = "pdo"; doCheck = false; } 508 { 509 name = "pdo_dblib"; 510 internalDeps = [ php.extensions.pdo ]; 511 configureFlags = [ "--with-pdo-dblib=${freetds}" ]; 512 # Doesn't seem to work on darwin. 513 enable = (!stdenv.isDarwin); 514 doCheck = false; 515 } 516 { 517 name = "pdo_mysql"; 518 internalDeps = with php.extensions; [ pdo mysqlnd ]; 519 configureFlags = [ "--with-pdo-mysql=mysqlnd" "PHP_MYSQL_SOCK=/run/mysqld/mysqld.sock" ]; 520 doCheck = false; 521 } 522 { 523 name = "pdo_odbc"; 524 internalDeps = [ php.extensions.pdo ]; 525 configureFlags = [ "--with-pdo-odbc=unixODBC,${unixODBC}" ]; 526 doCheck = false; 527 } 528 { 529 name = "pdo_pgsql"; 530 internalDeps = [ php.extensions.pdo ]; 531 configureFlags = [ "--with-pdo-pgsql=${postgresql}" ]; 532 doCheck = false; 533 } 534 { 535 name = "pdo_sqlite"; 536 internalDeps = [ php.extensions.pdo ]; 537 buildInputs = [ sqlite ]; 538 configureFlags = [ "--with-pdo-sqlite=${sqlite.dev}" ]; 539 doCheck = false; 540 } 541 { 542 name = "pgsql"; 543 buildInputs = [ pcre2 ]; 544 configureFlags = [ "--with-pgsql=${postgresql}" ]; 545 doCheck = false; 546 } 547 { name = "posix"; doCheck = false; } 548 { name = "pspell"; configureFlags = [ "--with-pspell=${aspell}" ]; } 549 { 550 name = "readline"; 551 buildInputs = [ 552 readline 553 ]; 554 configureFlags = [ 555 "--with-readline=${readline.dev}" 556 ]; 557 postPatch = '' 558 # Fix `--with-readline` option not being available. 559 # `PHP_ALWAYS_SHARED` generated by phpize enables all options 560 # without the possibility to override them. But when `--with-libedit` 561 # is enabled, `--with-readline` is not registered. 562 echo ' 563 AC_DEFUN([PHP_ALWAYS_SHARED],[ 564 test "[$]$1" != "no" && ext_shared=yes 565 ])dnl 566 ' | cat - ext/readline/config.m4 > ext/readline/config.m4.tmp 567 mv ext/readline/config.m4{.tmp,} 568 ''; 569 doCheck = false; 570 } 571 { name = "session"; 572 doCheck = false; 573 } 574 { name = "shmop"; } 575 { 576 name = "simplexml"; 577 buildInputs = [ libxml2 pcre2 ]; 578 configureFlags = [ 579 "--enable-simplexml" 580 ]; 581 } 582 { 583 name = "snmp"; 584 buildInputs = [ net-snmp openssl ]; 585 configureFlags = [ "--with-snmp" ]; 586 # net-snmp doesn't build on darwin. 587 enable = (!stdenv.isDarwin); 588 doCheck = false; 589 } 590 { 591 name = "soap"; 592 buildInputs = [ libxml2 ]; 593 configureFlags = [ 594 "--enable-soap" 595 ]; 596 doCheck = false; 597 } 598 { 599 name = "sockets"; 600 doCheck = false; 601 } 602 { name = "sodium"; buildInputs = [ libsodium ]; } 603 { name = "sqlite3"; buildInputs = [ sqlite ]; } 604 { name = "sysvmsg"; } 605 { name = "sysvsem"; } 606 { name = "sysvshm"; } 607 { name = "tidy"; configureFlags = [ "--with-tidy=${html-tidy}" ]; doCheck = false; } 608 { 609 name = "tokenizer"; 610 patches = [ ../development/interpreters/php/fix-tokenizer-php81.patch ]; 611 } 612 { 613 name = "xml"; 614 buildInputs = [ libxml2 ]; 615 configureFlags = [ 616 "--enable-xml" 617 ]; 618 doCheck = false; 619 } 620 { 621 name = "xmlreader"; 622 buildInputs = [ libxml2 ]; 623 internalDeps = [ php.extensions.dom ]; 624 env.NIX_CFLAGS_COMPILE = toString [ "-I../.." "-DHAVE_DOM" ]; 625 doCheck = false; 626 configureFlags = [ 627 "--enable-xmlreader" 628 ]; 629 } 630 { 631 name = "xmlwriter"; 632 buildInputs = [ libxml2 ]; 633 configureFlags = [ 634 "--enable-xmlwriter" 635 ]; 636 } 637 { 638 name = "xsl"; 639 buildInputs = [ libxslt libxml2 ]; 640 doCheck = false; 641 configureFlags = [ "--with-xsl=${libxslt.dev}" ]; 642 } 643 { name = "zend_test"; } 644 { 645 name = "zip"; 646 buildInputs = [ libzip pcre2 ]; 647 configureFlags = [ 648 "--with-zip" 649 ]; 650 doCheck = false; 651 } 652 { 653 name = "zlib"; 654 buildInputs = [ zlib ]; 655 configureFlags = [ 656 "--with-zlib" 657 ]; 658 } 659 ]; 660 661 # Convert the list of attrs: 662 # [ { name = <name>; ... } ... ] 663 # to a list of 664 # [ { name = <name>; value = <extension drv>; } ... ] 665 # 666 # which we later use listToAttrs to make all attrs available by name. 667 # 668 # Also filter out extensions based on the enable property. 669 namedExtensions = builtins.map 670 (drv: { 671 name = drv.name; 672 value = mkExtension drv; 673 }) 674 (builtins.filter (i: i.enable or true) extensionData); 675 676 # Produce the final attribute set of all extensions defined. 677 in 678 builtins.listToAttrs namedExtensions 679 ); 680})