Skip to content

Build system and availability support for macCatalyst #29017

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

Merged
merged 6 commits into from
Jan 22, 2020

Conversation

devincoughlin
Copy link
Contributor

macCatalyst is an Apple technology that enables code targeting iOS to be recompiled so that it can be executed on macOS while still using iOS APIs.

This pull request adds initial build system and testing support for macCatalyst, as well as driver support, conditional conditional compilation, and availability attributes. It is the first in a series of PRs adding support in the compiler, runtime, standard library, and overlays. This later work depends on Clang and compiler-rt work that has not landed yet.

Swift for macCatalyst represents the work of multiple people, including @devincoughlin, @Rostepher, and @brentdax.

@devincoughlin
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Jan 6, 2020

Build failed
Swift Test Linux Platform
Git Sha - 7881c58f50aabadbb7607e07004ad4b4c8a01f6d

@swift-ci
Copy link
Contributor

swift-ci commented Jan 6, 2020

Build failed
Swift Test OS X Platform
Git Sha - 7881c58f50aabadbb7607e07004ad4b4c8a01f6d

@devincoughlin
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Jan 7, 2020

Build failed
Swift Test OS X Platform
Git Sha - 7881c58f50aabadbb7607e07004ad4b4c8a01f6d

@devincoughlin
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Jan 7, 2020

Build failed
Swift Test OS X Platform
Git Sha - 41d72391acc6f5efe5afacb6b1b1b1c7d8f9278a

@devincoughlin
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

swift-ci commented Jan 8, 2020

Build failed
Swift Test Linux Platform
Git Sha - 41d72391acc6f5efe5afacb6b1b1b1c7d8f9278a

@devincoughlin
Copy link
Contributor Author

@swift-ci please test

@devincoughlin
Copy link
Contributor Author

@swift-ci Please test Windows platform

1 similar comment
@gottesmm
Copy link
Contributor

gottesmm commented Jan 8, 2020

@swift-ci Please test Windows platform

@gottesmm
Copy link
Contributor

gottesmm commented Jan 8, 2020

@devincoughlin just reading the PR stream and noticed it didn't trigger the windows testing.

Copy link
Contributor

@beccadax beccadax left a comment

Choose a reason for hiding this comment

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

I feel like half of these are probably my own fault, but at least most of them are very minor.

bool isPlatformActive(PlatformKind Platform, LangOptions &LangOpts,
bool ForTargetVariant = false);


Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Extra newline.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

case PlatformKind::macCatalyst:
case PlatformKind::macCatalystApplicationExtension:
// ClangImporter does not yet support macCatalyst.
return false;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should these at least have name == "ios", or is that not even worth it until more complete clang support lands?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd like to keep this inert until the clang support lands.

@devincoughlin
Copy link
Contributor Author

@swift-ci Please test Windows platform

@devincoughlin
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

swift-ci commented Jan 9, 2020

Build failed
Swift Test OS X Platform
Git Sha - 2efcd043550cf83d56583ed69abf990a2bedbdaa

@swift-ci
Copy link
Contributor

swift-ci commented Jan 9, 2020

Build failed
Swift Test Linux Platform
Git Sha - 2efcd043550cf83d56583ed69abf990a2bedbdaa

@devincoughlin
Copy link
Contributor Author

@swift-ci Please smoke test and merge

@devincoughlin
Copy link
Contributor Author

@swift-ci Please test and merge

1 similar comment
@devincoughlin
Copy link
Contributor Author

@swift-ci Please test and merge

@devincoughlin
Copy link
Contributor Author

@swift-ci Please test and merge

Copy link
Contributor

@Rostepher Rostepher left a comment

Choose a reason for hiding this comment

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

I'm happy with merging these changes once testing passes. We can do more thorough cleanup in follow-up PRs. Thanks for getting these changes out!

@devincoughlin
Copy link
Contributor Author

@swift-ci Please test and merge

@devincoughlin
Copy link
Contributor Author

@swift-ci please smoke test and merge

