libtool: fix /usr/bin/file impurity affecting cross-compilation#166722
Conversation
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.
This commit makes two changes:
* It adds a `substituteInPlace` in the `libtool` expression so that
autoreconfHook'ed packages will find `file` in the correct
location. This is currently guarded by a check for
cross-compilation in order to prevent mass-rebuilds.
* It adds a top-level `fixPathToUsrBinFileInConfigureScript` to
`substituteInPlace` the `./configure` script of packages directly,
for use with packages which would break if autoreconfHook'ed.
This commit allows the mips64el-linux-gnuabi64 bootstrap-files to be
built in a sandbox (as required by Hydra) by implementing the two
changes above, adding `autoreconfHook` to `gmp`, `pcre`, `isl`, and
`libmpc`, as well as adding `fixPathToUsrBinFileInConfigureScript` to
`mpfr` (since `mpfr` breaks if autoreconf'ed with the latest
autotools); this was verified with:
```
nix-build \
--option sandbox true \
--option fallback false \
pkgs/top-level/release-cross.nix \
-A bootstrapTools.mips64el-linux-gnuabi64.build
```
| # staging, not to be merged until after nixpkgs-22.05 branch-off, | ||
| # which deletes this conditional and this comment. | ||
| # | ||
| preBuild = if stdenv.buildPlatform == stdenv.targetPlatform |
There was a problem hiding this comment.
I would appreciate a review of this line in particular. I think of libtool as being a "compiler-like" package that has a targetPlatform but I'm not sure if nixpkgs thinks of it this way. Please let me know if I should change this from build==target to build==host.
|
@ofborg build hey-ofborg-you-build-them-bootstrapballs-now |
Okay, I figured out how to make this work. See #166879. I prefer #166879 one over this PR, but I need to finish testing it first, and even if it works it probably needs to wait until the 22.05 branch-off (did that happen already?) and then go into staging since it messes around with the internals of stdenv. I don't want to be the guy who broke the builds a month before a release. |
This has been fixed upstream in libtool 2.4.7. However this still does not solve the problem of the fact that the old |
|
Marking this as draft in favor of #166879, which is going to be way more maintainable in the long run. If that PR is totally unacceptable we can revisit this one instead. |
Problem
libtool's libtool.m4 script assumes that
fileis available, and can be found at/usr/bin/file(this path is hardwired). This fails for sandboxed builds. Furthermore, the script with this assumption is vendored into the./configurescripts of an enormous number of packages.Solutions
Oftentimes the fact that
/usr/bin/filedoes not exist will not prevent a package from building. When it does prevent a successful build, there are a few options:set
NIX_REDIRECT=/usr/bin/file=${file}/bin/filefix
libtool.m4in the libtool packagea. ... and use autoreconfHook manually in packages which need it (and do not break when autoreconf'ed with the latest autotools).
Add
substituteInPlace ./configure --replace /usr/bin/file ${file}/bin/filein one of these ways:a. in
setup.sh'sfixLibtool(), which exists for the same reason: impurities in pervasively-vendoredlibtool.m4b. manually to packages which need it
There are already 36 packages in nixpkgs which use 3(b).
Implementation
This commit makes two changes:
It implements 2 with a
substituteInPlacein thelibtoolexpression, to allow 2(a) where possible.It implements 3(b) by adding a
top-levelexpressionfixPathToUsrBinFileInConfigureScriptwhich implements the third approach, patterned afterautoreconfHook.If there is some way to cleverly get
stdenvto injectfixPathToUsrBinFileInConfigureScriptas an extranativeBuildInputonly when cross-compiling to certainhostPlatforms, I would like to include that in this PR. However I had a very hard time finding an appropriate place to add that. Suggestions are welcome. I tried adding it topkgs/stdenv/cross/default.nixinextraNativeBuildInputs, where there is a similar workaround for cross-compiling to windows, but this didn't seem to work.(Immediate) Motivation
When cross-compiling a libtool.m4-derived package to
{x86_64, powerpc, s390, sparc, mips64*}-linux,x86_64-kfreebsd,*-solaris,*-irix, and*-hpux, the configure script will fail to generate shared libraries iffileis not callable via/usr/bin/file. It seems that cross-compilations to darwin, riscv, and arm64 hosts are among the few exceptions to this issue, which is why nixpkgs hasn't encountered it until now.This is currently preventing the generation of Hydra-built
bootstrap-filesfor mips64el-linux-gnuabi64, and will affect almost any other new platform we try to bootstrap on.The build of the
pcrepackage (and a few others) emits these lines when its configure script is run:The build does not fail until much later, when make-bootstrap-files.nix tries to make a copy libpcre.so, which was never built.
This commit allows the mips64el-linux-gnuabi64 bootstrap-files to be built in a sandbox (as required by Hydra) by implementing the two changes above, adding
autoreconfHooktogmpandpcre, andfixPathToUsrBinFileInConfigureScripttompfr(sincempfrbreaks if autoreconf'ed with the latest autotools); this was verified with:Things done
sandbox = trueset innix.conf? (See Nix manual)nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/)