Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
at 21.11 335 lines 12 kB view raw
1# We have tests for PCRE and PHP-FPM in nixos/tests/php/ or 2# both in the same attribute named nixosTests.php 3 4let 5 generic = 6 { callPackage 7 , lib 8 , stdenv 9 , nixosTests 10 , tests 11 , fetchurl 12 , makeWrapper 13 , symlinkJoin 14 , writeText 15 , autoconf 16 , automake 17 , bison 18 , flex 19 , libtool 20 , pkg-config 21 , re2c 22 , apacheHttpd 23 , libargon2 24 , libxml2 25 , pcre2 26 , systemd 27 , system-sendmail 28 , valgrind 29 , xcbuild 30 31 , version 32 , sha256 33 , extraPatches ? [ ] 34 , packageOverrides ? (final: prev: { }) 35 , phpAttrsOverrides ? (attrs: { }) 36 37 # Sapi flags 38 , cgiSupport ? true 39 , cliSupport ? true 40 , fpmSupport ? true 41 , pearSupport ? true 42 , pharSupport ? true 43 , phpdbgSupport ? true 44 45 # Misc flags 46 , apxs2Support ? !stdenv.isDarwin 47 , argon2Support ? true 48 , cgotoSupport ? false 49 , embedSupport ? false 50 , ipv6Support ? true 51 , systemdSupport ? stdenv.isLinux 52 , valgrindSupport ? !stdenv.isDarwin && lib.meta.availableOn stdenv.hostPlatform valgrind 53 , ztsSupport ? apxs2Support 54 }@args: 55 56 let 57 # Compose two functions of the type expected by 'overrideAttrs' 58 # into one where changes made in the first are available to the second. 59 composeOverrides = 60 f: g: attrs: 61 let 62 fApplied = f attrs; 63 attrs' = attrs // fApplied; 64 in 65 fApplied // g attrs'; 66 67 # buildEnv wraps php to provide additional extensions and 68 # configuration. Its usage is documented in 69 # doc/languages-frameworks/php.section.md. 70 # 71 # Create a buildEnv with earlier overridden values and 72 # extensions functions in its closure. This is necessary for 73 # consecutive calls to buildEnv and overrides to work as 74 # expected. 75 mkBuildEnv = prevArgs: prevExtensionFunctions: lib.makeOverridable ( 76 { extensions ? ({ enabled, ... }: enabled), extraConfig ? "", ... }@innerArgs: 77 let 78 allArgs = args // prevArgs // innerArgs; 79 filteredArgs = builtins.removeAttrs allArgs [ "extensions" "extraConfig" ]; 80 php = generic filteredArgs; 81 82 php-packages = (callPackage ../../../top-level/php-packages.nix { 83 phpPackage = phpWithExtensions; 84 }).overrideScope' packageOverrides; 85 86 allExtensionFunctions = prevExtensionFunctions ++ [ extensions ]; 87 enabledExtensions = 88 builtins.foldl' 89 (enabled: f: 90 f { inherit enabled; all = php-packages.extensions; }) 91 [ ] 92 allExtensionFunctions; 93 94 getExtName = ext: lib.removePrefix "php-" (builtins.parseDrvName ext.name).name; 95 96 # Recursively get a list of all internal dependencies 97 # for a list of extensions. 98 getDepsRecursively = extensions: 99 let 100 deps = lib.concatMap 101 (ext: (ext.internalDeps or [ ]) ++ (ext.peclDeps or [ ])) 102 extensions; 103 in 104 if ! (deps == [ ]) then 105 deps ++ (getDepsRecursively deps) 106 else 107 deps; 108 109 # Generate extension load configuration snippets from the 110 # extension parameter. This is an attrset suitable for use 111 # with textClosureList, which is used to put the strings in 112 # the right order - if a plugin which is dependent on 113 # another plugin is placed before its dependency, it will 114 # fail to load. 115 extensionTexts = 116 lib.listToAttrs 117 (map 118 (ext: 119 let 120 extName = getExtName ext; 121 phpDeps = (ext.internalDeps or [ ]) ++ (ext.peclDeps or [ ]); 122 type = "${lib.optionalString (ext.zendExtension or false) "zend_"}extension"; 123 in 124 lib.nameValuePair extName { 125 text = "${type}=${ext}/lib/php/extensions/${extName}.so"; 126 deps = map getExtName phpDeps; 127 }) 128 (enabledExtensions ++ (getDepsRecursively enabledExtensions))); 129 130 extNames = map getExtName enabledExtensions; 131 extraInit = writeText "php-extra-init-${version}.ini" '' 132 ${lib.concatStringsSep "\n" 133 (lib.textClosureList extensionTexts extNames)} 134 ${extraConfig} 135 ''; 136 137 phpWithExtensions = symlinkJoin { 138 name = "php-with-extensions-${version}"; 139 inherit (php) version; 140 nativeBuildInputs = [ makeWrapper ]; 141 passthru = php.passthru // { 142 buildEnv = mkBuildEnv allArgs allExtensionFunctions; 143 withExtensions = mkWithExtensions allArgs allExtensionFunctions; 144 overrideAttrs = 145 f: 146 let 147 newPhpAttrsOverrides = composeOverrides (filteredArgs.phpAttrsOverrides or (attrs: { })) f; 148 php = generic (filteredArgs // { phpAttrsOverrides = newPhpAttrsOverrides; }); 149 in 150 php.buildEnv { inherit extensions extraConfig; }; 151 phpIni = "${phpWithExtensions}/lib/php.ini"; 152 unwrapped = php; 153 # Select the right php tests for the php version 154 tests = { 155 nixos = lib.recurseIntoAttrs nixosTests."php${lib.strings.replaceStrings [ "." ] [ "" ] (lib.versions.majorMinor php.version)}"; 156 package = tests.php; 157 }; 158 inherit (php-packages) extensions buildPecl mkExtension; 159 packages = php-packages.tools; 160 meta = php.meta // { 161 outputsToInstall = [ "out" ]; 162 }; 163 }; 164 paths = [ php ]; 165 postBuild = '' 166 ln -s ${extraInit} $out/lib/php.ini 167 168 if test -e $out/bin/php; then 169 wrapProgram $out/bin/php --set PHP_INI_SCAN_DIR $out/lib 170 fi 171 172 if test -e $out/bin/php-fpm; then 173 wrapProgram $out/bin/php-fpm --set PHP_INI_SCAN_DIR $out/lib 174 fi 175 176 if test -e $out/bin/phpdbg; then 177 wrapProgram $out/bin/phpdbg --set PHP_INI_SCAN_DIR $out/lib 178 fi 179 ''; 180 }; 181 in 182 phpWithExtensions 183 ); 184 185 mkWithExtensions = prevArgs: prevExtensionFunctions: extensions: 186 mkBuildEnv prevArgs prevExtensionFunctions { inherit extensions; }; 187 in 188 stdenv.mkDerivation ( 189 let 190 attrs = { 191 pname = "php"; 192 193 inherit version; 194 195 enableParallelBuilding = true; 196 197 nativeBuildInputs = [ autoconf automake bison flex libtool pkg-config re2c ] 198 ++ lib.optional stdenv.isDarwin xcbuild; 199 200 buildInputs = 201 # PCRE extension 202 [ pcre2 ] 203 204 # Enable sapis 205 ++ lib.optional pearSupport [ libxml2.dev ] 206 207 # Misc deps 208 ++ lib.optional apxs2Support apacheHttpd 209 ++ lib.optional argon2Support libargon2 210 ++ lib.optional systemdSupport systemd 211 ++ lib.optional valgrindSupport valgrind 212 ; 213 214 CXXFLAGS = lib.optionalString stdenv.cc.isClang "-std=c++11"; 215 216 configureFlags = 217 # Disable all extensions 218 [ "--disable-all" ] 219 220 # PCRE 221 ++ lib.optionals (lib.versionAtLeast version "7.4") [ "--with-external-pcre=${pcre2.dev}" ] 222 ++ [ "PCRE_LIBDIR=${pcre2}" ] 223 224 225 # Enable sapis 226 ++ lib.optional (!cgiSupport) "--disable-cgi" 227 ++ lib.optional (!cliSupport) "--disable-cli" 228 ++ lib.optional fpmSupport "--enable-fpm" 229 ++ lib.optional pearSupport [ "--with-pear" "--enable-xml" "--with-libxml" ] 230 ++ lib.optionals (pearSupport && (lib.versionOlder version "7.4")) [ 231 "--enable-libxml" 232 "--with-libxml-dir=${libxml2.dev}" 233 ] 234 ++ lib.optional pharSupport "--enable-phar" 235 ++ lib.optional (!phpdbgSupport) "--disable-phpdbg" 236 237 238 # Misc flags 239 ++ lib.optional apxs2Support "--with-apxs2=${apacheHttpd.dev}/bin/apxs" 240 ++ lib.optional argon2Support "--with-password-argon2=${libargon2}" 241 ++ lib.optional cgotoSupport "--enable-re2c-cgoto" 242 ++ lib.optional embedSupport "--enable-embed" 243 ++ lib.optional (!ipv6Support) "--disable-ipv6" 244 ++ lib.optional systemdSupport "--with-fpm-systemd" 245 ++ lib.optional valgrindSupport "--with-valgrind=${valgrind.dev}" 246 ++ lib.optional (ztsSupport && (lib.versionOlder version "8.0")) "--enable-maintainer-zts" 247 ++ lib.optional (ztsSupport && (lib.versionAtLeast version "8.0")) "--enable-zts" 248 249 250 # Sendmail 251 ++ [ "PROG_SENDMAIL=${system-sendmail}/bin/sendmail" ] 252 ; 253 254 hardeningDisable = [ "bindnow" ]; 255 256 preConfigure = 257 # Don't record the configure flags since this causes unnecessary 258 # runtime dependencies 259 '' 260 for i in main/build-defs.h.in scripts/php-config.in; do 261 substituteInPlace $i \ 262 --replace '@CONFIGURE_COMMAND@' '(omitted)' \ 263 --replace '@CONFIGURE_OPTIONS@' "" \ 264 --replace '@PHP_LDFLAGS@' "" 265 done 266 267 export EXTENSION_DIR=$out/lib/php/extensions 268 '' 269 # PKG_CONFIG need not be a relative path 270 + lib.optionalString (!lib.versionAtLeast version "7.4") '' 271 for i in $(find . -type f -name "*.m4"); do 272 substituteInPlace $i \ 273 --replace 'test -x "$PKG_CONFIG"' 'type -P "$PKG_CONFIG" >/dev/null' 274 done 275 '' + '' 276 ./buildconf --copy --force 277 278 if test -f $src/genfiles; then 279 ./genfiles 280 fi 281 '' + lib.optionalString stdenv.isDarwin '' 282 substituteInPlace configure --replace "-lstdc++" "-lc++" 283 ''; 284 285 postInstall = '' 286 test -d $out/etc || mkdir $out/etc 287 cp php.ini-production $out/etc/php.ini 288 ''; 289 290 postFixup = '' 291 mkdir -p $dev/bin $dev/share/man/man1 292 mv $out/bin/phpize $out/bin/php-config $dev/bin/ 293 mv $out/share/man/man1/phpize.1.gz \ 294 $out/share/man/man1/php-config.1.gz \ 295 $dev/share/man/man1/ 296 ''; 297 298 src = fetchurl { 299 url = "https://www.php.net/distributions/php-${version}.tar.bz2"; 300 inherit sha256; 301 }; 302 303 patches = [ ./fix-paths-php7.patch ] ++ extraPatches; 304 305 separateDebugInfo = true; 306 307 outputs = [ "out" "dev" ]; 308 309 passthru = { 310 buildEnv = mkBuildEnv { } [ ]; 311 withExtensions = mkWithExtensions { } [ ]; 312 overrideAttrs = 313 f: 314 let 315 newPhpAttrsOverrides = composeOverrides phpAttrsOverrides f; 316 php = generic (args // { phpAttrsOverrides = newPhpAttrsOverrides; }); 317 in 318 php; 319 inherit ztsSupport; 320 }; 321 322 meta = with lib; { 323 description = "An HTML-embedded scripting language"; 324 homepage = "https://www.php.net/"; 325 license = licenses.php301; 326 maintainers = teams.php.members; 327 platforms = platforms.all; 328 outputsToInstall = [ "out" "dev" ]; 329 }; 330 }; 331 in 332 attrs // phpAttrsOverrides attrs 333 ); 334in 335generic