if (!triplesAreValidForZippering(target, variant)) {
diags.diagnose(SourceLoc(), diag::error_unsupported_target_variant,
variant.str(),
variant.isiOS());
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 working on porting this to swift-driver, and I've found that I don't understand this diagnostic. In particular, I think that if you pass -target x86_64-apple-ios13 -target-variant x86_64-apple-macos10.15, it will end up emitting an error claiming that -target is x86_64-apple-macos10.15. (The tests wouldn't catch this because they match this part of the diagnostic with a {{.*}}.) Am I misinterpreting the diagnostic, or should we be passing the value of target.str() rather than variant.str() when !variant.isiOS()?

This commit adds initial build system support for macCatalyst,
an Apple technology that enables code targeting iOS
to be recompiled so that it can be executed on macOS while still using
iOS APIs. This is the first in a series of commits building out support for
macCatalyst in the compiler, runtime, standard library, and overlays. Swift
for macCatalyst represents the work of multiple people, including
Devin Coughlin, Ross Bayer, and Brent Royal-Gordon.

Under macCatalyst, compiler-provided shared libraries (including overlays)
are built as one of four kinds (or "flavors") of libraries,
each with different install names and Mach-O load commands. This commit
adds the build system infrastructure to produce these different
library flavors.

**macOS-like Libraries**

A "macOS-like" library (such as the GLKit overlay) is a plain-old macOS library
that can only be loaded into regular macOS processes. It has a macOS slice with
a single load command allowing it to be loaded into normal macOS processes.

**iOS-like Libraries**

An "iOS-like" library, such as the UIKit overlay, is a library with a
macOS slice but with a load command that only allows it be loaded into
macCatalyst processes. iOS-like libraries are produced by passing a new
target tuple to the compiler:

  swiftc ... -target x86_64-apple-ios13.0-macabi ...

Here 'ios' (and an iOS version number) is used for OS portion
of the triple, but the 'macabi' environment tells the compiler
that the library is intended for macCatalyst.

**Zippered Libraries**

A "zippered" library can be loaded into either a macCatalyst process or
a standard macOS process. Since macCatalyst does not introduce a new Mach-O
slice, the same code is shared between both processes. Zippered libraries
are usually relatively low level and with an API surface that is similar
between macOS and iOS (for example, both the Foundation overlay and the Swift
Standard Library/Runtime itself are zippered).

Zippered libraries are created by passing both the usual `-target`
flag to the compiler and an additional `-target-variant` flag:

   swiftc ... -target x86_64-apple-macos10.15 \
              -target-variant x86_64-apple-ios13.0-macabi

Just like the -target flag, -target-variant takes a target tuple.
This tells the compiler to compile the library for the -target tuple but
to add an extra load command, allowing the library to be loaded into processes
of the -target-variant flavor as well.

While a single zippered library and slice is shared between macOS and
macCatalyst, zippered libraries require two separate .swiftinterface/.swiftmodule
files, one for macOS and one for macCatalyst. When a macOS or macCatalyst client
imports the library, it will use module file for its flavor to determine what
symbols are present. This enables a zippered library to expose a subset of its
target APIs to its target-variant.

**Unzippered-Twin Libraries**

"Unzippered Twins" are pairs of libraries with the same name but different
contents and install locations, one for use from macOS processes and one for
use from macCatalyst processes. Unzippered twins are usually libraries that
depend on AppKit on macOS and UIKit on iOS (for example, the MapKit overlay)
and so do not share a common implementation between macOS and macCatalyst.

The macCatalyst version of an unzippered twin is installed in a parallel
directory hierarchy rooted at /System/iOSSupport/. So, for example, while macOS
and zippered Swift overlays are installed in /usr/lib/swift/, iOS-like and
the macCatalyst side of unzippered twins are installed in
/System/iOSSupport/usr/lib/swift. When building for macCatalyst, the build system
passes additional search paths so that the macCatalyst version of libraries is
found before macOS versions.

The add_swift_target_library() funciton now take an
optional  MACCATALYST_BUILD_FLAVOR, which enables swift libraries to indicate
which flavor of library they are.
Add support for testing with macCatalyst to lit.cfg and the test CMake.

This adds lit test features for whether the standard library and runtime was
built with macCatalyst support:

  REQUIRES: maccatalyst_support

The test suite can also be run in two modes: one where the macOS tests
are run as usual (against a zippered standard library, runtime, and overlays)
and another where iOS tests are compiled with the macCatalyst target
triple and executed as macCatalyst processes.

The iOS tests for macCatalyst can be run by passing `--maccatalyst-ios-tests`
to build-script. There are new lit test features to enable a test to specify
whether it supports that environment:

  REQUIRES: OS=maccatalyst
  UNSUPPORTED: OS=macCatalyst
…ch paths

Add support in the driver and frontend for macCatalyst target
targets and library search paths.

The compiler now adds two library search paths for overlays when compiling
for macCatalyst: one for macCatalyst libraries and one for zippered macOS
libraries. The macCatalyst path must take priority over the normal macOS path
so that in the case of 'unzippered twins' the macCatalyst library is
found instead of the macOS library.

To support 'zippered' builds, also add support for a new -target-variant
flag. For zippered libraries, the driver invocation takes both a -target and a
-target-variant flag passes them along to the frontend. We support builds both
when the target is a macOS triple and the target variant is macCatalyst and
also the 'reverse zippered' configuration where the target is macCatalyst and the
target-variant is macOS.
Add support for conditional compilation under macCatalyst

Developers can now detect whether they are compiling for macCatalyst at
compile time with:

  #if targetEnvironment(macCatalyst)
    // Code only compiled under macCatalyst.
  #end
Add a platform kind and availability attributes for macCatalyst. macCatalyst
uses iOS version numbers and inherits availability from iOS attributes unless
a macCatalyst attribute is explicitly provided.
@devincoughlin
Copy link
Contributor Author

@swift-ci please test and merge

1 similar comment
@devincoughlin
Copy link
Contributor Author

@swift-ci please test and merge

@devincoughlin devincoughlin merged commit e9df206 into swiftlang:master Jan 22, 2020
cltnschlosser added a commit to cltnschlosser/swift-driver that referenced this pull request Feb 21, 2020
C++ implementation: swiftlang/swift#29017

Also fixes test/Driver/print_target_info.swift
cltnschlosser added a commit to cltnschlosser/swift-driver that referenced this pull request Mar 6, 2020
C++ implementation: swiftlang/swift#29017

Also fixes test/Driver/print_target_info.swift
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants