about summary refs log tree commit diff
path: root/pkgs/build-support/setup-hooks
diff options
context:
space:
mode:
authorVladimír Čunát <vcunat@gmail.com>2016-02-10 21:18:34 +0100
committerVladimír Čunát <vcunat@gmail.com>2016-04-23 10:52:00 +0200
commit6e7787e666c50558b5aa10ffcca8e6c0c9bc1ba3 (patch)
tree0112b955ff093ab55a30f65c9017d6810876ab13 /pkgs/build-support/setup-hooks
parent13df963c7eef2f2a6f469a881084bc5473d4cd88 (diff)
downloadnixlib-6e7787e666c50558b5aa10ffcca8e6c0c9bc1ba3.tar
nixlib-6e7787e666c50558b5aa10ffcca8e6c0c9bc1ba3.tar.gz
nixlib-6e7787e666c50558b5aa10ffcca8e6c0c9bc1ba3.tar.bz2
nixlib-6e7787e666c50558b5aa10ffcca8e6c0c9bc1ba3.tar.lz
nixlib-6e7787e666c50558b5aa10ffcca8e6c0c9bc1ba3.tar.xz
nixlib-6e7787e666c50558b5aa10ffcca8e6c0c9bc1ba3.tar.zst
nixlib-6e7787e666c50558b5aa10ffcca8e6c0c9bc1ba3.zip
stdenv for windows: auto-link dependency DLLs
For every *.{exe,dll} in $output/bin/ we try to find all (potential)
transitive dependencies and symlink those DLLs into $output/bin
so they are found on invocation.
(DLLs are first searched in the directory of the running exe file.)

The links are relative, so relocating whole /nix/store won't break them.
The hook is activated on cygwin and when cross-compiling to mingw.
Diffstat (limited to 'pkgs/build-support/setup-hooks')
-rw-r--r--pkgs/build-support/setup-hooks/win-dll-link.sh45
1 files changed, 45 insertions, 0 deletions
diff --git a/pkgs/build-support/setup-hooks/win-dll-link.sh b/pkgs/build-support/setup-hooks/win-dll-link.sh
new file mode 100644
index 000000000000..be63f69ca10b
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/win-dll-link.sh
@@ -0,0 +1,45 @@
+
+fixupOutputHooks+=(_linkDLLs)
+
+# For every *.{exe,dll} in $output/bin/ we try to find all (potential)
+# transitive dependencies and symlink those DLLs into $output/bin
+# so they are found on invocation.
+# (DLLs are first searched in the directory of the running exe file.)
+# The links are relative, so relocating whole /nix/store won't break them.
+_linkDLLs() {
+(
+    if [ ! -d "$prefix/bin" ]; then exit; fi
+    cd "$prefix/bin"
+
+    # Compose path list where DLLs should be located:
+    #   prefix $PATH by currently-built outputs
+    local DLLPATH=""
+    local outName
+    for outName in $outputs; do
+        addToSearchPath DLLPATH "${!outName}/bin"
+    done
+    DLLPATH="$DLLPATH:$PATH"
+
+    echo DLLPATH="'$DLLPATH'"
+
+    linkCount=0
+    # Iterate over any DLL that we depend on.
+    local dll
+    for dll in $(objdump -p *.{exe,dll} | sed -n 's/.*DLL Name: \(.*\)/\1/p' | sort -u); do
+        if [ -e "./$dll" ]; then continue; fi
+        # Locate the DLL - it should be an *executable* file on $DLLPATH.
+        local dllPath="$(PATH="$DLLPATH" type -P "$dll")"
+        if [ -z "$dllPath" ]; then continue; fi
+        # That DLL might have its own (transitive) dependencies,
+        # so add also all DLLs from its directory to be sure.
+        local dllPath2
+        for dllPath2 in "$dllPath" "$(dirname "$dllPath")"/*.dll; do
+            if [ -e ./"$(basename "$dllPath2")" ]; then continue; fi
+            ln -sr "$dllPath2" .
+            linkCount=$(($linkCount+1))
+        done
+    done
+    echo "Created $linkCount DLL link(s) in $prefix/bin"
+)
+}
+