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