就在不到一周前,Swift 世界貢獻(xiàn)了一份提前到達(dá)的圣誕節(jié)禮物 —— 開源Swift —— 可以在 Linux 上運行的 Swift。
這份大禮里面甚至又包含了另一份禮物:蘋果宣布了新的項目以及工具使得 Swift 成為 Linux 開發(fā)的一個相當(dāng)具有實踐性的選擇。這也產(chǎn)生了很多令人興奮的可能性,比如說從強(qiáng)大的 Linux 服務(wù)器到 5 美元的一臺樹莓派Zeros,或者其它大量的托管了 Linux 的環(huán)境都可以運行 Swift 了。
在這個教程中,我們將會在 Mac 中創(chuàng)建一個 Linux 環(huán)境,安裝 Swift,并且在這個 Linux 當(dāng)中編譯和運行一些基本的 Swift 示例程序。之后可以感覺一下蘋果提供的新工具,然后我們會透過時間的水晶球來預(yù)測 Swift 開發(fā)未來的走向。
此教程不要求讀者預(yù)先了解任何關(guān)于 Linux 的知識,甚至不需要讀者安裝過 Linux —— 但是如果你已經(jīng)有一個可以運行的 Ubuntu 系統(tǒng),那就再好不過了!你所需要的就是運行了最新的 EL Capitan 系統(tǒng)的 Mac 電腦,以及對開源 Swift 興趣就夠了。那就讓我們開始吧!
(譯者注:我也會補(bǔ)充關(guān)于如何在 Windows上安裝的資料。所以不用擔(dān)心!Don't Panic.)

在 Linux 上安裝 Swift
如果你已經(jīng)有一個可以運行的 Unbutn 14.04 LTS 或 Ubuntu 15.10,不管是裝在實體機(jī)上,還是裝在 Mac 或 Windows 下的虛擬機(jī)上,你都可以簡單地按照swift.org上面的教程(或者參考我的上一篇博客)下載并在 Linux 上安裝 Swift,然后直接跳到下一小節(jié)。
如果你沒有上面所列版本的 Ubuntu 系統(tǒng),那就按照我下面的教程,在你的 Mac 上安裝 VirtualBox 以及 Ubuntu。這會使用小于 1GB 的硬盤空間,并在虛擬機(jī)上面安裝 Linux —— 不會影響到你當(dāng)前的 OS X 系統(tǒng)。
安裝 VirtualBox
VirtualBox 是一個免費并且開源的程序,它可以作為虛擬機(jī)讓我們在運行當(dāng)前主系統(tǒng)的同時運行其它的操作系統(tǒng)。
前往VirtualBox下載頁,然后下載 VirtualBox 5.0.10或更新版本的鏡像。雙擊下載后的 DMG 文件,接著運行 VirtualBox.pkg 安裝包:

(剛剛那個下載頁也有 Windows 版本的 VirtualBox 安裝文件,直接下載,然后雙擊安裝文件,按照傳統(tǒng)的下一步下一步安裝步驟就可以安裝了?!?譯者注)
安裝及使用 Vagrant
Vagrant是一個 VirtualBox 的命令行界面;它可以下載虛擬機(jī)鏡像,運行配置腳本,并且在主操作系統(tǒng)與虛擬機(jī)系統(tǒng)之間設(shè)置網(wǎng)絡(luò)和共享文件夾以使其可以進(jìn)行交互。
前往Vagrant下載頁,然后下載 Mac OS X 版本的 Vagrant。雙擊下載的 DMG 硬盤鏡像,接著運行 Vagrant.pkg 安裝包:

(同樣地,Vagrant 的安裝包也有 Windows 版本,只需要在剛剛的下載頁面選擇 Windows 就行了,但是安裝 Ubuntu 系統(tǒng)以及 Swift 的方法跟以下的方法不太一樣,可以參考這篇博客來安裝 Ubuntu 系統(tǒng),然后參考我的上一篇博客來安裝 Swift —— 譯者注)
現(xiàn)在需要一個 Vagrantfile 來告訴 Vagrant 我們具體需要安裝哪個版本的 Linux,以及如何在那個版本的 Linux 上安裝 Swift。
在你的文檔目錄下(或者其它你覺得舒服的目錄下)創(chuàng)建一個空目錄,并且將它全名為 vagrant-swift。在那個目錄下,創(chuàng)建一個 Vagrantfile 然后輸入如下內(nèi)容:
Vagrant.configure(2) do |config|
## 1
config.vm.box = "https://cloud-images.ubuntu.com/vagrant/trusty/20151201/trusty-server-cloudimg-amd64-vagrant-disk1.box"
config.vm.provision "shell", inline: <<-SHELL
## 2
sudo apt-get --assume-yes install clang
## 3
curl -O https://swift.org/builds/ubuntu1404/swift-2.2-SNAPSHOT-2015-12-01-b/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu14.04.tar.gz
## 4
tar zxf swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu14.04.tar.gz
## 5
echo "export PATH=/home/vagrant/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu14.04/usr/bin:\"${PATH}\"" >> .profile
echo "Swift has successfully installed on Linux"
SHELL
end
現(xiàn)在運行 Vagrantfile。在你的 Mac 上打開終端(可以在 /Applications/Utilties/目錄下找到),切換到包含上面的那個文件的 vagrant-swfit 目錄下,然后輸入如下的命令運行這個腳本:
vagrant up
現(xiàn)在 Vagrant 會根據(jù) Vagrantfile 執(zhí)行如下步驟,你可以去泡杯咖啡慢慢等:
- 下載 Ubuntu LTS 14.04 的硬盤鏡像。鏡像只會被下載一次,然后保存起來,以供后續(xù)的使用。你大概會看到類似 "Adding it directly..." 后接著 "Attempting to find and install..." 的信息。
- 在虛擬機(jī)中運行下載完的硬盤鏡像。
- 安裝 clang 即蘋果公司的 C 編譯器,這是 Swift 編譯器所需要的組件。
- 下載 Swift 然后對其進(jìn)行解壓。
- 配置用戶家目錄的 PATH 路徑變量,以使其可以使用 swift 二進(jìn)制工具,REPL以及其它工具。
如果這些步驟都順利完成了,最后一條信息應(yīng)該會顯示 "Swift has successfully installed on Linux"。
下一步,需要連接上你的 Linux 虛擬機(jī)。在同一個 vagrant-swift 目錄下,運行如下的命令:
vagrant ssh
現(xiàn)在你可以看到自己在一個 Ubuntu 的提示符下,用戶名為 "vagrant"。為了驗證你現(xiàn)在可以運行 Swift 并且它的功能是否正確,運行如下的命令:
swift --version
你可以看到如下的信息:
vagrant@vagrant-ubuntu-trusty-64:~$ swift --version
Swift version 2.2-dev (LLVM 46be9ff861, Clang 4deb154edc, Swift 778f82939c)
啦啦啦!運行在 Linux 上面的 Swift。這真是一個圣誕對奇跡呀!:]

