Platform: port to msvcrt, add msvcrt module

This adds the swiftMSVCRT module which is similar in spirit to swiftGlibc and
swiftDarwin, exposing the Microsoft C Runtime library to swift.  Furthermore,
disable pieces of the standard library which are not immediately trivially
portable to Windows.  A lot of this functionality can still be implemented and
exposed to the user, however, this is the quickest means to a PoC for native
windows support.

As a temporary solution, add a -DCYGWIN flag to indicate that we are building
for the cygwin windows target.  This allows us to continue supporting the cygwin
environment whilst making the windows port work natively against the windows
environment (msvc).  Eventually, that will hopefully be replaced with an
environment check in swift.
This commit is contained in:
Saleem Abdulrasool
2016-07-03 14:43:06 -07:00
parent d39ad943d4
commit a05fd17b64
11 changed files with 301 additions and 19 deletions

View File

@@ -54,6 +54,9 @@ function(handle_swift_sources
if (NOT SWIFTSOURCES_IS_MAIN)
list(APPEND swift_compile_flags "-module-link-name" "${name}")
endif()
if("${SWIFTSOURCES_SDK}" STREQUAL "CYGWIN")
list(APPEND swift_compile_flags -DCYGWIN)
endif()
if(swift_sources)
# Special-case hack to create Swift.o for the core standard library.

View File

@@ -10,8 +10,8 @@
//
//===----------------------------------------------------------------------===//
// Spawn is not available on Android.
#if !defined(__ANDROID__)
// posix_spawn is not available on Android or Windows (MSVC).
#if !defined(__ANDROID__) && (!defined(_WIN32) || defined(__CYGWIN__))
#include "swift/Runtime/Config.h"
@@ -65,5 +65,5 @@ char ***swift_SwiftPrivateLibcExtras_NSGetEnviron(void) {
return _NSGetEnviron();
}
#endif // defined(__APPLE__)
#endif // defined(__ANDROID__)
#endif // !defined(__ANDROID__) && (!defined(_WIN32) || defined(__CGYWIN__))

View File

@@ -18,7 +18,8 @@ import Glibc
#endif
// posix_spawn is not available on Android.
#if !os(Windows) || CYGWIN
// posix_spawn is not available on Android or Windows.
#if !os(Android)
// swift_posix_spawn isn't available in the public watchOS SDK, we sneak by the
// unavailable attribute declaration here of the APIs that we need.
@@ -293,3 +294,5 @@ internal func _getEnviron() -> UnsafeMutablePointer<UnsafeMutablePointer<CChar>?
return __environ
#endif
}
#endif

View File

@@ -17,6 +17,7 @@ import Darwin
import Glibc
#endif
#if !os(Windows) || CYGWIN
public func _stdlib_mkstemps(_ template: inout String, _ suffixlen: CInt) -> CInt {
#if os(Android)
preconditionFailure("mkstemps doesn't work on Android")
@@ -32,6 +33,7 @@ public func _stdlib_mkstemps(_ template: inout String, _ suffixlen: CInt) -> CIn
return fd
#endif
}
#endif
public var _stdlib_FD_SETSIZE: CInt {
return 1024
@@ -81,6 +83,7 @@ public struct _stdlib_fd_set {
}
}
#if !os(Windows) || CYGWIN
public func _stdlib_select(
_ readfds: inout _stdlib_fd_set, _ writefds: inout _stdlib_fd_set,
_ errorfds: inout _stdlib_fd_set, _ timeout: UnsafeMutablePointer<timeval>?
@@ -104,6 +107,7 @@ public func _stdlib_select(
}
}
}
#endif
//
// Functions missing in `Darwin` module.

View File

