From 8622548160c5e29d5d2fb5d3fc942a3460a60a9c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 15 Jan 2014 13:39:52 +0100 Subject: [PATCH] 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. --- .../setup-hooks/fix-darwin-dylib-names.sh | 35 +++++++++++++++++++ pkgs/development/libraries/boost/1.55.nix | 6 ++-- .../libraries/http_parser/default.nix | 12 +++---- pkgs/development/libraries/icu/default.nix | 6 +++- pkgs/top-level/all-packages.nix | 2 ++ 5 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 pkgs/build-support/setup-hooks/fix-darwin-dylib-names.sh diff --git a/pkgs/build-support/setup-hooks/fix-darwin-dylib-names.sh b/pkgs/build-support/setup-hooks/fix-darwin-dylib-names.sh new file mode 100644 index 000000000000..5962bf039069 --- /dev/null +++ b/pkgs/build-support/setup-hooks/fix-darwin-dylib-names.sh @@ -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" +} diff --git a/pkgs/development/libraries/boost/1.55.nix b/pkgs/development/libraries/boost/1.55.nix index 1847a236fd07..70500a3c24e7 100644 --- a/pkgs/development/libraries/boost/1.55.nix +++ b/pkgs/development/libraries/boost/1.55.nix @@ -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; diff --git a/pkgs/development/libraries/http_parser/default.nix b/pkgs/development/libraries/http_parser/default.nix index 09371e4efb87..ca61a00f0344 100644 --- a/pkgs/development/libraries/http_parser/default.nix +++ b/pkgs/development/libraries/http_parser/default.nix @@ -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"; diff --git a/pkgs/development/libraries/icu/default.nix b/pkgs/development/libraries/icu/default.nix index 4437fc4bad2e..3ca8382c2da6 100644 --- a/pkgs/development/libraries/icu/default.nix +++ b/pkgs/development/libraries/icu/default.nix @@ -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} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index c7204e2a0b7f..c9026b6edb84 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -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