> On Nov 9, 2016, at 10:58 AM, Alex Blewitt via swift-evolution > <[email protected]> wrote: > > Although out of scope for phase 1, something that keeps cropping up in a > variety of Linux/Darwin Swift scripts is the conditional inclusion of Darwin > or GlibC per platform. The last point was an observation that creating a > 'nice' wrapper for LibC or a cleaned up POSIX API is a non-goal: > > https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161003/027621.html
I appreciate the desire to have a combined module for this but I'm not convinced that `Libc` (or `LibC`) is a particularly good choice of name here. The `Lib` prefix feels particularly non-Swifty here, most other instances of lib<something> on Darwin have their `lib` prefix dropped when imported as module. From a hierarchical point of view, the `Darwin` module encompasses a suite of libraries that are larger than libsystem_c.dylib (the Darwin Libc). Confusing the naming with layering here would be unfortunate. There's also a potentially confusing Darwin.C submodule that isn't what you're asking for but does step, somewhat, on the namespace. Perhaps names more along the lines of `Platform` or `Base` would work better here? On Darwin the all-encompasing base libraries are all under Libsystem, `System` would be another potentially platform-agnostic name. > >> I think it makes sense to have a cross platform “libc” which is an alias for >> darwin, glibc, or whatever, and just leave it at that. >> >> Other proposals for a “POSIX” module have gotten bogged down because >> inevitably the idea comes up to make the resultant API nicer in various >> ways: rename creat, handle errno more nicely, make use of multiple return >> values, … etc. The problem with this approach is that we don’t *want* >> people using these layer of APIs, we want higher level Foundation-like APIs >> to be used. >> >> ... >> >> >> I think we should formally decide that a “nice” wrapper for libc is a >> non-goal. There is too much that doesn’t make sense to wrap at this level - >> the only Swift code that should be using this is the implementation of >> higher level API, and such extremely narrow cases that we can live with them >> having to handle the problems of dealing with the raw APIs directly. >> >> -Chris >> > > I have created a draft for a proposal to create such a module. Comments are > welcome. > > Alex > > --- > > # Libc module for Swift > > * Proposal: [SE-NNNN](NNNN-filename.md) > * Authors: [Alex Blewitt](https://github.com/alblue) > * Review Manager: TBD > * Status: **Under discussion** > > ## Introduction > > When running on Darwin, the base module is called `Darwin`. When running > on Linux or other operating systems, it's called `GlibC`. > > This repeatedly leads to code such as: > > ```` > #if os(Linux) > import Glibc > #else > import Darwin > #endif > ``` > > As the set of operating systems evolve, one of these conditional imports > needs to be updated. Instead of repeating this, make it available via a > standard `Libc` module in the base Swift library. > > Swift-evolution thread: [Discussion thread topic for that > proposal](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161003/027621.html) > > ## Motivation > > The [set of > platforms](https://github.com/apple/swift/blob/fdf6ee20e4ca1fd32482f4b7b88a97ebdda52cd2/lib/Basic/LangOptions.cpp#L26-L36) > that Swift currently runs on can be divided into two; Darwin and XNU based > systems > (macOS, iOS, watchOS, tvOS), Windows, and Unix based systems > (Linux, FreeBSD, Android, PS4). > > The base module on Darwin is called `Darwin`, while on Linux and > other Unix systems the base module is called `Glibc`. The base > module is typically conditionally included when working at a lower layer > than Foundation (which has the same detail involved in importing the > base module). > > As a result, conditionally importing the right version typically uses > a conditional test based on the operating system, and the same code is > seen in a number of different modules, both internal to Swift and external: > > * [Test for mmap in > stdlib](https://github.com/apple/swift/blob/07b196d2f9a5facc490b35e3649e18937796239b/test/stdlib/mmap.swift#L4-L9) > * [Validation test for > PassIfChildCrashedDuringTestExecution](https://github.com/apple/swift/blob/c3b7709a7c4789f1ad7249d357f69509fb8be731/validation-test/StdlibUnittest/ChildProcessShutdown/PassIfChildCrashedDuringTestExecution.swift#L4-L9) > * [Kitura's Socket > definitions](https://github.com/IBM-Swift/BlueSocket/blob/49c5af8b6953cecc8674a7fcf746fa27a72c056a/Sources/Socket.swift#L21-L25) > * [Vapor's HTTP > Server](https://github.com/vapor/engine/blob/1f95094ee470408309e98dd56b2251210d6a2a3d/Sources/HTTP/Models/Server/HTTP%2BServer.swift#L1-L5) > > Some have already created a `Libc` module that effectively does what this > proposal suggests, such as [Vapor's Core > Libc](https://github.com/vapor/core/blob/master/Sources/libc/libc.swift) > > ``` > #if os(Linux) > @_exported import Glibc > #else > @_exported import Darwin.C > #endif > ``` > > Each of these examples has subtly different behaviour; for example, > whether or not the os tests only include Linux (and then fail over to > Darwin), or whether they contain other Unices such as FreeBSD and Android. > > ## Proposed solution > > The solution is to formalise these patterns in the base Swift library > and present a `Libc` module that conditionally imports `Glibc` or `Darwin` > based on the correct platform. Additional operating systems can be added > and kept up to date with the list of supported operating system conditionals > and including a failure message when an unknown operating system is detected. > > ## Detailed design > > This will add a `Libc` module for the standard library that re-exports > the correct import depending on the operating system: > > ``` > #if os(macOS) || os(iOS) || os(tvOS) || os(watchOS) > @_exported import Darwin > #elseif os(Linux) || os(FreeBSD) || os(Android) || os(PS4) > @_exported import Glibc > #else > fatalError("Libc not supported on operating system") > #endif > ``` > > As new operating systems are added or become supported (such as Windows) > the standard imports can be added appropriately to this module. > > ## Source compatibility > > There is no impact to source compatibility, since this proposal is additive. > Existing source code will work regardless of if this module is used or not. > However it improves source compatibility going forwards, since as new > operating systems are added this file will be updated, instead of the change > having to be made in multiple open-source projects. > > ## Effect on ABI stability > > There is no impact to ABI compatibility, since this proposal is additive. > Existing source code will work regardless of if this module is used or not. > > ## Effect on API resilience > > There is no impact to ABI resilience, since this proposal is additive. > Existing source code will work regardless of if this module is used or not. > > ## Alternatives considered > > The first alternative is to do nothing. Existing Swift projects already > conditionally import these modules, or import a higher-level module (such > as `Foundation`) that performs the conditional import. > > The second alternative is to export sub-modules of the modules. Clang > permits imports of sub-modules, so it could be possible to import only > `Darwin.POSIX` and `GlibC.POSIX`. However, in Swift, importing a sub-module > makes the whole module available anyway, so the difference between importing > a whole module versus a submodule is irrelevant. > > The third alternative is to explore creating standard functions (in Swift) > corresponding to POSIX functionality, but where the format of the return > results are known. This would require a per-operating system binding to > expose operating-system details such as the byte ordering of structures > as used in the various `getaddrinfo` calls. These may evolve out of future > evolution proposals and this does not conflict with those goals at this > stage. There are additional clean-ups that this could address, such as the > use of the (thread-local) `errno` which may not be reliably read from within > Swift. However, the (swift-evolution > thread)[https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161003/027602.html] > calls this "the perfect being the enemy of the good". Instead of trying to > solve all of these problems, they should be handled by subsequent > proposals (such as (Johannes' > proposal)[https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161031/028627.html] > regarding errno handling sent to swift-evolution previously). > _______________________________________________ > 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
