From 4d33f772d67a09dc17ce21de0d6a4808baac74ae Mon Sep 17 00:00:00 2001 From: Mirko Galimberti Date: Sun, 4 Feb 2024 16:50:33 +0100 Subject: [PATCH] Add build for iphoneos and iphonesimulator --- .github/workflows/build.yml | 12 ++ src/angle_builder/angle.py | 223 +++++++++++++++++++++++++++++++++++- 2 files changed, 230 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b1305df..7e75503 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,6 +31,18 @@ jobs: - name: Build artifacts for macos-universal run: angle-builder macos-universal --artifact-output-folder $ANGLE_BUILDER_OUTPUT_FOLDER + - name: Build artifacts for iphoneos-arm64 + run: angle-builder iphoneos-arm64 --artifact-output-folder $ANGLE_BUILDER_OUTPUT_FOLDER + + - name: Build artifacts for iphonesimulator-x86_64 + run: angle-builder iphonesimulator-x86_64 --artifact-output-folder $ANGLE_BUILDER_OUTPUT_FOLDER + + - name: Build artifacts for iphonesimulator-arm64 + run: angle-builder iphonesimulator-arm64 --artifact-output-folder $ANGLE_BUILDER_OUTPUT_FOLDER + + - name: Build artifacts for iphoneall-universal + run: angle-builder iphoneall-universal --artifact-output-folder $ANGLE_BUILDER_OUTPUT_FOLDER + - name: Store artifacts uses: actions/upload-artifact@v4 with: diff --git a/src/angle_builder/angle.py b/src/angle_builder/angle.py index aa9bcbb..884178b 100644 --- a/src/angle_builder/angle.py +++ b/src/angle_builder/angle.py @@ -150,7 +150,7 @@ def _generate_build_targets(self, output_artifact_mode: str) -> None: if output_artifact_mode in ( "iphoneos-arm64", - "iphone*-universal", + "iphoneall-universal", ): builds.append( { @@ -166,7 +166,7 @@ def _generate_build_targets(self, output_artifact_mode: str) -> None: if output_artifact_mode in ( "iphonesimulator-x64", - "iphone*-universal", + "iphoneall-universal", ): builds.append( { @@ -175,6 +175,7 @@ def _generate_build_targets(self, output_artifact_mode: str) -> None: + [ 'target_cpu="x64"', 'target_os="ios"', + 'target_environment="simulator"', "ios_enable_code_signing=false", ], } @@ -182,7 +183,7 @@ def _generate_build_targets(self, output_artifact_mode: str) -> None: if output_artifact_mode in ( "iphonesimulator-arm64", - "iphone*-universal", + "iphoneall-universal", ): builds.append( { @@ -191,6 +192,7 @@ def _generate_build_targets(self, output_artifact_mode: str) -> None: + [ 'target_cpu="arm64"', 'target_os="ios"', + 'target_environment="simulator"', "ios_enable_code_signing=false", ], } @@ -309,6 +311,210 @@ def _create_macos_dylibs(self, output_artifact_mode: str) -> list: return [libEGL_dylib_path, libGLESv2_dylib_path] + def _create_iphoneos_frameworks(self, output_artifact_mode: str) -> list: + libEGL_xcframework_path = os.path.join( + self.angle_path, "out", output_artifact_mode, "libEGL.xcframework" + ) + libGLESv2_xcframework_path = os.path.join( + self.angle_path, + "out", + output_artifact_mode, + "libGLESv2.xcframework", + ) + + self._logger.info( + "Creating iphoneos frameworks for branch %s and build target %s", + self.branch, + output_artifact_mode, + ) + + if output_artifact_mode == "iphoneall-universal": + # Ensure the fake all-universal folder exists (if exists, clean it up) + iphone_universal_folder = os.path.join( + self.angle_path, "out", "iphoneos-arm64", "iphoneall-universal" + ) + if os.path.exists(iphone_universal_folder): + shutil.rmtree(iphone_universal_folder) + + # Ensure the fake iphonesimulator-universal folder exists (if exists, clean it up) + iphonesimulator_universal_folder = os.path.join( + self.angle_path, "out", "iphonesimulator-universal" + ) + if os.path.exists(iphonesimulator_universal_folder): + shutil.rmtree(iphonesimulator_universal_folder) + + os.makedirs(iphonesimulator_universal_folder) + + self._logger.info( + "Lipo-ing iphonesimulator frameworks for branch %s and build target %s", + self.branch, + output_artifact_mode, + ) + + # Copy iphonesimulator-x64 frameworks to iphonesimulator-universal, by deleting the binaries + shutil.copytree( + os.path.join( + self.angle_path, + "out", + "iphonesimulator-x64", + "libEGL.framework", + ), + os.path.join( + self.angle_path, + "out", + "iphonesimulator-universal", + "libEGL.framework", + ), + ) + os.remove( + os.path.join( + self.angle_path, + "out", + "iphonesimulator-universal", + "libEGL.framework", + "libEGL", + ) + ) + shutil.copytree( + os.path.join( + self.angle_path, + "out", + "iphonesimulator-x64", + "libGLESv2.framework", + ), + os.path.join( + self.angle_path, + "out", + "iphonesimulator-universal", + "libGLESv2.framework", + ), + ) + os.remove( + os.path.join( + self.angle_path, + "out", + "iphonesimulator-universal", + "libGLESv2.framework", + "libGLESv2", + ) + ) + # Lipo-ize iphonesimulator frameworks into fat frameworks + subprocess.run( + [ + "lipo", + "-create", + os.path.join( + self.angle_path, + "out", + "iphonesimulator-x64", + "libEGL.framework", + "libEGL", + ), + os.path.join( + self.angle_path, + "out", + "iphonesimulator-arm64", + "libEGL.framework", + "libEGL", + ), + "-output", + os.path.join( + self.angle_path, + "out", + "iphonesimulator-universal", + "libEGL.framework", + "libEGL", + ), + ], + cwd=self.angle_path, + check=True, + ) + + subprocess.run( + [ + "lipo", + "-create", + os.path.join( + self.angle_path, + "out", + "iphonesimulator-x64", + "libGLESv2.framework", + "libGLESv2", + ), + os.path.join( + self.angle_path, + "out", + "iphonesimulator-arm64", + "libGLESv2.framework", + "libGLESv2", + ), + "-output", + os.path.join( + self.angle_path, + "out", + "iphonesimulator-universal", + "libGLESv2.framework", + "libGLESv2", + ), + ], + cwd=self.angle_path, + check=True, + ) + + # Create an xcframework for libEGL + subprocess.run( + [ + "xcodebuild", + "-create-xcframework", + "-framework", + os.path.join( + self.angle_path, + "out", + "iphoneos-arm64", + "libEGL.framework", + ), + "-framework", + os.path.join( + self.angle_path, + "out", + "iphonesimulator-universal", + "libEGL.framework", + ), + "-output", + libEGL_xcframework_path, + ], + cwd=self.angle_path, + check=True, + ) + + # Create an xcframework for libGLESv2 + subprocess.run( + [ + "xcodebuild", + "-create-xcframework", + "-framework", + os.path.join( + self.angle_path, + "out", + "iphoneos-arm64", + "libGLESv2.framework", + ), + "-framework", + os.path.join( + self.angle_path, + "out", + "iphonesimulator-universal", + "libGLESv2.framework", + ), + "-output", + libGLESv2_xcframework_path, + ], + cwd=self.angle_path, + check=True, + ) + + return [libEGL_xcframework_path, libGLESv2_xcframework_path] + def build(self, output_artifact_mode: str, output_folder: str) -> None: """ Build ANGLE for the specified output_artifact_mode. @@ -320,7 +526,7 @@ def build(self, output_artifact_mode: str, output_folder: str) -> None: - iphoneos-arm64 - iphonesimulator-x64 - iphonesimulator-arm64 - - iphone*-universal + - iphoneall-universal The produced artifact is a zip file containing: - libEGL @@ -345,6 +551,8 @@ def build(self, output_artifact_mode: str, output_folder: str) -> None: if output_artifact_mode.startswith("macos"): libs = self._create_macos_dylibs(output_artifact_mode) + elif output_artifact_mode.startswith("iphone"): + libs = self._create_iphoneos_frameworks(output_artifact_mode) with tempfile.TemporaryDirectory() as temp_dir: self._logger.info( @@ -354,7 +562,12 @@ def build(self, output_artifact_mode: str, output_folder: str) -> None: ) # Copy libs, include folder and LICENSE to temp_dir for lib in libs: - shutil.copy(lib, temp_dir) + if os.path.isdir(lib): + shutil.copytree( + lib, os.path.join(temp_dir, os.path.basename(lib)) + ) + else: + shutil.copy(lib, temp_dir) shutil.copytree( include_folder_path, os.path.join(temp_dir, "include")