Build Avalonia.MacOS.ps1 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. param (
  2. [Parameter()]
  3. [string]$Platform,
  4. [Parameter()]
  5. [string]$outputPath,
  6. [Parameter()]
  7. [string]$appVersion
  8. )
  9. # Define the core project path relative to the script's location
  10. $coreProjectPath = Join-Path -Path $PSScriptRoot -ChildPath "..\src\PicView.Core\PicView.Core.csproj"
  11. # Load the .csproj file as XML
  12. [xml]$coreCsproj = Get-Content $coreProjectPath
  13. # Define the package reference to replace
  14. $packageRefX64 = "Magick.NET-Q8-x64"
  15. $packageRefArm64 = "Magick.NET-Q8-arm64"
  16. # Find the Magick.NET package reference and update it based on the platform
  17. $packageNodes = $coreCsproj.Project.ItemGroup.PackageReference | Where-Object { $_.Include -eq $packageRefX64 -or $_.Include -eq $packageRefArm64 }
  18. if ($packageNodes) {
  19. foreach ($packageNode in $packageNodes) {
  20. if ($Platform -eq "arm64") {
  21. $packageNode.Include = $packageRefArm64
  22. } else {
  23. $packageNode.Include = $packageRefX64
  24. }
  25. }
  26. }
  27. # Save the updated .csproj file
  28. $coreCsproj.Save($coreProjectPath)
  29. # Define the project path for the actual build target
  30. $avaloniaProjectPath = Join-Path -Path $PSScriptRoot -ChildPath "../src/PicView.Avalonia.MacOS/PicView.Avalonia.MacOS.csproj"
  31. # Create temporary build output directory
  32. $tempBuildPath = Join-Path -Path $outputPath -ChildPath "temp"
  33. New-Item -ItemType Directory -Force -Path $tempBuildPath
  34. # Run dotnet publish for the Avalonia project
  35. dotnet publish $avaloniaProjectPath `
  36. --runtime "osx-$Platform" `
  37. --self-contained true `
  38. --configuration Release `
  39. -p:PublishSingleFile=false `
  40. --output $tempBuildPath
  41. # Create .app bundle structure
  42. $appBundlePath = Join-Path -Path $outputPath -ChildPath "PicView.app"
  43. $contentsPath = Join-Path -Path $appBundlePath -ChildPath "Contents"
  44. $macOSPath = Join-Path -Path $contentsPath -ChildPath "MacOS"
  45. $resourcesPath = Join-Path -Path $contentsPath -ChildPath "Resources"
  46. # Create directory structure
  47. New-Item -ItemType Directory -Force -Path $macOSPath
  48. New-Item -ItemType Directory -Force -Path $resourcesPath
  49. # Create Info.plist
  50. $infoPlistPath = Join-Path -Path $contentsPath -ChildPath "Info.plist" # Add this line to specify the correct path
  51. $infoPlistContent = @"
  52. <?xml version="1.0" encoding="UTF-8"?>
  53. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  54. <plist version="1.0">
  55. <dict>
  56. <key>CFBundleName</key>
  57. <string>PicView</string>
  58. <key>CFBundleDisplayName</key>
  59. <string>PicView</string>
  60. <key>CFBundleIdentifier</key>
  61. <string>ruben2776.picview</string>
  62. <key>CFBundleVersion</key>
  63. <string>${appVersion}</string>
  64. <key>CFBundlePackageType</key>
  65. <string>APPL</string>
  66. <key>CFBundleSignature</key>
  67. <string>????</string>
  68. <key>CFBundleExecutable</key>
  69. <string>PicView</string>
  70. <key>CFBundleIconFile</key>
  71. <string>AppIcon.icns</string>
  72. <key>CFBundleShortVersionString</key>
  73. <string>${appVersion}</string>
  74. <key>LSMinimumSystemVersion</key>
  75. <string>10.15</string>
  76. <key>NSHighResolutionCapable</key>
  77. <true/>
  78. <key>LSArchitecturePriority</key>
  79. <array>
  80. <string>$Platform</string>
  81. </array>
  82. <key>CFBundleSupportedPlatforms</key>
  83. <array>
  84. <string>MacOSX</string>
  85. </array>
  86. <key>NSRequiresAquaSystemAppearance</key>
  87. <false/>
  88. <key>LSApplicationCategoryType</key>
  89. <string>public.app-category.graphics-design</string>
  90. </dict>
  91. </plist>
  92. "@
  93. # Save Info.plist with UTF-8 encoding without BOM
  94. $utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $false
  95. [System.IO.File]::WriteAllText($infoPlistPath, $infoPlistContent, $utf8NoBomEncoding)
  96. # Copy build output to MacOS directory
  97. Copy-Item -Path "$tempBuildPath/*" -Destination $macOSPath -Recurse
  98. # Copy icon if it exists
  99. $iconSource = Join-Path -Path $PSScriptRoot -ChildPath "../src/PicView.Avalonia.MacOS/Assets/AppIcon.icns"
  100. if (Test-Path $iconSource) {
  101. Copy-Item -Path $iconSource -Destination $resourcesPath
  102. }
  103. # Find and ensure Magick.Native is properly copied
  104. $magickNativeFile = if ($Platform -eq "arm64") { "Magick.Native-Q8-arm64.dylib" } else { "Magick.Native-Q8-x64.dylib" }
  105. # Check for Magick.Native in the temp build output
  106. $magickNativePath = Get-ChildItem -Path $tempBuildPath -Filter $magickNativeFile -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
  107. # If found in temp build path, make sure it's copied to MacOS folder and check permissions
  108. if ($magickNativePath) {
  109. Write-Host "Found Magick.Native at $magickNativePath, ensuring it's in MacOS directory"
  110. Copy-Item -Path $magickNativePath -Destination $macOSPath -Force
  111. } else {
  112. # Try to find it elsewhere in the repository
  113. $magickNativePath = Get-ChildItem -Path $PSScriptRoot -Filter $magickNativeFile -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
  114. if ($magickNativePath) {
  115. Write-Host "Found Magick.Native at $magickNativePath, copying to MacOS directory"
  116. Copy-Item -Path $magickNativePath -Destination $macOSPath -Force
  117. } else {
  118. Write-Warning "Could not find $magickNativeFile anywhere! App may not function correctly."
  119. # Last resort: try NuGet cache
  120. $nugetCachePath = if ($env:HOME) { Join-Path $env:HOME ".nuget" } else { Join-Path $env:USERPROFILE ".nuget" }
  121. if (Test-Path $nugetCachePath) {
  122. $magickNativePaths = Get-ChildItem -Path $nugetCachePath -Filter $magickNativeFile -Recurse -ErrorAction SilentlyContinue
  123. if ($magickNativePaths) {
  124. $latestMagickNative = $magickNativePaths | Sort-Object LastWriteTime -Descending | Select-Object -First 1
  125. Write-Host "Found Magick.Native in NuGet cache at $($latestMagickNative.FullName), copying to MacOS directory"
  126. Copy-Item -Path $latestMagickNative.FullName -Destination $macOSPath -Force
  127. }
  128. }
  129. }
  130. }
  131. # After copying, verify the file exists in the MacOS directory
  132. if (Test-Path (Join-Path $macOSPath $magickNativeFile)) {
  133. Write-Host "$magickNativeFile successfully copied to MacOS directory"
  134. } else {
  135. Write-Warning "$magickNativeFile not found in MacOS directory after copy attempt"
  136. }
  137. # Remove PDB files
  138. Get-ChildItem -Path $macOSPath -Filter "*.pdb" -Recurse | Remove-Item -Force
  139. # Remove temporary build directory
  140. Remove-Item -Path $tempBuildPath -Recurse -Force
  141. # Set proper permissions for the entire .app bundle
  142. if ($IsLinux -or $IsMacOS) {
  143. # Set executable permissions on all binaries and dylibs
  144. Get-ChildItem -Path $macOSPath -Recurse | ForEach-Object {
  145. if ($_.Extension -in @('.dylib', '') -or $_.Name -eq 'PicView.Avalonia.MacOS') {
  146. chmod +x $_.FullName
  147. }
  148. }
  149. # Specifically check for Magick.Native and ensure it's executable
  150. $magickNativeInMacOS = Join-Path -Path $macOSPath -ChildPath $magickNativeFile
  151. if (Test-Path $magickNativeInMacOS) {
  152. Write-Host "Setting executable permission on $magickNativeInMacOS"
  153. chmod +x $magickNativeInMacOS
  154. }
  155. # Set proper ownership and permissions for the entire .app bundle
  156. chmod -R 755 $appBundlePath
  157. }