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) if (NOT SWIFTSOURCES_IS_MAIN)
list(APPEND swift_compile_flags "-module-link-name" "${name}") list(APPEND swift_compile_flags "-module-link-name" "${name}")
endif() endif()
if("${SWIFTSOURCES_SDK}" STREQUAL "CYGWIN")
list(APPEND swift_compile_flags -DCYGWIN)
endif()
if(swift_sources) if(swift_sources)
# Special-case hack to create Swift.o for the core standard library. # Special-case hack to create Swift.o for the core standard library.

View File

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

View File

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

View File

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

View File

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

View File

@@ -98,9 +98,14 @@ public var errno : Int32 {
get { get {
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) || os(FreeBSD) || os(PS4) #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) || os(FreeBSD) || os(PS4)
return __error().pointee return __error().pointee
// FIXME: os(Windows) should be replaced, such as triple(Cygwin) #elseif os(Android)
#elseif os(Android) || os(Windows)
return __errno().pointee return __errno().pointee
#elseif os(Windows)
#if CYGWIN
return __errno().pointee
#else
return _errno().pointee
#endif
#else #else
return __errno_location().pointee return __errno_location().pointee
#endif #endif
@@ -108,8 +113,14 @@ public var errno : Int32 {
set(val) { set(val) {
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) || os(FreeBSD) || os(PS4) #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) || os(FreeBSD) || os(PS4)
return __error().pointee = val return __error().pointee = val
#elseif os(Android) || os(Windows) #elseif os(Android)
return __errno().pointee = val return __errno().pointee = val
#elseif os(Windows)
#if CYGWIN
return __errno().pointee = val
#else
return _errno().pointee = val
#endif
#else #else
return __errno_location().pointee = val return __errno_location().pointee = val
#endif #endif
@@ -165,13 +176,23 @@ public func snprintf(ptr: UnsafeMutablePointer<Int8>, _ len: Int, _ format: Unsa
// fcntl.h // fcntl.h
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if !os(Windows) || CYGWIN
@_silgen_name("_swift_Platform_open") @_silgen_name("_swift_Platform_open")
func _swift_Platform_open( func _swift_Platform_open(
_ path: UnsafePointer<CChar>, _ path: UnsafePointer<CChar>,
_ oflag: Int32, _ oflag: Int32,
_ mode: mode_t _ mode: mode_t
) -> Int32 ) -> 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") @_silgen_name("_swift_Platform_openat")
func _swift_Platform_openat( func _swift_Platform_openat(
_ fd: Int32, _ fd: Int32,
@@ -179,6 +200,7 @@ func _swift_Platform_openat(
_ oflag: Int32, _ oflag: Int32,
_ mode: mode_t _ mode: mode_t
) -> Int32 ) -> Int32
#endif
public func open( public func open(
_ path: UnsafePointer<CChar>, _ path: UnsafePointer<CChar>,
@@ -187,6 +209,7 @@ public func open(
return _swift_Platform_open(path, oflag, 0) return _swift_Platform_open(path, oflag, 0)
} }
#if !os(Windows) || CYGWIN
public func open( public func open(
_ path: UnsafePointer<CChar>, _ path: UnsafePointer<CChar>,
_ oflag: Int32, _ oflag: Int32,
@@ -211,7 +234,17 @@ public func openat(
) -> Int32 { ) -> Int32 {
return _swift_Platform_openat(fd, path, oflag, mode) 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") @_silgen_name("_swift_Platform_fcntl")
internal func _swift_Platform_fcntl( internal func _swift_Platform_fcntl(
_ fd: Int32, _ fd: Int32,
@@ -248,7 +281,9 @@ public func fcntl(
) -> Int32 { ) -> Int32 {
return _swift_Platform_fcntlPtr(fd, cmd, ptr) 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_IFMT: mode_t { return mode_t(0o170000) }
public var S_IFIFO: mode_t { return mode_t(0o010000) } public var S_IFIFO: mode_t { return mode_t(0o010000) }
public var S_IFCHR: mode_t { return mode_t(0o020000) } 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_IWRITE: mode_t { return S_IWUSR }
public var S_IEXEC: mode_t { return S_IXUSR } public var S_IEXEC: mode_t { return S_IXUSR }
#endif #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 // ioctl.h
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if !os(Windows) || CYGWIN
@_silgen_name("_swift_Platform_ioctl") @_silgen_name("_swift_Platform_ioctl")
internal func _swift_Platform_ioctl( internal func _swift_Platform_ioctl(
_ fd: CInt, _ fd: CInt,
@@ -327,8 +375,8 @@ public func ioctl(
) -> CInt { ) -> CInt {
return _swift_Platform_ioctl(fd, request, 0) return _swift_Platform_ioctl(fd, request, 0)
} }
#endif
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// unistd.h // 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_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_ERR: sig_t { return unsafeBitCast(-1, to: sig_t.self) }
public var SIG_HOLD: sig_t { return unsafeBitCast(5, 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) #elseif os(Linux) || os(FreeBSD) || os(PS4) || os(Android)
#if os(Windows) public typealias sighandler_t = __sighandler_t
// 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 var SIG_DFL: sighandler_t? { return nil }
public typealias sighandler_t = _sig_func_ptr public var SIG_IGN: sighandler_t {
#else 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 public typealias sighandler_t = __sighandler_t
#endif
public var SIG_DFL: sighandler_t? { return nil } public var SIG_DFL: sighandler_t? { return nil }
public var SIG_IGN: sighandler_t { public var SIG_IGN: sighandler_t {
@@ -374,6 +430,15 @@ public var SIG_HOLD: sighandler_t {
return unsafeBitCast(2, to: sighandler_t.self) return unsafeBitCast(2, to: sighandler_t.self)
} }
#else #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() internal var _ignore = _UnsupportedPlatformError()
#endif #endif
@@ -381,14 +446,22 @@ internal var _ignore = _UnsupportedPlatformError()
// semaphore.h // semaphore.h
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#if !os(Windows) || CYGWIN
/// The value returned by `sem_open()` in the case of failure. /// The value returned by `sem_open()` in the case of failure.
public var SEM_FAILED: UnsafeMutablePointer<sem_t>? { public var SEM_FAILED: UnsafeMutablePointer<sem_t>? {
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS) #if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
// The value is ABI. Value verified to be correct for OS X, iOS, watchOS, tvOS. // The value is ABI. Value verified to be correct for OS X, iOS, watchOS, tvOS.
return UnsafeMutablePointer<sem_t>(bitPattern: -1) 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. // The value is ABI. Value verified to be correct on Glibc.
return UnsafeMutablePointer<sem_t>(bitPattern: 0) 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 #else
_UnsupportedPlatformError() _UnsupportedPlatformError()
#endif #endif
@@ -423,6 +496,7 @@ public func sem_open(
) -> UnsafeMutablePointer<sem_t>? { ) -> UnsafeMutablePointer<sem_t>? {
return _swift_Platform_sem_open4(name, oflag, mode, value) return _swift_Platform_sem_open4(name, oflag, mode, value)
} }
#endif
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Misc. // 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 T == 'Double':
#if os(Linux) #if os(Linux)
return Int(__fpclassify(CDouble(value))) return Int(__fpclassify(CDouble(value)))
#elseif os(Windows)
#if CYGWIN
return Int(__fpclassify(CDouble(value)))
#else
return Int(_dclass(CDouble(value)))
#endif
#else #else
return Int(__fpclassifyd(CDouble(value))) return Int(__fpclassifyd(CDouble(value)))
#endif #endif
%else: %else:
#if os(Windows)
#if CYGWIN
return Int(__fpclassify${f}(${CT}(value))) return Int(__fpclassify${f}(${CT}(value)))
#else
return Int(_${f}dclass(${CT}(value)))
#endif
#else
return Int(__fpclassify${f}(${CT}(value)))
#endif
%end %end
} }
@@ -247,13 +261,24 @@ public func scalbn(_ x: ${T}, _ n: Int) -> ${T} {
% # This is AllFloatTypes not OverlayFloatTypes because of the tuple return. % # This is AllFloatTypes not OverlayFloatTypes because of the tuple return.
% for T, CT, f in AllFloatTypes(): % 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 @_transparent
public func lgamma(_ x: ${T}) -> (${T}, Int) { public func lgamma(_ x: ${T}) -> (${T}, Int) {
var sign = Int32(0) var sign = Int32(0)
let value = lgamma${f}_r(${CT}(x), &sign) let value = lgamma${f}_r(${CT}(x), &sign)
return (${T}(value), Int(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 #else
% # On Darwin platform, % # On Darwin platform,
% # The real lgamma_r is not imported because it hides behind macro _REENTRANT. % # 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. % # These C functions only support double. The overlay fixes the Int parameter.
@_transparent @_transparent
public func jn(_ n: Int, _ x: Double) -> Double { public func jn(_ n: Int, _ x: Double) -> Double {
#if os(Windows)
#if CYGWIN
return jn(Int32(n), x) return jn(Int32(n), x)
#else
return _jn(Int32(n), x)
#endif
#else
return jn(Int32(n), x)
#endif
} }
@_transparent @_transparent
public func yn(_ n: Int, _ x: Double) -> Double { public func yn(_ n: Int, _ x: Double) -> Double {
#if os(Windows)
#if CYGWIN
return yn(Int32(n), x) return yn(Int32(n), x)
#else
return _yn(Int32(n), x)
#endif
#else
return yn(Int32(n), x)
#endif
} }
% end % 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 *
}
}