-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[stdlib] Add a version number for the stdlib itself; use it in unit tests #24254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
74731e4
5704f9b
309e564
65728ea
9ba4dfa
71f57d3
3ed8432
dd09383
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See https://swift.org/LICENSE.txt for license information | ||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
public struct StdlibVersion: RawRepresentable { | ||
public let rawValue: (Int, Int) | ||
|
||
public init(rawValue: (Int, Int)) { | ||
self.rawValue = rawValue | ||
} | ||
} | ||
|
||
extension StdlibVersion { | ||
public static func custom(_ version1: Int, _ version2: Int) -> StdlibVersion { | ||
return StdlibVersion(rawValue: (version1, version2)) | ||
} | ||
|
||
public static var currentlyRunning: StdlibVersion { | ||
return StdlibVersion(rawValue: _stdlibDynamicVersion) | ||
} | ||
|
||
// Shipped in macOS 10.14.2, iOS 12.2, watchOS 5.2, tvOS 13.2 | ||
public static var swift5_0: StdlibVersion { | ||
return StdlibVersion(rawValue: (1000, 0)) | ||
} | ||
} | ||
|
||
extension StdlibVersion: CustomStringConvertible { | ||
public var description: String { | ||
return "\(rawValue)" | ||
} | ||
} | ||
|
||
extension StdlibVersion: Equatable { | ||
public static func == (left: StdlibVersion, right: StdlibVersion) -> Bool { | ||
return left.rawValue == right.rawValue | ||
} | ||
} | ||
|
||
extension StdlibVersion: Hashable { | ||
public func hash(into hasher: inout Hasher) { | ||
hasher.combine(rawValue.0) | ||
hasher.combine(rawValue.1) | ||
} | ||
} | ||
|
||
extension StdlibVersion: Comparable { | ||
public static func < (left: StdlibVersion, right: StdlibVersion) -> Bool { | ||
return left.rawValue < right.rawValue | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,3 +45,52 @@ public func _stdlib_isOSVersionAtLeast( | |
return false._value | ||
#endif | ||
} | ||
|
||
/// Returns the version number for the Swift Standard Library that the code | ||
/// calling this was originally compiled with. | ||
/// | ||
/// The version number is an arbitrary pair of integers, with lexicographical | ||
/// ordering. Version numbers of (logically) successive stdlib releases form a | ||
/// monotonically increasing sequence; i.e., versions should not decrease, but | ||
/// they are allowed to stay the same. | ||
/// | ||
/// The two integer components are not intended to correspond to major or minor | ||
/// versions in a semantic versioning scheme. Neither do they correlate with | ||
/// toolchain or OS version numbers. | ||
public var _stdlibStaticVersion: (Int, Int) { | ||
@_alwaysEmitIntoClient | ||
lorentey marked this conversation as resolved.
Show resolved
Hide resolved
|
||
get { | ||
// On the master branch, increment the first number. | ||
// On release branches, increment the second number. | ||
return (1001, 0) | ||
} | ||
} | ||
|
||
/// Returns the version number for the Swift Standard Library that is currently | ||
/// loaded. | ||
/// | ||
/// The version number is an arbitrary pair of integers, with lexicographical | ||
/// ordering. Version numbers of (logically) successive stdlib releases form a | ||
/// monotonically increasing sequence; i.e., versions should not decrease, but | ||
/// they are allowed to stay the same. | ||
/// | ||
/// The two integer components are not intended to correspond to major or minor | ||
/// versions in a semantic versioning scheme. Neither do they correlate with | ||
/// toolchain or OS version numbers. | ||
@_alwaysEmitIntoClient // Introduced in 5.1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we want back-deployment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a reason we shouldn't? I expect to always be able to retrieve a version number; tying it to an explicit availability check would reduce its usefulness. |
||
public var _stdlibDynamicVersion: (Int, Int) { | ||
if #available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *) { | ||
return _stdlibOpaqueVersion | ||
} | ||
else { | ||
// When linked with the 5.0 stdlib, we return this default value. | ||
return (1000, 0) | ||
} | ||
} | ||
|
||
@available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *) | ||
@usableFromInline | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not needed if not back deploying |
||
internal var _stdlibOpaqueVersion: (Int, Int) { | ||
return _stdlibStaticVersion | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still a little confused. Why is this public?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It allows tests to easily determine if they are back/forward deployed. Binaries that are intimately tied to a particular revision of the stdlib and should not be separately back/forward deployed (e.g. libswiftFoundation) could use it for sanity checks.
This is not strictly necessary, but it seems like a cheap addition. If it's available, the "current" version need not be duplicated (and updated) in more than one place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, dyld provides two similar version numbers through
NSVersionOfRunTimeLibrary
andNSVersionOfLinkTimeLibrary
.(The link-time version queries the linkage of the main executable, not the current object, so it's different(ly useful) than the static version number implemented here.)