145 lines
3.3 KiB
PowerShell
145 lines
3.3 KiB
PowerShell
param(
|
|
[Parameter(Mandatory = $true)]
|
|
[string]$Executable,
|
|
|
|
[Parameter(Mandatory = $false)]
|
|
[string]$Output = "artifacts"
|
|
)
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
if (-not (Test-Path $Executable)) {
|
|
throw "Executable does not exist: $Executable"
|
|
}
|
|
|
|
New-Item -ItemType Directory -Force -Path $Output | Out-Null
|
|
|
|
$vswherePath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
|
|
|
if (-not (Test-Path $vswherePath)) {
|
|
throw "Could not locate vswhere.exe. Verify that Visual Studio or Visual Studio Build Tools is installed."
|
|
}
|
|
|
|
$visualStudioPath = & $vswherePath `
|
|
-latest `
|
|
-products * `
|
|
-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 `
|
|
-property installationPath
|
|
|
|
if (-not $visualStudioPath) {
|
|
throw "Could not locate a Visual Studio installation with the MSVC C++ tools installed."
|
|
}
|
|
|
|
$toolsetVersionPath = Join-Path `
|
|
$visualStudioPath `
|
|
"VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt"
|
|
|
|
if (-not (Test-Path $toolsetVersionPath)) {
|
|
throw "Could not locate the MSVC toolset version file."
|
|
}
|
|
|
|
$toolsetVersion = (Get-Content $toolsetVersionPath -Raw).Trim()
|
|
|
|
$dumpbinPath = Join-Path `
|
|
$visualStudioPath `
|
|
"VC\Tools\MSVC\$toolsetVersion\bin\Hostx64\x64\dumpbin.exe"
|
|
|
|
if (-not (Test-Path $dumpbinPath)) {
|
|
throw "Could not locate dumpbin.exe at: $dumpbinPath"
|
|
}
|
|
|
|
Write-Host "Using dumpbin: $dumpbinPath"
|
|
|
|
$windowsDirectories = @(
|
|
$env:WINDIR,
|
|
(Join-Path $env:WINDIR "System32"),
|
|
(Join-Path $env:WINDIR "SysWOW64")
|
|
)
|
|
|
|
$processed = @{}
|
|
|
|
function Test-IsWindowsSystemDll {
|
|
param(
|
|
[string]$Name
|
|
)
|
|
|
|
foreach ($directory in $windowsDirectories) {
|
|
$path = Join-Path $directory $Name
|
|
|
|
if (Test-Path $path) {
|
|
return $true
|
|
}
|
|
}
|
|
|
|
return $false
|
|
}
|
|
|
|
function Find-Dependency {
|
|
param(
|
|
[string]$Name,
|
|
[string]$BinaryDirectory
|
|
)
|
|
|
|
$localPath = Join-Path $BinaryDirectory $Name
|
|
|
|
if (Test-Path $localPath) {
|
|
return $localPath
|
|
}
|
|
|
|
$command = Get-Command $Name -ErrorAction SilentlyContinue
|
|
|
|
if ($command) {
|
|
return $command.Source
|
|
}
|
|
|
|
return $null
|
|
}
|
|
|
|
function Copy-Dependencies {
|
|
param(
|
|
[string]$Binary
|
|
)
|
|
|
|
$binaryDirectory = Split-Path -Parent $Binary
|
|
|
|
$dependencies = & $dumpbinPath /DEPENDENTS $Binary |
|
|
Select-String '^\s+.*\.dll$' |
|
|
ForEach-Object { $_.Line.Trim() } |
|
|
Sort-Object -Unique
|
|
|
|
foreach ($dll in $dependencies) {
|
|
$key = $dll.ToLowerInvariant()
|
|
|
|
if ($processed.ContainsKey($key)) {
|
|
continue
|
|
}
|
|
|
|
$processed[$key] = $true
|
|
|
|
if (Test-IsWindowsSystemDll $dll) {
|
|
Write-Host "Skipping Windows system dependency: $dll"
|
|
continue
|
|
}
|
|
|
|
$source = Find-Dependency `
|
|
-Name $dll `
|
|
-BinaryDirectory $binaryDirectory
|
|
|
|
if (-not $source) {
|
|
Write-Warning "Could not locate dependency: $dll"
|
|
continue
|
|
}
|
|
|
|
$destination = Join-Path $Output (Split-Path -Leaf $source)
|
|
|
|
if (-not (Test-Path $destination)) {
|
|
Write-Host "Copying dependency: $source"
|
|
Copy-Item $source $destination -Force
|
|
}
|
|
|
|
Copy-Dependencies -Binary $source
|
|
}
|
|
}
|
|
|
|
Copy-Dependencies -Binary $Executable
|