summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdam Joseph <adam@westernsemico.com>2022-04-12 14:46:57 -0700
committerAdam Joseph <adam@westernsemico.com>2022-05-26 13:53:36 -0700
commit97c43828fb7e016b4ee8fe434bc4d5e0b8a8b4be (patch)
tree8e5b3888d73c5d084efe8bfe174a21806950dcc8
parentb20b6fa0d86738235316981b9c706376bd29fc81 (diff)
downloadnixpkgs-97c43828fb7e016b4ee8fe434bc4d5e0b8a8b4be.tar
nixpkgs-97c43828fb7e016b4ee8fe434bc4d5e0b8a8b4be.tar.gz
nixpkgs-97c43828fb7e016b4ee8fe434bc4d5e0b8a8b4be.tar.bz2
nixpkgs-97c43828fb7e016b4ee8fe434bc4d5e0b8a8b4be.tar.lz
nixpkgs-97c43828fb7e016b4ee8fe434bc4d5e0b8a8b4be.tar.xz
nixpkgs-97c43828fb7e016b4ee8fe434bc4d5e0b8a8b4be.tar.zst
nixpkgs-97c43828fb7e016b4ee8fe434bc4d5e0b8a8b4be.zip
fixLibtool(): patch ./configure, add `file` to common-path.nix
libtool's libtool.m4 script assumes that `file` is available, and can
be found at `/usr/bin/file` (this path is hardwired).  Furthermore,
the script with this assumption is vendored into the ./configure
scripts of an enormous number of packages.  Without this commit, you
will frequently see errors like this during the configurePhase with
the sandbox enabled:

  ./configure: line 9595: /usr/bin/file: command not found

Due mostly to luck, this error does not affect native compiles on
nixpkgs' two most popular platforms, x86_64-linux and aarch64-linux.
However it will cause incorrect linker flag detection and a failure to
generate shared libraries for sandboxed cross-builds to a x86_64-linux
host as well as any sandboxed build (cross or native) for the following
hosts: x86_64-freebsd, *-hpux, *-irix, mips64*-linux, powerpc*-linux,
s390x-linux, s390x-tpf, sparc-linux, and *-solaris.

This commit fixes the problem by adding an extra line to fixLibtool()
in pkgs/stdenv/generic/setup.sh.  This extra line will scan the
unpacked source code for executable files named "configure" which
contain the following text:

'GNU Libtool is free software; you can redistribute it and/or modify'

This text is taken to be an indicator of a vendored libtool.m4.  When
it is found, the configure script containing it is subjected to `sed
-i s_/usr/bin/file_file_` which replaces all occurrences of
`/usr/bin/file` with `file`.

Additionally, the `file` package is now considered to be part of
`stdenv`.  It has been added to `common-path.nix` so that the `file`
binary will be found in the `$PATH` of every build, except for the
bootstrap-tools and the first few stages of stdenv boostrapping.

Verified no regressions under:

  nix-build --arg pkgs 'import ./. {}' ./lib/tests/release.nix

This commit allows the following commands to complete, which should
enable Hydra to produce bootstrap-files for mips64el:

  nix-build \
    --option sandbox true \
    --option sandbox-fallback false \
    pkgs/top-level/release-cross.nix \
    -A bootstrapTools.mips64el-linux-gnuabi64.build

  nix-build \
    --option sandbox true \
    --option sandbox-fallback false \
    . \
    -A pkgsCross.mips64el-linux-gnuabi64.nix_2_4
-rw-r--r--pkgs/stdenv/common-path.nix8
-rw-r--r--pkgs/stdenv/darwin/default.nix3
-rw-r--r--pkgs/stdenv/generic/setup.sh15
-rw-r--r--pkgs/stdenv/linux/default.nix2
4 files changed, 27 insertions, 1 deletions
diff --git a/pkgs/stdenv/common-path.nix b/pkgs/stdenv/common-path.nix
index da468d56a2c..8c1acfb50dd 100644
--- a/pkgs/stdenv/common-path.nix
+++ b/pkgs/stdenv/common-path.nix
@@ -12,4 +12,12 @@
   pkgs.bash
   pkgs.patch
   pkgs.xz.bin
