Swift Package Manager 重寫 macOS 部署目標

原文連接=oleb.net/blog/2017/0…
做者=Ole Begemann
原文日期=2017-04-07
譯者=EyreFree
校對=liberalism,Firecrest
定稿=CMB
html

注:小編友情提醒:由於這篇文章翻譯得比較早,因此有些內容不是最新的,不過度析問題的思路和一些底層原理的知識仍是值得學習的~git

Swift 3.1 修復了 Swift Package Manager 沒法重寫 MacOS 部署目標的 Bug。github

當你在 macOS 上執行 swift build 命令時,包管理器目前(Swift 3.0 和 3.1)會將部署目標硬編碼爲 macOS 10.10 ¹ 現已證實是命令參數的一個 Bug 引發的 Swift 3.0 中沒法重寫部署目標這個問題。macos

所以,你不能輕鬆編譯用到了最新 API 的代碼 ² 舉個栗子,假設有一個很是簡單的包,只包含幾行代碼在一個源文件中。這個程序用到了 macOS 10.12 引入的新的 單位和測量類型 來將一個值從以 km/h 轉換爲 m/s :swift

// main.swift
import Foundation

let kph = Measurement(value: 100,
    unit: UnitSpeed.kilometersPerHour)
let mps = kph.converted(to: .metersPerSecond)
print("\(kph) is \(mps)")
複製代碼

在 macOS(Swift 3.0 或 3.1)上用 swift build 命令編譯上面這段代碼會報錯,由於這段代碼用到的 API 在 macOS 10.10 上不可用:bash

$ swift build
Compile Swift Module 'Units' (1 sources)
main.swift:3:11: error: 'Measurement' is only available on OS X 10.12 or newer
let kph = Measurement(value: 100,
          ^
main.swift:3:11: note: add 'if #available' version check
let kph = Measurement(value: 100,
          ^
...
<unknown>:0: error: build had 1 command failures
error: exit(1): /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift-build-tool -f .build/debug.yaml
複製代碼

在 Swift 3.1 中,你能夠在命令行中修改部署目標,以下所示:app

$ swift build -Xswiftc "-target" \
    -Xswiftc "x86_64-apple-macosx10.12"
Compile Swift Module 'Units' (1 sources)
Linking ./.build/debug/Units
複製代碼

如今,你能夠正常執行以前的這段代碼了:學習

$ .build/debug/Units
100.0 km/h is 27.7778 m/s
複製代碼

結論

除了部署目標,另外一個常見的自定義編譯設置例子是傳遞一個 DEBUG 標誌給編譯器,因此能夠在你的代碼中使用 #if DEBUG/#endif 代碼段做爲標誌傳遞給編譯器,從而來判斷是否處於 Debug 模式 - 當前包管理器並無在 Debug 構建模式下自動完成這些工做。你能夠經過 swift build -Xswiftc "-D" -Xswiftc "DEBUG" 命令實現這一目的。ui

這仍然不夠理想 - 你在每次執行 swift buildswift test 命令時都須要手動輸入命令行參數 - 但至少這是可行的。編碼

對於包管理器來講可以在包配置清單中指定自定義編譯設置是 Swift 4 路線圖的一部分。我猜咱們很快就會看到一個和這一特性有關的 Swift 發展提案


  1. 你能夠經過添加以下代碼段到你的 main.swift 文件而後編譯並執行對應包的方式來驗證這一點:
#if os(macOS)
     print("macOS deployment target:", __MAC_OS_X_VERSION_MIN_REQUIRED)
#endif
複製代碼

若是在 macOS 執行,將會打印:

macOS deployment target: 101000
複製代碼
  1. 你必須把全部依賴新 API 的代碼用 if #available(macOS 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *) { ... } 或相似的 block 進行包裹。
相關文章
相關標籤/搜索