Loading pkgs/os-specific/cygwin/cygwin-dll-link-hook/cygwin-dll-link.sh +75 −29 Original line number Diff line number Diff line Loading @@ -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 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 "$check" || -n "${allowedImpureDLLsMap[$dll]}" ]]; then if [[ -z "$inOutput" || -n "${allowedImpureDLLsMap[$dll]}" ]]; then continue fi echo unable to find "$dll" in "$searchPath" >&2 exit 1 fi 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 "$dllPath" "$dir" fi _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 Loading @@ -70,15 +105,26 @@ linkDLLs() { allowedImpureDLLsMap[$dll]=1 done cd "$prefix" local target file for target in "$@"; do # 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" 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) Loading
pkgs/os-specific/cygwin/cygwin-dll-link-hook/cygwin-dll-link.sh +75 −29 Original line number Diff line number Diff line Loading @@ -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 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 "$check" || -n "${allowedImpureDLLsMap[$dll]}" ]]; then if [[ -z "$inOutput" || -n "${allowedImpureDLLsMap[$dll]}" ]]; then continue fi echo unable to find "$dll" in "$searchPath" >&2 exit 1 fi 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 "$dllPath" "$dir" fi _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 Loading @@ -70,15 +105,26 @@ linkDLLs() { allowedImpureDLLsMap[$dll]=1 done cd "$prefix" local target file for target in "$@"; do # 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" 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)