+
+  # The `file` command is added here because an enormous number of
+  # packages have a vendored dependency upon `file` in their
+  # `./configure` script, due to libtool<=2.4.6, or due to
+  # libtool>=2.4.7 in which the package author decided to set FILECMD
+  # when running libtoolize.  In fact, file-5.4.6 *depends on itself*
+  # and tries to invoke `file` from its own ./configure script.
+  pkgs.file
 ]
diff --git a/pkgs/stdenv/darwin/default.nix b/pkgs/stdenv/darwin/default.nix
index 32e4fe9749a..bbc15bad262 100644
--- a/pkgs/stdenv/darwin/default.nix
+++ b/pkgs/stdenv/darwin/default.nix
@@ -486,6 +486,7 @@ rec {
           gmp
           libiconv
           brotli.lib
+          file
         ] ++ lib.optional haveKRB5 libkrb5) ++
         (with pkgs."${finalLlvmPackages}"; [
           libcxx
@@ -561,6 +562,7 @@ rec {
           gmp
           libiconv
           brotli.lib
+          file
         ] ++ lib.optional haveKRB5 libkrb5) ++
         (with pkgs."${finalLlvmPackages}"; [
           libcxx
@@ -737,6 +739,7 @@ rec {
         brotli.lib
         cc.expand-response-params
         libxml2.out
+        file
       ] ++ lib.optional haveKRB5 libkrb5
       ++ lib.optionals localSystem.isAarch64 [
         pkgs.updateAutotoolsGnuConfigScriptsHook
diff --git a/pkgs/stdenv/generic/setup.sh b/pkgs/stdenv/generic/setup.sh
index 6d30e6c01ff..40ffd9344e3 100644
--- a/pkgs/stdenv/generic/setup.sh
+++ b/pkgs/stdenv/generic/setup.sh
@@ -1021,6 +1021,21 @@ configurePhase() {
             echo "fixing libtool script $i"
             fixLibtool "$i"
         done
+
+        # replace `/usr/bin/file` with `file` in any `configure`
+        # scripts with vendored libtool code.  Preserve mtimes to
+        # prevent some packages (e.g. libidn2) from spontaneously
+        # autoreconf'ing themselves
+        CONFIGURE_MTIME_REFERENCE=$(mktemp configure.mtime.reference.XXX)
+        find . \
+          -executable \
+          -type f \
+          -name configure \
+          -execdir grep -l 'GNU Libtool is free software; you can redistribute it and/or modify' {} \; \
+          -execdir touch -r {} "$CONFIGURE_MTIME_REFERENCE" \; \
+          -execdir sed -i s_/usr/bin/file_file_g {} \;    \
+          -execdir touch -r "$CONFIGURE_MTIME_REFERENCE" {} \;
+        rm -f "$CONFIGURE_MTIME_REFERENCE"
     fi
 
     if [[ -z "${dontAddPrefix:-}" && -n "$prefix" ]]; then
diff --git a/pkgs/stdenv/linux/default.nix b/pkgs/stdenv/linux/default.nix
index 956aeff4946..b00332bae4c 100644
--- a/pkgs/stdenv/linux/default.nix
+++ b/pkgs/stdenv/linux/default.nix
@@ -414,7 +414,7 @@ in
         # Simple executable tools
         concatMap (p: [ (getBin p) (getLib p) ]) [
             gzip bzip2 xz bash binutils.bintools coreutils diffutils findutils
-            gawk gnumake gnused gnutar gnugrep gnupatch patchelf ed
+            gawk gnumake gnused gnutar gnugrep gnupatch patchelf ed file
           ]
         # Library dependencies
         ++ map getLib (