2020年8月7日, 2020年8月31日更新, 2021年9月18日追記
株式会社あいはら 研究開発チームWSL (Windows Subsystem for Linux) の登場によって、Windows 上でも手軽に Linux 環境 (様々な Linux 上で動作するコマンドラインツールやプログラミング言語など) を利用することが可能になりました。特にプログラミング言語については、コマンドラインでの利用が Linux と同様に可能になるので、主に研究などで大量な計算をする場合などには、向いた環境であると言えます。
そこで、本稿では、WSL のセットアップから、Swift、プログラミング言語 C を利用できるようにするまでを解説します。
なお、WSL を利用するには 64 bit 版 Windows 10 が必要です。また、本稿で用いている Windows のバージョンは 64 bit 版 Windows 10 Pro Version 1909 です。
まず、Windows の「設定」を開き、[アプリ]をクリックして、「関連設定」の [プログラムと機能] をクリックします。次に、そこで開くウィンドウの [Windows の機能を有効化または無効化] をクリックします。
次に、そこで表示される「Windows の機能」ダイアログで、「Windows Subsystem for Linux」 (Windows のバージョンによっては「Linux 用 Windows サブシステム」) にチェックを入れて、[OK] をクリックします。しばらくすると Windows の再起動を促す画面が表示されるので、指示に従って再起動します。
Windows が再起動したら、「Microsoft Store」で、Ubuntu を検索します。いくつか候補が現れますが、ここでは「Ubuntu 20.04 LTS」を入手・インストールします。
インストール後、初めて Ubuntu 20.04 LTS 起動したときは、次のようにメッセージが表示されますので、準備が完了するまで、しばらく待ちます。
Installing, this may take a few minutes...
続いて、次のように WSL 利用時のユーザ名とパスワードの設定を求められるので、指示に従って入力します。以降、WSL で sudo を使う場合は、ここで設定したパスワードを使います。
Please create a default UNIX user account. The username does not need to match your Windows username. For more information visit: https://aka.ms/wslusers Enter new UNIX username: New password: Retype new password:
さて、WSL では Windows のコマンドプロンプトで使えていた、Ctrl + V でペーストなどの、キーボードショートカットが使えないため、とても不便です。しかし、次の手順で、代わりに Ctrl + Shift + C でコピー、Ctrl + Shift + V でペーストが行えるようになりますので、設定しておきましょう。
まず、Ubuntu ウィンドウの左上の Ubuntu のアイコンをクリックして現れるポップアップメニューの「プロパティ」を選択します。
続いて表示されるダイアログで「Ctrl + Shift + C/V をコピー/貼り付けとして使用する(C)」にチェックを入れて、[OK] をクリックすれば完了です。
続いて、次のコマンドを使って、Ubuntu にインストールされているプログラム等の更新を行います。適宜画面に表示される指示に従って進めてください。
$ sudo apt update $ sudo apt upgrade
更新が完了したら、WSL の準備完了です。
続いて、Swift に必要なパッケージをインストールします。
下記サイトに必要なパッケージの一覧が載っていますので、自身の環境に合わせてインストールしましょう
ここでは、Ubuntu 20.04 LTS をインストールしていますので、以下のように必要なパッケージをインストールします。
$ sudo apt install binutils git gnupg2 libc6-dev libcurl4 libedit2 libgcc-9-dev libpython2.7 libsqlite3-0 libstdc++-9-dev libxml2 libz3-dev pkg-config tzdata zlib1g-dev
その他、プログラミング言語 C や、プログラム開発をする上で有用な以下のパッケージをインストールします。
$ sudo apt install clang $ sudo apt install make $ sudo apt install emacs $ sudo apt install zsh $ sudo apt install zip
いよいよ、Swift をインストールします。
なお、以下の操作はすべて ${HOME} ディレクトリで行っています。
まず、下記サイトから、自身の環境に合った最新のリリース版をダウンロードします。
ここでは、Ubuntu 20.04 LTS 用の swift-5.2.5-RELEASE のツールチェーンと、電子署名をダウンロードします。
$ wget -N https://swift.org/builds/swift-5.2.5-release/ubuntu2004/swift-5.2.5-RELEASE/swift-5.2.5-RELEASE-ubuntu20.04.tar.gz $ wget -N https://swift.org/builds/swift-5.2.5-release/ubuntu2004/swift-5.2.5-RELEASE/swift-5.2.5-RELEASE-ubuntu20.04.tar.gz.sig
次に、以下のようにして PGP 鍵をインポートし、更新もしておきます。
$ wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import - $ gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift
これで PGP 署名確認の準備ができたので、次のようにしてダウンロードしたファイルの確認を行います。
$ gpg --verify swift-5.2.5-RELEASE-ubuntu20.04.tar.gz.sig
その結果、以下のように Good signature と表示されていれば、検証に成功です。
もし、BAD signature と表示された場合、なんらかの理由で正しいファイルをダウンロードできなかったことになりますので、そのファイルは決して展開しないでください。
gpg: assuming signed data in 'swift-5.2.5-RELEASE-ubuntu20.04.tar.gz' gpg: Signature made Thu Aug 6 04:04:48 2020 JST gpg: using RSA key 925CC1CCED3D1561 gpg: Good signature from "Swift 5.x Release Signing Key <swift-infrastructure@swift.org>" [unknown]
また、以下のような WARNING が表示されることがありますが、ここに書かれた説明によれば、そこに記載された正しい手順で鍵を取得していれば、この警告は無害であるとのことです。
gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: A62A E125 BBBF BB96 A6E0 42EC 925C C1CC ED3D 1561
さて、PGP 署名による検証が問題なければ、ダウンロードしたファイルを展開します。
展開すると、swift-5.2.5-RELEASE-ubuntu20.04/ というディレクトリが作られます。その中の usr/bin/ ディレクトリにパスを通せば Swift が利用可能になります。
ここでは一例として、以下の通り、/opt/org.swift/ に配置するようにします。
$ sudo mkdir /opt/org.swift $ cd /opt/org.swift $ sudo tar xvzf ~/swift-5.2.5-RELEASE-ubuntu20.04.tar.gz
そして、swift-5.2.5-RELEASE-ubuntu20.04 のシンボリックリンクを Swift という名前で作成します。
$ sudo ln -s swift-5.2.5-RELEASE-ubuntu20.04 Swift
次に ~/.bashrc の最後の行に以下を追記します。bash 以外のシェルを使っている場合は、それぞれのシェルに合わせて、適宜設定を行ってください。
export PATH=/opt/org.swift/Swift/usr/bin:"${PATH}"
そして、次のコマンドで追記を反映させます。
$ source ~/.bashrc
これでインストールは完了したので、次のコマンドで確認を行います。
$ swift --version
問題なければ、以下のようなメッセージが表示されます。
Swift version 5.2.5 (swift-5.2.5-RELEASE) Target: x86_64-unknown-linux-gnu
このようにしておくことで、別のバージョンの Swift を利用したい場合は、/opt/org.swift/ に新たにツールチェーンを展開し、シンボリックリンクを作成し直すことで利用可能になり、それまで使っていたバージョンも残しておくことができます。
この項目は必要がある人のみ行ってください。(2021/9/18追記)
リリース版は残しつつ、最新の開発版スナップショットを利用したいときは、次のように行います。
リリース版と同様、下記サイトから、自身の環境に合った最新開発版スナップショットをダウンロードします。
なお、下記の実行例の URL は、2020年8月7日現在のものなので、適宜最新版 URL に読み換えてください。
また、PGP 鍵はインストール済みなので、更新のみを行っています。
$ wget -N https://swift.org/builds/development/ubuntu2004/swift-DEVELOPMENT-SNAPSHOT-2020-08-04-a/swift-DEVELOPMENT-SNAPSHOT-2020-08-04-a-ubuntu20.04.tar.gz $ wget -N https://swift.org/builds/development/ubuntu2004/swift-DEVELOPMENT-SNAPSHOT-2020-08-04-a/swift-DEVELOPMENT-SNAPSHOT-2020-08-04-a-ubuntu20.04.tar.gz.sig $ gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift $ gpg --verify swift-DEVELOPMENT-SNAPSHOT-2020-08-04-a-ubuntu20.04.tar.gz.sig
リリース版のときと同様に、検証に成功していたら、次のようにファイルを展開し、シンボリックリンクを作り直します。
$ cd /opt/org.swift $ sudo tar xvzf ~/swift-DEVELOPMENT-SNAPSHOT-2020-08-04-a-ubuntu20.04.tar.gz $ sudo ln -nfs swift-DEVELOPMENT-SNAPSHOT-2020-08-04-a-ubuntu20.04 Swift
これで開発版スナップショットのインストールは完了したので、次のコマンドでバージョン確認を行います。
リリース版とは違うバージョン情報が表示されていれば、成功です。
$ swift --version Swift version 5.3-dev (LLVM ab0a317622eabba, Swift b50a2cf430c9e63) Target: x86_64-unknown-linux-gnu
(2021/9/18追記)リリース版に戻す場合は、以下のようにシンボリックリンクを作り直しますが、まず ls で状況を確認します。
$ cd /opt/org.swift $ ls Swift swift-5.2.5-RELEASE-ubuntu20.04 swift-DEVELOPMENT-SNAPSHOT-2020-08-04-a-ubuntu20.04
ここで、ls で表示されるファイルやディレクトリはインストールされている swift のバージョンによって違いがあります。
さて、ここで表示されているディレクトリうち、RELEASE が含まれているものがリリース版になります。ここでは、swift-5.2.5-RELEASE-ubuntu20.04 ですが、自身の状況に合わせて、下記コマンドは適宜読み替えて実行してください。
$ sudo ln -nfs swift-5.2.5-RELEASE-ubuntu20.04 Swift
Swift を使った簡単なコマンドラインプログラムの作成例を解説します。
Swift.org - Getting Started の説明に従って、パッケージマネージャーを使ってコマンドラインプログラムを作成してみましょう。
次のようにコマンドを入力して、${HOME} ディレクトリにパッケージを作成します。ここでは、Hello という名前にしています。
$ cd $ mkdir Hello $ cd Hello $ swift package init --type executable
すると、以下のように表示され、パッケージが作成されます。
Creating executable package: Hello Creating Package.swift Creating README.md Creating .gitignore Creating Sources/ Creating Sources/Hello/main.swift Creating Tests/ Creating Tests/LinuxMain.swift Creating Tests/HelloTests/ Creating Tests/HelloTests/HelloTests.swift Creating Tests/HelloTests/XCTestManifests.swift
ここで作成された Sources/Hello/main.swift の内容を見てみましょう。以下に、そのコマンドと結果を示します。
$ cat Sources/Hello/main.swift
print("Hello, world!")
これを見ると、Sources/Hello/main.swift には Hello, world! と表示されるプログラムが既に記述されています。
そこで、次のコマンドでコマンドラインプログラムをビルドして実行してみると、以下のようにビルドの結果と、実行結果が表示されます。
$ swift run [4/4] Linking Hello Hello, world!
ここでビルドされたコマンドラインプログラムは .build/debug/Hello になりますので、以降は次のコマンドで実行できます。
$ .build/debug/Hello Hello, world!
なお、上記の実行ファイルはデバッグ版ですが、次のコマンドでリリース版のコマンドラインプログラム .build/release/Hello を作成し、実行することができます。
$ swift build -c release $ .build/release/Hello Hello, world!
make コマンドは、ファイルの依存関係と処理などを記述したファイル makefile に従って、必要最低限の処理だけで、コマンドラインプログラムのビルドなどを行うツールです。
前述のパッケージ Hello のソースコードを題材に説明します。
まず、次のようにコマンドを入力して、${HOME} ディレクトリに HelloWorld という作業用ディレクトリを作り、そのディレクトリに移動します。
$ cd $ mkdir HelloWorld $ cd HelloWorld
次に、~/Hello/Sources/Hello/main.swift をカレントディレクトリにコピーします。コピーせずに、emacs等のテキストエディタを使って、下記のような内容のファイル main.swift を作成してもよいです。
print("Hello, world!")
次に下記のような内容のファイル makefile を作成します。
TARGET=HelloWorld SWIFTCFLAGS=-O all: $(TARGET) $(TARGET): main.swift swiftc $(SWIFTCFLAGS) -o $@ $^ clean: rm -f $(TARGET)
main.swift と makefile が作成できたら、make コマンドを使って、コマンドラインプログラム HelloWorld をビルドしてみましょう。
以下に、make コマンドと作成された HelloWorld の実行結果を示します。
$ make swiftc -O -o HelloWorld main.swift $ ./HelloWorld Hello, world!
ここで作成した makefile は、HelloWorld をビルドするには main.swift が必要であり、ビルドには swiftc を使うというルールとが記述されています。
よって、main.swift を修正して、HelloWorld のタイムスタンプが main.swift より古くなった場合、再度 make コマンドを使うと、再ビルドできます。
また、下記のようなコマンドを使うと、HelloWorld を削除することができますが、これも makefile に記述されたルールに従って動作しています。
$ make clean rm -f HelloWorld
ここでは make を使ったコマンドラインプログラムの作成方法を説明してきましたが、それ以外にも makefile 次第で多彩な利用をすることが可能です。是非活用していきましょう。
~taiji/lecture-2020 contents で公開されているコマンドラインプログラムをいくつかダウンロードしてビルドしてみましょう。
以下の例では、ダウンロードしたファイルに makefile も同梱されていますので、そのまま利用します。
次のように、zip ファイルをダウンロードして、展開します。
$ cd $ wget -N https://www.aihara.co.jp/~taiji/lecture-2020/URLcat-20200806.zip $ unzip URLcat-20200806.zip
続いて、ソースコードの置いてあるディレクトリに移動して、make コマンドを使ってビルドします。
最後の make test では、makefile に記述されたルールに従って、動作確認を行っています。
$ cd URLcat/URLcat $ make clean $ make $ make test
Linux 版の Swift では、UIKit や Cocoa が入っていないなど、macOS 版との違いがあります。そのため、~taiji/lecture-2020 contents で公開されているコマンドラインプログラムの中でも、Linux 版でビルドできないものがありますので、以下に Linux対応を示します。
| ファイル名 | Linux対応 | Linuxにおける備考 | |
|---|---|---|---|
| ModuloOperation-20200806.zip | ✔ | ||
| ComprehensiveModuloOperation-20200806.zip | ✔ | ||
| URLcat-20200806.zip | ✔ | ||
| SampleXMLParser-20200806.zip | ✔ | ||
| EmojiList-20200806.zip | Unicode.Scalar.Properties に isEmoji 等がないため。 | ||
| EasyQuestions.playground-20200806.zip | ✔ | ||
| Playunderground-20200806.zip | Playunderground01.Start.swift | ○ | arc4random() を Int.random() に置き換えることで対応。 |
| Playunderground02.Function.swift | ✔ | ||
| Playunderground03.Structure.swift | △ | Cocoa モジュールがないため。 | |
| Playunderground04.Optional.swift | ✔ | ||
| Playunderground05.Protocol.swift | ✔ | ||
| Playunderground05.Protocol.v3.swift | ✔ | ||
| Playunderground06.BasicTypes.swift | △ | Unicode.Scalar.Properties に isEmoji 等がないため。 526行目で発生する "error: argument type 'String' does not conform to expected type 'CVarArg'" は Linux 版の不具合かもしれません。 | |
| Playunderground07.Operators.swift | ✔ | ||
| Playunderground07.Pattern.swift | ✔ | ||
| Playunderground08.Class.swift | ✔ | ||
| Playunderground09.MemoryManagement.swift | ✔ | ||
| Playunderground10.Extension.swift | △ | CoreGraphics モジュールがないため。 | |
| Playunderground11.Error.swift | ✔ | ||
| Playunderground12.Closure.swift | ✔ | ||
| Playunderground13.Generics.swift | ✔ | ||
| Playunderground14.DataOfObjective-C.swift | Cocoa モジュールがないため。
他、いくつか Linux 版未対応箇所あり。 | ||
| Playunderground15.CustomAttributeAndDSL.swift | ✔ | ||
| Playunderground15.OfObjective-C.dir | Selector 型がないため。 #selector はObjective-Cランタイムでのみ使用可能。 | ||
| Playunderground16.IntegrationWithGUI.swift | SwiftUI モジュールがないため。 | ||
| Playunderground18.Appendix.swift | ✔ | ||
| MyPlaygrounds-20190831.zip | MyPlayground.playground | ○ | UIKit モジュールがないため。 |
| MyPlayground1.playground | △ | Playground 用のコードが含まれているため。 | |
| MyPlayground2.playground | ✔ | ||
| MyPlayground3.playground | △ | Playground 用のコードが含まれているため。 | |
| MyPlayground4.playground | ✔ | ||
| MyPlayground5.playground | ○ | Cocoa モジュールがないため。 | |
| MyPlayground6.playground | △ | Playground 用のコードが含まれているため。 | |
| MyPlayground7.playground | △ | Playground 用のコードが含まれているため。 | |
| MyPlayground8.playground | △ | Cocoa モジュールがないため。
Playground 用のコードが使われているため。 String(format:) で「%@」がエラーになるなど、Linux 版の不具合かもしれない箇所があるため。 | |
| MyPlayground9.playground | ✔ | ||
| MyPlayground10.playground | △ | Playground 用のコードが含まれているため。 | |
| MyPlayground11.playground | Cocoa モジュールがないため。
String(format:) で「%@」がエラーになるなど、Linux 版の不具合かもしれない箇所があるため。 他、いくつか Linux 版未対応箇所あり。 | ||
| MyPlayground12.playground | Linux 版未対応箇所あり。 | ||
| MyPlayground13.playground | Linux 版未対応箇所あり。 | ||
| MyPlayground14.playground | ○ | 複数のソースファイルからなるプログラムをコンパイルする場合、最初に実行されるコードとして main.swift が必要なため、Contents.swift のシンボリックリンクを main.swift という名前で作成し、コンパイルするようにして対応。 | |
| MyPlayground15.playground | △ | String(format:) で「%@」がエラーになるなど、Linux 版の不具合かもしれない箇所があるため。 | |
| MyPlayground-JuniorHighSchoolMath.playground-20200826.zip | ✔ | swiftc の -O オプションはつけずにコンパイルしてください。 | |
| MyPlayground-JuniorHighSchoolMath.playground-20200828.zip | ○ | arc4random() を UInt32.random() に置き換えることで対応。swiftc の -O オプションはつけずにコンパイルしてください。
MyPlayground-JuniorHighSchoolMath.playground-20200828.patch | |
Playground の実体はディレクトリになっています。上記の例では EasyQuestions.playground-20200806.zip から展開される EasyQuestions.playground がそれで、その中にある Contents.swift がプログラムになり、ビルドすると下記のようしてに実行することができます。
$ ./EasyQuestions.playground/Pages/A01_Basics.xcplaygroundpage/Contents $ ./EasyQuestions.playground/Pages/A02_Syntax.xcplaygroundpage/Contents $ ./EasyQuestions.playground/Pages/A03_Object.xcplaygroundpage/Contents
Playunderground-20200806.zip は、一つの makefile で複数のプログラムをビルドするようになっています。そのため、ビルドできないプログラムのところで全体のビルドが止まってしまいます。そこで、Linux 版では対応していない箇所を除外してビルドするパッチを用意しました。
パッチの適用方法は以下の通りです。
$ wget -N https://www.aihara.co.jp/~taiji/lecture-2020/Playunderground-20200806.zip $ wget -N https://www.aihara.co.jp/~junt/SwiftOnWSL/Playunderground-20200806.patch $ unzip Playunderground-20200806.zip $ cd Playunderground $ patch -p0 -b -z.org < ../Playunderground-20200806.patch
MyPlaygrounds-20190831.zip は、Playground 用のコードが含まれているため、コンパイルできない箇所があります。そこで、それらの箇所や、Linux 版では対応していない箇所を除外してビルドする makefile とパッチを用意しました。
パッチの適用およびビルド方法は以下の通りです。
この例では、作業ディレクトリとして、MyPlaygrounds-20190831 を作っていますが、別の名前でもかまいません。また、ビルドの際に、MyPlaygrounds-20190831-makefile をダウンロードしたままのファイル名で使っていますが、makefile に名前を変更すれば、これまでと同様、make だけでビルドすることができます。
$ mkdir MyPlaygrounds-20190831 $ cd MyPlaygrounds-20190831 $ wget -N https://www.aihara.co.jp/~taiji/lecture-2020/MyPlaygrounds-20190831.zip $ wget -N https://www.aihara.co.jp/~junt/SwiftOnWSL/MyPlaygrounds-20190831-makefile $ wget -N https://www.aihara.co.jp/~junt/SwiftOnWSL/MyPlaygrounds-20190831.patch $ unzip MyPlaygrounds-20190831.zip $ patch -p0 -b -z.org < MyPlaygrounds-20190831.patch $ make -f MyPlaygrounds-20190831-makefile
swiftc で -O (最適化) オプションをつけてコンパイルした場合、まれにリンクで失敗することがあります。
2020年8月21日
Windows 10 Version 2004 からは、WSL の新しいバージョン WSL 2 が利用可能になりました。
その違いは、Microsoft の文書「WSL 1 と WSL 2 の比較」に記載されており、WSL 2 ではファイルシステムのパフォーマンスの向上、Linux システムコールの完全な互換性のサポートが図られています。ただし、Windows ファイルシステムへのアクセスは WSL 1 より低下しているようです。
また、WSL 1 では動作しなかった、Swift の REPL も WSL 2 では動作することが手元の環境で確認できました。
以下では、既に WSL が利用可能な環境において、WSL 2 へ更新する手順を解説します。
なお、以下の説明で用いている Windows のバージョンは 64 bit 版 Windows 10 Pro Version 2004 です。
(2020年8月21日追記) Windows 10 Version 1903/1909 でも、更新プログラムの適用によって、WSL 2 が利用可能になりました。詳しくは下記を参照してください。
まず、WSL 2 の導入に必要な Windows のオプション機能を有効にします。
Windows の「設定」を開き、[アプリ]をクリックして、「関連設定」の [プログラムと機能] をクリックします。そして、そこで開くウィンドウの [Windows の機能を有効化または無効化] をクリックします。
次に、そこで表示される「Windows の機能」ダイアログで、「仮想マシン プラットフォーム」にチェックを入れて、[OK] をクリックします。しばらくすると Windows の再起動を促す画面が表示されるので、指示に従って再起動します。
Windows が再起動したら、コマンドプロンプトを開き、以下のコマンドを実行し、インストールされている Linux ディストリビューションの名前と WSL バージョンを確認します。
C:\>wsl -l -v NAME STATE VERSION * Ubuntu-20.04 Stopped 1
この例では、Linux ディストリビューションの名前は Ubuntu-20.04 で、WSL バージョンが 1 であることがわかります。
続いて、次のコマンドで、WSL 2 に更新します。ここで入力している Ubuntu-20.04 は上記で確認した、Linux ディストリビューションの名前です。2 は新たに設定する WSL バージョンです。
C:\>wsl --set-version Ubuntu-20.04 2 変換中です。この処理には数分かかることがあります... WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
変換にはしばらく時間がかかりますが、以下のようなメッセージが表示され、変換が行われなかった場合は、PC の BIOS 設定で仮想化が無効になっているかもしれません。BIOS 設定は機種により違いがあるので、詳しくはお使いの PC のマニュアル等を参考にしてください。「Virtualization」などのキーワードで探すとよいかと思います。
Windows の仮想マシン プラットフォーム機能を有効にして、BIOS で仮想化が有効になっていることを確認してください。 詳細については、https://aka.ms/wsl2-install を参照してください
その他、なんらかの理由で変換ができない場合は、Microsoft の文書「WSL 2 に更新する」などを参考にしてみてください。
変換が完了すると以下のようなメッセージが表示されますので、前述のコマンドでバージョンを確認すると、バージョンが 2 になっていることがわかります。
変換が完了しました。 C:\>wsl -l -v NAME STATE VERSION * Ubuntu-20.04 Stopped 2
WSL 2 に更新後は、Swift の REPL が利用できるようになっていると思います。
Ubuntu 20.04 LTS を起動し、以下のように swift とだけ入力してコマンドを実行すると、REPL の入力待ち画面が表示されます。
$ swift Welcome to Swift version 5.2.5 (swift-5.2.5-RELEASE). Type :help for assistance. 1>