Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 131 additions & 28 deletions src/windows/build/build-installer.ps1
Original file line number Diff line number Diff line change
@@ -1,62 +1,162 @@
param(
[string]$OutputName = "installer.exe"
[string]$OutputName = "installer.exe",
[ValidateSet("x64", "x86", "arm64")]
[string]$Arch = "x64" # default value (adjust if needed)
Comment thread
tejas-sharma27 marked this conversation as resolved.
)

# ==============================================================================
# Configuration
# ==============================================================================

$Script:OutputRoot = Join-Path $PSScriptRoot "target"
$Script:DriversDir = "drivers"
$Script:ToolsDir = "tools"
$Script:PayloadName = "payload.zip"
$Script:VersionFile = Join-Path $PSScriptRoot "..\qcversion.h"

# Files to promote from tools/ to the payload root (alongside drivers/ and tools/)
$Script:PromotedTools = @("qdclr.exe", "qdinstall.exe")
# Libusb related parameters
$Script:LibusbVersion = "1.0.29"
$Script:LibusbLibrary = "libusb-1.0.dll"
$Script:LibusbArchive = "libusb-$($Script:LibusbVersion).7z"

# Mapping from our arch names to the folder names inside the libusb binaries archive.
# These correspond to the MinGW-compiled DLL subdirectories in libusb-<ver>.7z.
$Script:LibusbArchMap = @{
"x64" = "MinGW64"
"x86" = "MinGW32"
"arm64" = "MinGW-llvm-aarch64"
}

# Items to include in the payload zip (files or directories under target/).
# Promote: optional list of file names to move to the payload root.
$Script:PayloadItems = @(
@{ Path = "libusb"; Arch = $Arch; Promote = $null }
@{ Path = "drivers"; Promote = $null }
@{ Path = "tools"; Promote = @("qdclr.exe", "qdinstall.exe") }
)

# ==============================================================================
# Functions
# ==============================================================================

