- Proposal: SE-NNNN
- Authors: Amir-Abbas Mousavian
- Review Manager: TBD
- Implementation: TBD
- Status: Pending Review
This proposal intends to indroduce a unified way to check building and evironment
conditions and allow to expand them in future. Another intnetion is to decrease os check
as all Apple platforms can be checked by #if target(kernel: Darwin)
rather than
checking for 4 different OSes.
A developer usually must check for environment to expose different behavior in different
building situations. In Swift, this usually is done with #if
precompiling directive.
A flow with current approach is we should check every OS separately, this can lead to confusion and increase maintanence cost for currnet codes as Swift is expanding to new environments and a code should be checked against 12 OSes and architectures.
This proposal deprecates existing #if arch()
& #if os()
grammer and introduces new way:
#if (type: condition)
The type
can be arch
, os
, kernel
, config
and env
. This design allows to replace:
#if os(macOS) || os(ios) || os(tvOS) || os(watchOS)
simply with a more meaningful:
#if target(kernel: Darwin)
If a new operating system would be introduced by Apple based on Darwin, new code will be compiled correctly without any modification.
This will conditions available:
For arch
type, condition can be x86_64, arm, arm64, i386, powerpc64, powerpc64le and s390x
For os
type, condition can be macOS, iOS, watchOS, tvOS, GNU, Windows, FreeBSD, Android, PS4, Cygwin, Haiku, Fuchsia
Please note Linux is a kernel. GNU fits better as operating system.
for kernel
type, condition can be Darwin, Linux, Posix, Zircon
.
Darwin will cover macOS, iOS, watchOS, tvOS
.
Linux will cover GNU, Android, Cygwin
.
BSD will cover FreeBSD, PS4
.
Posix will cover all Darwin, BSD and Linux OSes.
This type simplifies importing in Foundation and StdLib to:
#if target(kernel: Darwin)
import Darwin
#elseif target(kernel: Linux) || target(kernel: BSD)
// equal with `#elseif target(kernel: Posix)` as we checked Darwin already
import Glibc
#endif
For env
type, condition can be simulator, embedded, desktop
.
Also we can define mobile, tablet, watch
as environment, but these
conditions should be handled runtime rather than compile time.
This section covers proposal 190.
For config
type, condition can be debug, release
. This will be affected by Xcode build configuration.
For endian
type, condition can be little, big
. This will be mapped to corresponding arch
types.
We may add support for Metal version by this approach. e.g. #if target(metal: 2)
.
Technically, Linux is a kernel and Gnu is userland of operating system.
In existing system it's a condition for os
.
Cygwin is considered as operating system. We can define it as env with Windows as operating system. But this may add complexity.
This is an additive proposal, existing code will continue to work but we can deprecate existing approach.
A warning and fixit may be provided for migrating recognizable cases in existing code, but this will not be necessarily.
None
None
Some possible alternatives can be considered:
- Keep current approach for architecture and os determination.
- Add
#if config()
and#if kernel()
to existing directives. - Using
cpu
as type instead ofarch
.