[cmdletbinding()] param([string]$targetBinary, [string]$installedDir, [string]$tlogFile, [string]$copiedFilesLog) $g_searched = @{} # Note: installedDir is actually the bin\ directory. $g_install_root = Split-Path $installedDir -parent $g_is_debug = (Split-Path $g_install_root -leaf) -eq 'debug' # Ensure we create the copied files log, even if we don't end up copying any files if ($copiedFilesLog) { Set-Content -Path $copiedFilesLog -Value "" -Encoding UTF8 } function computeHash([System.Security.Cryptography.HashAlgorithm]$alg, [string]$str) { $bytes = [System.Text.Encoding]::UTF8.GetBytes($str) $hash = $alg.ComputeHash($bytes) return [Convert]::ToBase64String($hash) } function getMutex([string]$targetDir) { try { $sha512Hash = [System.Security.Cryptography.SHA512]::Create() if ($sha512Hash) { $hash = (computeHash $sha512Hash $targetDir) -replace ('/' ,'-') $mtxName = "VcpkgAppLocalDeployBinary-" + $hash return New-Object System.Threading.Mutex($false, $mtxName) } return New-Object System.Threading.Mutex($false, "VcpkgAppLocalDeployBinary") } catch { Write-Error -Message $_ -ErrorAction Stop } } # Note: this function signature is depended upon by the qtdeploy.ps1 script introduced in 5.7.1-7 function deployBinary([string]$targetBinaryDir, [string]$SourceDir, [string]$targetBinaryName) { try { $mtx = getMutex($targetBinaryDir) if ($mtx) { $mtx.WaitOne() | Out-Null } $sourceBinaryFilePath = Join-Path $SourceDir $targetBinaryName $targetBinaryFilePath = Join-Path $targetBinaryDir $targetBinaryName if (Test-Path $targetBinaryFilePath) { $sourceModTime = (Get-Item $sourceBinaryFilePath).LastWriteTime $destModTime = (Get-Item $targetBinaryFilePath).LastWriteTime if ($destModTime -lt $sourceModTime) { Write-Verbose " ${targetBinaryName}: Updating from $sourceBinaryFilePath" Copy-Item $sourceBinaryFilePath $targetBinaryDir } else { Write-Verbose " ${targetBinaryName}: already present" } } else { Write-Verbose " ${targetBinaryName}: Copying $sourceBinaryFilePath" Copy-Item $sourceBinaryFilePath $targetBinaryDir } if ($copiedFilesLog) { Add-Content $copiedFilesLog $targetBinaryFilePath -Encoding UTF8 } if ($tlogFile) { Add-Content $tlogFile $targetBinaryFilePath -Encoding Unicode } } finally { if ($mtx) { $mtx.ReleaseMutex() | Out-Null $mtx.Dispose() | Out-Null } } } Write-Verbose "Resolving base path $targetBinary..." try { $baseBinaryPath = Resolve-Path $targetBinary -erroraction stop $baseTargetBinaryDir = Split-Path $baseBinaryPath -parent } catch [System.Management.Automation.ItemNotFoundException] { return } # Note: this function signature is depended upon by the qtdeploy.ps1 script function resolve([string]$targetBinary) { Write-Verbose "Resolving $targetBinary..." try { $targetBinaryPath = Resolve-Path $targetBinary -erroraction stop } catch [System.Management.Automation.ItemNotFoundException] { return } $targetBinaryDir = Split-Path $targetBinaryPath -parent if (Get-Command "dumpbin" -ErrorAction SilentlyContinue) { $a = $(dumpbin /DEPENDENTS $targetBinaryPath| ? { $_ -match "^ [^ ].*\.dll" } | % { $_ -replace "^ ","" }) } elseif (Get-Command "llvm-objdump" -ErrorAction SilentlyContinue) { $a = $(llvm-objdump -p $targetBinary| ? { $_ -match "^ {4}DLL Name: .*\.dll" } | % { $_ -replace "^ {4}DLL Name: ","" }) } elseif (Get-Command "objdump" -ErrorAction SilentlyContinue) { $a = $(objdump -p $targetBinary| ? { $_ -match "^\tDLL Name: .*\.dll" } | % { $_ -replace "^\tDLL Name: ","" }) } else { Write-Error "Neither dumpbin, llvm-objdump nor objdump could be found. Can not take care of dll dependencies." } $a | % { if ([string]::IsNullOrEmpty($_)) { return } if ($g_searched.ContainsKey($_)) { Write-Verbose " ${_}: previously searched - Skip" return } $g_searched.Set_Item($_, $true) $installedItemFilePath = Join-Path $installedDir $_ $targetItemFilePath = Join-Path $targetBinaryDir $_ if (Test-Path $installedItemFilePath) { deployBinary $baseTargetBinaryDir $installedDir "$_" if (Test-Path function:\deployPluginsIfQt) { deployPluginsIfQt $baseTargetBinaryDir (Join-Path $g_install_root 'plugins') "$_" } if (Test-Path function:\deployOpenNI2) { deployOpenNI2 $targetBinaryDir "$g_install_root" "$_" } if (Test-Path function:\deployPluginsIfMagnum) { if ($g_is_debug) { deployPluginsIfMagnum $targetBinaryDir (Join-Path (Join-Path "$g_install_root" 'bin') 'magnum-d') "$_" } else { deployPluginsIfMagnum $targetBinaryDir (Join-Path (Join-Path "$g_install_root" 'bin') 'magnum') "$_" } } if (Test-Path function:\deployAzureKinectSensorSDK) { deployAzureKinectSensorSDK $targetBinaryDir "$g_install_root" "$_" } resolve (Join-Path $baseTargetBinaryDir "$_") } elseif (Test-Path $targetItemFilePath) { Write-Verbose " ${_}: $_ not found in $g_install_root; locally deployed" resolve "$targetItemFilePath" } else { Write-Verbose " ${_}: $installedItemFilePath not found" } } Write-Verbose "Done Resolving $targetBinary." } # Note: This is a hack to make Qt5 work. # Introduced with Qt package version 5.7.1-7 if (Test-Path "$g_install_root\plugins\qtdeploy.ps1") { . "$g_install_root\plugins\qtdeploy.ps1" } # Note: This is a hack to make OpenNI2 work. if (Test-Path "$g_install_root\bin\OpenNI2\openni2deploy.ps1") { . "$g_install_root\bin\OpenNI2\openni2deploy.ps1" } # Note: This is a hack to make Magnum work. if (Test-Path "$g_install_root\bin\magnum\magnumdeploy.ps1") { . "$g_install_root\bin\magnum\magnumdeploy.ps1" } elseif (Test-Path "$g_install_root\bin\magnum-d\magnumdeploy.ps1") { . "$g_install_root\bin\magnum-d\magnumdeploy.ps1" } # Note: This is a hack to make Azure Kinect Sensor SDK work. if (Test-Path "$g_install_root\tools\azure-kinect-sensor-sdk\k4adeploy.ps1") { . "$g_install_root\tools\azure-kinect-sensor-sdk\k4adeploy.ps1" } resolve($targetBinary) Write-Verbose $($g_searched | out-string)