From 6518df71f669d9c85f5066c1735df0a99c1bbcbe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 08:15:13 +0000 Subject: [PATCH 01/20] Initial plan From 5521b703209fc7af542a6adcd6e985a4528258fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 08:30:13 +0000 Subject: [PATCH 02/20] Convert iOS builds from dylibs to frameworks and re-enable device builds Co-authored-by: dellis1972 <810617+dellis1972@users.noreply.github.com> --- build/BuildMacOSTask.cs | 73 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index b6deaa5..5150865 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -1,6 +1,7 @@ using System.Runtime.InteropServices; using System.Collections.Generic; using System; +using System.IO; using Spectre.Console; namespace BuildScripts; @@ -21,8 +22,8 @@ public override void Run(BuildContext context) context.StartProcess("cmake", new ProcessSettings { WorkingDirectory = buildWorkingDir, Arguments = "--build . --config Release" }); var files = Directory.GetFiles(System.IO.Path.Combine(buildWorkingDir), "libopenal.*.*.*.dylib", SearchOption.TopDirectoryOnly); context.CopyFile(files[0], $"{context.ArtifactsDir}/osx/libopenal.dylib"); - // Don't build iphone binary as we cannot use dylibs. - //BuildiOS(context, "arm64", "ios-arm64", releaseDir: "Release-iphoneos"); + // Build iOS device and simulator binaries as frameworks instead of dylibs + BuildiOS(context, "arm64", "ios-arm64", false, "Release-iphoneos"); BuildiOS(context, "x86_64", "iossimulator-x64", true, "Release-iphonesimulator"); BuildiOS(context, "arm64", "iossimulator-arm64", true, "Release-iphonesimulator"); } @@ -39,11 +40,71 @@ void BuildiOS (BuildContext context, string arch, string rid, bool simulator = f //This does not work when used as an argument? $(xcodebuild -version -sdk iphonesimulator Path)"; sdk = $" -DCMAKE_OSX_SYSROOT={output.First()}"; } - context.StartProcess("cmake", new ProcessSettings { WorkingDirectory = buildWorkingDir, Arguments = $"-GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=\"{arch}\" -DALSOFT_REQUIRE_COREAUDIO=ON -DALSOFT_TESTS=OFF -DALSOFT_UTILS=OFF -DALSOFT_EXAMPLES=OFF -DALSOFT_INSTALL=OFF -DCMAKE_BUILD_TYPE=Release{sdk} .." }); + // Build static library instead of dylib for iOS + context.StartProcess("cmake", new ProcessSettings { WorkingDirectory = buildWorkingDir, Arguments = $"-GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=\"{arch}\" -DALSOFT_REQUIRE_COREAUDIO=ON -DALSOFT_TESTS=OFF -DALSOFT_UTILS=OFF -DALSOFT_EXAMPLES=OFF -DALSOFT_INSTALL=OFF -DCMAKE_BUILD_TYPE=Release -DLIBTYPE=STATIC{sdk} .." }); context.StartProcess("cmake", new ProcessSettings { WorkingDirectory = buildWorkingDir, Arguments = $"--build . --config Release" }); - var files = Directory.GetFiles(System.IO.Path.Combine(buildWorkingDir, releaseDir), "libopenal.*.*.*.dylib", SearchOption.TopDirectoryOnly); - //if (files.Length > 0) - context.CopyFile(files[0], $"{context.ArtifactsDir}/{rid}/libopenal.dylib"); + + // Create iOS Framework structure + var frameworkName = "OpenAL"; + var frameworkDir = $"{context.ArtifactsDir}/{rid}/{frameworkName}.framework"; + context.CreateDirectory(frameworkDir); + context.CreateDirectory($"{frameworkDir}/Headers"); + + // Find and copy the static library + var staticLibFiles = Directory.GetFiles(System.IO.Path.Combine(buildWorkingDir, releaseDir), "libopenal.a", SearchOption.TopDirectoryOnly); + if (staticLibFiles.Length > 0) + { + context.CopyFile(staticLibFiles[0], $"{frameworkDir}/{frameworkName}"); + } + + // Copy headers + var headerSourceDir = "openal-soft/include/AL"; + var headerFiles = Directory.GetFiles(headerSourceDir, "*.h", SearchOption.TopDirectoryOnly); + foreach (var headerFile in headerFiles) + { + var fileName = System.IO.Path.GetFileName(headerFile); + context.CopyFile(headerFile, $"{frameworkDir}/Headers/{fileName}"); + } + + // Create Info.plist for the framework + CreateFrameworkInfoPlist(context, frameworkDir, frameworkName, arch); + } + + void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string frameworkName, string arch) + { + var infoPlistContent = $@" + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + {frameworkName} + CFBundleIdentifier + org.monogame.{frameworkName.ToLower()} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + {frameworkName} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + CFBundleSupportedPlatforms + + iPhoneOS + iPhoneSimulator + + MinimumOSVersion + 9.0 + +"; + + File.WriteAllText(System.IO.Path.Combine(frameworkDir, "Info.plist"), infoPlistContent); } void BuildAndroid (BuildContext context, string arch, string rid, string minNdk) From 7b3897b003da8a267e6ae90b310a90ab7fc5ee94 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 08:51:47 +0000 Subject: [PATCH 03/20] Fix iOS framework Info.plist: change bundle ID to net.monogame and make platform support accurate Co-authored-by: dellis1972 <810617+dellis1972@users.noreply.github.com> --- build/BuildMacOSTask.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index 5150865..abe69de 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -67,11 +67,14 @@ void BuildiOS (BuildContext context, string arch, string rid, bool simulator = f } // Create Info.plist for the framework - CreateFrameworkInfoPlist(context, frameworkDir, frameworkName, arch); + CreateFrameworkInfoPlist(context, frameworkDir, frameworkName, simulator); } - void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string frameworkName, string arch) + void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string frameworkName, bool isSimulator) { + // Determine the correct supported platforms based on whether this is a simulator build + var supportedPlatforms = isSimulator ? " iPhoneSimulator" : " iPhoneOS"; + var infoPlistContent = $@" @@ -81,7 +84,7 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string CFBundleExecutable {frameworkName} CFBundleIdentifier - org.monogame.{frameworkName.ToLower()} + net.monogame.{frameworkName.ToLower()} CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -96,8 +99,7 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string 1 CFBundleSupportedPlatforms - iPhoneOS - iPhoneSimulator +{supportedPlatforms} MinimumOSVersion 9.0 From f0e7d3e79056eea17be2bf7ec96f0af1f0d20c35 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 11:46:17 +0000 Subject: [PATCH 04/20] Add universal iOS framework creation using lipo to merge all architectures Co-authored-by: dellis1972 <810617+dellis1972@users.noreply.github.com> --- build/BuildMacOSTask.cs | 87 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index abe69de..cf52b85 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -26,6 +26,9 @@ public override void Run(BuildContext context) BuildiOS(context, "arm64", "ios-arm64", false, "Release-iphoneos"); BuildiOS(context, "x86_64", "iossimulator-x64", true, "Release-iphonesimulator"); BuildiOS(context, "arm64", "iossimulator-arm64", true, "Release-iphonesimulator"); + + // Create universal iOS framework combining all architectures + CreateUniversaliOSFramework(context); } void BuildiOS (BuildContext context, string arch, string rid, bool simulator = false, string releaseDir = "") @@ -109,6 +112,90 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string File.WriteAllText(System.IO.Path.Combine(frameworkDir, "Info.plist"), infoPlistContent); } + void CreateUniversaliOSFramework(BuildContext context) + { + var frameworkName = "OpenAL"; + var universalFrameworkDir = $"{context.ArtifactsDir}/ios/{frameworkName}.framework"; + context.CreateDirectory(universalFrameworkDir); + context.CreateDirectory($"{universalFrameworkDir}/Headers"); + + // Collect all static libraries from individual architecture builds + var staticLibPaths = new List(); + var architectures = new[] { "ios-arm64", "iossimulator-x64", "iossimulator-arm64" }; + + foreach (var arch in architectures) + { + var archFrameworkDir = $"{context.ArtifactsDir}/{arch}/{frameworkName}.framework"; + var staticLibPath = $"{archFrameworkDir}/{frameworkName}"; + if (File.Exists(staticLibPath)) + { + staticLibPaths.Add(staticLibPath); + } + } + + if (staticLibPaths.Count > 0) + { + // Use lipo to create universal binary + var universalBinaryPath = $"{universalFrameworkDir}/{frameworkName}"; + var lipoArgs = $"-create {string.Join(" ", staticLibPaths)} -output {universalBinaryPath}"; + context.StartProcess("lipo", new ProcessSettings { Arguments = lipoArgs }); + + // Copy headers from any of the individual frameworks (they're all the same) + var sourceHeadersDir = $"{context.ArtifactsDir}/ios-arm64/{frameworkName}.framework/Headers"; + if (Directory.Exists(sourceHeadersDir)) + { + var headerFiles = Directory.GetFiles(sourceHeadersDir, "*.h", SearchOption.TopDirectoryOnly); + foreach (var headerFile in headerFiles) + { + var fileName = System.IO.Path.GetFileName(headerFile); + context.CopyFile(headerFile, $"{universalFrameworkDir}/Headers/{fileName}"); + } + } + + // Create Info.plist supporting both device and simulator platforms + CreateUniversalFrameworkInfoPlist(context, universalFrameworkDir, frameworkName); + + AnsiConsole.MarkupLine($"[green]Created universal iOS framework at: {universalFrameworkDir}[/]"); + } + } + + void CreateUniversalFrameworkInfoPlist(BuildContext context, string frameworkDir, string frameworkName) + { + var infoPlistContent = $@" + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + {frameworkName} + CFBundleIdentifier + net.monogame.{frameworkName.ToLower()} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + {frameworkName} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + CFBundleSupportedPlatforms + + iPhoneOS + iPhoneSimulator + + MinimumOSVersion + 9.0 + +"; + + File.WriteAllText(System.IO.Path.Combine(frameworkDir, "Info.plist"), infoPlistContent); + } + void BuildAndroid (BuildContext context, string arch, string rid, string minNdk) { var ndk = System.Environment.GetEnvironmentVariable ("ANDROID_NDK_HOME"); From 8c944ad5d0ef2f961f7ed49e11ecca5472d3f625 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 13:08:15 +0000 Subject: [PATCH 05/20] Fix lipo architecture conflict between ios-arm64 and iossimulator-arm64 Co-authored-by: dellis1972 <810617+dellis1972@users.noreply.github.com> --- build/BuildMacOSTask.cs | 95 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 7 deletions(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index cf52b85..00d13d1 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System; using System.IO; +using System.Linq; using Spectre.Console; namespace BuildScripts; @@ -119,8 +120,8 @@ void CreateUniversaliOSFramework(BuildContext context) context.CreateDirectory(universalFrameworkDir); context.CreateDirectory($"{universalFrameworkDir}/Headers"); - // Collect all static libraries from individual architecture builds - var staticLibPaths = new List(); + // Collect all static libraries from individual architecture builds with their info + var libraryInfo = new List<(string path, string rid, string[] archs)>(); var architectures = new[] { "ios-arm64", "iossimulator-x64", "iossimulator-arm64" }; foreach (var arch in architectures) @@ -129,16 +130,92 @@ void CreateUniversaliOSFramework(BuildContext context) var staticLibPath = $"{archFrameworkDir}/{frameworkName}"; if (File.Exists(staticLibPath)) { - staticLibPaths.Add(staticLibPath); + // Get architecture info using lipo -info + IEnumerable lipoOutput; + var lipoInfoResult = context.StartProcess("lipo", + new ProcessSettings { + Arguments = $"-info {staticLibPath}", + RedirectStandardOutput = true + }, out lipoOutput); + + if (lipoInfoResult == 0) + { + var lipoInfo = string.Join(" ", lipoOutput); + // Parse architecture from lipo output like "Non-fat file: path is architecture: arm64" + var archParts = lipoInfo.Split(':'); + if (archParts.Length >= 2) + { + var detectedArch = archParts[archParts.Length - 1].Trim(); + libraryInfo.Add((staticLibPath, arch, new[] { detectedArch })); + AnsiConsole.MarkupLine($"[yellow]Detected architecture {detectedArch} for {arch}[/]"); + } + } + else + { + AnsiConsole.MarkupLine($"[red]Failed to get architecture info for {staticLibPath}[/]"); + } + } + } + + // Resolve architecture conflicts - prioritize device builds over simulators for duplicate architectures + var finalLibraries = new List(); + var usedArchitectures = new HashSet(); + + // First pass: add device libraries (ios-*) + foreach (var (path, rid, archs) in libraryInfo.Where(x => x.rid.StartsWith("ios-"))) + { + var hasConflict = archs.Any(arch => usedArchitectures.Contains(arch)); + if (!hasConflict) + { + finalLibraries.Add(path); + foreach (var arch in archs) + { + usedArchitectures.Add(arch); + } + AnsiConsole.MarkupLine($"[green]Including {rid} with architectures: {string.Join(", ", archs)}[/]"); + } + else + { + AnsiConsole.MarkupLine($"[yellow]Skipping {rid} due to architecture conflict with: {string.Join(", ", archs.Where(usedArchitectures.Contains))}[/]"); + } + } + + // Second pass: add simulator libraries (iossimulator-*) that don't conflict + foreach (var (path, rid, archs) in libraryInfo.Where(x => x.rid.StartsWith("iossimulator-"))) + { + var hasConflict = archs.Any(arch => usedArchitectures.Contains(arch)); + if (!hasConflict) + { + finalLibraries.Add(path); + foreach (var arch in archs) + { + usedArchitectures.Add(arch); + } + AnsiConsole.MarkupLine($"[green]Including {rid} with architectures: {string.Join(", ", archs)}[/]"); + } + else + { + AnsiConsole.MarkupLine($"[yellow]Skipping {rid} due to architecture conflict with: {string.Join(", ", archs.Where(usedArchitectures.Contains))}[/]"); } } - if (staticLibPaths.Count > 0) + if (finalLibraries.Count > 0) { - // Use lipo to create universal binary var universalBinaryPath = $"{universalFrameworkDir}/{frameworkName}"; - var lipoArgs = $"-create {string.Join(" ", staticLibPaths)} -output {universalBinaryPath}"; - context.StartProcess("lipo", new ProcessSettings { Arguments = lipoArgs }); + + if (finalLibraries.Count == 1) + { + // Only one library, just copy it + context.CopyFile(finalLibraries[0], universalBinaryPath); + AnsiConsole.MarkupLine($"[yellow]Created single-architecture iOS framework (only one compatible library found)[/]"); + } + else + { + // Use lipo to create universal binary from non-conflicting libraries + var lipoArgs = $"-create {string.Join(" ", finalLibraries)} -output {universalBinaryPath}"; + context.StartProcess("lipo", new ProcessSettings { Arguments = lipoArgs }); + AnsiConsole.MarkupLine($"[green]Created universal iOS framework with {finalLibraries.Count} architectures[/]"); + } // Copy headers from any of the individual frameworks (they're all the same) var sourceHeadersDir = $"{context.ArtifactsDir}/ios-arm64/{frameworkName}.framework/Headers"; @@ -157,6 +234,10 @@ void CreateUniversaliOSFramework(BuildContext context) AnsiConsole.MarkupLine($"[green]Created universal iOS framework at: {universalFrameworkDir}[/]"); } + else + { + AnsiConsole.MarkupLine($"[red]No compatible libraries found for universal framework creation[/]"); + } } void CreateUniversalFrameworkInfoPlist(BuildContext context, string frameworkDir, string frameworkName) From e202ed7bdbbcfdce690e66ce3b274a191972544a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 13:36:18 +0000 Subject: [PATCH 06/20] Replace lipo-based universal framework with XCFramework creation Co-authored-by: dellis1972 <810617+dellis1972@users.noreply.github.com> --- build/BuildMacOSTask.cs | 173 +++++++++------------------------------- 1 file changed, 38 insertions(+), 135 deletions(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index 00d13d1..21e9c0a 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -28,8 +28,8 @@ public override void Run(BuildContext context) BuildiOS(context, "x86_64", "iossimulator-x64", true, "Release-iphonesimulator"); BuildiOS(context, "arm64", "iossimulator-arm64", true, "Release-iphonesimulator"); - // Create universal iOS framework combining all architectures - CreateUniversaliOSFramework(context); + // Create universal iOS XCFramework combining all architectures + CreateiOSXCFramework(context); } void BuildiOS (BuildContext context, string arch, string rid, bool simulator = false, string releaseDir = "") @@ -113,169 +113,72 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string File.WriteAllText(System.IO.Path.Combine(frameworkDir, "Info.plist"), infoPlistContent); } - void CreateUniversaliOSFramework(BuildContext context) + void CreateiOSXCFramework(BuildContext context) { var frameworkName = "OpenAL"; - var universalFrameworkDir = $"{context.ArtifactsDir}/ios/{frameworkName}.framework"; - context.CreateDirectory(universalFrameworkDir); - context.CreateDirectory($"{universalFrameworkDir}/Headers"); + var xcframeworkPath = $"{context.ArtifactsDir}/ios/{frameworkName}.xcframework"; - // Collect all static libraries from individual architecture builds with their info - var libraryInfo = new List<(string path, string rid, string[] archs)>(); - var architectures = new[] { "ios-arm64", "iossimulator-x64", "iossimulator-arm64" }; - - foreach (var arch in architectures) + // Remove any existing XCFramework + if (Directory.Exists(xcframeworkPath)) { - var archFrameworkDir = $"{context.ArtifactsDir}/{arch}/{frameworkName}.framework"; - var staticLibPath = $"{archFrameworkDir}/{frameworkName}"; - if (File.Exists(staticLibPath)) - { - // Get architecture info using lipo -info - IEnumerable lipoOutput; - var lipoInfoResult = context.StartProcess("lipo", - new ProcessSettings { - Arguments = $"-info {staticLibPath}", - RedirectStandardOutput = true - }, out lipoOutput); - - if (lipoInfoResult == 0) - { - var lipoInfo = string.Join(" ", lipoOutput); - // Parse architecture from lipo output like "Non-fat file: path is architecture: arm64" - var archParts = lipoInfo.Split(':'); - if (archParts.Length >= 2) - { - var detectedArch = archParts[archParts.Length - 1].Trim(); - libraryInfo.Add((staticLibPath, arch, new[] { detectedArch })); - AnsiConsole.MarkupLine($"[yellow]Detected architecture {detectedArch} for {arch}[/]"); - } - } - else - { - AnsiConsole.MarkupLine($"[red]Failed to get architecture info for {staticLibPath}[/]"); - } - } + Directory.Delete(xcframeworkPath, true); } - // Resolve architecture conflicts - prioritize device builds over simulators for duplicate architectures - var finalLibraries = new List(); - var usedArchitectures = new HashSet(); + // Collect all framework paths from individual architecture builds + var frameworkPaths = new List(); + var architectures = new[] { "ios-arm64", "iossimulator-x64", "iossimulator-arm64" }; - // First pass: add device libraries (ios-*) - foreach (var (path, rid, archs) in libraryInfo.Where(x => x.rid.StartsWith("ios-"))) + foreach (var arch in architectures) { - var hasConflict = archs.Any(arch => usedArchitectures.Contains(arch)); - if (!hasConflict) + var archFrameworkDir = $"{context.ArtifactsDir}/{arch}/{frameworkName}.framework"; + if (Directory.Exists(archFrameworkDir) && File.Exists($"{archFrameworkDir}/{frameworkName}")) { - finalLibraries.Add(path); - foreach (var arch in archs) - { - usedArchitectures.Add(arch); - } - AnsiConsole.MarkupLine($"[green]Including {rid} with architectures: {string.Join(", ", archs)}[/]"); + frameworkPaths.Add(archFrameworkDir); + AnsiConsole.MarkupLine($"[green]Found framework for {arch} at {archFrameworkDir}[/]"); } else { - AnsiConsole.MarkupLine($"[yellow]Skipping {rid} due to architecture conflict with: {string.Join(", ", archs.Where(usedArchitectures.Contains))}[/]"); + AnsiConsole.MarkupLine($"[yellow]Framework not found for {arch} at {archFrameworkDir}[/]"); } } - // Second pass: add simulator libraries (iossimulator-*) that don't conflict - foreach (var (path, rid, archs) in libraryInfo.Where(x => x.rid.StartsWith("iossimulator-"))) + if (frameworkPaths.Count > 0) { - var hasConflict = archs.Any(arch => usedArchitectures.Contains(arch)); - if (!hasConflict) - { - finalLibraries.Add(path); - foreach (var arch in archs) - { - usedArchitectures.Add(arch); - } - AnsiConsole.MarkupLine($"[green]Including {rid} with architectures: {string.Join(", ", archs)}[/]"); - } - else + // Build xcodebuild command to create XCFramework + var xcframeworkArgs = new List { "-create-xcframework" }; + + foreach (var frameworkPath in frameworkPaths) { - AnsiConsole.MarkupLine($"[yellow]Skipping {rid} due to architecture conflict with: {string.Join(", ", archs.Where(usedArchitectures.Contains))}[/]"); + xcframeworkArgs.Add("-framework"); + xcframeworkArgs.Add(frameworkPath); } - } - - if (finalLibraries.Count > 0) - { - var universalBinaryPath = $"{universalFrameworkDir}/{frameworkName}"; - if (finalLibraries.Count == 1) + xcframeworkArgs.Add("-output"); + xcframeworkArgs.Add(xcframeworkPath); + + var arguments = string.Join(" ", xcframeworkArgs.Select(arg => arg.Contains(" ") ? $"\"{arg}\"" : arg)); + + AnsiConsole.MarkupLine($"[blue]Creating XCFramework with command: xcodebuild {arguments}[/]"); + + var result = context.StartProcess("xcodebuild", new ProcessSettings { Arguments = arguments }); + + if (result == 0) { - // Only one library, just copy it - context.CopyFile(finalLibraries[0], universalBinaryPath); - AnsiConsole.MarkupLine($"[yellow]Created single-architecture iOS framework (only one compatible library found)[/]"); + AnsiConsole.MarkupLine($"[green]Successfully created XCFramework at: {xcframeworkPath}[/]"); + AnsiConsole.MarkupLine($"[green]XCFramework contains {frameworkPaths.Count} platform-specific frameworks[/]"); } else { - // Use lipo to create universal binary from non-conflicting libraries - var lipoArgs = $"-create {string.Join(" ", finalLibraries)} -output {universalBinaryPath}"; - context.StartProcess("lipo", new ProcessSettings { Arguments = lipoArgs }); - AnsiConsole.MarkupLine($"[green]Created universal iOS framework with {finalLibraries.Count} architectures[/]"); - } - - // Copy headers from any of the individual frameworks (they're all the same) - var sourceHeadersDir = $"{context.ArtifactsDir}/ios-arm64/{frameworkName}.framework/Headers"; - if (Directory.Exists(sourceHeadersDir)) - { - var headerFiles = Directory.GetFiles(sourceHeadersDir, "*.h", SearchOption.TopDirectoryOnly); - foreach (var headerFile in headerFiles) - { - var fileName = System.IO.Path.GetFileName(headerFile); - context.CopyFile(headerFile, $"{universalFrameworkDir}/Headers/{fileName}"); - } + AnsiConsole.MarkupLine($"[red]Failed to create XCFramework. Exit code: {result}[/]"); } - - // Create Info.plist supporting both device and simulator platforms - CreateUniversalFrameworkInfoPlist(context, universalFrameworkDir, frameworkName); - - AnsiConsole.MarkupLine($"[green]Created universal iOS framework at: {universalFrameworkDir}[/]"); } else { - AnsiConsole.MarkupLine($"[red]No compatible libraries found for universal framework creation[/]"); + AnsiConsole.MarkupLine($"[red]No framework paths found for XCFramework creation[/]"); } } - void CreateUniversalFrameworkInfoPlist(BuildContext context, string frameworkDir, string frameworkName) - { - var infoPlistContent = $@" - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - {frameworkName} - CFBundleIdentifier - net.monogame.{frameworkName.ToLower()} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - {frameworkName} - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - CFBundleSupportedPlatforms - - iPhoneOS - iPhoneSimulator - - MinimumOSVersion - 9.0 - -"; - - File.WriteAllText(System.IO.Path.Combine(frameworkDir, "Info.plist"), infoPlistContent); - } + void BuildAndroid (BuildContext context, string arch, string rid, string minNdk) { From b3dc35c6f95d64b3cb0389f327d79dfca072a8e7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 15:34:39 +0000 Subject: [PATCH 07/20] Combine x86_64 and arm64 simulator frameworks using lipo before XCFramework creation Co-authored-by: dellis1972 <810617+dellis1972@users.noreply.github.com> --- build/BuildMacOSTask.cs | 94 +++++++++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 13 deletions(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index 21e9c0a..9289bd6 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -113,6 +113,67 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string File.WriteAllText(System.IO.Path.Combine(frameworkDir, "Info.plist"), infoPlistContent); } + string? CreateCombinedSimulatorFramework(BuildContext context, string frameworkName) + { + var x64SimulatorFramework = $"{context.ArtifactsDir}/iossimulator-x64/{frameworkName}.framework"; + var arm64SimulatorFramework = $"{context.ArtifactsDir}/iossimulator-arm64/{frameworkName}.framework"; + var combinedSimulatorFramework = $"{context.ArtifactsDir}/iossimulator-combined/{frameworkName}.framework"; + + // Check if both simulator frameworks exist + if (!Directory.Exists(x64SimulatorFramework) || !File.Exists($"{x64SimulatorFramework}/{frameworkName}")) + { + AnsiConsole.MarkupLine($"[yellow]x86_64 simulator framework not found at {x64SimulatorFramework}[/]"); + return null; + } + + if (!Directory.Exists(arm64SimulatorFramework) || !File.Exists($"{arm64SimulatorFramework}/{frameworkName}")) + { + AnsiConsole.MarkupLine($"[yellow]arm64 simulator framework not found at {arm64SimulatorFramework}[/]"); + return null; + } + + // Create combined simulator framework directory + context.CreateDirectory($"{context.ArtifactsDir}/iossimulator-combined/"); + + if (Directory.Exists(combinedSimulatorFramework)) + { + Directory.Delete(combinedSimulatorFramework, true); + } + + context.CreateDirectory(combinedSimulatorFramework); + context.CreateDirectory($"{combinedSimulatorFramework}/Headers"); + + // Use lipo to combine the x86_64 and arm64 simulator binaries + var x64Binary = $"{x64SimulatorFramework}/{frameworkName}"; + var arm64Binary = $"{arm64SimulatorFramework}/{frameworkName}"; + var combinedBinary = $"{combinedSimulatorFramework}/{frameworkName}"; + + AnsiConsole.MarkupLine($"[blue]Combining simulator binaries using lipo...[/]"); + var lipoArgs = $"-create \"{x64Binary}\" \"{arm64Binary}\" -output \"{combinedBinary}\""; + var result = context.StartProcess("lipo", new ProcessSettings { Arguments = lipoArgs }); + + if (result != 0) + { + AnsiConsole.MarkupLine($"[red]Failed to combine simulator binaries with lipo. Exit code: {result}[/]"); + return null; + } + + // Copy headers from one of the simulator frameworks (they should be identical) + var headerSourceDir = $"{x64SimulatorFramework}/Headers"; + var headerFiles = Directory.GetFiles(headerSourceDir, "*.h", SearchOption.TopDirectoryOnly); + foreach (var headerFile in headerFiles) + { + var fileName = System.IO.Path.GetFileName(headerFile); + context.CopyFile(headerFile, $"{combinedSimulatorFramework}/Headers/{fileName}"); + } + + // Create Info.plist for the combined simulator framework + CreateFrameworkInfoPlist(context, combinedSimulatorFramework, frameworkName, true); + + AnsiConsole.MarkupLine($"[green]Successfully created combined simulator framework at: {combinedSimulatorFramework}[/]"); + return combinedSimulatorFramework; + } + void CreateiOSXCFramework(BuildContext context) { var frameworkName = "OpenAL"; @@ -124,22 +185,29 @@ void CreateiOSXCFramework(BuildContext context) Directory.Delete(xcframeworkPath, true); } - // Collect all framework paths from individual architecture builds + // Create combined simulator framework by merging x86_64 and arm64 simulator binaries using lipo + var combinedSimulatorFrameworkPath = CreateCombinedSimulatorFramework(context, frameworkName); + + // Collect framework paths - device and combined simulator var frameworkPaths = new List(); - var architectures = new[] { "ios-arm64", "iossimulator-x64", "iossimulator-arm64" }; - foreach (var arch in architectures) + // Add device framework + var deviceFrameworkDir = $"{context.ArtifactsDir}/ios-arm64/{frameworkName}.framework"; + if (Directory.Exists(deviceFrameworkDir) && File.Exists($"{deviceFrameworkDir}/{frameworkName}")) { - var archFrameworkDir = $"{context.ArtifactsDir}/{arch}/{frameworkName}.framework"; - if (Directory.Exists(archFrameworkDir) && File.Exists($"{archFrameworkDir}/{frameworkName}")) - { - frameworkPaths.Add(archFrameworkDir); - AnsiConsole.MarkupLine($"[green]Found framework for {arch} at {archFrameworkDir}[/]"); - } - else - { - AnsiConsole.MarkupLine($"[yellow]Framework not found for {arch} at {archFrameworkDir}[/]"); - } + frameworkPaths.Add(deviceFrameworkDir); + AnsiConsole.MarkupLine($"[green]Found device framework at {deviceFrameworkDir}[/]"); + } + else + { + AnsiConsole.MarkupLine($"[yellow]Device framework not found at {deviceFrameworkDir}[/]"); + } + + // Add combined simulator framework + if (!string.IsNullOrEmpty(combinedSimulatorFrameworkPath)) + { + frameworkPaths.Add(combinedSimulatorFrameworkPath); + AnsiConsole.MarkupLine($"[green]Found combined simulator framework at {combinedSimulatorFrameworkPath}[/]"); } if (frameworkPaths.Count > 0) From e4719164acdd82f665e50b4360a87cfae912f11d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 15:54:44 +0000 Subject: [PATCH 08/20] Change combined simulator framework directory name to ios-arm64_x86_64-simulator Co-authored-by: dellis1972 <810617+dellis1972@users.noreply.github.com> --- build/BuildMacOSTask.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index 9289bd6..dd04440 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -117,7 +117,7 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string { var x64SimulatorFramework = $"{context.ArtifactsDir}/iossimulator-x64/{frameworkName}.framework"; var arm64SimulatorFramework = $"{context.ArtifactsDir}/iossimulator-arm64/{frameworkName}.framework"; - var combinedSimulatorFramework = $"{context.ArtifactsDir}/iossimulator-combined/{frameworkName}.framework"; + var combinedSimulatorFramework = $"{context.ArtifactsDir}/ios-arm64_x86_64-simulator/{frameworkName}.framework"; // Check if both simulator frameworks exist if (!Directory.Exists(x64SimulatorFramework) || !File.Exists($"{x64SimulatorFramework}/{frameworkName}")) @@ -133,7 +133,7 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string } // Create combined simulator framework directory - context.CreateDirectory($"{context.ArtifactsDir}/iossimulator-combined/"); + context.CreateDirectory($"{context.ArtifactsDir}/ios-arm64_x86_64-simulator/"); if (Directory.Exists(combinedSimulatorFramework)) { From d49aded917b7f096e185fbbf3743a24c2c390be6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 24 Jul 2025 16:01:53 +0000 Subject: [PATCH 09/20] Change combined simulator framework directory name to iossimulator Co-authored-by: dellis1972 <810617+dellis1972@users.noreply.github.com> --- build/BuildMacOSTask.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index dd04440..5b3b6d2 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -117,7 +117,7 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string { var x64SimulatorFramework = $"{context.ArtifactsDir}/iossimulator-x64/{frameworkName}.framework"; var arm64SimulatorFramework = $"{context.ArtifactsDir}/iossimulator-arm64/{frameworkName}.framework"; - var combinedSimulatorFramework = $"{context.ArtifactsDir}/ios-arm64_x86_64-simulator/{frameworkName}.framework"; + var combinedSimulatorFramework = $"{context.ArtifactsDir}/iossimulator/{frameworkName}.framework"; // Check if both simulator frameworks exist if (!Directory.Exists(x64SimulatorFramework) || !File.Exists($"{x64SimulatorFramework}/{frameworkName}")) @@ -133,7 +133,7 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string } // Create combined simulator framework directory - context.CreateDirectory($"{context.ArtifactsDir}/ios-arm64_x86_64-simulator/"); + context.CreateDirectory($"{context.ArtifactsDir}/iossimulator/"); if (Directory.Exists(combinedSimulatorFramework)) { From 3c1f4fad5a809b420074ad109d414c7cbac5751d Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 25 Jul 2025 18:41:50 +0100 Subject: [PATCH 10/20] TRy these scripts --- buildscripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildscripts b/buildscripts index 5cd1ee3..a2b3dd3 160000 --- a/buildscripts +++ b/buildscripts @@ -1 +1 @@ -Subproject commit 5cd1ee39dfa0e570b125260d4d19753232c1c29e +Subproject commit a2b3dd33654aed0ba8ecaaf69e07f008912c446b From 951a6c379a299b4d9c96f5971fddcb53032c0f67 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 25 Jul 2025 19:30:08 +0100 Subject: [PATCH 11/20] Don't upload the individual ios frameworks --- build/BuildMacOSTask.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index 5b3b6d2..1859c64 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -35,8 +35,10 @@ public override void Run(BuildContext context) void BuildiOS (BuildContext context, string arch, string rid, bool simulator = false, string releaseDir = "") { var buildWorkingDir = $"openal-soft/build_{rid}"; + var tempArtifactsDir = $"artifacts"; context.CreateDirectory(buildWorkingDir); - context.CreateDirectory($"{context.ArtifactsDir}/{rid}/"); + context.CreateDirectory(tempArtifactsDir); + context.CreateDirectory($"{tempArtifactsDir}/{rid}/"); var sdk = ""; if (simulator) { IEnumerable output; @@ -50,7 +52,7 @@ void BuildiOS (BuildContext context, string arch, string rid, bool simulator = f // Create iOS Framework structure var frameworkName = "OpenAL"; - var frameworkDir = $"{context.ArtifactsDir}/{rid}/{frameworkName}.framework"; + var frameworkDir = $"{tempArtifactsDir}/{rid}/{frameworkName}.framework"; context.CreateDirectory(frameworkDir); context.CreateDirectory($"{frameworkDir}/Headers"); @@ -115,10 +117,11 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string string? CreateCombinedSimulatorFramework(BuildContext context, string frameworkName) { - var x64SimulatorFramework = $"{context.ArtifactsDir}/iossimulator-x64/{frameworkName}.framework"; - var arm64SimulatorFramework = $"{context.ArtifactsDir}/iossimulator-arm64/{frameworkName}.framework"; - var combinedSimulatorFramework = $"{context.ArtifactsDir}/iossimulator/{frameworkName}.framework"; - + var tempArtifactsDir = $"artifacts"; + var x64SimulatorFramework = $"{tempArtifactsDir}/iossimulator-x64/{frameworkName}.framework"; + var arm64SimulatorFramework = $"{tempArtifactsDir}/iossimulator-arm64/{frameworkName}.framework"; + var combinedSimulatorFramework = $"{tempArtifactsDir}/iossimulator/{frameworkName}.framework"; + // Check if both simulator frameworks exist if (!Directory.Exists(x64SimulatorFramework) || !File.Exists($"{x64SimulatorFramework}/{frameworkName}")) { @@ -133,7 +136,7 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string } // Create combined simulator framework directory - context.CreateDirectory($"{context.ArtifactsDir}/iossimulator/"); + context.CreateDirectory($"{tempArtifactsDir}/iossimulator/"); if (Directory.Exists(combinedSimulatorFramework)) { From 1e4c20c5d7ae67f9a0283347ac77103e395e02b1 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 25 Jul 2025 19:41:21 +0100 Subject: [PATCH 12/20] Use a temp folder --- build/BuildMacOSTask.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index 1859c64..241dbbc 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -35,7 +35,7 @@ public override void Run(BuildContext context) void BuildiOS (BuildContext context, string arch, string rid, bool simulator = false, string releaseDir = "") { var buildWorkingDir = $"openal-soft/build_{rid}"; - var tempArtifactsDir = $"artifacts"; + var tempArtifactsDir = $"temp_artifacts"; context.CreateDirectory(buildWorkingDir); context.CreateDirectory(tempArtifactsDir); context.CreateDirectory($"{tempArtifactsDir}/{rid}/"); @@ -117,7 +117,7 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string string? CreateCombinedSimulatorFramework(BuildContext context, string frameworkName) { - var tempArtifactsDir = $"artifacts"; + var tempArtifactsDir = $"temp_artifacts"; var x64SimulatorFramework = $"{tempArtifactsDir}/iossimulator-x64/{frameworkName}.framework"; var arm64SimulatorFramework = $"{tempArtifactsDir}/iossimulator-arm64/{frameworkName}.framework"; var combinedSimulatorFramework = $"{tempArtifactsDir}/iossimulator/{frameworkName}.framework"; From 5ae3c3bc9e7e4e761e32851d6be231cae62715c7 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 25 Jul 2025 20:29:51 +0100 Subject: [PATCH 13/20] try this --- .github/workflows/main.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5c33ceb..bae4289 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -49,7 +49,6 @@ jobs: packages: write contents: write needs: [ build ] - if: ${{ github.event_name == 'push' }} steps: - name: Expose GitHub Runtime uses: crazy-max/ghaction-github-runtime@v3 @@ -74,4 +73,3 @@ jobs: removeArtifacts: true artifacts: "bin/Release/*.nupkg" token: ${{ secrets.GITHUB_TOKEN }} - if: github.ref_type == 'tag' From aaa3ad820650de946cf58cf6bdc58181327319d4 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 25 Jul 2025 21:56:52 +0100 Subject: [PATCH 14/20] Bump build scripts --- buildscripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildscripts b/buildscripts index a2b3dd3..60b9d46 160000 --- a/buildscripts +++ b/buildscripts @@ -1 +1 @@ -Subproject commit a2b3dd33654aed0ba8ecaaf69e07f008912c446b +Subproject commit 60b9d46d698e225929d2a08c7e118e3141139f87 From 6dcc0cfda89fde203aa785495b2bc86d9df7c3df Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 25 Jul 2025 22:28:05 +0100 Subject: [PATCH 15/20] ff --- buildscripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildscripts b/buildscripts index 60b9d46..9de36a3 160000 --- a/buildscripts +++ b/buildscripts @@ -1 +1 @@ -Subproject commit 60b9d46d698e225929d2a08c7e118e3141139f87 +Subproject commit 9de36a3e9b06c710b0fcfc032c81dfa164d594e5 From e859accb60b3d3ca2c0f5f8bec06b84c85d8f426 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Fri, 25 Jul 2025 22:47:10 +0100 Subject: [PATCH 16/20] Fix missing ios-arm64 --- build/BuildMacOSTask.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index 241dbbc..e50cf0e 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -179,6 +179,7 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string void CreateiOSXCFramework(BuildContext context) { + var tempArtifactsDir = $"temp_artifacts"; var frameworkName = "OpenAL"; var xcframeworkPath = $"{context.ArtifactsDir}/ios/{frameworkName}.xcframework"; @@ -195,7 +196,7 @@ void CreateiOSXCFramework(BuildContext context) var frameworkPaths = new List(); // Add device framework - var deviceFrameworkDir = $"{context.ArtifactsDir}/ios-arm64/{frameworkName}.framework"; + var deviceFrameworkDir = $"{tempArtifactsDir}/ios-arm64/{frameworkName}.framework"; if (Directory.Exists(deviceFrameworkDir) && File.Exists($"{deviceFrameworkDir}/{frameworkName}")) { frameworkPaths.Add(deviceFrameworkDir); From 46fa8d812d00db90d124e54029dec0407fbab474 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 25 Jul 2025 22:25:55 +0000 Subject: [PATCH 17/20] Add LICENSE and README files to iOS frameworks Co-authored-by: dellis1972 <810617+dellis1972@users.noreply.github.com> --- build/BuildMacOSTask.cs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index e50cf0e..a9ad2e2 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -72,6 +72,20 @@ void BuildiOS (BuildContext context, string arch, string rid, bool simulator = f context.CopyFile(headerFile, $"{frameworkDir}/Headers/{fileName}"); } + // Copy LICENSE file (rename LICENSE-pffft to LICENSE) + var licenseSourcePath = "openal-soft/LICENSE-pffft"; + if (File.Exists(licenseSourcePath)) + { + context.CopyFile(licenseSourcePath, $"{frameworkDir}/LICENSE"); + } + + // Copy README file + var readmeSourcePath = "openal-soft/README.md"; + if (File.Exists(readmeSourcePath)) + { + context.CopyFile(readmeSourcePath, $"{frameworkDir}/README"); + } + // Create Info.plist for the framework CreateFrameworkInfoPlist(context, frameworkDir, frameworkName, simulator); } @@ -170,6 +184,19 @@ void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string context.CopyFile(headerFile, $"{combinedSimulatorFramework}/Headers/{fileName}"); } + // Copy LICENSE and README files from the x64 simulator framework (they should be identical across frameworks) + var licenseSourcePath = $"{x64SimulatorFramework}/LICENSE"; + if (File.Exists(licenseSourcePath)) + { + context.CopyFile(licenseSourcePath, $"{combinedSimulatorFramework}/LICENSE"); + } + + var readmeSourcePath = $"{x64SimulatorFramework}/README"; + if (File.Exists(readmeSourcePath)) + { + context.CopyFile(readmeSourcePath, $"{combinedSimulatorFramework}/README"); + } + // Create Info.plist for the combined simulator framework CreateFrameworkInfoPlist(context, combinedSimulatorFramework, frameworkName, true); From a6adec6482cc3857e739283fa4bbcbb91a4a8590 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 30 Jul 2025 18:42:48 +0000 Subject: [PATCH 18/20] Remove framework/XCFramework code, place iOS static libraries directly in artifacts Co-authored-by: dellis1972 <810617+dellis1972@users.noreply.github.com> --- build/BuildMacOSTask.cs | 236 +--------------------------------------- 1 file changed, 5 insertions(+), 231 deletions(-) diff --git a/build/BuildMacOSTask.cs b/build/BuildMacOSTask.cs index a9ad2e2..bd6c63e 100644 --- a/build/BuildMacOSTask.cs +++ b/build/BuildMacOSTask.cs @@ -23,22 +23,17 @@ public override void Run(BuildContext context) context.StartProcess("cmake", new ProcessSettings { WorkingDirectory = buildWorkingDir, Arguments = "--build . --config Release" }); var files = Directory.GetFiles(System.IO.Path.Combine(buildWorkingDir), "libopenal.*.*.*.dylib", SearchOption.TopDirectoryOnly); context.CopyFile(files[0], $"{context.ArtifactsDir}/osx/libopenal.dylib"); - // Build iOS device and simulator binaries as frameworks instead of dylibs + // Build iOS device and simulator static libraries BuildiOS(context, "arm64", "ios-arm64", false, "Release-iphoneos"); BuildiOS(context, "x86_64", "iossimulator-x64", true, "Release-iphonesimulator"); BuildiOS(context, "arm64", "iossimulator-arm64", true, "Release-iphonesimulator"); - - // Create universal iOS XCFramework combining all architectures - CreateiOSXCFramework(context); } void BuildiOS (BuildContext context, string arch, string rid, bool simulator = false, string releaseDir = "") { var buildWorkingDir = $"openal-soft/build_{rid}"; - var tempArtifactsDir = $"temp_artifacts"; context.CreateDirectory(buildWorkingDir); - context.CreateDirectory(tempArtifactsDir); - context.CreateDirectory($"{tempArtifactsDir}/{rid}/"); + context.CreateDirectory($"{context.ArtifactsDir}/{rid}/"); var sdk = ""; if (simulator) { IEnumerable output; @@ -46,239 +41,18 @@ void BuildiOS (BuildContext context, string arch, string rid, bool simulator = f //This does not work when used as an argument? $(xcodebuild -version -sdk iphonesimulator Path)"; sdk = $" -DCMAKE_OSX_SYSROOT={output.First()}"; } - // Build static library instead of dylib for iOS + // Build static library for iOS context.StartProcess("cmake", new ProcessSettings { WorkingDirectory = buildWorkingDir, Arguments = $"-GXcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=\"{arch}\" -DALSOFT_REQUIRE_COREAUDIO=ON -DALSOFT_TESTS=OFF -DALSOFT_UTILS=OFF -DALSOFT_EXAMPLES=OFF -DALSOFT_INSTALL=OFF -DCMAKE_BUILD_TYPE=Release -DLIBTYPE=STATIC{sdk} .." }); context.StartProcess("cmake", new ProcessSettings { WorkingDirectory = buildWorkingDir, Arguments = $"--build . --config Release" }); - // Create iOS Framework structure - var frameworkName = "OpenAL"; - var frameworkDir = $"{tempArtifactsDir}/{rid}/{frameworkName}.framework"; - context.CreateDirectory(frameworkDir); - context.CreateDirectory($"{frameworkDir}/Headers"); - - // Find and copy the static library + // Find and copy the static library to artifacts var staticLibFiles = Directory.GetFiles(System.IO.Path.Combine(buildWorkingDir, releaseDir), "libopenal.a", SearchOption.TopDirectoryOnly); if (staticLibFiles.Length > 0) { - context.CopyFile(staticLibFiles[0], $"{frameworkDir}/{frameworkName}"); - } - - // Copy headers - var headerSourceDir = "openal-soft/include/AL"; - var headerFiles = Directory.GetFiles(headerSourceDir, "*.h", SearchOption.TopDirectoryOnly); - foreach (var headerFile in headerFiles) - { - var fileName = System.IO.Path.GetFileName(headerFile); - context.CopyFile(headerFile, $"{frameworkDir}/Headers/{fileName}"); - } - - // Copy LICENSE file (rename LICENSE-pffft to LICENSE) - var licenseSourcePath = "openal-soft/LICENSE-pffft"; - if (File.Exists(licenseSourcePath)) - { - context.CopyFile(licenseSourcePath, $"{frameworkDir}/LICENSE"); - } - - // Copy README file - var readmeSourcePath = "openal-soft/README.md"; - if (File.Exists(readmeSourcePath)) - { - context.CopyFile(readmeSourcePath, $"{frameworkDir}/README"); - } - - // Create Info.plist for the framework - CreateFrameworkInfoPlist(context, frameworkDir, frameworkName, simulator); - } - - void CreateFrameworkInfoPlist(BuildContext context, string frameworkDir, string frameworkName, bool isSimulator) - { - // Determine the correct supported platforms based on whether this is a simulator build - var supportedPlatforms = isSimulator ? " iPhoneSimulator" : " iPhoneOS"; - - var infoPlistContent = $@" - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - {frameworkName} - CFBundleIdentifier - net.monogame.{frameworkName.ToLower()} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - {frameworkName} - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - CFBundleSupportedPlatforms - -{supportedPlatforms} - - MinimumOSVersion - 9.0 - -"; - - File.WriteAllText(System.IO.Path.Combine(frameworkDir, "Info.plist"), infoPlistContent); - } - - string? CreateCombinedSimulatorFramework(BuildContext context, string frameworkName) - { - var tempArtifactsDir = $"temp_artifacts"; - var x64SimulatorFramework = $"{tempArtifactsDir}/iossimulator-x64/{frameworkName}.framework"; - var arm64SimulatorFramework = $"{tempArtifactsDir}/iossimulator-arm64/{frameworkName}.framework"; - var combinedSimulatorFramework = $"{tempArtifactsDir}/iossimulator/{frameworkName}.framework"; - - // Check if both simulator frameworks exist - if (!Directory.Exists(x64SimulatorFramework) || !File.Exists($"{x64SimulatorFramework}/{frameworkName}")) - { - AnsiConsole.MarkupLine($"[yellow]x86_64 simulator framework not found at {x64SimulatorFramework}[/]"); - return null; - } - - if (!Directory.Exists(arm64SimulatorFramework) || !File.Exists($"{arm64SimulatorFramework}/{frameworkName}")) - { - AnsiConsole.MarkupLine($"[yellow]arm64 simulator framework not found at {arm64SimulatorFramework}[/]"); - return null; - } - - // Create combined simulator framework directory - context.CreateDirectory($"{tempArtifactsDir}/iossimulator/"); - - if (Directory.Exists(combinedSimulatorFramework)) - { - Directory.Delete(combinedSimulatorFramework, true); - } - - context.CreateDirectory(combinedSimulatorFramework); - context.CreateDirectory($"{combinedSimulatorFramework}/Headers"); - - // Use lipo to combine the x86_64 and arm64 simulator binaries - var x64Binary = $"{x64SimulatorFramework}/{frameworkName}"; - var arm64Binary = $"{arm64SimulatorFramework}/{frameworkName}"; - var combinedBinary = $"{combinedSimulatorFramework}/{frameworkName}"; - - AnsiConsole.MarkupLine($"[blue]Combining simulator binaries using lipo...[/]"); - var lipoArgs = $"-create \"{x64Binary}\" \"{arm64Binary}\" -output \"{combinedBinary}\""; - var result = context.StartProcess("lipo", new ProcessSettings { Arguments = lipoArgs }); - - if (result != 0) - { - AnsiConsole.MarkupLine($"[red]Failed to combine simulator binaries with lipo. Exit code: {result}[/]"); - return null; - } - - // Copy headers from one of the simulator frameworks (they should be identical) - var headerSourceDir = $"{x64SimulatorFramework}/Headers"; - var headerFiles = Directory.GetFiles(headerSourceDir, "*.h", SearchOption.TopDirectoryOnly); - foreach (var headerFile in headerFiles) - { - var fileName = System.IO.Path.GetFileName(headerFile); - context.CopyFile(headerFile, $"{combinedSimulatorFramework}/Headers/{fileName}"); - } - - // Copy LICENSE and README files from the x64 simulator framework (they should be identical across frameworks) - var licenseSourcePath = $"{x64SimulatorFramework}/LICENSE"; - if (File.Exists(licenseSourcePath)) - { - context.CopyFile(licenseSourcePath, $"{combinedSimulatorFramework}/LICENSE"); - } - - var readmeSourcePath = $"{x64SimulatorFramework}/README"; - if (File.Exists(readmeSourcePath)) - { - context.CopyFile(readmeSourcePath, $"{combinedSimulatorFramework}/README"); + context.CopyFile(staticLibFiles[0], $"{context.ArtifactsDir}/{rid}/libopenal.a"); } - - // Create Info.plist for the combined simulator framework - CreateFrameworkInfoPlist(context, combinedSimulatorFramework, frameworkName, true); - - AnsiConsole.MarkupLine($"[green]Successfully created combined simulator framework at: {combinedSimulatorFramework}[/]"); - return combinedSimulatorFramework; } - void CreateiOSXCFramework(BuildContext context) - { - var tempArtifactsDir = $"temp_artifacts"; - var frameworkName = "OpenAL"; - var xcframeworkPath = $"{context.ArtifactsDir}/ios/{frameworkName}.xcframework"; - - // Remove any existing XCFramework - if (Directory.Exists(xcframeworkPath)) - { - Directory.Delete(xcframeworkPath, true); - } - - // Create combined simulator framework by merging x86_64 and arm64 simulator binaries using lipo - var combinedSimulatorFrameworkPath = CreateCombinedSimulatorFramework(context, frameworkName); - - // Collect framework paths - device and combined simulator - var frameworkPaths = new List(); - - // Add device framework - var deviceFrameworkDir = $"{tempArtifactsDir}/ios-arm64/{frameworkName}.framework"; - if (Directory.Exists(deviceFrameworkDir) && File.Exists($"{deviceFrameworkDir}/{frameworkName}")) - { - frameworkPaths.Add(deviceFrameworkDir); - AnsiConsole.MarkupLine($"[green]Found device framework at {deviceFrameworkDir}[/]"); - } - else - { - AnsiConsole.MarkupLine($"[yellow]Device framework not found at {deviceFrameworkDir}[/]"); - } - - // Add combined simulator framework - if (!string.IsNullOrEmpty(combinedSimulatorFrameworkPath)) - { - frameworkPaths.Add(combinedSimulatorFrameworkPath); - AnsiConsole.MarkupLine($"[green]Found combined simulator framework at {combinedSimulatorFrameworkPath}[/]"); - } - - if (frameworkPaths.Count > 0) - { - // Build xcodebuild command to create XCFramework - var xcframeworkArgs = new List { "-create-xcframework" }; - - foreach (var frameworkPath in frameworkPaths) - { - xcframeworkArgs.Add("-framework"); - xcframeworkArgs.Add(frameworkPath); - } - - xcframeworkArgs.Add("-output"); - xcframeworkArgs.Add(xcframeworkPath); - - var arguments = string.Join(" ", xcframeworkArgs.Select(arg => arg.Contains(" ") ? $"\"{arg}\"" : arg)); - - AnsiConsole.MarkupLine($"[blue]Creating XCFramework with command: xcodebuild {arguments}[/]"); - - var result = context.StartProcess("xcodebuild", new ProcessSettings { Arguments = arguments }); - - if (result == 0) - { - AnsiConsole.MarkupLine($"[green]Successfully created XCFramework at: {xcframeworkPath}[/]"); - AnsiConsole.MarkupLine($"[green]XCFramework contains {frameworkPaths.Count} platform-specific frameworks[/]"); - } - else - { - AnsiConsole.MarkupLine($"[red]Failed to create XCFramework. Exit code: {result}[/]"); - } - } - else - { - AnsiConsole.MarkupLine($"[red]No framework paths found for XCFramework creation[/]"); - } - } - - - void BuildAndroid (BuildContext context, string arch, string rid, string minNdk) { var ndk = System.Environment.GetEnvironmentVariable ("ANDROID_NDK_HOME"); From fc70a904e836feedcc37f3caa58ebd7f46f2e95b Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 30 Jul 2025 19:55:19 +0100 Subject: [PATCH 19/20] Revert buildscripts bump --- buildscripts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildscripts b/buildscripts index 9de36a3..5cd1ee3 160000 --- a/buildscripts +++ b/buildscripts @@ -1 +1 @@ -Subproject commit 9de36a3e9b06c710b0fcfc032c81dfa164d594e5 +Subproject commit 5cd1ee39dfa0e570b125260d4d19753232c1c29e From 3817bce7859b317bb64a53f5b7c885e2b157f826 Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 30 Jul 2025 23:44:23 +0100 Subject: [PATCH 20/20] revert workflow change --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bae4289..5c33ceb 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -49,6 +49,7 @@ jobs: packages: write contents: write needs: [ build ] + if: ${{ github.event_name == 'push' }} steps: - name: Expose GitHub Runtime uses: crazy-max/ghaction-github-runtime@v3 @@ -73,3 +74,4 @@ jobs: removeArtifacts: true artifacts: "bin/Release/*.nupkg" token: ${{ secrets.GITHUB_TOKEN }} + if: github.ref_type == 'tag'