on Wed Nov 09 2016, Matt Wright <swift-evolution@swift.org> wrote: >> On Nov 9, 2016, at 10:58 AM, Alex Blewitt via swift-evolution >> <swift-evolution@swift.org> 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.
Howzat going to work out on Windows? >> >>> 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 >> swift-evolution@swift.org >> https://lists.swift.org/mailman/listinfo/swift-evolution > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution -- -Dave _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution