From 497d46b0125741a8be64dcf2d1fa340ebf5eba11 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 30 Apr 2022 02:24:55 +0200 Subject: [PATCH 1/4] php.mkExtension: Format --- pkgs/top-level/php-packages.nix | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/pkgs/top-level/php-packages.nix b/pkgs/top-level/php-packages.nix index a5d553ac629..de750079a00 100644 --- a/pkgs/top-level/php-packages.nix +++ b/pkgs/top-level/php-packages.nix @@ -80,13 +80,21 @@ lib.makeScope pkgs.newScope (self: with self; { pname = "php-${name}"; extensionName = name; + outputs = [ "out" "dev" ]; + inherit (php.unwrapped) version src; sourceRoot = "php-${php.version}/ext/${name}"; enableParallelBuilding = true; - nativeBuildInputs = [ php.unwrapped autoconf pkg-config re2c ]; - inherit configureFlags internalDeps buildInputs - zendExtension doCheck; + + nativeBuildInputs = [ + php.unwrapped + autoconf + pkg-config + re2c + ]; + + inherit configureFlags internalDeps buildInputs zendExtension doCheck; prePatch = "pushd ../.."; postPatch = "popd"; @@ -101,18 +109,25 @@ lib.makeScope pkgs.newScope (self: with self; { fi $nullglobRestore + phpize ${postPhpize} - ${lib.concatMapStringsSep "\n" + + ${lib.concatMapStringsSep + "\n" (dep: "mkdir -p ext; ln -s ${dep.dev}/include ext/${dep.extensionName}") - internalDeps} + internalDeps + } ''; + checkPhase = '' runHook preCheck + NO_INTERACTON=yes SKIP_PERF_SENSITIVE=yes make test + runHook postCheck ''; - outputs = [ "out" "dev" ]; + installPhase = '' mkdir -p $out/lib/php/extensions cp modules/${name}.so $out/lib/php/extensions/${name}.so From b2ae4d5a0ed0578f3bed6424c0ba51fc9dd61a18 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 30 Apr 2022 02:25:22 +0200 Subject: [PATCH 2/4] php.mkExtension: Run installPhase pre/post hooks --- pkgs/top-level/php-packages.nix | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkgs/top-level/php-packages.nix b/pkgs/top-level/php-packages.nix index de750079a00..2210a080a72 100644 --- a/pkgs/top-level/php-packages.nix +++ b/pkgs/top-level/php-packages.nix @@ -129,6 +129,8 @@ lib.makeScope pkgs.newScope (self: with self; { ''; installPhase = '' + runHook preInstall + mkdir -p $out/lib/php/extensions cp modules/${name}.so $out/lib/php/extensions/${name}.so mkdir -p $dev/include @@ -137,6 +139,8 @@ lib.makeScope pkgs.newScope (self: with self; { --filter="- *" \ --prune-empty-dirs \ . $dev/include/ + + runHook postInstall ''; meta = { From 03e31c533ce0bc568d2aebed5847934d7224c735 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 30 Apr 2022 02:15:56 +0200 Subject: [PATCH 3/4] php.mkExtension: make source name agnostic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHP obtained from Git contains files directly in the top-level directory, which will be placed in Nix store. The generic builder will then copy it to the /build sandbox as its basename with hash stripped (e.g. source/). This breaks the assumption of `mkExtension`, which expects that PHP’s source will be extracted into `php-«version»/` directory, since that is what the release tarballs contain. Let’s unset the `sourceRoot`, leaving it to `unpackPhase` to find the source directory. Then, we will be able go to the extension directory from there. We use custom pre-configure phase so that both `postPatch` and `preConfigure` is available to consumers. --- pkgs/top-level/php-packages.nix | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pkgs/top-level/php-packages.nix b/pkgs/top-level/php-packages.nix index 2210a080a72..11189f2522d 100644 --- a/pkgs/top-level/php-packages.nix +++ b/pkgs/top-level/php-packages.nix @@ -83,7 +83,6 @@ lib.makeScope pkgs.newScope (self: with self; { outputs = [ "out" "dev" ]; inherit (php.unwrapped) version src; - sourceRoot = "php-${php.version}/ext/${name}"; enableParallelBuilding = true; @@ -96,8 +95,14 @@ lib.makeScope pkgs.newScope (self: with self; { inherit configureFlags internalDeps buildInputs zendExtension doCheck; - prePatch = "pushd ../.."; - postPatch = "popd"; + preConfigurePhases = [ + "cdToExtensionRootPhase" + ]; + + cdToExtensionRootPhase = '' + # Go to extension source root. + cd "ext/${name}" + ''; preConfigure = '' nullglobRestore=$(shopt -p nullglob) From 9cdbd72004edee9f6b7ed0181996c2104cafb48a Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Mon, 2 May 2022 04:05:57 +0200 Subject: [PATCH 4/4] php.extensions.readline: Actually use readline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building readline extension would say: checking for libedit readline replacement... yes, shared even when configuring `--without-libedit`. This is because `PHP_ARG_WITH(libedit, …)`, internally calls `PHP_ALWAYS_SHARED`, which in `phpize`-generated `configure.ac` is defined as always forcing the value to shared. This will prevent `PHP_ARG_WITH(readline, …)` from being invoked so `READLINE_DIR` variable will never be defined. This was not an issue before we split the extension out of php.unwrapped in https://github.com/NixOS/nixpkgs/commit/282337799b08844c145c295110f20025541f829a, as `PHP_ALWAYS_SHARED` is empty there. ----- Additionally, because the build script passed `-L$READLINE_DIR/lib` as a flag to the compiler on PHP < 7.4 (built by the nix-phps repository), this ended up with a FHS-like path being passed to the linker. And once we bumped GCC to 11 in https://github.com/NixOS/nixpkgs/commit/52f8cf58a4504e5e219faebffa51033e400e3aec, the linker would fail: gcc -shared .libs/readline.o .libs/readline_cli.o -Wl,--rpath -Wl,/lib -L/lib -ledit -lncurses -Wl,-soname -Wl,readline.so -o .libs/readline.so impure path `/lib' used in link collect2: error: ld returned 1 exit status This no longer happens with PHP ≥ 7.4, since they switched to getting the linker flags from pkg-config in https://github.com/php/php-src/commit/b537203d20d7c1c425aee44d00f1d53758ac8747. ---- As a compromise, let’s make the `PHP_ALWAYS_SHARED` function force `shared` status but only for flags that are not disabled. That will allow us to remove the libedit dependency and also the nasty patch for configure script due to `--with-libedit` not being passed (which would be required for PHP < 7.4 to be able to find readline.h from libedit). Thanks to Pol Dellaiera for both bisections. --- pkgs/top-level/php-packages.nix | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/pkgs/top-level/php-packages.nix b/pkgs/top-level/php-packages.nix index 11189f2522d..f95af7c2071 100644 --- a/pkgs/top-level/php-packages.nix +++ b/pkgs/top-level/php-packages.nix @@ -19,7 +19,6 @@ , html-tidy , icu64 , libXpm -, libedit , libffi , libiconv , libjpeg @@ -542,10 +541,23 @@ lib.makeScope pkgs.newScope (self: with self; { { name = "pspell"; configureFlags = [ "--with-pspell=${aspell}" ]; } { name = "readline"; - buildInputs = [ libedit readline ]; - configureFlags = [ "--with-readline=${readline.dev}" ]; - postPhpize = lib.optionalString (lib.versionOlder php.version "7.4") '' - substituteInPlace configure --replace 'as_fn_error $? "Please reinstall libedit - I cannot find readline.h" "$LINENO" 5' ':' + buildInputs = [ + readline + ]; + configureFlags = [ + "--with-readline=${readline.dev}" + ]; + postPatch = '' + # Fix `--with-readline` option not being available. + # `PHP_ALWAYS_SHARED` generated by phpize enables all options + # without the possibility to override them. But when `--with-libedit` + # is enabled, `--with-readline` is not registered. + echo ' + AC_DEFUN([PHP_ALWAYS_SHARED],[ + test "[$]$1" != "no" && ext_shared=yes + ])dnl + ' | cat - ext/readline/config.m4 > ext/readline/config.m4.tmp + mv ext/readline/config.m4{.tmp,} ''; doCheck = false; }