sci

最果て風呂

Swift の SPM を使ってみる

この記事に関連しそうなお話です。

コンソールアプリケーションの作成

Swift でもパッケージの作成が簡単にできるようになっているそうです。先にプロジェクトディレクトリを作成しておいてその中に入り、次のようなコマンドを使用してパッケージの雛形を作成します。

mkdir Swimto
cd Swimto
swift package init --type executable

作成されるファイルは下記のとおり。

Creating executable package: Swimto
Creating Package.swift
Creating .gitignore
Creating Sources/
Creating Sources/main.swift
Creating Tests/

自分の環境は Swift 3.0.2 なので、4.0 系とは違うのですけれど、最小限のファイル類が作成されました。

試しに 1 ファイルで作成されている (いつもの) mto.swift の内容を main.swift にコピーして

swift build

とすると、.build/debug/Swimto バイナリが作成されました。動作も問題ありません。デバッグではなくリリースとしてビルドする場合は次のようにすると良いらしいです。

swift build -c release -Xswiftc -static-stdlib

これで .build/release 以下にバイナリが作成されます。ちなみに

swift package generate-xcodeproj

とすることで、Xcode で扱えるようになるそうです。

テストの作成

テストをしやすいように、プログラムを main.swift (メインと引数処理部分) と Swimto.swift (ライブラリ的な部分) に分けました。この時点でビルドはできています。

Tests/ 以下にテスト SwimtoTests/SwimtoTests.swift を追加したのですけれど、テストプログラムがうまく動きません。というかビルドができないのです。

Linking ./.build/debug/SwimtoPackageTests.xctest/Contents/MacOS/SwimtoPackageTests
Undefined symbols for architecture x86_64:
  "__TFC6Swimto6SwimtoCfT8dictfileSS_S0_", referenced from:
      __TFC11SwimtoTests11SwimtoTests8testDictfT_T_ in SwimtoTests.swift.o
  "__TMaC6Swimto6Swimto", referenced from:
      __TFC11SwimtoTests11SwimtoTests8testDictfT_T_ in SwimtoTests.swift.o
ld: symbol(s) not found for architecture x86_64
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)
<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 /Users/project/Swimto/.build/debug.yaml test

スコープの関係っぽい?

調べてみると、4.0 系では Sources/ 以下にサブディレクトリが作成されていて、その中にソースが入るみたいです。コマンドとしての swimto/ ディレクトリとライブラリとしての SwimtoLib/ のように分けてみます。Tests/ 以下も同様にすれば良いのかもしれません。Package.swift の書き方がわかりません……。

プロジェクトの公開

git リポジトリとして公開しておけば GitHub 以外でも大丈夫っぽい?

追記

Swift Package Manager を利用してのビルド&テストは相変わらずできていませんが、XCode 内において、テストで利用する外部ファイルの場所を指定する方法がわかりました。

XCode の Product -> Scheme -> Edit Scheme... から Run -> Arguments -> Environment Variables 項目で

Name Value
PROJECT_DIR $(PROJECT_DIR)

のように設定し、Test.swift で

let PROJECT_DIR = ProcessInfo.processInfo.environment["PROJECT_DIR"]!

として利用することができるようになります。ちなみに各種の環境変数

xcodebuild -showBuildSettings

で確認できます。

XCode 内ではビルドもテストもできているのですが、SPM を利用しての作業はできていません。

swiftc -o swimto Sources/SwimtoLib/SwimtoLib.swift Sources/swimto/main.swift

のようにすればバイナリは作成できるのですけれど、やっぱり

swift build

のようにして作業したいじゃないですか。