Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Migrate iOS and OS X targets to checked-in Xcode projects #4641

Merged
merged 20 commits into from
Apr 17, 2016

Conversation

1ec5
Copy link
Contributor

@1ec5 1ec5 commented Apr 7, 2016

This PR replaces the various iOS-specific targets in ios.xcodeproj and OS X–specific targets in osx.xcodeproj with checked-in targets created within Xcode. The core targets remain in the GYP-generated platform.xcodeproj projects. New Xcode workspaces bind ios.xcodeproj to platform.xcodeproj and manages dependencies between the two; likewise for osx.xcodeproj. The ios.xcworkspace also contains ios-test.xcodeproj and KIF.xcodeproj for convenience. (Although we really should be pulling in KIF via a package manager like CocoaPods: #1522.)

You still set up your development environment with make iproj and make xproj, but now those make rules open the workspace. Other workflows have been streamlined:

  • When you add or remove an SDK file, you can do so inside Xcode. No more build failures because you forgot to also update platform.gypi and rerun make iproj.
  • You can leave the workspace open in Xcode while performing Git operations that add and remove SDK files. You can also run make iproj or make xproj with the workspace still open.
  • You can debug the iOS SDK and core code while running KIF-based integration tests.
  • Derived data locations are shared between the Xcode GUI and xcodebuild command line tool, so you no longer have to rebuild from scratch when switching between the two. Cleaning in one environment automatically affects the other environment.
  • The MAPBOX_ACCESS_TOKEN environment variable no longer gets blown away every time you have to regenerate the GYP targets, as long as you set the variable on a shared scheme (iosapp, ios-bench, CI, etc.) or a non-shared, non-GYP-generated scheme (which could be a duplicate of a GYP-generated scheme).
  • Incremental builds of the SDK are much faster.
  • make clean is more thorough, wiping away Xcode’s index and module cache along with the intermediate files.
  • You can add additional test bundles or demo applications inside Xcode without having to reverse-engineer undocumented GYP features.

libmbgl-platform-ios.a has been reduced to a very small library that contains just the iOS-specific code needed by core code. (The same was done for libmbgl-platform-osx.a in #4608.) The iOS SDK dynamic framework and iOS SDK static library link the core static libraries directly, making it possible for the two to have differing content should the need ever arise. To significantly reduce binary sizes and build times, the iOS SDK no longer builds the armv7s slice; iPhone 5 and iPhone 5c will fall back to the armv7 slice automatically without a noticeable performance hit.

make test-ios additionally runs the same “Darwin” unit tests that we’ve been running against the OS X SDK. It’d be trivial to add functional tests (whether the existing KIF tests or future XCUITest tests) to this make rule.

The workspaces come with disabled Objective-C exception breakpoints by default. They also include schemes that exactly replicate what gets built on Bitrise and what gets built by package.sh for distribution.

Project upgrade warnings in GYP targets have been fixed. The default warnings that come with Xcode’s target templates exposed some additional warnings for issues that have been lurking silently in GYP-generated targets; those issues have been fixed. Conversely, the iOS and OS X targets no longer pull in pedantic warnings (treated as errors) from the core targets, so now we can use modern Objective-C syntax, including designated initializers.

The new iOS SDK static library target comes with OTHER_LDFLAGS=-ObjC by default, so the various workarounds we’ve been using to avoid -ObjC have been removed. The size decrease from removing the armv7s slice and from switching to -Os optimization in #3183 more than makes up for the addition of -ObjC. Developers who manually install the static framework no longer need to set -ObjC in their own application targets, so the net effect is a potentially drastic decrease in application size.

Numerous images used by iosapp and the iOS benchmarking application have been placed inside asset catalogs. Storyboards are now localizable. Unused SVG files have been removed from the SDK’s resource bundle.

  • Create iosapp.xcodeproj and iosapp target that depends on ios.xcodeproj
  • Create ios.xcworkspace
  • Bring osxtest over to iOS
  • Add ios-tests.xcodeproj to ios.xcworkspace
  • Fold ios-tests.xcodeproj into ios.xcodeproj
  • Define dependencies in .xcconfig files
  • Move dynamic framework from GYP-generated project to ios.xcodeproj
  • Move static library from GYP-generated project to ios.xcodeproj
  • Ensure derived data ends up in build/
  • Simplify package.sh
  • Fix up make rules (ref [WIP] [build] Refactor and simplify build system #4608)
  • Do the same for OS X targets
  • Update documentation
  • Squash uninteresting commits

Fixes #3275, fixes #4481, fixes #4191, fixes #4264, fixes #4704, and fixes #4495.

/cc @boundsj @friedbunny @jfirebaugh @kkaefer

@1ec5 1ec5 self-assigned this Apr 7, 2016
@1ec5 1ec5 added iOS Mapbox Maps SDK for iOS build tests labels Apr 7, 2016
@1ec5 1ec5 added this to the ios-v3.3.0 milestone Apr 7, 2016
@jfirebaugh
Copy link
Contributor

Is there an advantage to having multiple .xcodeproj files and a workspace, versus a monolithic .xcodeproj with multiple targets?

@1ec5
Copy link
Contributor Author

1ec5 commented Apr 7, 2016

Ultimately, I'd like for there to be a workspace with two projects: one that pulls in mbgl, as generated by gyp, and the other that includes targets for iossdk, iosapp, etc.

@jfirebaugh
Copy link
Contributor

To adjust from the changes in #4608, you'll need to:

  • Change the location of the core .xcodeproj referenced by the workspace. It's now at build/ios-all/platform/ios/platform.xcodeproj.
  • Remove the targets you want to move to the checked in .xcodeproj from platform/ios/platform.xcodeproj (iossdk, iosapp, ios-bench, I assume).

I think that's it.

@jfirebaugh
Copy link
Contributor

Another change that I recommend making as part of this is to move all the Objective C sources from the platform-lib target to the iossdk target.

I did this for the osx platform in #4608 but held off for ios because I'm not familiar with the packaging requirements.

@1ec5
Copy link
Contributor Author

1ec5 commented Apr 8, 2016

Thanks for trying to minimize conflicts – much appreciated.

The OS X SDK project is a little simpler because it only produces a dynamic framework. The iOS project produces an intermediate static framework that we actually ship. I think it'll be possible to move them out of the platform-lib target though.

@1ec5
Copy link
Contributor Author

1ec5 commented Apr 11, 2016

After moving the SDK classes into the dynamic framework proper, the fat framework sees a 40% size reduction versus the 3.2.0 official build (25 MB), a 66% size reduction if you exclude simulator content (12 MB), and that’s before the extra strip invocation in package.sh.

@1ec5 1ec5 force-pushed the 1ec5-iosapp-project branch 2 times, most recently from 7a2d766 to 3884e19 Compare April 12, 2016 17:06
@1ec5 1ec5 mentioned this pull request Apr 14, 2016
@1ec5
Copy link
Contributor Author

1ec5 commented Apr 14, 2016

The size savings are due in part to setting ARCHS=$(ARCHS_STANDARD) in build settings for the dynamic and static SDK products. Apparently $(ARCHS_STANDARD) omits armv7s, which we still include for all gyp-managed targets. I filed #4704 to discuss removing support for this architecture.

@1ec5 1ec5 force-pushed the 1ec5-iosapp-project branch from 3884e19 to c03e7a5 Compare April 14, 2016 17:22
@1ec5 1ec5 added the ⚠️ DO NOT MERGE Work in progress, proof of concept, or on hold label Apr 14, 2016
@1ec5 1ec5 force-pushed the 1ec5-iosapp-project branch from a5845a1 to c1cda8a Compare April 15, 2016 05:19
@1ec5 1ec5 force-pushed the 1ec5-iosapp-project branch from 2eec87e to d27a6b4 Compare April 15, 2016 20:23
@1ec5
Copy link
Contributor Author

1ec5 commented Apr 15, 2016

iOS builds continue to fail on Bitrise but not locally with:

Application path /Users/vagrant/git/build/ios-all/Debug-iphonesimulator/ios-test.app doesn't exist!
make: *** [test-ios] Error 1

@jfirebaugh
Copy link
Contributor

I don't know why it would be different on Bitrise than locally for you, but the gyp-generated projects use this hack to force xcodebuild output to build/ios-all. Do you have something equivalent in place for the checked in projects / workspace?

1ec5 added 2 commits April 16, 2016 22:46
Added a new Cocoa dynamic framework target target to the main OS X Xcode project. The target is based on the template provided by Xcode. It contains headers and source files in the darwin/ and osx/ subdirectories. Headers are explicitly marked public or project-internal instead of implicitly by subdirectory. Removed the osxsdk target from platform.gypi.

The SDK target has a few dependencies that are managed by mason. Transform the config.gypi generated by configure into an .xcconfig file that Xcode uses to fill in compiler and linker flags.

Added a CI scheme that builds the All aggregate target generated by gyp and the osxapp and SDK test targets.
Fixed some issues that were obscured by the old gyp-generated build settings.
@1ec5 1ec5 force-pushed the 1ec5-iosapp-project branch from cf5b1ea to 6da746a Compare April 17, 2016 05:48
@1ec5 1ec5 added the macOS Mapbox Maps SDK for macOS label Apr 17, 2016
@1ec5 1ec5 changed the title Migrate iOS targets to checked-in Xcode projects Migrate iOS and OS X targets to checked-in Xcode projects Apr 17, 2016
@1ec5 1ec5 merged commit 6da746a into master Apr 17, 2016
@1ec5 1ec5 deleted the 1ec5-iosapp-project branch April 17, 2016 06:07
1ec5 added a commit that referenced this pull request Apr 17, 2016
Now that #4641 has removed the prohibition against C99 extensions, this change removes many pragma statements that suppress warnings about variadic macros and designated initializers. Designated initializers and Elvis operators have been introduced wherever appropriate.
@jfirebaugh
Copy link
Contributor

👏

@boundsj
Copy link
Contributor

boundsj commented Apr 18, 2016

🎉

@Gerz-inc
Copy link

Gerz-inc commented May 19, 2016

Starting with version 3.3 alpha-1 is not possible to connect a static framework. Perhaps additional settings are needed? Version 3.2 connects without problems. #5071

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.