編譯一個程序
我們已經(jīng)在 Linux 上面安裝了 Swift. 現(xiàn)在我們可以來編譯和運行一些東西了。
當(dāng)然,神圣的代碼傳統(tǒng)意味著我們的第一個程序?qū)⒅挥幸粋€功能,那就是輸出一句"Hello, world"。依照程序員的性格,我們將以最懶最簡單的方式來完成這個功能。:]
切換到 Linux 的命令行環(huán)境下并且執(zhí)行如下的命令:
cat > helloworld.swift
現(xiàn)在輸入下面一行的 Swift 代碼:
print("Hello, world")
按下 Enter 鍵,接著使用 Ctrl-D 來創(chuàng)建這個文件。
執(zhí)行一下 ls 命令來列出當(dāng)前目錄的文件,確保我們創(chuàng)建了一個名為 helloworld.swift 的文件。
現(xiàn)在在命令行提示符下運行如下的命令來調(diào)用 swift 編譯器對程序進(jìn)行編譯:
swiftc helloworld.swift
注意:如果你在編譯時遇到了錯誤,你可能需要更新 clang:
sudo apt-get install clang-3.6
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.6 100
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-3.6 100
在命令行下執(zhí)行 ls -l h*命令來查看當(dāng)前目錄下以 h 開頭的文件:
-rwxrwxr-x 1 vagrant vagrant 13684 Dec 4 17:55 helloworld
-rw-rw-r-- 1 vagrant vagrant 22 Dec 4 17:55 helloworld.swift
在輸出結(jié)果的第一列中我們可以看到 helloworld 有一個 x 字符,說明它是一個可執(zhí)行文件。執(zhí)行如下的命令來運行 helloworld:
./helloworld
你將會看到如下的輸出:
Hello, world
你是電!你是光!你是唯一的神話!我們在 Linux 上運行了第一個 Swift 程序。So easy! :]
但是這意味著什么呢?我們究竟可以在 Linux 上用 Swift 來做什么呢?現(xiàn)在就讓我們在跨平臺開發(fā)的高速路上稍微踩下剎車,抽一點時間來重溫下蘋果究竟開源了哪些東西。
蘋果開源了哪些東西
到目前為止,蘋果開源了五個類目的軟件:
1) Swift 編譯器(源代碼以及可執(zhí)行二進(jìn)制文件),調(diào)試器,以及交互性命令行(如,REPL)
這是 Swift 語言的核心。蘋果開源了 Swift 編譯器的源代碼,即與 Xcode 中用于編譯 iOS 以及 Mac 應(yīng)用一致的 swiftc 程序。
2) Swift 標(biāo)準(zhǔn)庫
這與 Swift 發(fā)布后一直使用的標(biāo)準(zhǔn)庫是(幾乎)完全一致的。它定義了字符串,集合類型,協(xié)議,以及其它基礎(chǔ)結(jié)構(gòu)的實現(xiàn)。你是否一直渴望看到標(biāo)準(zhǔn)庫對于基礎(chǔ)類型的實現(xiàn),像 Double 以及 Array?現(xiàn)在你完全可以看到了。
然而,只有單獨的 Swift 標(biāo)準(zhǔn)庫并起不了多大的作用。有多少個你寫過的 Swift 應(yīng)用沒有**導(dǎo)入 UIKit ?大概沒有幾個吧。至少,F(xiàn)oundation 的功能,對于開發(fā)一些有用的軟件(而非"Hello, world",以及千千萬的計算階乘的函數(shù))是十分有必要的。這一切代表著蘋果也會開源 ...
3) Swift 核心庫
這些是針對蘋果庫的全新,跨平臺以及獨立于 Objective-C 的重新實現(xiàn)。它們提供了比較高階的功能比如網(wǎng)絡(luò),文件系統(tǒng)交互,日期和時間計算。一個警告:它們尚未完全開發(fā)完成。但不止于此,蘋果還開源了...
4) Swift 包管理器
Swift 包管理器與Carthage有點類似;它可以下載依賴,編譯,然后對其進(jìn)行鏈接以生成庫和可執(zhí)行文件。
5) 其它組件
如果你瀏覽過蘋果的Github主頁,你還會發(fā)現(xiàn)其它的組件:一個基于 Swift 的 libdispatch包裝器(即,Grand Central Dispatch),Swift 3.0未來計劃的說明,甚至還有一個 Markdown 方言 CommonMark 的解析和渲染器。
蘋果所沒有開源的東西
蘋果開源的東西真是相當(dāng)多啊 —— 那么,他們沒有開源哪些東西呢?
讓我們來數(shù)數(shù)吧,Xcode 沒有開源,AppKit 沒有開源,UIKit 沒有開源。還有 Core Graphics, Core Animation, AVFoundation以及其它我們所熟悉的 Objective-C 核心類庫都沒有開源?;旧?,所有你用來創(chuàng)建漂亮的 iOS 或者 Mac 應(yīng)用所需要的庫都沒有開源。
但是,蘋果已經(jīng)開源的東西,具有十分重大的意義??紤]一下核心類庫這個項目。為什么蘋果會費那么多力氣重新實現(xiàn)這個他們已經(jīng)千錘百煉,并且經(jīng)過重重測試的 Foundation 庫呢?
事實就是這個核心類庫不需要依賴于 Objective-C 運行時,這意味著蘋果在創(chuàng)造一個可以在未來用 Swift 完全替代 Objective-C 的基礎(chǔ)。并且它的跨平臺特性意味著蘋果十分希望用戶使用 Swift 進(jìn)行 Linux 的軟件開發(fā) —— 至少是服務(wù)端軟件,而非 GUI 應(yīng)用開發(fā)。
但是包管理器是最重要的一個開源組件。在深入解釋原因之前,讓我們先快速過一下,來了解包管理器的使用,和認(rèn)識一下它究竟是什么東西。
使用 Swift 包管理器
包管理器為任何需要構(gòu)建成一個可執(zhí)行文件或者庫的 Swift 代碼定義了一個簡潔,直觀的目錄結(jié)構(gòu)。我們將在安裝過 Ubuntu 和 Vagrant 的 VirtualBox 中一探究竟。
首先,在命令行提示符執(zhí)行如下的命令來創(chuàng)建一個 helloworld-project 目錄,并且切換到該目錄:
mkdir helloworld-project && cd helloworld-project
現(xiàn)在執(zhí)行如下命令用來創(chuàng)建一個空的 Package.swift 文件:
touch Package.swift
這個文件的存在,表明當(dāng)前目錄定義了一個 Swift 的包。
接著,用下面的命令來為源代碼創(chuàng)建一個子目錄:
mkdir Sources
下一步,執(zhí)行如下命令來把之前的舊程序,hello.swift,復(fù)制到 Sources/ 目錄下,并且重新命名為 main.swift:
cp ../helloworld.swift Sources/main.swift
helloworld-project 目錄當(dāng)前的結(jié)構(gòu)定義一個最基礎(chǔ)的包,并且它的結(jié)構(gòu)應(yīng)該是這樣的:
├── Package.swift
└── Sources/
└── main.swift
執(zhí)行如下命令來構(gòu)建這個包:
swift build
可以看到如下的輸出:
vagrant@vagrant-ubuntu-trusty-64:~/helloworld-project$ swift build
Compiling Swift Module 'helloworldproject' (1 sources)
Linking Executable: .build/debug/helloworld-project
這里為構(gòu)建完成的產(chǎn)品創(chuàng)建了一個新的,并且是隱藏的目錄—— .build?,F(xiàn)在目錄結(jié)構(gòu)看起來應(yīng)該是這樣的:
.
├── .build/
│ └── debug/
│ ├── helloworld-project*
│ ├── helloworld-project.o/
│ │ ├── build.db
│ │ ├── helloworld-project/
│ │ │ ├── main.d
│ │ │ ├── main~partial.swiftdoc
│ │ │ ├── main~partial.swiftmodule
│ │ │ ├── main.swiftdeps
│ │ │ ├── master.swiftdeps
│ │ │ └── output-file-map.json
│ │ ├── home/
│ │ │ └── vagrant/
│ │ │ └── helloworld-project/
│ │ │ └── .build/
│ │ │ └── debug/
│ │ ├── llbuild.yaml
│ │ └── Sources/
│ │ └── main.swift.o
│ ├── helloworldproject.swiftdoc
│ └── helloworldproject.swiftmodule
├── Package.swift
└── Sources/
└── main.swift
可以使用ls -aR命令來驗證這個隱藏目錄的存在。
最重要的文件就是 .build/debug/helloworld-project了,它被標(biāo)記了星號,代表著它是一個可執(zhí)行文件 。這就是我們所需要的可執(zhí)行文件,可以在命令行輸入它的名字來運行,就像這樣:
vagrant@vagrant-ubuntu-trusty-64:~/helloworld-project$ .build/debug/helloworld-project
Hello, world
相當(dāng)酷,有沒有!但是目錄里的那些雜七雜八的東西都有什么作用呢?
所有這些構(gòu)建中間產(chǎn)物表明了包管理器真正的能力范圍。記住——它不只是一個編譯器。作為一個構(gòu)建工具(類似make),包管理器的主要責(zé)任是編譯單個包所需要的多個源文件,并將它們鏈接到一起。
作為一個包管理器(類似 Carthage 或 CocoaPods),它也有將多個包鏈接到一起,并且到互聯(lián)網(wǎng)上拉取依賴包的責(zé)任。這意味著包需要了解一些版本與兼容性(比如,“哪一個依賴可以滿足我的需求?”),以及位置(比如,“我應(yīng)該到哪里去獲得這個包呢?”)的概念。
作為一個比較復(fù)雜的例子,我們來看一下蘋果提供的示例程序;它模擬了一個撲克牌游戲。
安裝 Git,切換到一個新的目錄,使用如下的命令來獲取一個最頂層的包:
cd ~
sudo apt-get --assume-yes install git
git clone https://github.com/apple/example-package-dealer.git
cd example-package-dealer
查看一下這個目錄,你可以發(fā)現(xiàn)里面幾乎沒有任何東西:
.
├── CONTRIBUTING.md
├── main.swift
├── Package.swift
└── README.md
但是,這次的 Package.swift 不是一個空文件了;它包含了一小段的 Swift 表明了這個包依賴了另一個版本 1 的包,example-package-deckofplayingcards,而這個包是存放在github鏈接上的,同時這個包又依賴了其它的包,如此類推。
最終的結(jié)果就是,如果你對這個示例程序運行了 swift build 命令,它會下載超過 400 個的文件,因為構(gòu)建工具會去下載其它依賴的倉庫源,對其進(jìn)行編譯,然后鏈接。
蘋果在 Swift.org 里對包管理器進(jìn)行了更加詳細(xì)的描述。下面的列表列出了這個新的包管理器值得注意的一些點:
- 為包的布局使用一個簡潔的目錄結(jié)構(gòu),以及一個簡單的基于 Swift 的 manifest 文件,相對地, Xcode可以使用任何的目錄結(jié)構(gòu),但是需要一個 Xcode 特有的項目文件用于追蹤由自由而造成的混亂的結(jié)構(gòu)
- 使用語義化版本,一個用于描述包版本以及兼容性的事實標(biāo)準(zhǔn)
- 與 Swift 的模塊概念緊密集成,而這正是蘋果在 Objective-C 上使用和在 C 語言中大力推廣的標(biāo)準(zhǔn)
- 與 xcodebuild 構(gòu)建系統(tǒng)的功能存在一些重疊
- 執(zhí)行了依賴傳遞分析,但是還不能對依賴沖突進(jìn)行處理
- 構(gòu)建可執(zhí)行文件和靜態(tài)庫,但是還不支持動態(tài)庫
- 使用 git,但是還未對其它版本控制系統(tǒng)提供支持
- 包含了一份特別詳細(xì)周到的社區(qū)文件方案,詳細(xì)描述了這個設(shè)計背后的思想。
如果你使用過 CocoaPods, Carthage 或者其它的包管理器,這些對你來說看起來應(yīng)該非常熟悉。確實,在技術(shù)上來講,這里并沒有什么新的東西。但這對蘋果來說是全新的,并且是十分顯著的。
那就讓我們穿過時間的迷霧,來探索下 ...
這一切意味著什么?
為什么包管理器如此重要?原因在于包管理器不僅僅是一個工具。包管理器與圍繞著技術(shù)社區(qū)的軟件生態(tài)有著緊密的聯(lián)系,它們定義了人們在創(chuàng)作軟件時對于基本事務(wù)上的相互幫助是如何交互的。
對于 Ruby 和 Node 社區(qū),如果缺少了 gem 和 npm 管理器,它們能達(dá)到現(xiàn)在這樣狀態(tài)么?并不。而且毫不夸張地說,CocoaPods 讓 iOS 開發(fā)者的聯(lián)系更加緊密了,因為它讓共享工作成果與互相幫助變得更加簡單。
蘋果在與開發(fā)者交流方面一直名聲不太好;他們沒有為開發(fā)者的反饋提供頻道支持,也很少支持開發(fā)者之間進(jìn)行溝通。一個很明顯的例子就是 Radar 漏洞追蹤系統(tǒng),它就像一個星際黑洞,靜靜地吞噬掉一切信息,卻不為外界留下一絲一毫的追蹤痕跡。
但是包管理器必將成為社區(qū)的一個基礎(chǔ)設(shè)施;它是一個用于開發(fā)者與開發(fā)者,而不是與蘋果,之間進(jìn)行交流的東西。蘋果現(xiàn)在領(lǐng)導(dǎo)發(fā)布了這樣一個工具,說明它已經(jīng)開始慢慢在這方面起步了。
這個工具感覺上就像是一個普通的包管理器,它使用了語義化版本,Git,以及其它普通的工具和模式,并沒有使用蘋果家一貫的封閉原則,這也是一個很好的跡象。蘋果甚至為 Swift 提供了一個基于 JIRA 的漏洞追蹤系統(tǒng)來替代 Radar,這使得開發(fā)者可以實實在在地看到自己或其它人提交過的漏洞。
我們能真真切切地感受到 Swift 開發(fā)者的誠意!:]

