1#!/bin/bash
2# Copyright (c) 2011 The Native Client Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6set -Ceu
7
8
9prefix="$1"
10
11if [[ ! -d "$prefix" ]]; then
12  echo "Usage: $0 toolchain-prefix"
13  exit 1
14fi
15
16if ! cygcheck -V >/dev/null 2>/dev/null; then
17  echo "No cygcheck found"
18  exit 1
19fi
20
21echo "WARNING: hang can occur on FAT, use NTFS"
22
23
24# Redirectors on windows:
25#   NaCl tools are cygwin programs. To run, they need cygwin DLLs of the same
26#   or later version of cygwin they were compiled with.
27#
28#   To avoid requiring users to install or upgrade cygwin, we couple the tools
29#   with the corresponding DLLs. We place these DLLs in every directory where
30#   the tools are, so that windows algorithm for locating DLLs pick DLLs
31#   provided by us.
32#
33#   Unfortunately, when cygwin program is forked/execed by another cygwin
34#   program, both are required to use the same version of cygwin DLLs. The
35#   common case is when user starts a tool from cygwin bash.
36#
37#   This is solved by hiding actual tools under /libexec (which is a directory
38#   for programs to be run by other programs rather than by users) and providing
39#   trivial non-cygwin redirectors (launchers) for these tools.
40#
41# Symbolic links vs. hard links:
42#   On windows/cygwin, hard links are needed to run linked programs outside of
43#   the cygwin shell. On *nix, there is no usage difference.
44#   Here we handle only the windows/cygwin case and use the hard links.
45
46
47# Destination of a redirector is always under /libexec. When redirector source
48# name is equal to redirector destination name, it means the source is an actual
49# tool to be hidden under /libexec.
50#
51# Redirector source can be updated after the redirector was created. Overwrite
52# the destination in this case.
53
54./redirector.exe | while IFS='|' read src dst arg; do
55  if [[ -e "$prefix/$src" ]]; then
56    if ! cmp -s ./redirector.exe "$prefix/$src"; then
57      if [[ "$(basename "$src")" = "$(basename "$dst")" ]]; then
58        mv -f "$prefix/$src" "$prefix/$dst"
59      fi
60    fi
61  fi
62done
63
64# Install redirectors for existing redirector destinations.
65
66./redirector.exe | while IFS='|' read src dst arg; do
67  if [[ -e "$prefix/$dst" ]]; then
68    ln -fn ./redirector.exe "$prefix/$src"
69  fi
70done
71
72
73# Inject DLLs:
74#   get list of (directory, dll):
75#     for each exe:
76#       run cygcheck to get list of DLLs
77#     keep unique pairs only
78#   for each (directory, dll):
79#     if dll is from /usr/bin:
80#       add link to the dll in the directory
81#
82# We dump all DLLs and filter /usr/bin DLLs later to save cygpath calls.
83
84find "$prefix" -name "*.exe" -print0 | while read -r -d $'\0' exe; do
85  dir="$(dirname "$exe")"
86  win_exe="$(cygpath -w "$exe")"
87  cd "$dir" && cygcheck "$win_exe" | while read -r win_dll; do
88    echo "$dir:$win_dll"
89  done
90done | sort -u | while IFS=':' read -r dir win_dll; do
91  dll="$(cygpath "$win_dll")"
92  if [[ "$dll" = /usr/bin/*.dll ]]; then
93    ln -fn "$dll" "$dir"
94  fi
95done
96