综合平台编程器项目的远程存储
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

175 lines
7.2 KiB

  1. [CmdletBinding()]
  2. param(
  3. [string]$OutputName = 'integrated_platform-win64',
  4. [string]$ProjectFile = ''
  5. )
  6. Set-StrictMode -Version Latest
  7. $ErrorActionPreference = 'Stop'
  8. $projectRoot = Split-Path -Parent $PSScriptRoot
  9. $qtRoot = if ($env:QTDIR) { $env:QTDIR } else { 'D:\Qt5.15.2\5.15.2\mingw81_64' }
  10. $mingwBin = 'D:\Qt5.15.2\Tools\mingw810_64\bin'
  11. $qmakePath = Join-Path $qtRoot 'bin\qmake.exe'
  12. $makePath = Join-Path $mingwBin 'mingw32-make.exe'
  13. $pluginDirectory = Join-Path $qtRoot 'plugins'
  14. $platformPlugin = Join-Path $pluginDirectory 'platforms\qwindows.dll'
  15. $stylePlugin = Join-Path $pluginDirectory 'styles\qwindowsvistastyle.dll'
  16. $qtProjectFile = Join-Path $projectRoot 'app\integrated_platform.pro'
  17. $runtimeBuildRoot = Join-Path $projectRoot 'build\runtime-export'
  18. $buildDirectory = Join-Path $runtimeBuildRoot ([guid]::NewGuid().ToString('N'))
  19. $executablePath = Join-Path $buildDirectory 'release\integrated_platform.exe'
  20. $packageRoot = Join-Path $projectRoot 'build\package'
  21. foreach ($requiredPath in @($qmakePath, $makePath, $platformPlugin, $stylePlugin, $qtProjectFile)) {
  22. if (-not (Test-Path -LiteralPath $requiredPath)) {
  23. throw "未找到必要文件:$requiredPath"
  24. }
  25. }
  26. if ([string]::IsNullOrWhiteSpace($OutputName) -or
  27. $OutputName -in @('.', '..') -or
  28. $OutputName.IndexOfAny([System.IO.Path]::GetInvalidFileNameChars()) -ge 0 -or
  29. [System.IO.Path]::GetFileName($OutputName) -ne $OutputName) {
  30. throw "输出名称不是有效的 Windows 文件名:$OutputName"
  31. }
  32. if (-not [string]::IsNullOrWhiteSpace($ProjectFile)) {
  33. $resolvedProjectFile = [System.IO.Path]::GetFullPath($ProjectFile)
  34. if (-not (Test-Path -LiteralPath $resolvedProjectFile -PathType Leaf)) {
  35. throw "未找到运行版工程文件:$resolvedProjectFile"
  36. }
  37. }
  38. $packageDirectory = Join-Path $packageRoot $OutputName
  39. $archivePath = Join-Path $packageRoot "$OutputName.zip"
  40. $resolvedProjectRoot = [System.IO.Path]::GetFullPath($projectRoot).TrimEnd('\')
  41. $resolvedPackageRoot = [System.IO.Path]::GetFullPath($packageRoot).TrimEnd('\')
  42. $resolvedPackageDirectory = [System.IO.Path]::GetFullPath($packageDirectory)
  43. if (-not $resolvedPackageRoot.StartsWith("$resolvedProjectRoot\build\", [System.StringComparison]::OrdinalIgnoreCase) -or
  44. [System.IO.Path]::GetDirectoryName($resolvedPackageDirectory) -ne $resolvedPackageRoot) {
  45. throw "打包目录必须是 build\package 的直接子目录:$resolvedPackageDirectory"
  46. }
  47. New-Item -ItemType Directory -Path $buildDirectory -Force | Out-Null
  48. New-Item -ItemType Directory -Path $packageRoot -Force | Out-Null
  49. $runtimeResourceFile = $null
  50. if (-not [string]::IsNullOrWhiteSpace($ProjectFile)) {
  51. $runtimeResourceFile = Join-Path $buildDirectory 'runtime_project.qrc'
  52. $escapedProjectPath = [System.Security.SecurityElement]::Escape($resolvedProjectFile)
  53. @(
  54. '<?xml version="1.0" encoding="UTF-8"?>'
  55. '<RCC><qresource prefix="/">'
  56. "<file alias=`"runtime-project.json`">$escapedProjectPath</file>"
  57. '</qresource></RCC>'
  58. ) | Set-Content -LiteralPath $runtimeResourceFile -Encoding UTF8
  59. $resourceText = Get-Content -LiteralPath $runtimeResourceFile -Raw -Encoding UTF8
  60. if (-not $resourceText.Contains($escapedProjectPath)) {
  61. throw "运行版资源未正确指向工程文件:$resolvedProjectFile"
  62. }
  63. }
  64. $originalPath = $env:Path
  65. $env:Path = "$qtRoot\bin;$mingwBin;$env:Path"
  66. try {
  67. Push-Location $buildDirectory
  68. try {
  69. Write-Host 'RUNTIME_EXPORT_STAGE: qmake'
  70. $qmakeArguments = @($qtProjectFile, 'CONFIG+=release', 'CONFIG-=debug')
  71. if ($null -ne $runtimeResourceFile) {
  72. $qmakeArguments += "RUNTIME_PROJECT_RESOURCE=$($runtimeResourceFile.Replace('\', '/'))"
  73. }
  74. & $qmakePath @qmakeArguments
  75. if ($LASTEXITCODE -ne 0) {
  76. throw "qmake 执行失败,退出码:$LASTEXITCODE"
  77. }
  78. Write-Host 'RUNTIME_EXPORT_STAGE: compile'
  79. & $makePath -j2
  80. if ($LASTEXITCODE -ne 0) {
  81. throw "mingw32-make 执行失败,退出码:$LASTEXITCODE"
  82. }
  83. }
  84. finally {
  85. Pop-Location
  86. }
  87. if (-not (Test-Path -LiteralPath $executablePath)) {
  88. throw "未生成可执行文件:$executablePath"
  89. }
  90. if ($null -ne $runtimeResourceFile) {
  91. $generatedResourceSource = Join-Path $buildDirectory 'release\qrc_runtime_project.cpp'
  92. if (-not (Test-Path -LiteralPath $generatedResourceSource)) {
  93. throw "未生成运行版工程资源:$generatedResourceSource"
  94. }
  95. $generatedResourceText = Get-Content -LiteralPath $generatedResourceSource -Raw -Encoding UTF8
  96. if ($generatedResourceText -notlike '*runtime-project.json*') {
  97. throw '编译结果中缺少 runtime-project.json 资源'
  98. }
  99. }
  100. if (Test-Path -LiteralPath $packageDirectory) {
  101. Remove-Item -LiteralPath $packageDirectory -Recurse -Force
  102. }
  103. if (Test-Path -LiteralPath $archivePath) {
  104. Remove-Item -LiteralPath $archivePath -Force
  105. }
  106. Write-Host 'RUNTIME_EXPORT_STAGE: package'
  107. New-Item -ItemType Directory -Path $packageDirectory | Out-Null
  108. $packagedExecutableName = if ([string]::IsNullOrWhiteSpace($ProjectFile)) {
  109. 'integrated_platform.exe'
  110. } else {
  111. "$OutputName.exe"
  112. }
  113. $packagedExecutable = Join-Path $packageDirectory $packagedExecutableName
  114. Copy-Item -LiteralPath $executablePath -Destination $packagedExecutable
  115. $runtimeFiles = @(
  116. 'Qt5Core.dll', 'Qt5Gui.dll', 'Qt5Network.dll',
  117. 'Qt5SerialBus.dll', 'Qt5SerialPort.dll', 'Qt5Widgets.dll',
  118. 'libgcc_s_seh-1.dll', 'libstdc++-6.dll', 'libwinpthread-1.dll'
  119. )
  120. foreach ($runtimeFile in $runtimeFiles) {
  121. $runtimeSource = Join-Path $(if ($runtimeFile -like 'Qt5*') { "$qtRoot\bin" } else { $mingwBin }) $runtimeFile
  122. if (-not (Test-Path -LiteralPath $runtimeSource)) {
  123. throw "未找到运行库:$runtimeSource"
  124. }
  125. Copy-Item -LiteralPath $runtimeSource -Destination $packageDirectory
  126. }
  127. $packagedPlatformDirectory = Join-Path $packageDirectory 'platforms'
  128. $packagedStyleDirectory = Join-Path $packageDirectory 'styles'
  129. New-Item -ItemType Directory -Path $packagedPlatformDirectory | Out-Null
  130. New-Item -ItemType Directory -Path $packagedStyleDirectory | Out-Null
  131. Copy-Item -LiteralPath $platformPlugin -Destination $packagedPlatformDirectory
  132. Copy-Item -LiteralPath $stylePlugin -Destination $packagedStyleDirectory
  133. Write-Host 'RUNTIME_EXPORT_STAGE: verify'
  134. foreach ($requiredOutput in @(
  135. $packagedExecutable,
  136. (Join-Path $packageDirectory 'Qt5Core.dll'),
  137. (Join-Path $packageDirectory 'Qt5SerialBus.dll'),
  138. (Join-Path $packagedPlatformDirectory 'qwindows.dll')
  139. )) {
  140. if (-not (Test-Path -LiteralPath $requiredOutput)) {
  141. throw "打包结果缺少必要文件:$requiredOutput"
  142. }
  143. }
  144. if ([string]::IsNullOrWhiteSpace($ProjectFile)) {
  145. Compress-Archive -LiteralPath $packageDirectory -DestinationPath $archivePath -CompressionLevel Optimal
  146. }
  147. Write-Host "打包完成"
  148. Write-Host "运行目录:$packageDirectory"
  149. if ([string]::IsNullOrWhiteSpace($ProjectFile)) {
  150. Write-Host "压缩包:$archivePath"
  151. }
  152. }
  153. finally {
  154. $env:Path = $originalPath
  155. }