Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make iOS export fast and easy #26263

Closed
wants to merge 2 commits into from

Conversation

samgreen
Copy link
Contributor

@samgreen samgreen commented Feb 25, 2019

I'd like to get to 1-click deploy from the editor for iOS games. The first step is ensuring the export pipeline is solid, up-to-date and has very reasonable defaults.

Changes

  • Move to Truly Automatic ™️ code-signing. The trick is providing a default value of iPhone Developer and iPhone Distribution to pick from available code signing identities (Beward, this can cause iOS export configuration needs better validation #24866 and loss of sanity). The old behavior is still here if you choose to modify the export settings. Most of this process should now be automatic for most users
  • Depend on modifying the .xcodeproj much less. We want to stay away from modifying this file and instead let Xcode manage it. To that end, most settings have been moved to xcconfig files.
  • Add Common.xcconfig these settings are applied to all (Debug and Release) builds
  • Generate tweakable settings in godot.xcconfig and add to xcodeproj
  • Don't require any icons for successful export, iOS will use a white icon with concentric circles until the art is in place. This was just one more hurdle people needed to see their games run on their devices, I've personally spent a bit of time generating random PNGs just to skip an error in this part of the export. Note that we (obviously) still set the icons if the developer provides them.
  • Disambiguate the two versions needed on export. One is a 3 digit version that MUST increment, one is for public display.
  • Remove Access WiFi capability from export option, as it does something else.
  • Bump deployment target to iOS 10 (to match the export templates).
  • Enabled just about every optional warning and set some to errors, to ensure the best hygiene. Also fixed all warnings that resulted from this.

Resolves

Clean Up

  • Remove CFBundleSignature from plist (This is an OS X key).
  • Remove CFBundleIcons from `plist (We previously migrated to Asset Catalogs)
  • Resolve all build warnings from exported Xcode project

Proposal for future work

  • Remove identity and export method entirely and depend on Xcode export from Archive (this allows re-exporting the same build repeatedly with different certs, profiles, and capabilities).
  • Add better documentation around capabilities and what they mean.

@samgreen
Copy link
Contributor Author

samgreen commented Feb 25, 2019

Example of the final godot.xcconfig that developers will see in Xcode (with a project named Prickles):

#include "Common.xcconfig"

//
//  Build Settings
//
ENABLE_BITCODE = NO;

//
//  Deploy Settings
//
TARGETED_DEVICE_FAMILY = 1,2; // Target iPhone and iPad
IPHONEOS_DEPLOYMENT_TARGET = 10.0;

ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;

PRODUCT_NAME = $(TARGET_NAME);

// 
// Godot Exported from Editor
//
INFOPLIST_FILE = Prickles/Prickles-Info.plist;
PRODUCT_BUNDLE_IDENTIFIER = com.samgreen.prickles;
DEVELOPMENT_TEAM = USYS****Y9;
ARCHS = arm64;
FRAMEWORK_SEARCH_PATHS = $(inherited) Prickles;
OTHER_LDFLAGS = $(inherited);

@@ -197,7 +199,7 @@
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.AccessWiFi = {
enabled = $access_wifi;
enabled = 0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All games can still access wifi. This is poorly named (on Apple's part).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah Apple has some strange ideas about these capabilities. Unless someone runs into a situation where this needs to be turned on, take it out.


// if enabled, add development (sandbox) APNS entitlements
if ((bool)p_preset->get("capabilities/push_notifications")) {
strnew += "\n\"CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]\" = " + binary_path + ".entitlements;\n";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can probably drop this in the future and let Xcode generate entitlements as well what it's already doing in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a fan of letting XCode do as much of the work for us as possible, that way if apple decides to change/enhance it we should end up piggy backing on that change.

PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "$provisioning_profile_uuid_debug";
TARGETED_DEVICE_FAMILY = "1,2";
VALID_ARCHS = "armv7 armv7s arm64 i386 x86_64";
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No more i386 OS X machines will run a recent version of Xcode :(

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think its worth discussing whether we want to get rid of the 32bit stuff as well. Apple is about to pull the plug on that anyway. Or maybe wait for 3.2 for that one?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd wait for 3.2, but then yeah, we can likely drop 32-bit stuff. See discussion in godotengine/godot-docs#2212.

@akien-mga akien-mga added this to the 3.2 milestone Feb 25, 2019
@samgreen
Copy link
Contributor Author

@akien-mga I just realized there's a section in the docs about cross compiling iOS apps on Linux. I'm not sure if this is still supported, or even a goal of this project. Certainly the code signing aspects wouldn't work. This PR will further add a dependence on Xcode, but that's already required for submitting to the App Store.

@akien-mga
Copy link
Member

As long as we can still build the templates themselves on Linux (which we currently do for official templates), that should be fine :)

@@ -243,26 +244,24 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));

r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id", PROPERTY_HINT_PLACEHOLDER_TEXT, "ZXSYZ493U4"), ""));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is ZXSYZ493U4 just a dummy value?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably Sams team id so we can now all release games in his name 😉

@@ -100,7 +100,7 @@
D0BCFE2B18AEBDA2004A7AAE = {
isa = PBXGroup;
children = (
87D30C9722235A2200E688DC /* Config.xcconfig */
87D30C9722235A2200E688DC /* Config.xcconfig */,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if you could squash this commit into its parent (40a2122b).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and/or group some of the other related commits that iteratively modify the same file.

@akien-mga akien-mga modified the milestones: 3.2, 3.1 Feb 25, 2019
@akien-mga
Copy link
Member

I'll tentatively put this on the 3.1 milestone even though it's quite late in the process, as the iOS export pipeline is far from optimal currently, so those changes might be very welcome in our new minor release.

I'll need help from experienced iOS devs to validate these changes ASAP though, cc @bruvzg @BastiaanOlij @endragor.

// This warnings detects when a function will recursively call itself on every
// code path though that function. More information can be found here:
// http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20131216/096004.html
CLANG_WARN_INFINITE_RECURSION = YES
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing newline at EOF.

@@ -19,3 +18,5 @@ WRAPPER_EXTENSION = app;

ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;

PRODUCT_NAME = "$(TARGET_NAME)";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing newline at EOF.

@@ -6,7 +6,7 @@
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
SDKROOT = iphoneos;
VALID_ARCHS = "armv7 armv7s arm64 x86_64";
ENABLE_BITCODE = NO
ENABLE_BITCODE = NO;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good if this hotfix was amended into the commit where the line was added in the first place.

@@ -4,7 +4,7 @@
// Build Settings
//
SDKROOT = iphoneos;
VALID_ARCHS = "armv7 armv7s arm64 x86_64";
VALID_ARCHS = armv7 armv7s arm64 x86_64;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for this one.

r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_method_release", PROPERTY_HINT_ENUM, "App Store,Development,Ad-Hoc,Enterprise"), 0));

r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/public_version"), "1.0.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "2019"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is application/copyright meant to be a year?

@@ -257,7 +257,7 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.game"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/public_version"), "1.0.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "2019"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This answers my previous question... should be squashed in the commit where it was changed.

@akien-mga
Copy link
Member

The changes look good to me overall, but I'd like the git history to be amended a bit to make it easier to follow the changes, removing intermediate changes that are no longer relevant once merged.

So typo fixes and cleanups should be made directly in the original commit that added the need for such fixes. The final commits that we do merge should not add bugs, even temporarily; each commit should bring the engine from one valid state to another valid state, so that changes can be bisected if need be.

@hpvb
Copy link
Member

hpvb commented Feb 25, 2019

I'd very much like to push this to 3.2, maybe it can go in 3.1.1 if we have to. This will take a while to sort out on my end.

@samgreen
Copy link
Contributor Author

I agree that we shouldn’t rush this out. This is a vast change that deserves more testing.

@hpvb hpvb modified the milestones: 3.1, 3.2 Feb 25, 2019
@gianmichelemariani
Copy link

Is this going to be in 3.2? Very much looking forward to it!

@akien-mga
Copy link
Member

Moving to 4.0 milestone as this is not ready to merge.

@akien-mga akien-mga modified the milestones: 3.2, 4.0 Oct 30, 2019
@akien-mga
Copy link
Member

See also #33086 for a related PR with probably a smaller scope.

Sam Green added 2 commits December 10, 2019 17:01
Remove CFBundleSignature since that key is for legacy OS X apps

Rename short_version to public version for clarity. Use 2 periods for version string as Apple recommends
Add missing comma in xcode project. Add xcconfig file

Skip missing icons on export

Remove IPHONEOS_DEPLOYMENT_TARGET and use value in xcconfig

Remove asset catalog references from xcodeproj

Include a Common.xcconfig so we can modify the godot xcconfig

Export to xcodeproj now works with automatic profile and certificate selection

Default to iphone developer and distribution

Migrated almost all build variables to xcconfig

Move more permanent settings to Common.xcconfig

Add CLANG_WARN_SUSPICIOUS_MOVE to silence Xcode project upgrade

Enable testability in debug to prevent project upgrade warning

Prevent empty signing identity
@samgreen
Copy link
Contributor Author

@akien-mga @godotengine/ios

This has been rebased and updated.

@aaronfranke aaronfranke marked this pull request as draft May 26, 2020 15:04
@aaronfranke
Copy link
Member

@samgreen What is the status of this PR? The two PRs linked by Akien are both closed. If this is still desired, this should be rebased and re-tested so that we know it still works.

@samgreen
Copy link
Contributor Author

I don’t have a good answer here. I’m happy to make this and any further changes. I’d love to see iOS export get some love. This is a huge barrier to wider adoption.

@akien-mga akien-mga requested a review from a team September 13, 2021 11:26
@trojanfoe
Copy link

@samgreen Hi, I am kinda new to Godot, but not to Xcode. One thing I don't understand is why the Godot "runtime" isn't exported to Xcode as source instead of built binary, which would allow Xcode to build the source for device or simulator? This would presumably also cut down on the maintenance effort of the exporter itself?

@samgreen
Copy link
Contributor Author

samgreen commented Oct 6, 2021

@samgreen Hi, I am kinda new to Godot, but not to Xcode. One thing I don't understand is why the Godot "runtime" isn't exported to Xcode as source instead of built binary, which would allow Xcode to build the source for device or simulator? This would presumably also cut down on the maintenance effort of the exporter itself?

There is no Xcode on Linux.

@trojanfoe
Copy link

@samgreen

There is no Xcode on Linux.

No what I meant was the iOS exporter is comprised of the source files of the Godot runtime and the necessary Xcode project files so when the user exports to iOS on their Mac they then built it to whatever target they like (device, simulator, arm64, x64, whatever). Has this not been considered?

@Calinou
Copy link
Member

Calinou commented Oct 6, 2021

No what I meant was the iOS exporter is comprised of the source files of the Godot runtime and the necessary Xcode project files so when the user exports to iOS on their Mac they then built it to whatever target they like (device, simulator, arm64, x64, whatever). Has this not been considered?

I presume doing this would slow down exporting speeds, since the native code would have to be compiled when you export the project (at least for the first time). Nonetheless, this is how custom builds for Android work (they're still opt-in right now).

By shipping precompiled libraries within the iOS export template ZIP, we avoid this slowdown.

@trojanfoe
Copy link

I presume doing this would slow down exporting speeds, since the native code would have to be compiled when you export the project (at least for the first time). Nonetheless, this is how custom builds for Android work (they're still opt-in right now).

By shipping precompiled libraries within the iOS export template ZIP, we avoid this slowdown.

It would be slower for sure, but with the mix of arm64 and x64 Macs and arm64 and x64 iOS Simulators it might prove useful to some users. Avoiding having to provide all the icons in the export dialog would be a win if you already a pre-prepared AppIcon.iconset for example. Anyway it was just a thought.

@clofresh
Copy link
Contributor

clofresh commented Nov 5, 2021

I can test this change but I'm having trouble rebasing onto master or 3.x as there's a bunch of conflicts in godot_ios.xcodeproj/project.pbxproj that I don't understand. If someone resolves them, I can test it on my end.

@akien-mga akien-mga modified the milestones: 4.0, 4.x Jul 26, 2022
@Vennnot
Copy link

Vennnot commented May 9, 2023

Seems that if this was retested we could see if we merge it or not

@akien-mga
Copy link
Member

This PR is sadly abandoned, but #70662 should supersede it.

@akien-mga akien-mga closed this May 9, 2023
@YuriSizov YuriSizov removed this from the 4.x milestone Dec 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.