Add a setup hook for fixing dylib install names on Darwin

Install names need to be absolute paths, otherwise programs that link
against the dylib won't work without setting $DYLD_LIBRARY_PATH.  Most
packages do this correctly, but some (like Boost and ICU) do not.
This setup hook absolutizes all install names.
This commit is contained in:
Eelco Dolstra 2014-01-15 13:39:52 +01:00
parent abf6896aaf
commit 8622548160
5 changed files with 51 additions and 10 deletions

View File

@ -0,0 +1,35 @@
# On Mac OS X, binaries refer to dynamic library dependencies using
# either relative paths (e.g. "libicudata.dylib", searched relative to
# $DYLD_LIBRARY_PATH) or absolute paths
# (e.g. "/nix/store/.../lib/libicudata.dylib"). In Nix, the latter is
# preferred since it allows programs to just work. When linking
# against a library (e.g. "-licudata"), the linker uses the install
# name embedded in the dylib (which can be shown using "otool -D").
# Most packages create dylibs with absolute install names, but some do
# not. This setup hook fixes dylibs by setting their install names to
# their absolute path (using "install_name_tool -id"). It also
# rewrites references in other dylibs to absolute paths.
fixDarwinDylibNames() {
local flags=()
local old_id
for fn in "$@"; do
flags+=(-change "$(basename "$fn")" "$fn")
done
for fn in "$@"; do
if [ -L "$fn" ]; then continue; fi
echo "$fn: fixing dylib"
install_name_tool -id "$fn" "${flags[@]}" "$fn"
done
}
fixDarwinDylibNamesIn() {
local dir="$1"
fixDarwinDylibNames $(find "$dir" -name "*.dylib")
}
postFixup() {
fixDarwinDylibNamesIn "$prefix"
}

View File

@ -1,4 +1,4 @@
{ stdenv, fetchurl, icu, expat, zlib, bzip2, python
{ stdenv, fetchurl, icu, expat, zlib, bzip2, python, fixDarwinDylibNames
, toolset ? null
, enableRelease ? true
, enableDebug ? false
@ -59,7 +59,9 @@ stdenv.mkDerivation {
enableParallelBuilding = true;
buildInputs = [icu expat zlib bzip2 python];
buildInputs =
[ icu expat zlib bzip2 python ]
++ stdenv.lib.optional stdenv.isDarwin fixDarwinDylibNames;
configureScript = "./bootstrap.sh";
configureFlags = "--with-icu=${icu} --with-python=${python}/bin/python" + withToolset;

View File

@ -1,4 +1,4 @@
{ stdenv, fetchurl, gyp, utillinux, python }:
{ stdenv, fetchurl, gyp, utillinux, python, fixDarwinDylibNames }:
let
version = "2.1";
@ -16,7 +16,10 @@ in stdenv.mkDerivation {
buildFlags = [ "BUILDTYPE=Release" ];
buildInputs = [ gyp ] ++ (stdenv.lib.optional stdenv.isLinux utillinux) ++ stdenv.lib.optional stdenv.isDarwin python;
buildInputs =
[ gyp ]
++ stdenv.lib.optional stdenv.isLinux utillinux
++ stdenv.lib.optionals stdenv.isDarwin [ python fixDarwinDylibNames ];
doCheck = !stdenv.isDarwin;
@ -33,11 +36,6 @@ in stdenv.mkDerivation {
mv http_parser.h $out/include
'';
postFixup = if stdenv.isDarwin then ''
install_name_tool -id $out/lib/libhttp_parser.dylib $out/lib/libhttp_parser.dylib
install_name_tool -id $out/lib/libhttp_parser_strict.dylib $out/lib/libhttp_parser_strict.dylib
'' else null;
meta = {
description = "An HTTP message parser written in C";

View File

@ -1,4 +1,4 @@
{stdenv, fetchurl}:
{ stdenv, fetchurl, fixDarwinDylibNames }:
let
@ -16,6 +16,10 @@ stdenv.mkDerivation {
sha256 = "14l0kl17nirc34frcybzg0snknaks23abhdxkmsqg3k9sil5wk9g";
};
# FIXME: This fixes dylib references in the dylibs themselves, but
# not in the programs in $out/bin.
buildInputs = stdenv.lib.optional stdenv.isDarwin fixDarwinDylibNames;
postUnpack = ''
sourceRoot=''${sourceRoot}/source
echo Source root reset to ''${sourceRoot}

View File

@ -394,6 +394,8 @@ let
setJavaClassPath = makeSetupHook { } ../build-support/setup-hooks/set-java-classpath.sh;
fixDarwinDylibNames = makeSetupHook { } ../build-support/setup-hooks/fix-darwin-dylib-names.sh;
### TOOLS