cygwin-dll-link: allow linkDLLs to be used on individual dirs/files
This commit is contained in:
@@ -24,39 +24,74 @@ _dllDeps() {
|
||||
| sort -u
|
||||
}
|
||||
|
||||
declare -Ag _linkDeps_visited
|
||||
|
||||
_linkDeps() {
|
||||
local target="$1" dir="$2" check="$3"
|
||||
[[ ! -x "$target" ]] && echo "_linkDeps: $target is not executable, skipping." 1>&2 && return
|
||||
local target="$1" dir="$2"
|
||||
if [[ -v _linkDeps_visited[$target] ]]; then
|
||||
echo "_linkDeps: $target was already linked." 1>&2
|
||||
return
|
||||
fi
|
||||
if [[ ! -f "$target" || ! -x "$target" ]]; then
|
||||
echo "_linkDeps: $target is not an executable file, skipping." 1>&2
|
||||
return
|
||||
fi
|
||||
|
||||
local realTarget output inOutput
|
||||
realTarget="$(readlink -f "$target")"
|
||||
for output in $outputs ; do
|
||||
if [[ $realTarget == "${!output}"* ]]; then
|
||||
echo "_linkDeps: $target ($realTarget) is in $output (${!output})." 1>&2
|
||||
inOutput=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
echo 'target:' "$target"
|
||||
local dll
|
||||
_dllDeps "$target" | while read -r dll; do
|
||||
while read -r dll; do
|
||||
echo ' dll:' "$dll"
|
||||
if [[ -L "$dir/$dll" || -e "$dir/$dll" ]]; then continue; fi
|
||||
if [[ $dll = cygwin1.dll ]]; then
|
||||
CYGWIN+=\ winsymlinks:nativestrict ln -sr /bin/cygwin1.dll "$dir"
|
||||
if [[ -v _linkDeps_visited[$dir/$dll] ]]; then
|
||||
echo "_linkDeps: $dll was already linked into $dir." 1>&2
|
||||
continue
|
||||
fi
|
||||
# Locate the DLL - it should be an *executable* file on $HOST_PATH.
|
||||
local dllPath searchPath
|
||||
searchPath=$(dirname "$target"):$_linkDeps_outputPath:$_linkDeps_inputPath:$HOST_PATH
|
||||
if ! dllPath="$(PATH="$searchPath" type -P "$dll")"; then
|
||||
if [[ -z "$check" || -n "${allowedImpureDLLsMap[$dll]}" ]]; then
|
||||
continue
|
||||
if [[ -L "$dir/$dll" || -e "$dir/$dll" ]]; then
|
||||
echo ' already exists'
|
||||
_linkDeps "$dir/$dll" "$dir"
|
||||
else
|
||||
local dllPath
|
||||
if [[ $dll = cygwin1.dll ]]; then
|
||||
dllPath=/bin/cygwin1.dll
|
||||
else
|
||||
local searchPath
|
||||
searchPath=$(dirname "$target"):$_linkDeps_outputPath:$_linkDeps_inputPath:$HOST_PATH
|
||||
# Locate the DLL - it should be an *executable* file on $HOST_PATH.
|
||||
# This intentionally doesn't use $dir because we want to prefer dependencies
|
||||
# that are already linked next to the target.
|
||||
if ! dllPath="$(PATH="$searchPath" type -P "$dll")"; then
|
||||
if [[ -z "$inOutput" || -n "${allowedImpureDLLsMap[$dll]}" ]]; then
|
||||
continue
|
||||
fi
|
||||
echo unable to find "$dll" in "$searchPath" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo unable to find "$dll" in "$searchPath" >&2
|
||||
exit 1
|
||||
echo ' linking to:' "$dllPath"
|
||||
CYGWIN+=\ winsymlinks:nativestrict ln -sr "$dllPath" "$dir"
|
||||
_linkDeps "$dllPath" "$dir"
|
||||
fi
|
||||
echo ' linking to:' "$dllPath"
|
||||
CYGWIN+=\ winsymlinks:nativestrict ln -sr "$dllPath" "$dir"
|
||||
# That DLL might have its own (transitive) dependencies,
|
||||
# so add also all DLLs from its directory to be sure.
|
||||
_linkDeps "$dllPath" "$dir" ""
|
||||
done
|
||||
_linkDeps_visited[$dir/$dll]=1
|
||||
done < <(_dllDeps "$target")
|
||||
}
|
||||
|
||||
# linkDLLsDir can be used to override the destination path for links. This is
|
||||
# useful if you're trying to link dependencies of libraries into the directory
|
||||
# containing an executable.
|
||||
#
|
||||
# Arguments can be a file or directory path. Directories are searched
|
||||
# recursively.
|
||||
linkDLLs() {
|
||||
# shellcheck disable=SC2154
|
||||
if [ ! -d "$prefix" ]; then return; fi
|
||||
(
|
||||
set -e
|
||||
shopt -s globstar nullglob
|
||||
@@ -70,15 +105,26 @@ linkDLLs() {
|
||||
allowedImpureDLLsMap[$dll]=1
|
||||
done
|
||||
|
||||
cd "$prefix"
|
||||
|
||||
# Iterate over any DLL that we depend on.
|
||||
local target
|
||||
for target in {bin,lib,libexec}/**/*.{exe,dll}; do
|
||||
[[ ! -f "$target" || ! -x "$target" ]] ||
|
||||
_linkDeps "$target" "$(dirname "$target")" "1"
|
||||
local target file
|
||||
for target in "$@"; do
|
||||
# Iterate over any DLL that we depend on.
|
||||
if [[ -f "$target" ]]; then
|
||||
_linkDeps "$target" "${linkDLLsDir-$(dirname "$target")}"
|
||||
elif [[ -d "$target" ]]; then
|
||||
for file in "${target%/}"/**/*.{exe,dll}; do
|
||||
_linkDeps "$file" "${linkDLLsDir-$(dirname "$file")}"
|
||||
done
|
||||
else
|
||||
echo "linkDLLs: $target is not a file or directory, skipping." 1>&2
|
||||
fi
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
fixupOutputHooks+=(linkDLLs)
|
||||
_linkDLLs() {
|
||||
# shellcheck disable=SC2154
|
||||
if [[ ! -d $prefix || ${dontLinkDLLs-} ]]; then return; fi
|
||||
linkDLLs "$prefix"/{bin,lib,libexec}/
|
||||
}
|
||||
|
||||
fixupOutputHooks+=(_linkDLLs)
|
||||
|
||||
Reference in New Issue
Block a user