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
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.
This makes the product computation more terse and adds the missing
options. The functional aspects of this change include renaming the
`SKIP_BUILD_SWIFT_STATIC_LIBDISPATCH` to `SKIP_BUILD_STATIC_LIBDISPATCH`
which keeps it in line with the other skip options. We also now list
the option properly.
Move the special flag handling for the non-atomic runtime into the build
system rather than spreading it across the build system and the helper
utilities.
This reorders the option list. It tries to categorise them by area and
then sort them alphabetically. This should help work through the list
and remove the now defunct options as well as try to reduce the set of
options into different build configurations that we can support and try
to organise the CMake invocations properly.
There is still a group of uncategorised options that should get sorted
out at some point. However, this is still a huge step forward towards
simplifying (and hopefully eradicating) this monstrous script.
libdispatch is required by Foundation. The
`FOUNDATION_ENABLE_LIBDISPATCH` flag was removed a while ago from
Foundation itself. Remove the handling for this option and simplify the
flag handling.
If IFS remains set, it may cause compilation errors due to unanticipated
replacement of characters in some parameters.
Addresses rdar://problem/57927748
In the majority of cases, we can derive the value of SWIFT_HOST_VARIANT,
SWIFT_HOST_VARIANT_SDK, and SWIFT_HOST_VARIANT_ARCH from the value of `host`
itself. The goal of this patch is to make those derivations and avoid lots of
manual setting of values. Because we verify that we have a valid host before
doing this, we can be sure that errors should be caught before we try to
deconstruct the host into platform and architecture values.
For situations where you can't derive those values from the host, we leave
existing behavior -- that is, we handle them in a switch statement.
By verifying that the host is supported before doing any operations, we can
assume that the host value is properly formed, meaning we can simplify the logic
to set values based on the host. Follow-up commits will do exactly that.