Strong +1, in my experience in other languages OS based tests (or worse, browser tests in Javascript, *shudders*) are far too often misused, modules are definitely the better way to go.
My only question is whether there should be a way to test minimum module versions? If I add support for a module but target a particularly recent version then that support won’t compile for platforms with older versions of the same module, so I should be able to prevent them from being a match. > On 22 Mar 2016, at 22:14, Erica Sadun via swift-evolution > <[email protected]> wrote: > > Here's another one, hopefully with a little more grounding than the debug > test. > I welcome feedback both positive and critical, -- E > > Adding an Build Configuration Import Test > > Proposal: SE-00XX > Author(s): Erica Sadun <http://github.com/erica> > Status: TBD > Review manager: TBD > <https://gist.github.com/erica/b7f4226b8201945602f2#introduction>Introduction > > Expanding the build configuration suite to test for the ability to import > certain modules was first introduced > <http://article.gmane.org/gmane.comp.lang.swift.evolution/7516/match=darwin> > on the Swift-Evolution list by Kevin Ballard. Although his initial idea > (checking for Darwin to differentiate Apple targets from non-Apple targets) > proved problematic, developers warmly greeted the notion of an import-based > configuration test. Dmitri Gribenko wrote, "There's a direction that we want > to move to a unified name for the libc module for all platform, so 'can > import Darwin' might not be a viable long-term strategy." Testing for imports > offers advantages that stand apart from this one use-case: to test for API > availability before use. > > <https://gist.github.com/erica/b7f4226b8201945602f2#motivation>Motivation > > Swift's existing set of build configurations specify platform differences, > not module commonalities. For example, UIKit enables you to write view code > supported on both iOS and tvOS. SpriteKit allows common code to render on OS > X, iOS, and tvOS that would require an alternate UI on Linux. Testing for > Metal support or Media Player would guard code that will not function on the > simulator. If the simulator adopted these modules at some future time, the > code would naturally expand to provide compatible execution without source > modification. > > #if canImport(UIKit) > // UIKit-based code > #elseif canImport(Cocoa) > // OSX code > #elseif > // Workaround/text, whatever > #endif > Guarding code with operating system tests can be less future-proofed than > testing for module support. Excluding OS X to use UIColor creates code that > might eventually find its way to a Linux plaform. Targeting Apple platforms > by inverting a test for Linux essentially broke after the introduction of > Windows and FreeBSD build configurations: > > // Exclusive os tests are brittle > #if !os(Linux) > // Matches OSX, iOS, watchOS, tvOS, Windows, FreeBSD > #endif > Inclusive OS tests (if os1 || os2 || os3...) must be audited each time the > set of possible platforms expands. In addition, compound build statements are > harder to write, to validate, and are more confusing to read. They are more > prone to errors than a single test that's tied to the API capabilities used > by the code it guards. > > Evan Maloney writes, "Being able to test for the importability of a given > module/framework at runtime would be extremely helpful. We use several > frameworks that are only available in a subset of the platforms we support, > and on only certain OS versions. To work around this problem now, we > dynamically load frameworks from Obj-C only when we're running on an OS > version we know is supported by the framework(s) in question. We can't > dynamically load them from Swift because if they're included in an import, > the runtime tries to load it right away, leading to a crash on any > unsupported platform. The only way to selectively load dynamic frameworks at > runtime is to do it via Obj-C. Some sort of check like the ones you propose > should let us avoid this." > > <https://gist.github.com/erica/b7f4226b8201945602f2#detail-design>Detail > Design > > #if canImport(module-name) tests for module support by name. My proposed name > uses lower camelCase, which is not currently used in the current build > configuration vocabulary but is (in my opinion) clearer in intention than the > other two terms brought up on the evolution list, #if imports() and #if > supports(). > > This build configuration does not import the module it names > This build configuration is intended to differentiate API access > This build configuration should not be used to differentiate platforms > The supplied module token is an arbitrary string. It does not belong to an > enumerated set of known members as this configuration test is intended for > use with both first and third party modules for the greatest flexibility. At > compile time, Swift determines whether the module can or cannot be linked and > builds accordingly. > #if canImport(module) > import module > // use module APIs safely > #endif > > #if canImport(module) > // provide solution with module APIs > #else > // provide alternative solution that does not depend on that module > #endif > <https://gist.github.com/erica/b7f4226b8201945602f2#current-art>Current Art > > Swift currently supports the following configuration tests: > > The literals true and false > The os() function that tests for OSX, iOS, watchOS, tvOS, Linux, Windows, and > FreeBSD > The arch() function that tests for x86_64, arm, arm64, i386, powerpc64, and > powerpc64le > The swift() function that tests for specific Swift language releases, e.g. > swift(>=2.2) > > <https://gist.github.com/erica/b7f4226b8201945602f2#alternatives-considered>Alternatives > Considered > > There are no alternatives considered. > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