@@ -22,6 +22,11 @@ add_swift_library(swiftGlibc ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
TARGET_SDKS ANDROID CYGWIN FREEBSD LINUX
DEPENDS glibc_modulemap)
add_swift_library(swiftMSVCRT ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
msvcrt.swift
${swift_platform_sources}
TARGET_SDKS WINDOWS)
set(glibc_modulemap_target_list)
foreach(sdk ${SWIFT_SDKS})
if("${sdk}" STREQUAL "LINUX" OR

View File

@@ -11,18 +11,33 @@
//===----------------------------------------------------------------------===//
#include <fcntl.h>
#if !defined(_WIN32) || defined(__CYGWIN__)
#include <semaphore.h>
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <io.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#if !defined(_WIN32) || defined(__CYGWIN__)
#include <sys/ioctl.h>
#endif
#include "swift/Runtime/Config.h"
#if !defined(_WIN32) || defined(__CYGWIN__)
SWIFT_CC(swift)
extern int _swift_Platform_open(const char *path, int oflag, mode_t mode) {
return open(path, oflag, mode);
}
#else
SWIFT_CC(swift)
extern int _swift_Platform_open(const char *path, int oflag, int mode) {
return _open(path, oflag, mode);
}
#endif
#if !defined(_WIN32) || defined(__CYGWIN__)
SWIFT_CC(swift)
extern int _swift_Platform_openat(int fd, const char *path, int oflag,
mode_t mode) {
@@ -61,6 +76,7 @@ extern int
_swift_Platform_ioctlPtr(int fd, unsigned long int request, void* ptr) {
return ioctl(fd, request, ptr);
}
#endif
#if defined(__APPLE__)
#define _REENTRANT

View File

@@ -98,9 +98,14 @@ public var errno : Int32 {
get {
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) || os(FreeBSD) || os(PS4)
return __error().pointee
// FIXME: os(Windows) should be replaced, such as triple(Cygwin)
#elseif os(Android) || os(Windows)
#elseif os(Android)
return __errno().pointee
#elseif os(Windows)
#if CYGWIN
return __errno().pointee
#else
return _errno().pointee
#endif
#else
return __errno_location().pointee
#endif
@@ -108,8 +113,14 @@ public var errno : Int32 {
set(val) {
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) || os(FreeBSD) || os(PS4)
return __error().pointee = val
#elseif os(Android) || os(Windows)
#elseif os(Android)
return __errno().pointee = val
#elseif os(Windows)
#if CYGWIN
return __errno().pointee = val
#else
return _errno().pointee = val
#endif
#else
return __errno_location().pointee = val
#endif
@@ -165,13 +176,23 @@ public func snprintf(ptr: UnsafeMutablePointer<Int8>, _ len: Int, _ format: Unsa
// fcntl.h
//===----------------------------------------------------------------------===//
#if !os(Windows) || CYGWIN
@_silgen_name("_swift_Platform_open")
func _swift_Platform_open(
_ path: UnsafePointer<CChar>,
_ oflag: Int32,
_ mode: mode_t
) -> Int32
#else
@_silgen_name("_swift_Platform_open")
func _swift_Platform_open(
_ path: UnsafePointer<CChar>,
_ oflag: Int32,
_ mode: Int32
) -> Int32
#endif
#if !os(Windows) || CYGWIN
@_silgen_name("_swift_Platform_openat")
func _swift_Platform_openat(
_ fd: Int32,
@@ -179,6 +200,7 @@ func _swift_Platform_openat(
_ oflag: Int32,
_ mode: mode_t
) -> Int32
#endif
public func open(
_ path: UnsafePointer<CChar>,
@@ -187,6 +209,7 @@ public func open(
return _swift_Platform_open(path, oflag, 0)
}
#if !os(Windows) || CYGWIN
public func open(
_ path: UnsafePointer<CChar>,
_ oflag: Int32,
@@ -211,7 +234,17 @@ public func openat(
) -> Int32 {
return _swift_Platform_openat(fd, path, oflag, mode)
}
#else
public func open(
_ path: UnsafePointer<CChar>,
_ oflag: Int32,
_ mode: Int32
) -> Int32 {
return _swift_Platform_open(path, oflag, mode)
}
#endif
#if !os(Windows) || CYGWIN
@_silgen_name("_swift_Platform_fcntl")
internal func _swift_Platform_fcntl(
_ fd: Int32,
@@ -248,7 +281,9 @@ public func fcntl(
) -> Int32 {
return _swift_Platform_fcntlPtr(fd, cmd, ptr)
}
#endif
#if !os(Windows) || CYGWIN
public var S_IFMT: mode_t { return mode_t(0o170000) }
public var S_IFIFO: mode_t { return mode_t(0o010000) }
public var S_IFCHR: mode_t { return mode_t(0o020000) }
@@ -286,11 +321,24 @@ public var S_IREAD: mode_t { return S_IRUSR }
public var S_IWRITE: mode_t { return S_IWUSR }
public var S_IEXEC: mode_t { return S_IXUSR }
#endif
#else
public var S_IFMT: Int32 { return Int32(0xf000) }
public var S_IFREG: Int32 { return Int32(0x8000) }
public var S_IFDIR: Int32 { return Int32(0x4000) }
public var S_IFCHR: Int32 { return Int32(0x2000) }
public var S_IFIFO: Int32 { return Int32(0x1000) }
public var S_IREAD: Int32 { return Int32(0x0100) }
public var S_IWRITE: Int32 { return Int32(0x0080) }
public var S_IEXEC: Int32 { return Int32(0x0040) }
#endif
//===----------------------------------------------------------------------===//
// ioctl.h
//===----------------------------------------------------------------------===//
#if !os(Windows) || CYGWIN
@_silgen_name("_swift_Platform_ioctl")
internal func _swift_Platform_ioctl(
_ fd: CInt,
@@ -327,7 +375,7 @@ public func ioctl(
) -> CInt {
return _swift_Platform_ioctl(fd, request, 0)
}
#endif
//===----------------------------------------------------------------------===//
// unistd.h
@@ -354,14 +402,22 @@ public var SIG_DFL: sig_t? { return nil }
public var SIG_IGN: sig_t { return unsafeBitCast(1, to: sig_t.self) }
public var SIG_ERR: sig_t { return unsafeBitCast(-1, to: sig_t.self) }
public var SIG_HOLD: sig_t { return unsafeBitCast(5, to: sig_t.self) }
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Windows)
#if os(Windows)
// In Cygwin, the below SIG_* have the same value with Linux.
// Verified with libstdc++6 v5.3.0 in Cygwin v2.4.1 64bit.
public typealias sighandler_t = _sig_func_ptr
#else
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
public typealias sighandler_t = __sighandler_t
public var SIG_DFL: sighandler_t? { return nil }
public var SIG_IGN: sighandler_t {
return unsafeBitCast(1, to: sighandler_t.self)
}
public var SIG_ERR: sighandler_t {
return unsafeBitCast(-1, to: sighandler_t.self)
}
public var SIG_HOLD: sighandler_t {
return unsafeBitCast(2, to: sighandler_t.self)
}
#elseif os(Windows)
#if CYGWIN
public typealias sighandler_t = __sighandler_t
#endif
public var SIG_DFL: sighandler_t? { return nil }
public var SIG_IGN: sighandler_t {
@@ -374,6 +430,15 @@ public var SIG_HOLD: sighandler_t {
return unsafeBitCast(2, to: sighandler_t.self)
}
#else
public var SIG_DFL: _crt_signal_t? { return nil }
public var SIG_IGN: _crt_signal_t {
return unsafeBitCast(1, to: _crt_signal_t.self)
}
public var SIG_ERR: _crt_signal_t {
return unsafeBitCast(-1, to: _crt_signal_t.self)
}
#endif
#else
internal var _ignore = _UnsupportedPlatformError()
#endif
@@ -381,14 +446,22 @@ internal var _ignore = _UnsupportedPlatformError()
// semaphore.h
//===----------------------------------------------------------------------===//
#if !os(Windows) || CYGWIN
/// The value returned by `sem_open()` in the case of failure.
public var SEM_FAILED: UnsafeMutablePointer<sem_t>? {
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
// The value is ABI. Value verified to be correct for OS X, iOS, watchOS, tvOS.
return UnsafeMutablePointer<sem_t>(bitPattern: -1)
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Windows)
#elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
// The value is ABI. Value verified to be correct on Glibc.
return UnsafeMutablePointer<sem_t>(bitPattern: 0)
#elseif os(Windows)
#if CYGWIN
// The value is ABI. Value verified to be correct on Glibc.
return UnsafeMutablePointer<sem_t>(bitPattern: 0)
#else
_UnsupportedPlatformError()
#endif
#else
_UnsupportedPlatformError()
#endif
@@ -423,6 +496,7 @@ public func sem_open(
) -> UnsafeMutablePointer<sem_t>? {
return _swift_Platform_sem_open4(name, oflag, mode, value)
}
#endif
//===----------------------------------------------------------------------===//
// Misc.

View File

@@ -0,0 +1,15 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
@_exported import ucrt // Clang module
@_exported import visualc // Clang module

View File

@@ -171,11 +171,25 @@ public func fpclassify(_ value: ${T}) -> Int {
%if T == 'Double':
#if os(Linux)
return Int(__fpclassify(CDouble(value)))
#elseif os(Windows)
#if CYGWIN
return Int(__fpclassify(CDouble(value)))
#else
return Int(_dclass(CDouble(value)))
#endif
#else
return Int(__fpclassifyd(CDouble(value)))
#endif
%else:
#if os(Windows)
#if CYGWIN
return Int(__fpclassify${f}(${CT}(value)))
#else
return Int(_${f}dclass(${CT}(value)))
#endif
#else
return Int(__fpclassify${f}(${CT}(value)))
#endif
%end
}
@@ -247,13 +261,24 @@ public func scalbn(_ x: ${T}, _ n: Int) -> ${T} {
% # This is AllFloatTypes not OverlayFloatTypes because of the tuple return.
% for T, CT, f in AllFloatTypes():
#if os(Linux) || os(FreeBSD) || os(PS4) || os(Android) || os(Windows)
#if os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
@_transparent
public func lgamma(_ x: ${T}) -> (${T}, Int) {
var sign = Int32(0)
let value = lgamma${f}_r(${CT}(x), &sign)
return (${T}(value), Int(sign))
}
#elseif os(Windows)
#if CYGWIN
@_transparent
public func lgamma(_ x: ${T}) -> (${T}, Int) {
var sign = Int32(0)
let value = lgamma${f}_r(${CT}(x), &sign)
return (${T}(value), Int(sign))
}
#else
// TODO(compnerd): implement
#endif
#else
% # On Darwin platform,
% # The real lgamma_r is not imported because it hides behind macro _REENTRANT.
@@ -305,12 +330,28 @@ public func fma(_ x: ${T}, _ y: ${T}, _ z: ${T}) -> ${T} {
% # These C functions only support double. The overlay fixes the Int parameter.
@_transparent
public func jn(_ n: Int, _ x: Double) -> Double {
#if os(Windows)
#if CYGWIN
return jn(Int32(n), x)
#else
return _jn(Int32(n), x)
#endif
#else
return jn(Int32(n), x)
#endif
}
@_transparent
public func yn(_ n: Int, _ x: Double) -> Double {
#if os(Windows)
#if CYGWIN
return yn(Int32(n), x)
#else
return _yn(Int32(n), x)
#endif
#else
return yn(Int32(n), x)
#endif
}
% end

View File

@@ -0,0 +1,102 @@
//===--- ucrt.modulemap ---------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
module ucrt [system] {
module C {
module complex {
header "complex.h"
export *
}
module ctype {
header "ctype.h"
export *
}
module errno {
header "errno.h"
export *
}
module fenv {
header "fenv.h"
export *
}
module inttypes {
header "inttypes.h"
export *
}
module locale {
header "locale.h"
export *
}
module math {
header "math.h"
export *
}
module signal {
header "signal.h"
export *
}
module stddef {
header "stddef.h"
export *
}
module stdio {
header "stdio.h"
export *
}
module stdlib {
header "stdlib.h"
export *
}
module string {
header "string.h"
export *
}
module time {
header "time.h"
export *
}
module POSIX {
module sys {
export *
module stat {
header "sys/stat.h"
export *
}
module types {
header "sys/types.h"
export *
}
module utime {
header "sys/utime.h"
export *
}
}
}
}
}

View File

@@ -0,0 +1,19 @@
//===--- vc.modulemap -----------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
module visualc [system] {
module SAL {
header "sal.h"
export *
}
}