058f6cd2cc
Now that the llm runner is an executable and not just a dll, more users are facing problems with security policy configurations on windows that prevent users writing to directories and then executing binaries from the same location. This change removes payloads from the main executable on windows and shifts them over to be packaged in the installer and discovered based on the executables location. This also adds a new zip file for people who want to "roll their own" installation model.
167 lines
6.7 KiB
PowerShell
167 lines
6.7 KiB
PowerShell
#!powershell
|
|
#
|
|
# powershell -ExecutionPolicy Bypass -File .\scripts\build_windows.ps1
|
|
#
|
|
# gcloud auth application-default login
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
|
|
function checkEnv() {
|
|
write-host "Locating required tools and paths"
|
|
$script:SRC_DIR=$PWD
|
|
if (!$env:VCToolsRedistDir) {
|
|
$MSVC_INSTALL=(Get-CimInstance MSFT_VSInstance -Namespace root/cimv2/vs)[0].InstallLocation
|
|
$env:VCToolsRedistDir=(get-item "${MSVC_INSTALL}\VC\Redist\MSVC\*")[0]
|
|
}
|
|
# Try to find the CUDA dir
|
|
if ($null -eq $env:NVIDIA_DIR) {
|
|
$d=(get-command -ea 'silentlycontinue' nvcc).path
|
|
if ($d -ne $null) {
|
|
$script:NVIDIA_DIR=($d| split-path -parent)
|
|
} else {
|
|
$cudaList=(get-item "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v*\bin\" -ea 'silentlycontinue')
|
|
if ($cudaList.length > 0) {
|
|
$script:NVIDIA_DIR=$cudaList[0]
|
|
}
|
|
}
|
|
} else {
|
|
$script:NVIDIA_DIR=$env:NVIDIA_DIR
|
|
}
|
|
|
|
$script:INNO_SETUP_DIR=(get-item "C:\Program Files*\Inno Setup*\")[0]
|
|
|
|
$script:DEPS_DIR="${script:SRC_DIR}\dist\windows-amd64"
|
|
$env:CGO_ENABLED="1"
|
|
echo "Checking version"
|
|
if (!$env:VERSION) {
|
|
$data=(git describe --tags --first-parent --abbrev=7 --long --dirty --always)
|
|
$pattern="v(.+)"
|
|
if ($data -match $pattern) {
|
|
$script:VERSION=$matches[1]
|
|
}
|
|
} else {
|
|
$script:VERSION=$env:VERSION
|
|
}
|
|
$pattern = "(\d+[.]\d+[.]\d+).*"
|
|
if ($script:VERSION -match $pattern) {
|
|
$script:PKG_VERSION=$matches[1]
|
|
} else {
|
|
$script:PKG_VERSION="0.0.0"
|
|
}
|
|
write-host "Building Ollama $script:VERSION with package version $script:PKG_VERSION"
|
|
|
|
# Note: Windows Kits 10 signtool crashes with GCP's plugin
|
|
if ($null -eq $env:SIGN_TOOL) {
|
|
${script:SignTool}="C:\Program Files (x86)\Windows Kits\8.1\bin\x64\signtool.exe"
|
|
} else {
|
|
${script:SignTool}=${env:SIGN_TOOL}
|
|
}
|
|
if ("${env:KEY_CONTAINER}") {
|
|
${script:OLLAMA_CERT}=$(resolve-path "${script:SRC_DIR}\ollama_inc.crt")
|
|
Write-host "Code signing enabled"
|
|
} else {
|
|
write-host "Code signing disabled - please set KEY_CONTAINERS to sign and copy ollama_inc.crt to the top of the source tree"
|
|
}
|
|
|
|
}
|
|
|
|
|
|
function buildOllama() {
|
|
write-host "Building ollama CLI"
|
|
if ($null -eq ${env:OLLAMA_SKIP_GENERATE}) {
|
|
& go generate ./...
|
|
if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
|
|
} else {
|
|
write-host "Skipping generate step with OLLAMA_SKIP_GENERATE set"
|
|
}
|
|
& go build -trimpath -ldflags "-s -w -X=github.com/ollama/ollama/version.Version=$script:VERSION -X=github.com/ollama/ollama/server.mode=release" .
|
|
if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
|
|
if ("${env:KEY_CONTAINER}") {
|
|
& "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${script:OLLAMA_CERT}" `
|
|
/csp "Google Cloud KMS Provider" /kc ${env:KEY_CONTAINER} ollama.exe
|
|
if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
|
|
}
|
|
New-Item -ItemType Directory -Path .\dist\windows-amd64\ -Force
|
|
cp .\ollama.exe .\dist\windows-amd64\ollama-windows-amd64.exe
|
|
}
|
|
|
|
function buildApp() {
|
|
write-host "Building Ollama App"
|
|
cd "${script:SRC_DIR}\app"
|
|
& windres -l 0 -o ollama.syso ollama.rc
|
|
& go build -trimpath -ldflags "-s -w -H windowsgui -X=github.com/ollama/ollama/version.Version=$script:VERSION -X=github.com/ollama/ollama/server.mode=release" .
|
|
if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
|
|
if ("${env:KEY_CONTAINER}") {
|
|
& "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${script:OLLAMA_CERT}" `
|
|
/csp "Google Cloud KMS Provider" /kc ${env:KEY_CONTAINER} app.exe
|
|
if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
|
|
}
|
|
}
|
|
|
|
function gatherDependencies() {
|
|
write-host "Gathering runtime dependencies"
|
|
cd "${script:SRC_DIR}"
|
|
md "${script:DEPS_DIR}" -ea 0 > $null
|
|
|
|
# TODO - this varies based on host build system and MSVC version - drive from dumpbin output
|
|
# currently works for Win11 + MSVC 2019 + Cuda V11
|
|
cp "${env:VCToolsRedistDir}\x64\Microsoft.VC*.CRT\msvcp140.dll" "${script:DEPS_DIR}\"
|
|
cp "${env:VCToolsRedistDir}\x64\Microsoft.VC*.CRT\vcruntime140.dll" "${script:DEPS_DIR}\"
|
|
cp "${env:VCToolsRedistDir}\x64\Microsoft.VC*.CRT\vcruntime140_1.dll" "${script:DEPS_DIR}\"
|
|
|
|
cp "${script:NVIDIA_DIR}\cudart64_*.dll" "${script:DEPS_DIR}\"
|
|
cp "${script:NVIDIA_DIR}\cublas64_*.dll" "${script:DEPS_DIR}\"
|
|
cp "${script:NVIDIA_DIR}\cublasLt64_*.dll" "${script:DEPS_DIR}\"
|
|
|
|
cp "${script:SRC_DIR}\app\ollama_welcome.ps1" "${script:SRC_DIR}\dist\"
|
|
if ("${env:KEY_CONTAINER}") {
|
|
write-host "about to sign"
|
|
foreach ($file in (get-childitem "${script:DEPS_DIR}/cu*.dll") + @("${script:SRC_DIR}\dist\ollama_welcome.ps1")){
|
|
write-host "signing $file"
|
|
& "${script:SignTool}" sign /v /fd sha256 /t http://timestamp.digicert.com /f "${script:OLLAMA_CERT}" `
|
|
/csp "Google Cloud KMS Provider" /kc ${env:KEY_CONTAINER} $file
|
|
if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
|
|
}
|
|
}
|
|
if ($null -ne $env:HIP_PATH) {
|
|
# Assumes v5.7, may need adjustments for v6
|
|
rm -ea 0 -recurse -force -path "${script:DEPS_DIR}\rocm\"
|
|
md "${script:DEPS_DIR}\rocm\rocblas\library\" -ea 0 > $null
|
|
cp "${env:HIP_PATH}\bin\hipblas.dll" "${script:DEPS_DIR}\rocm\"
|
|
cp "${env:HIP_PATH}\bin\rocblas.dll" "${script:DEPS_DIR}\rocm\"
|
|
# amdhip64.dll dependency comes from the driver and must be installed on the host to use AMD GPUs
|
|
cp "${env:HIP_PATH}\bin\rocblas\library\*" "${script:DEPS_DIR}\rocm\rocblas\library\"
|
|
}
|
|
}
|
|
|
|
function buildInstaller() {
|
|
write-host "Building Ollama Installer"
|
|
cd "${script:SRC_DIR}\app"
|
|
$env:PKG_VERSION=$script:PKG_VERSION
|
|
if ("${env:KEY_CONTAINER}") {
|
|
& "${script:INNO_SETUP_DIR}\ISCC.exe" /SMySignTool="${script:SignTool} sign /fd sha256 /t http://timestamp.digicert.com /f ${script:OLLAMA_CERT} /csp `$qGoogle Cloud KMS Provider`$q /kc ${env:KEY_CONTAINER} `$f" .\ollama.iss
|
|
} else {
|
|
& "${script:INNO_SETUP_DIR}\ISCC.exe" .\ollama.iss
|
|
}
|
|
if ($LASTEXITCODE -ne 0) { exit($LASTEXITCODE)}
|
|
}
|
|
|
|
function distZip() {
|
|
write-host "Generating stand-alone distribution zip file ${script:SRC_DIR}\dist\ollama-windows-amd64.zip"
|
|
Compress-Archive -Path "${script:SRC_DIR}\dist\windows-amd64\*" -DestinationPath "${script:SRC_DIR}\dist\ollama-windows-amd64.zip" -Force
|
|
}
|
|
|
|
try {
|
|
checkEnv
|
|
buildOllama
|
|
buildApp
|
|
gatherDependencies
|
|
buildInstaller
|
|
distZip
|
|
} catch {
|
|
write-host "Build Failed"
|
|
write-host $_
|
|
} finally {
|
|
set-location $script:SRC_DIR
|
|
$env:PKG_VERSION=""
|
|
}
|