google / filament

Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WebGL2
https://google.github.io/filament/
Apache License 2.0
17.44k stars 1.84k forks source link

feat: Add builds for iOS Silicon Simulator #7704

Open chrfalch opened 4 months ago

chrfalch commented 4 months ago

On iOS The current build system only builds for one architecture for iPhone (arm64) and one for iPhone Simulator (x86-64). This worked before the new Apple Silicon Macs arrived - since Xcode/iOS Simulator now supports both x86-64 and arm64 architectures which is not directly supported by the current build setup in Google/Filament.

Multiple iOS simulator architectures makes it a bit harder to package on iOS, since we can no longer just create fat binaries with the two architectures - we now have three that we somehow need to fit into the build:

The old list of library architectures and platforms were: iPhone - arm64 iOS Simulator - x86-64

The new list on iOS will now be: iPhone - arm64 iOS Simulator - x86-64 iOS Simulator - arm64

To accomplish distributing the above binaries we need to change from distributing our libraries as .a files in universal format (containing multiple architectures in one .a file), and move over to XC Frameworks. An XC Framework is a way for Xcode to consume multiple architectures and multiple platforms (where a platform would typically be iPhone or iPhoneSimulator which both have different SDKs).

This pull request fixes this by introducing platform as a directory element so that we can build multiple outputs configured for the same architecture, and also changes the build so the final iOS build step is to create the XC framework-files. The Cocoapods spec file is also updated so that it now references the XC frameworks instead of the library files directly.

This PR fixes #6714

mrousavy commented 4 months ago

Wow!! 🥳

chrfalch commented 4 months ago

Thank you for your contribution! I took a quick look -- so far everything is on the right path. The samples in ios/samples do need to be updated to reflect the build directory renaming.

I think this build.sh help message should be updated to reflect that "universal" libraries now means XC Frameworks and will contain 3 different platform/arch combinations.

Finally, do we need to keep the create-universal-libs.sh script? Could we run your new create-xc-frameworks.sh script like:

build/ios/create-xc-frameworks.sh \
    -o out/ios-debug/filament/lib \
    out/ios-debug/filament/lib/arm64-iphoneos \
    out/ios-debug/filament/lib/arm64-iphonesimulator \
    out/ios-debug/filament/lib/x86_64-iphonesimulator

Thanks again!

Np! Super fun task to work on :)

The reason we still have to use the create-universal-libs.sh script is that an XC Framework cannot contain two library files built for the same platform (simulator) - these two needs to be distributed as a universal library - built with create-universal-libs.sh.

So the process now will become (with this PR): 1) Run build/install as usual 2) Create universal libraries of all platform simulator into the lib/universal folder 3) Create XC Frameworks with the universal libraries + the arm64 iPhoneOS libraries.

Reagarding the ios/samples/app-template.yml file and building the samples - I'll take a quick look at this now.

chrfalch commented 4 months ago

I've updated release_notes and updated example projects on iOS - hope it is in line with how you expect this. It seems to build correctly locally - excited to see how the tests are working.

Btw, I was not sure if the generated project files in iOS should be committed - so I left them out.

Added iOS sample project files after running generate - CI runs these projects without re-generating so project files needs to be committed.

chrfalch commented 3 months ago

Sorry for the delayed feedback here - been having a few days of during easter.

I can look into fixing moving release/debug paths into settings.config files - but we need to discuss the build process now that we make XCFrameworks.

Either we switch to always building all platforms, or we only build those defined by the input parameters and then add some logic to the build scripts to include the libraries that was actually built into XCFramework files.

What do you think?

bejado commented 3 months ago

Either we switch to always building all platforms

We definitely don't want to do that. It's common for us while developing to just build debug, i.e. run build.sh -i -p ios debug. The extra cost of building all platforms would be too high.

add some logic to the build scripts to include the libraries that was actually built into XCFramework files

I think this is the best solution. How does that sound?

chrfalch commented 3 months ago

@bejado The last commit I pushed will now make sure we always build XCFrameworks in Release mode - making the builds to (hopefully) pass even though simulator builds was not requested!

It was not possible from my research to change the build scripts on iOS (project.yml etc) to support XCFrameworks in debug/release version - so they are now linked against the release versions.

Hope this is sufficient :)

bejado commented 3 months ago

It was not possible from my research to change the build scripts on iOS (project.yml etc) to support XCFrameworks in debug/release version

Do you know if this is a limitation of Xcode itself, or of XcodeGen (the Xcode project generator tool we use)?

so they are now linked against the release versions.

I think we're close to a solution, but unfortunately building and running our samples against a Debug build of Filament is important for us. Maybe we need to do a symlink or something.

Thanks for all your work on this, I'm happy to take a look myself when I get a chance.

chrfalch commented 3 months ago

Do you know if this is a limitation of Xcode itself, or of XcodeGen (the Xcode project generator tool we use)?

To my knowledge this is an issue with how Xcode embeds XC Frameworks - not XCodeGen.

so they are now linked against the release versions.

I think we're close to a solution, but unfortunately building and running our samples against a Debug build of Filament is important for us. Maybe we need to do a symlink or something.

Yeah, let me think a bit on this one, I understand your use case - let me see if I can come up with something, maybe change the script that builds the samples or something.

Thanks for all your work on this, I'm happy to take a look myself when I get a chance.

It is super fun to be able to help :)