Home > Software design >  `@available` attribute incorrectly constrained on macOS version
`@available` attribute incorrectly constrained on macOS version

Time:06-27

I've an issue with using FileHandle.read(upToCount:) on macOS 10.15.7; whenever I attempt to do so, I get the following error:

error: 'read(upToCount:)' is only available in macOS 10.15.4 or newer

This constraint matches with what I can see at:

/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/swift/Foundation.swiftmodule/x86_64.swiftinterface
extension FileHandle {
  ...
  @available(OSX 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *)
  public func read(upToCount count: Swift.Int) throws -> Foundation.Data?
  ...
}

I'm able to replicate this availability issue with a small test; with a main.swift like so:

@available(OSX 10.15.4, *)
func test() {}

test()

which gives me the same general error:

error: 'test()' is only available in macOS 10.15.4 or newer

If I change the @available constraint to either OSX 10.15 or OSX 10.15.0 this compiles fine, but OSX 10.15.1 or higher will report the same error, which seems to indicate that the toolchain thinks the build target is 10.15.0. Looking at what swiftc is doing under the hood, though, it appears to be using the correct SDK and triple:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift \
  -frontend \
  -c \
  -primary-file main.swift \
  -target x86_64-apple-darwin19.6.0 \
  -enable-objc-interop \
  -stack-check \
  -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk \
  -color-diagnostics \
  -target-sdk-version 11.1 \
  -module-name main \
  -o /var/folders/ml/3hynjc6s5v96y4k_wfy3gt6r0000gn/T/main-9906ee.o

Can anyone shed some light on to what is happening, and what I can do to convince my toolchain that these functions are available for me to build against?

CodePudding user response:

Short answer

Use:

-target x86_64-apple-macos10.15.7

Long answer

Looking at what Xcode does, as suggested by @Willeke has put me on the right path. A new command-line project in Xcode passes:

-target x86_64-apple-macos10.15

to the Swift backend at compilation, which still fails due to the @available constraint, but modifying this to:

-target x86_64-apple-macos10.15.7

works as expected.

It is annoying that the use of corresponding darwin versions in the triple doesn't cause the same behaviour as the use of macos versions, but I imagine that this is due to the legacy of a time when there was only one Darwin based operating system coming out of Apple. Now, a given Darwin version can mean different versions of macOS, iOS, tvOS etc., each with different available API sets. ✌️

  • Related