從包管理器我們可以感覺到蘋果隱藏在開源背后更為廣闊的想法。對于開源,蘋果不僅僅是將源代碼公開了事。它為支持 Linux 上的 Swift 生產(chǎn)開發(fā)踏出了第一步。不僅如此,他們還在鼓勵和歡迎其它開發(fā)者對此作出貢獻(xiàn)上踏出了更大的一步。
停止虛擬機(jī)
當(dāng)你使用完了虛擬機(jī)后,使用 logout 命令退出命令行,然后執(zhí)行vagrant suspend來使它掛起,以備以后的使用,或者你也可以直接使用vagrant destroy來讓它完全銷毀然后釋放硬盤空間。
接下來呢?
在這個教程當(dāng)中,你安裝了 Linux, 在 Linux 上安裝了 Swift,在 Linux 編譯了 Swift 代碼,并且快速地了解了下蘋果的包管理工具?,F(xiàn)在完全可以在 Linux 上運行 Swift 的事實已經(jīng)十分有趣了,但是事實上,蘋果也十分鼓勵我們這樣做,它提供了技術(shù)以及社區(qū)來對其進(jìn)行支持,這實在是帥呆了!:]
你現(xiàn)在只是快速粗略地了解了一下 Linux 上面的 Swift,但這些新工具大部分也對 OS X 上的 Swift 造成了影響,比如包管理工具;現(xiàn)在我們可以更容易地共享代碼以及構(gòu)建命令行工具。很難想像這不是對 Xcode 未來方向的一個暗示。新的代碼倉庫,新路線圖的曝光以及對 Swift 未來開發(fā)的討論,都預(yù)示著這是一個十分令人看好——也是十分令人驚喜——的開發(fā)之旅。
有趣的日子即將來臨!
這篇譯文可以作為我上篇博客的后續(xù),我本來也打算開始寫了,但是突然發(fā)現(xiàn) Ray 上面有了這篇博客,與我打算寫的如出一轍(當(dāng)然肯定是人家的質(zhì)量要高),于是我第一時間就把這篇文章翻譯過來,也算是補(bǔ)了上一篇博客的坑吧。
本文翻譯自:raywenderlich
原文地址:Introduction to Open Source Swift on Linux
本人博客地址:SwiftBits