# Assembles a payload zip from target/drivers and target/tools.
function New-Payload {
# Downloads libusb binaries from the official GitHub release and places
# libusb-1.0.dll for each architecture under $PSScriptRoot\libusb\<arch>\.
# Skips the download if all required DLLs are already present.
function Get-LibusbBinaries {
Write-Host "========================================"
Write-Host " Packaging Payload"
Write-Host " Fetching libusb $($Script:LibusbVersion) Binaries"
Write-Host "========================================`n"

$driversSource = Join-Path $Script:OutputRoot $Script:DriversDir
$toolsSource = Join-Path $Script:OutputRoot $Script:ToolsDir
$libusbDir = Join-Path $PSScriptRoot "libusb"

# Check if all DLLs are already present; skip download if so.
$allPresent = $true
foreach ($arch in $Script:LibusbArchMap.Keys) {
if (-not (Test-Path (Join-Path (Join-Path $libusbDir $arch) $Script:LibusbLibrary))) {
$allPresent = $false
break
}
}
if ($allPresent) {
Write-Host "[SKIP] libusb DLLs already present in: $libusbDir`n"
return
}

# Download the archive to the current script directory.
$downloadUrl = "https://github.com/libusb/libusb/releases/download/v$($Script:LibusbVersion)/$($Script:LibusbArchive)"
$tempArchive = Join-Path $PSScriptRoot $Script:LibusbArchive

if (-not (Test-Path $driversSource)) {
Write-Error "[ERROR] Drivers directory not found: $driversSource"
Write-Host "[DOWNLOAD] $downloadUrl"
try {
Invoke-WebRequest -Uri $downloadUrl -OutFile $tempArchive
} catch {
Write-Error "[ERROR] Failed to download libusb: $_"
exit 1
}
if (-not (Test-Path $toolsSource)) {
Write-Error "[ERROR] Tools directory not found: $toolsSource"

# Extract to a subdirectory in the current script directory.
$tarExe = Get-Command 'tar.exe' -ErrorAction SilentlyContinue
if (-not $tarExe) {
Write-Error '[ERROR] tar.exe not found. Windows 10 build 17763 or later is required.'
exit 1
}

$extractedRoot = Join-Path $PSScriptRoot ([System.IO.Path]::GetFileNameWithoutExtension($Script:LibusbArchive))
New-Item -ItemType Directory -Path $extractedRoot -Force | Out-Null
try {
Write-Host "[EXTRACT] Extracting $($Script:LibusbArchive)"
& tar.exe -xf $tempArchive -C $extractedRoot
if ($LASTEXITCODE -ne 0) {
Write-Error "[ERROR] Failed to extract $($Script:LibusbArchive) (exit code $LASTEXITCODE)."
exit 1
}

# Copy libusb-1.0.dll for each architecture.
foreach ($arch in $Script:LibusbArchMap.Keys) {
$srcDll = Join-Path $extractedRoot "$($Script:LibusbArchMap[$arch])\dll\$Script:LibusbLibrary"
$destDir = Join-Path $libusbDir $arch
New-Item -ItemType Directory -Path $destDir -Force | Out-Null

if (Test-Path $srcDll) {
Copy-Item -Path $srcDll -Destination $destDir -Force
Write-Host "[COPY] $($Script:LibusbArchMap[$arch])/dll/$($Script:LibusbLibrary) -> libusb/$arch/"
} else {
Write-Warning "[WARNING] DLL not found in archive at expected path: $srcDll"
}
}

Write-Host "[OK] libusb $($Script:LibusbVersion) binaries ready in: $libusbDir`n" -ForegroundColor Green
}
finally {
Remove-Item $tempArchive -Force -ErrorAction SilentlyContinue
Remove-Item $extractedRoot -Recurse -Force -ErrorAction SilentlyContinue
}
}

# Assembles a payload zip from target/drivers and target/tools.
function New-Payload {
Write-Host "========================================"
Write-Host " Packaging Payload"
Write-Host "========================================`n"

# Create a temp staging directory
$stagingDir = Join-Path ([System.IO.Path]::GetTempPath()) ([Guid]::NewGuid().ToString("N"))
New-Item -ItemType Directory -Path $stagingDir -Force | Out-Null

try {
# Copy drivers/ and tools/ into the staging root
Copy-Item -Path $driversSource -Destination $stagingDir -Recurse -Force
Copy-Item -Path $toolsSource -Destination $stagingDir -Recurse -Force
Write-Host "[COPY] $Script:DriversDir, $Script:ToolsDir -> $stagingDir"

# Promote specified tools to staging root and remove from tools/
$destTools = Join-Path $stagingDir $Script:ToolsDir
foreach ($toolFile in $Script:PromotedTools) {
$srcFile = Join-Path $destTools $toolFile
if (Test-Path $srcFile) {
Copy-Item -Path $srcFile -Destination $stagingDir -Force
Remove-Item -Path $srcFile -Force
Write-Host "[PROMOTE] $toolFile -> payload root"
# Copy all payload items into the staging root.
foreach ($item in $Script:PayloadItems) {
if ($item.Arch) {
$archSource = Join-Path $PSScriptRoot "$($item.Path)\$($item.Arch)"
$destDir = Join-Path $stagingDir $item.Path
if (-not (Test-Path $archSource)) {
Write-Warning "[WARNING] $($item.Path) arch folder not found: $archSource"
continue
}
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
Copy-Item -Path $archSource -Destination $destDir -Recurse -Force
Write-Host "[COPY] $($item.Path)/$($item.Arch) -> staging"
continue
}

$src = Join-Path $Script:OutputRoot $item.Path
if (Test-Path $src) {
Copy-Item -Path $src -Destination $stagingDir -Recurse -Force
Write-Host "[COPY] $($item.Path) -> staging"
} else {
Write-Warning "[WARNING] Promoted tool not found in Tools: $toolFile"
Write-Warning "[WARNING] Payload item not found: $src"
continue
}

if ($item.Promote) {
foreach ($fileName in $item.Promote) {
$srcFile = Join-Path (Join-Path $stagingDir $item.Path) $fileName
if (Test-Path $srcFile) {
Copy-Item -Path $srcFile -Destination $stagingDir -Force
Remove-Item -Path $srcFile -Force
Write-Host "[PROMOTE] $($item.Path)/$fileName -> payload root"
} else {
Write-Warning "[WARNING] Promoted file not found: $($item.Path)/$fileName"
}
}
}
}

Expand Down Expand Up @@ -85,6 +185,9 @@ function New-Payload {
# Main Logic
# ==============================================================================

# --- Fetch libusb binaries ---
Get-LibusbBinaries

# --- Build payload ---
$PayloadFullPath = (Resolve-Path (New-Payload)).Path

Expand Down
4 changes: 2 additions & 2 deletions src/windows/build/build_installer.bat
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ for %%A in (x86 x64 arm64) do (
powershell -ExecutionPolicy Bypass -File "%SCRIPT_DIR%build_tools.ps1" -Platform %%A
if !ERRORLEVEL! neq 0 exit /b !ERRORLEVEL!

REM Build installer with arch-specific output name
powershell -ExecutionPolicy Bypass -File "%SCRIPT_DIR%build-installer.ps1" -OutputName "qcom_usb_userspace_drivers_%%A.exe"
REM Build installer with arch-specific output name and architecture
powershell -ExecutionPolicy Bypass -File "%SCRIPT_DIR%build-installer.ps1" -OutputName "qcom_usb_userspace_drivers_%%A.exe" -Arch %%A
if !ERRORLEVEL! neq 0 exit /b !ERRORLEVEL!

REM Sign the installer
Expand Down
Loading