aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-22 11:35:16 +0000
committer_ov4 <ov4@ov4.org>2026-10-22 11:35:16 +0000
commit2f033fe5c922cc7d1ca1b619dc665cbc21341983 (patch)
treec6d5eafaf4eaa7881f60a00427a1fb60e3332d43
parent0ee55887474146f7a8b679db65ff12c2e9b61815 (diff)
build: package and invoke install.cmd instead of install.ps1
The Windows ZIP now ships install.cmd, rewritten to CRLF by configure_file so the package is right on any build host. The CMake install target runs it through "cmd /d /c call", and install.cmd replaces install.ps1 in the version input paths. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--.github/workflows/nightly-build.yml2
-rw-r--r--cmake/CompilerPaths.txt2
-rw-r--r--cmake/Install.cmake.in11
-rw-r--r--cmake/Release.cmake12
-rw-r--r--install.ps1160
5 files changed, 16 insertions, 171 deletions
diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml
index 70e8d41..b2af0b9 100644
--- a/.github/workflows/nightly-build.yml
+++ b/.github/workflows/nightly-build.yml
@@ -401,7 +401,7 @@ jobs:
$smokeDir = Join-Path $env:RUNNER_TEMP 'cpsc-smoke'
Expand-Archive -LiteralPath $packages[0].FullName -DestinationPath $smokeDir
$packageDir = Join-Path $smokeDir $packages[0].BaseName
- foreach ($file in @('cpsc.exe', 'install.ps1', 'LICENSE', 'doc/cpsc.html', 'doc/language/cpsc-language-overview.html')) {
+ foreach ($file in @('cpsc.exe', 'install.cmd', 'LICENSE', 'doc/cpsc.html', 'doc/language/cpsc-language-overview.html')) {
if (-not (Test-Path -LiteralPath (Join-Path $packageDir $file) -PathType Leaf)) {
throw "Missing package file: $file"
}
diff --git a/cmake/CompilerPaths.txt b/cmake/CompilerPaths.txt
index 42beb57..18ab18d 100644
--- a/cmake/CompilerPaths.txt
+++ b/cmake/CompilerPaths.txt
@@ -7,6 +7,6 @@ tests
tools
CMakeLists.txt
install.sh
-install.ps1
+install.cmd
LICENSE
.github
diff --git a/cmake/Install.cmake.in b/cmake/Install.cmake.in
index c6cd83f..7ee27a5 100644
--- a/cmake/Install.cmake.in
+++ b/cmake/Install.cmake.in
@@ -11,12 +11,13 @@ endif()
set(cpsc_install_windows "@WIN32@")
if(cpsc_install_windows)
- cpsc_find_dependency(PROGRAM cpsc_powershell NAMES powershell.exe REQUIRED)
+ cpsc_find_dependency(PROGRAM cpsc_cmd NAMES cmd.exe REQUIRED)
+ file(TO_NATIVE_PATH "@CMAKE_CURRENT_SOURCE_DIR@/install.cmd" cpsc_installer)
+ # An explicit "call" keeps cmd's handling of the quoted script path the same on CMake 3.x and 4.x.
execute_process(
- COMMAND "${cpsc_powershell}" -NoProfile -NonInteractive -ExecutionPolicy Bypass
- -File "@CMAKE_CURRENT_SOURCE_DIR@/install.ps1"
- -SourceDir "@CMAKE_CURRENT_BINARY_DIR@"
- -Prefix "${CMAKE_INSTALL_PREFIX}"
+ COMMAND "${cpsc_cmd}" /d /c call "${cpsc_installer}"
+ --source-dir "@CMAKE_CURRENT_BINARY_DIR@"
+ --prefix "${CMAKE_INSTALL_PREFIX}"
RESULT_VARIABLE cpsc_install_result
)
else()
diff --git a/cmake/Release.cmake b/cmake/Release.cmake
index c825f74..c1ab9be 100644
--- a/cmake/Release.cmake
+++ b/cmake/Release.cmake
@@ -23,7 +23,6 @@ set(cpsc_package_dir "${CPSC_BINARY_DIR}/release/${cpsc_package_name}")
if(CPSC_WINDOWS)
set(cpsc_archive "${CPSC_BINARY_DIR}/${cpsc_package_name}.zip")
set(cpsc_binary_name cpsc.exe)
- set(cpsc_installer install.ps1)
set(cpsc_manual cpsc.html)
set(cpsc_language_extension html)
set(cpsc_tar_flags cf)
@@ -31,7 +30,6 @@ if(CPSC_WINDOWS)
else()
set(cpsc_archive "${CPSC_BINARY_DIR}/${cpsc_package_name}.tar.xz")
set(cpsc_binary_name cpsc)
- set(cpsc_installer install.sh)
set(cpsc_manual cpsc.1)
set(cpsc_language_extension 7)
set(cpsc_tar_flags cJf)
@@ -41,8 +39,14 @@ endif()
file(REMOVE_RECURSE "${cpsc_package_dir}")
file(MAKE_DIRECTORY "${cpsc_package_dir}/doc")
configure_file("${CPSC_EXECUTABLE}" "${cpsc_package_dir}/${cpsc_binary_name}" COPYONLY)
-file(COPY "${CPSC_SOURCE_DIR}/${cpsc_installer}" "${CPSC_SOURCE_DIR}/LICENSE"
- DESTINATION "${cpsc_package_dir}")
+file(COPY "${CPSC_SOURCE_DIR}/LICENSE" DESTINATION "${cpsc_package_dir}")
+if(CPSC_WINDOWS)
+ # cmd needs CRLF line endings whatever the packaging host is; install.cmd contains no @NAME@ sequences.
+ configure_file("${CPSC_SOURCE_DIR}/install.cmd" "${cpsc_package_dir}/install.cmd"
+ @ONLY NEWLINE_STYLE CRLF)
+else()
+ file(COPY "${CPSC_SOURCE_DIR}/install.sh" DESTINATION "${cpsc_package_dir}")
+endif()
file(COPY "${CPSC_BINARY_DIR}/doc/${cpsc_manual}" DESTINATION "${cpsc_package_dir}/doc")
# Package the current source set, preserving categories and ignoring stale outputs.
file(GLOB_RECURSE cpsc_language_sources "${CPSC_SOURCE_DIR}/doc/language/cpsc-*.7.md")
diff --git a/install.ps1 b/install.ps1
deleted file mode 100644
index e09efb3..0000000
--- a/install.ps1
+++ /dev/null
@@ -1,160 +0,0 @@
-#requires -Version 5.1
-<#
-.SYNOPSIS
-Installs cpsc and its HTML manual for the current user.
-.DESCRIPTION
-Copies cpsc.exe, doc\cpsc.html and doc\language HTML pages, creates a help shortcut, and
-adds the installation directory to the user PATH. No administrator is needed
-for the default location: %LOCALAPPDATA%\Programs\cpsc.
-.EXAMPLE
-.\install.ps1 -SourceDir .\build
-.EXAMPLE
-.\install.ps1 -Prefix 'D:\My Programs\cpsc'
-#>
-[CmdletBinding()]
-param(
- [ValidateNotNullOrEmpty()]
- [string]$Prefix,
- [ValidateNotNullOrEmpty()]
- [string]$SourceDir = $PSScriptRoot,
- [switch]$Help
-)
-
-Set-StrictMode -Version 2.0
-$ErrorActionPreference = 'Stop'
-
-if ($Help) {
- Write-Output 'Usage: install.ps1 [-Prefix DIR] [-SourceDir DIR] [-Help]'
- Write-Output 'Default destination: %LOCALAPPDATA%\Programs\cpsc'
- Write-Output 'Source must contain cpsc.exe, doc\cpsc.html and doc\language HTML pages; default: script directory.'
- return
-}
-
-function Test-PathEntry([string]$PathValue, [string]$Directory) {
- $key = $Directory.Replace('/', '\').TrimEnd('\')
- foreach ($entry in ($PathValue -split ';')) {
- $expanded = [Environment]::ExpandEnvironmentVariables($entry.Trim().Trim('"'))
- if ($expanded.Replace('/', '\').TrimEnd('\') -ieq $key) {
- return $true
- }
- }
- return $false
-}
-
-try {
- if ([Environment]::OSVersion.Platform -ne [PlatformID]::Win32NT) {
- throw 'This installer requires Windows.'
- }
- if (-not [string]::IsNullOrEmpty($env:DESTDIR)) {
- throw 'DESTDIR staging is unsupported on Windows; use -Prefix instead.'
- }
- if (-not $PSBoundParameters.ContainsKey('Prefix')) {
- $localAppData = [Environment]::GetFolderPath('LocalApplicationData')
- if ([string]::IsNullOrWhiteSpace($localAppData)) {
- throw 'Cannot locate the current user application directory; specify -Prefix.'
- }
- $Prefix = Join-Path $localAppData 'Programs\cpsc'
- }
- if ($Prefix -notmatch '^(?:[A-Za-z]:[\\/]|\\\\[^\\]+\\[^\\]+)' -or $Prefix.Contains(';')) {
- throw '-Prefix must be an absolute Windows path without a semicolon.'
- }
- $Prefix = [IO.Path]::GetFullPath($Prefix)
- if (-not (Test-Path -LiteralPath $SourceDir -PathType Container)) {
- throw "Cannot open source directory: $SourceDir"
- }
- $SourceDir = (Resolve-Path -LiteralPath $SourceDir).ProviderPath
- $sourceExe = Join-Path $SourceDir 'cpsc.exe'
- $sourceManual = Join-Path $SourceDir 'doc\cpsc.html'
- foreach ($source in @($sourceExe, $sourceManual)) {
- if (-not (Test-Path -LiteralPath $source -PathType Leaf)) {
- throw "Missing source file: $source; build cpsc and the doc target first."
- }
- }
-
- $sourceLanguageDir = Join-Path $SourceDir 'doc\language'
- if (-not (Test-Path -LiteralPath $sourceLanguageDir -PathType Container)) {
- throw "Missing language manuals: $sourceLanguageDir; build the doc target first."
- }
- $sourceOverview = Join-Path $sourceLanguageDir 'cpsc-language-overview.html'
- if (-not (Test-Path -LiteralPath $sourceOverview -PathType Leaf)) {
- throw "Missing language overview: $sourceOverview; build the doc target first."
- }
- $languageManuals = @(Get-Item -LiteralPath $sourceOverview)
- foreach ($category in @('function', 'keyword')) {
- $categoryDir = Join-Path $sourceLanguageDir $category
- $categoryManuals = @(Get-ChildItem -LiteralPath $categoryDir -Filter "cpsc-$category-*.html" -File)
- if ($categoryManuals.Count -eq 0) {
- throw "Missing language manuals: $categoryDir; build the doc target first."
- }
- $languageManuals += $categoryManuals
- }
- if ($languageManuals.Count -eq 0) {
- throw "Missing language manuals: $sourceLanguageDir; build the doc target first."
- }
-
- $docDir = Join-Path $Prefix 'doc'
- $languageDir = Join-Path $docDir 'language'
- $targetExe = Join-Path $Prefix 'cpsc.exe'
- $targetManual = Join-Path $docDir 'cpsc.html'
- foreach ($directory in @($Prefix, $docDir, $languageDir, (Join-Path $languageDir 'function'), (Join-Path $languageDir 'keyword'))) {
- if ((Test-Path -LiteralPath $directory) -and
- -not (Test-Path -LiteralPath $directory -PathType Container)) {
- throw "Installation directory is occupied by a file: $directory"
- }
- }
- $targetFiles = @($targetExe, $targetManual) + @($languageManuals | ForEach-Object {
- Join-Path $languageDir ($_.FullName.Substring($sourceLanguageDir.Length + 1))
- })
- foreach ($file in $targetFiles) {
- if (Test-Path -LiteralPath $file -PathType Container) {
- throw "Installation file is occupied by a directory: $file"
- }
- }
- $programs = [Environment]::GetFolderPath('Programs')
- if ([string]::IsNullOrWhiteSpace($programs)) {
- throw 'Cannot locate the current user Start Menu.'
- }
- $shortcutDir = Join-Path $programs 'cpsc'
- $userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
- $shell = New-Object -ComObject WScript.Shell
-
- # Directory.CreateDirectory treats paths literally, including spaces and brackets.
- foreach ($category in @('function', 'keyword')) {
- [IO.Directory]::CreateDirectory((Join-Path $languageDir $category)) | Out-Null
- }
- if ($sourceExe -ine $targetExe) {
- Copy-Item -LiteralPath $sourceExe -Destination $targetExe -Force
- }
- if ($sourceManual -ine $targetManual) {
- Copy-Item -LiteralPath $sourceManual -Destination $targetManual -Force
- }
- foreach ($manual in $languageManuals) {
- $destination = Join-Path $languageDir ($manual.FullName.Substring($sourceLanguageDir.Length + 1))
- if ($manual.FullName -ine $destination) {
- Copy-Item -LiteralPath $manual.FullName -Destination $destination -Force
- }
- }
- [IO.Directory]::CreateDirectory($shortcutDir) | Out-Null
- $shortcut = $shell.CreateShortcut((Join-Path $shortcutDir 'cpsc Help.lnk'))
- $shortcut.TargetPath = $targetManual
- $shortcut.WorkingDirectory = $docDir
- $shortcut.Description = 'cpsc command-line manual'
- $shortcut.Save()
-
- # Read only the user PATH; never persist the combined process/system PATH.
- if (-not (Test-PathEntry $userPath $Prefix)) {
- $separator = if ([string]::IsNullOrEmpty($userPath) -or $userPath.EndsWith(';')) { '' } else { ';' }
- [Environment]::SetEnvironmentVariable('Path', "$userPath$separator$Prefix", 'User')
- }
- if (-not (Test-PathEntry $env:PATH $Prefix)) {
- $env:PATH = "$env:PATH;$Prefix"
- }
- Write-Output "Installed $targetExe"
- Write-Output "Installed $targetManual and $($languageManuals.Count) language manuals in $languageDir"
- Write-Output 'Open the manual from Start Menu > cpsc > cpsc Help.'
- Write-Output 'Open a new terminal to use cpsc by name (existing parent terminals keep their old PATH).'
-}
-catch {
- Write-Error "install.ps1: $($_.Exception.Message) Check the destination permissions and supplied paths." -ErrorAction Continue
- exit 1
-}