php: Implement overrideAttrs that composes with buildEnv/withExtensions
Hopefully. Also add a couple of tests to check that.
This commit is contained in:
parent
fe630fcb1f
commit
968d180452
|
@ -7,6 +7,7 @@ let
|
||||||
, lib
|
, lib
|
||||||
, stdenv
|
, stdenv
|
||||||
, nixosTests
|
, nixosTests
|
||||||
|
, tests
|
||||||
, fetchurl
|
, fetchurl
|
||||||
, makeWrapper
|
, makeWrapper
|
||||||
, symlinkJoin
|
, symlinkJoin
|
||||||
|
@ -31,6 +32,7 @@ let
|
||||||
, sha256
|
, sha256
|
||||||
, extraPatches ? [ ]
|
, extraPatches ? [ ]
|
||||||
, packageOverrides ? (final: prev: { })
|
, packageOverrides ? (final: prev: { })
|
||||||
|
, phpAttrsOverrides ? (attrs: { })
|
||||||
|
|
||||||
# Sapi flags
|
# Sapi flags
|
||||||
, cgiSupport ? true
|
, cgiSupport ? true
|
||||||
|
@ -52,6 +54,16 @@ let
|
||||||
}@args:
|
}@args:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
# Compose two functions of the type expected by 'overrideAttrs'
|
||||||
|
# into one where changes made in the first are available to the second.
|
||||||
|
composeOverrides =
|
||||||
|
f: g: attrs:
|
||||||
|
let
|
||||||
|
fApplied = f attrs;
|
||||||
|
attrs' = attrs // fApplied;
|
||||||
|
in
|
||||||
|
fApplied // g attrs';
|
||||||
|
|
||||||
# buildEnv wraps php to provide additional extensions and
|
# buildEnv wraps php to provide additional extensions and
|
||||||
# configuration. Its usage is documented in
|
# configuration. Its usage is documented in
|
||||||
# doc/languages-frameworks/php.section.md.
|
# doc/languages-frameworks/php.section.md.
|
||||||
|
@ -129,10 +141,20 @@ let
|
||||||
passthru = php.passthru // {
|
passthru = php.passthru // {
|
||||||
buildEnv = mkBuildEnv allArgs allExtensionFunctions;
|
buildEnv = mkBuildEnv allArgs allExtensionFunctions;
|
||||||
withExtensions = mkWithExtensions allArgs allExtensionFunctions;
|
withExtensions = mkWithExtensions allArgs allExtensionFunctions;
|
||||||
|
overrideAttrs =
|
||||||
|
f:
|
||||||
|
let
|
||||||
|
newPhpAttrsOverrides = composeOverrides (filteredArgs.phpAttrsOverrides or (attrs: { })) f;
|
||||||
|
php = generic (filteredArgs // { phpAttrsOverrides = newPhpAttrsOverrides; });
|
||||||
|
in
|
||||||
|
php.buildEnv { inherit extensions extraConfig; };
|
||||||
phpIni = "${phpWithExtensions}/lib/php.ini";
|
phpIni = "${phpWithExtensions}/lib/php.ini";
|
||||||
unwrapped = php;
|
unwrapped = php;
|
||||||
# Select the right php tests for the php version
|
# Select the right php tests for the php version
|
||||||
tests = nixosTests."php${lib.strings.replaceStrings [ "." ] [ "" ] (lib.versions.majorMinor php.version)}";
|
tests = {
|
||||||
|
nixos = lib.recurseIntoAttrs nixosTests."php${lib.strings.replaceStrings [ "." ] [ "" ] (lib.versions.majorMinor php.version)}";
|
||||||
|
package = tests.php;
|
||||||
|
};
|
||||||
inherit (php-packages) extensions buildPecl mkExtension;
|
inherit (php-packages) extensions buildPecl mkExtension;
|
||||||
packages = php-packages.tools;
|
packages = php-packages.tools;
|
||||||
meta = php.meta // {
|
meta = php.meta // {
|
||||||
|
@ -163,139 +185,151 @@ let
|
||||||
mkWithExtensions = prevArgs: prevExtensionFunctions: extensions:
|
mkWithExtensions = prevArgs: prevExtensionFunctions: extensions:
|
||||||
mkBuildEnv prevArgs prevExtensionFunctions { inherit extensions; };
|
mkBuildEnv prevArgs prevExtensionFunctions { inherit extensions; };
|
||||||
in
|
in
|
||||||
stdenv.mkDerivation {
|
stdenv.mkDerivation (
|
||||||
pname = "php";
|
let
|
||||||
|
attrs = {
|
||||||
|
pname = "php";
|
||||||
|
|
||||||
inherit version;
|
inherit version;
|
||||||
|
|
||||||
enableParallelBuilding = true;
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
nativeBuildInputs = [ autoconf automake bison flex libtool pkg-config re2c ]
|
nativeBuildInputs = [ autoconf automake bison flex libtool pkg-config re2c ]
|
||||||
++ lib.optional stdenv.isDarwin xcbuild;
|
++ lib.optional stdenv.isDarwin xcbuild;
|
||||||
|
|
||||||
buildInputs =
|
buildInputs =
|
||||||
# PCRE extension
|
# PCRE extension
|
||||||
[ pcre2 ]
|
[ pcre2 ]
|
||||||
|
|
||||||
# Enable sapis
|
# Enable sapis
|
||||||
++ lib.optional pearSupport [ libxml2.dev ]
|
++ lib.optional pearSupport [ libxml2.dev ]
|
||||||
|
|
||||||
# Misc deps
|
# Misc deps
|
||||||
++ lib.optional apxs2Support apacheHttpd
|
++ lib.optional apxs2Support apacheHttpd
|
||||||
++ lib.optional argon2Support libargon2
|
++ lib.optional argon2Support libargon2
|
||||||
++ lib.optional systemdSupport systemd
|
++ lib.optional systemdSupport systemd
|
||||||
++ lib.optional valgrindSupport valgrind
|
++ lib.optional valgrindSupport valgrind
|
||||||
;
|
;
|
||||||
|
|
||||||
CXXFLAGS = lib.optionalString stdenv.cc.isClang "-std=c++11";
|
CXXFLAGS = lib.optionalString stdenv.cc.isClang "-std=c++11";
|
||||||
|
|
||||||
configureFlags =
|
configureFlags =
|
||||||
# Disable all extensions
|
# Disable all extensions
|
||||||
[ "--disable-all" ]
|
[ "--disable-all" ]
|
||||||
|
|
||||||
# PCRE
|
# PCRE
|
||||||
++ lib.optionals (lib.versionAtLeast version "7.4") [ "--with-external-pcre=${pcre2.dev}" ]
|
++ lib.optionals (lib.versionAtLeast version "7.4") [ "--with-external-pcre=${pcre2.dev}" ]
|
||||||
++ [ "PCRE_LIBDIR=${pcre2}" ]
|
++ [ "PCRE_LIBDIR=${pcre2}" ]
|
||||||
|
|
||||||
|
|
||||||
# Enable sapis
|
# Enable sapis
|
||||||
++ lib.optional (!cgiSupport) "--disable-cgi"
|
++ lib.optional (!cgiSupport) "--disable-cgi"
|
||||||
++ lib.optional (!cliSupport) "--disable-cli"
|
++ lib.optional (!cliSupport) "--disable-cli"
|
||||||
++ lib.optional fpmSupport "--enable-fpm"
|
++ lib.optional fpmSupport "--enable-fpm"
|
||||||
++ lib.optional pearSupport [ "--with-pear" "--enable-xml" "--with-libxml" ]
|
++ lib.optional pearSupport [ "--with-pear" "--enable-xml" "--with-libxml" ]
|
||||||
++ lib.optionals (pearSupport && (lib.versionOlder version "7.4")) [
|
++ lib.optionals (pearSupport && (lib.versionOlder version "7.4")) [
|
||||||
"--enable-libxml"
|
"--enable-libxml"
|
||||||
"--with-libxml-dir=${libxml2.dev}"
|
"--with-libxml-dir=${libxml2.dev}"
|
||||||
]
|
]
|
||||||
++ lib.optional pharSupport "--enable-phar"
|
++ lib.optional pharSupport "--enable-phar"
|
||||||
++ lib.optional (!phpdbgSupport) "--disable-phpdbg"
|
++ lib.optional (!phpdbgSupport) "--disable-phpdbg"
|
||||||
|
|
||||||
|
|
||||||
# Misc flags
|
# Misc flags
|
||||||
++ lib.optional apxs2Support "--with-apxs2=${apacheHttpd.dev}/bin/apxs"
|
++ lib.optional apxs2Support "--with-apxs2=${apacheHttpd.dev}/bin/apxs"
|
||||||
++ lib.optional argon2Support "--with-password-argon2=${libargon2}"
|
++ lib.optional argon2Support "--with-password-argon2=${libargon2}"
|
||||||
++ lib.optional cgotoSupport "--enable-re2c-cgoto"
|
++ lib.optional cgotoSupport "--enable-re2c-cgoto"
|
||||||
++ lib.optional embedSupport "--enable-embed"
|
++ lib.optional embedSupport "--enable-embed"
|
||||||
++ lib.optional (!ipv6Support) "--disable-ipv6"
|
++ lib.optional (!ipv6Support) "--disable-ipv6"
|
||||||
++ lib.optional systemdSupport "--with-fpm-systemd"
|
++ lib.optional systemdSupport "--with-fpm-systemd"
|
||||||
++ lib.optional valgrindSupport "--with-valgrind=${valgrind.dev}"
|
++ lib.optional valgrindSupport "--with-valgrind=${valgrind.dev}"
|
||||||
++ lib.optional (ztsSupport && (lib.versionOlder version "8.0")) "--enable-maintainer-zts"
|
++ lib.optional (ztsSupport && (lib.versionOlder version "8.0")) "--enable-maintainer-zts"
|
||||||
++ lib.optional (ztsSupport && (lib.versionAtLeast version "8.0")) "--enable-zts"
|
++ lib.optional (ztsSupport && (lib.versionAtLeast version "8.0")) "--enable-zts"
|
||||||
|
|
||||||
|
|
||||||
# Sendmail
|
# Sendmail
|
||||||
++ [ "PROG_SENDMAIL=${system-sendmail}/bin/sendmail" ]
|
++ [ "PROG_SENDMAIL=${system-sendmail}/bin/sendmail" ]
|
||||||
;
|
;
|
||||||
|
|
||||||
hardeningDisable = [ "bindnow" ];
|
hardeningDisable = [ "bindnow" ];
|
||||||
|
|
||||||
preConfigure =
|
preConfigure =
|
||||||
# Don't record the configure flags since this causes unnecessary
|
# Don't record the configure flags since this causes unnecessary
|
||||||
# runtime dependencies
|
# runtime dependencies
|
||||||
''
|
''
|
||||||
for i in main/build-defs.h.in scripts/php-config.in; do
|
for i in main/build-defs.h.in scripts/php-config.in; do
|
||||||
substituteInPlace $i \
|
substituteInPlace $i \
|
||||||
--replace '@CONFIGURE_COMMAND@' '(omitted)' \
|
--replace '@CONFIGURE_COMMAND@' '(omitted)' \
|
||||||
--replace '@CONFIGURE_OPTIONS@' "" \
|
--replace '@CONFIGURE_OPTIONS@' "" \
|
||||||
--replace '@PHP_LDFLAGS@' ""
|
--replace '@PHP_LDFLAGS@' ""
|
||||||
done
|
done
|
||||||
|
|
||||||
export EXTENSION_DIR=$out/lib/php/extensions
|
export EXTENSION_DIR=$out/lib/php/extensions
|
||||||
''
|
''
|
||||||
# PKG_CONFIG need not be a relative path
|
# PKG_CONFIG need not be a relative path
|
||||||
+ lib.optionalString (!lib.versionAtLeast version "7.4") ''
|
+ lib.optionalString (!lib.versionAtLeast version "7.4") ''
|
||||||
for i in $(find . -type f -name "*.m4"); do
|
for i in $(find . -type f -name "*.m4"); do
|
||||||
substituteInPlace $i \
|
substituteInPlace $i \
|
||||||
--replace 'test -x "$PKG_CONFIG"' 'type -P "$PKG_CONFIG" >/dev/null'
|
--replace 'test -x "$PKG_CONFIG"' 'type -P "$PKG_CONFIG" >/dev/null'
|
||||||
done
|
done
|
||||||
'' + ''
|
'' + ''
|
||||||
./buildconf --copy --force
|
./buildconf --copy --force
|
||||||
|
|
||||||
if test -f $src/genfiles; then
|
if test -f $src/genfiles; then
|
||||||
./genfiles
|
./genfiles
|
||||||
fi
|
fi
|
||||||
'' + lib.optionalString stdenv.isDarwin ''
|
'' + lib.optionalString stdenv.isDarwin ''
|
||||||
substituteInPlace configure --replace "-lstdc++" "-lc++"
|
substituteInPlace configure --replace "-lstdc++" "-lc++"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
postInstall = ''
|
postInstall = ''
|
||||||
test -d $out/etc || mkdir $out/etc
|
test -d $out/etc || mkdir $out/etc
|
||||||
cp php.ini-production $out/etc/php.ini
|
cp php.ini-production $out/etc/php.ini
|
||||||
'';
|
'';
|
||||||
|
|
||||||
postFixup = ''
|
postFixup = ''
|
||||||
mkdir -p $dev/bin $dev/share/man/man1
|
mkdir -p $dev/bin $dev/share/man/man1
|
||||||
mv $out/bin/phpize $out/bin/php-config $dev/bin/
|
mv $out/bin/phpize $out/bin/php-config $dev/bin/
|
||||||
mv $out/share/man/man1/phpize.1.gz \
|
mv $out/share/man/man1/phpize.1.gz \
|
||||||
$out/share/man/man1/php-config.1.gz \
|
$out/share/man/man1/php-config.1.gz \
|
||||||
$dev/share/man/man1/
|
$dev/share/man/man1/
|
||||||
'';
|
'';
|
||||||
|
|
||||||
src = fetchurl {
|
src = fetchurl {
|
||||||
url = "https://www.php.net/distributions/php-${version}.tar.bz2";
|
url = "https://www.php.net/distributions/php-${version}.tar.bz2";
|
||||||
inherit sha256;
|
inherit sha256;
|
||||||
};
|
};
|
||||||
|
|
||||||
patches = [ ./fix-paths-php7.patch ] ++ extraPatches;
|
patches = [ ./fix-paths-php7.patch ] ++ extraPatches;
|
||||||
|
|
||||||
separateDebugInfo = true;
|
separateDebugInfo = true;
|
||||||
|
|
||||||
outputs = [ "out" "dev" ];
|
outputs = [ "out" "dev" ];
|
||||||
|
|
||||||
passthru = {
|
passthru = {
|
||||||
buildEnv = mkBuildEnv { } [ ];
|
buildEnv = mkBuildEnv { } [ ];
|
||||||
withExtensions = mkWithExtensions { } [ ];
|
withExtensions = mkWithExtensions { } [ ];
|
||||||
inherit ztsSupport;
|
overrideAttrs =
|
||||||
};
|
f:
|
||||||
|
let
|
||||||
|
newPhpAttrsOverrides = composeOverrides phpAttrsOverrides f;
|
||||||
|
php = generic (args // { phpAttrsOverrides = newPhpAttrsOverrides; });
|
||||||
|
in
|
||||||
|
php;
|
||||||
|
inherit ztsSupport;
|
||||||
|
};
|
||||||
|
|
||||||
meta = with lib; {
|
meta = with lib; {
|
||||||
description = "An HTML-embedded scripting language";
|
description = "An HTML-embedded scripting language";
|
||||||
homepage = "https://www.php.net/";
|
homepage = "https://www.php.net/";
|
||||||
license = licenses.php301;
|
license = licenses.php301;
|
||||||
maintainers = teams.php.members;
|
maintainers = teams.php.members;
|
||||||
platforms = platforms.all;
|
platforms = platforms.all;
|
||||||
outputsToInstall = [ "out" "dev" ];
|
outputsToInstall = [ "out" "dev" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
in
|
||||||
|
attrs // phpAttrsOverrides attrs
|
||||||
|
);
|
||||||
in
|
in
|
||||||
generic
|
generic
|
||||||
|
|
|
@ -37,6 +37,8 @@ with pkgs;
|
||||||
|
|
||||||
cross = callPackage ./cross {};
|
cross = callPackage ./cross {};
|
||||||
|
|
||||||
|
php = recurseIntoAttrs (callPackages ./php {});
|
||||||
|
|
||||||
rustCustomSysroot = callPackage ./rust-sysroot {};
|
rustCustomSysroot = callPackage ./rust-sysroot {};
|
||||||
buildRustCrate = callPackage ../build-support/rust/build-rust-crate/test { };
|
buildRustCrate = callPackage ../build-support/rust/build-rust-crate/test { };
|
||||||
importCargoLock = callPackage ../build-support/rust/test/import-cargo-lock { };
|
importCargoLock = callPackage ../build-support/rust/test/import-cargo-lock { };
|
||||||
|
|
116
pkgs/test/php/default.nix
Normal file
116
pkgs/test/php/default.nix
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
{ lib
|
||||||
|
, php
|
||||||
|
, runCommand
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
runTest = name: body: runCommand name { } ''
|
||||||
|
testFailed=
|
||||||
|
checking() {
|
||||||
|
echo -n "Checking $1... " > /dev/stderr
|
||||||
|
}
|
||||||
|
ok() {
|
||||||
|
echo ok > /dev/stderr
|
||||||
|
}
|
||||||
|
nok() {
|
||||||
|
echo fail > /dev/stderr
|
||||||
|
testFailed=1
|
||||||
|
}
|
||||||
|
|
||||||
|
${body}
|
||||||
|
|
||||||
|
if test -n "$testFailed"; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
touch $out
|
||||||
|
'';
|
||||||
|
|
||||||
|
check = cond: if cond then "ok" else "nok";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
withExtensions-enables-previously-disabled-extensions = runTest "php-test-withExtensions-enables-previously-disabled-extensions" ''
|
||||||
|
php="${php}"
|
||||||
|
|
||||||
|
checking "that imagick is not present by default"
|
||||||
|
$php/bin/php -r 'exit(extension_loaded("imagick") ? 1 : 0);' && ok || nok
|
||||||
|
|
||||||
|
phpWithImagick="${php.withExtensions ({ all, ... }: [ all.imagick ])}"
|
||||||
|
checking "that imagick extension is present when enabled"
|
||||||
|
$phpWithImagick/bin/php -r 'exit(extension_loaded("imagick") ? 0 : 1);' && ok || nok
|
||||||
|
'';
|
||||||
|
|
||||||
|
overrideAttrs-preserves-enabled-extensions =
|
||||||
|
let
|
||||||
|
customPhp =
|
||||||
|
(php.withExtensions ({ all, ... }: [ all.imagick ])).overrideAttrs (attrs: {
|
||||||
|
postInstall = attrs.postInstall or "" + ''
|
||||||
|
touch "$out/oApee-was-here"
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
in
|
||||||
|
runTest "php-test-overrideAttrs-preserves-enabled-extensions" ''
|
||||||
|
php="${customPhp}"
|
||||||
|
phpUnwrapped="${customPhp.unwrapped}"
|
||||||
|
|
||||||
|
checking "if overrides took hold"
|
||||||
|
test -f "$phpUnwrapped/oApee-was-here" && ok || nok
|
||||||
|
|
||||||
|
checking "if imagick extension is still present"
|
||||||
|
$php/bin/php -r 'exit(extension_loaded("imagick") ? 0 : 1);' && ok || nok
|
||||||
|
|
||||||
|
checking "if imagick extension is linked against the overridden PHP"
|
||||||
|
echo $php
|
||||||
|
$php/bin/php -r 'exit(extension_loaded("imagick") ? 0 : 1);' && ok || nok
|
||||||
|
'';
|
||||||
|
|
||||||
|
unwrapped-overrideAttrs-stacks =
|
||||||
|
let
|
||||||
|
customPhp =
|
||||||
|
lib.pipe php.unwrapped [
|
||||||
|
(pkg: pkg.overrideAttrs (attrs: {
|
||||||
|
postInstall = attrs.postInstall or "" + ''
|
||||||
|
touch "$out/oAs-first"
|
||||||
|
'';
|
||||||
|
}))
|
||||||
|
|
||||||
|
(pkg: pkg.overrideAttrs (attrs: {
|
||||||
|
postInstall = attrs.postInstall or "" + ''
|
||||||
|
touch "$out/oAs-second"
|
||||||
|
'';
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
in
|
||||||
|
runTest "php-test-unwrapped-overrideAttrs-stacks" ''
|
||||||
|
checking "if first override remained"
|
||||||
|
${check (builtins.match ".*oAs-first.*" customPhp.postInstall != null)}
|
||||||
|
|
||||||
|
checking "if second override is there"
|
||||||
|
${check (builtins.match ".*oAs-second.*" customPhp.postInstall != null)}
|
||||||
|
'';
|
||||||
|
|
||||||
|
wrapped-overrideAttrs-stacks =
|
||||||
|
let
|
||||||
|
customPhp =
|
||||||
|
lib.pipe php [
|
||||||
|
(pkg: pkg.overrideAttrs (attrs: {
|
||||||
|
postInstall = attrs.postInstall or "" + ''
|
||||||
|
touch "$out/oAs-first"
|
||||||
|
'';
|
||||||
|
}))
|
||||||
|
|
||||||
|
(pkg: pkg.overrideAttrs (attrs: {
|
||||||
|
postInstall = attrs.postInstall or "" + ''
|
||||||
|
touch "$out/oAs-second"
|
||||||
|
'';
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
in
|
||||||
|
runTest "php-test-wrapped-overrideAttrs-stacks" ''
|
||||||
|
checking "if first override remained"
|
||||||
|
${check (builtins.match ".*oAs-first.*" customPhp.unwrapped.postInstall != null)}
|
||||||
|
|
||||||
|
checking "if second override is there"
|
||||||
|
${check (builtins.match ".*oAs-second.*" customPhp.unwrapped.postInstall != null)}
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Reference in a new issue