5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

外部ライブラリをimportして実行可能な*.swiftファイルをつくる

Posted at

モチベーション

(コミット数とforkでは)CocoaPods派のbanjunです。
今回はCocoaPodsにあるような外部ライブラリを含むSwiftスクリプトをつくります。

かつてはまさにそのあたりを支援するApousというツールがあったのですが,Swiftの進化に追いついていないので一旦忘れます。
https://github.com/owensd/apous

使ってみたい外部ライブラリは SourceKitten です。 SwiftLintのようなツールを作れるそうです。

導入

*.swiftswiftコマンドで実行可能なので,shebangで*.swiftファイルの頭に付けてやれば起動はできます。

#!/usr/bin/swift

ただし,ここに import SourceKittenFramework を追加するには,フレームワークサーチパスの指定が必要になります。

そこで*.swiftファイルの隣りに Cartfile を書いて, carthage bootstrap します。CocoaPodsしか持っていない人は brew install carthage しましょう。

Cartfile

github "jpsim/SourceKitten"

すると Carthage/Build/Mac にframeworkがビルドされるので, swift -Fに渡すことでフレームワークサーチパスを指定できます。
それをshebangで指定しますが,*.swift自体はどこか別のディレクトリから,または ~/bin/* からシンボリックリンクでも起動できるようにします。
そのために一旦swiftではなくシェルスクリプトで受けたいので,*.swiftの頭を次のようにします。

#!/bin/sh
":" //#; exec swift -sdk $(xcrun --sdk macosx --show-sdk-path) -F "$(dirname $(readlink $0 || echo $0))/Carthage/Build/Mac" -target x86_64-apple-macosx10.10 "$0" "$@"
import Foundation
import SourceKittenFramework
(続く...)

:はshでnopなので,exec より前を無視します。ただちにexec swiftするのでシェルスクリプトの解釈はこの行でおしまいです。
引数には,起動されたパスから,Carthageでビルドしたframeworkのフルパスを解決して swift -F に渡しておきます。

さてexec swiftされると今度は同じファイルがSwiftスクリプトとして実行されます。一行目の":"はただの文字列であり, // はコメントなのでその行はなにもしません。続く行が実際のSwiftコードです。

ここでは import SourceKittenFramework したので,このSwiftスクリプト内ではSourceKittenを使ってコードを書けます。スクリプトに引数がほしい場合はexec swiftで"$@"したところから取得可能なので,それを使います。

SourceKittenを使うSwiftスクリプトの例です。

これは ./bansan.swift としても実行できますし,PATHを通した~/bin/bansanからシンボリックリンクを貼っておいて,どこからでもbansanで実行できます。

課題とworkaround

Carthageのバイナリインストール

Carthageにはバイナリインストールモードがあり,frameworkをビルドせずに,ビルド済みframeworkを置いてくれる仕組みがあるようです。
ただしSwiftが生成するバイナリはSwiftバージョンに対して互換性が悪いので(Swiftで静的ライブラリが作れなかったり,libDarwinとかをいつも付属させてたり,‥とかが関係する?),Xcodeのバージョンが変わるときにはハマります。

そんなときは carthage bootstrapcarthage checkout--no-use-binaries を付けて,ソースからビルドしましょう。

swift -targetのデフォルト値

-target の引数はXcodeのバージョンで変わるかもしれません。これはXcode 7.3のものです。動かないときはswift -vで実行してみて,swiftコマンドが生成するオプションを見てみるといいかもしれません。
例えば x86_64-apple-macosx10.9 だと 10.10をminimum deployment targetにしているframeworkはimportできません。

まとめ

  • 外部ライブラリを含む実行可能*.swiftを作りたいときはCarthageとexec swiftを使うことができる
  • Carthageはその場にframeworkを作ってくれるのでべんり
  • Carthageのバイナリインストールモードは,Swift自体がバイナリ互換性がないことを考えると筋が悪い
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?