ソースファイルごとに異なったオプション(主に最適化オプション)でコンパイルしたくなるときがあります.Xcodeで設定してもなぜか反映されません(?).そこで,コマンドラインでmakeなどを使ってビルドできるよう,分割コンパイルの方法を調べてみました.
swift -frontend
とは
Xcodeでのビルドログを眺めると-frontend
というスイッチを使ってごちゃごちゃとやっていたので,試しにコマンドラインでswift -frontend -help
と打ってみると,ずらずらと見慣れないヘルプが出てきます.
基本的な使い方は,
swift -frontend [MODE] [OPTIONS] [SOURCES]
となるようです.
[MODE]はアセンブラで出力(-S
)とかオブジェクトファイルで出力(-c
)とかがあります.
分割コンパイルで最重要なのは-primary-file
というオプションです.ソースファイル名の直前にこのオプションをつけると,そのソースだけがコンパイル対象になります.
分割コンパイル例
いま,TestA.swift, TestB.swiftというソースがあるとします.TestBはTestAに依存(TestAの関数を参照している)とします.
TestAの最適化なしオブジェクトファイル(.o)を出力:
swift -frontend -c -Onone -primary-file TestA.swift TestB.swift -sdk SDK
TestBの最適化ありオブジェクトファイル(.o)を出力:
swift -frontend -c -O TestA.swift -primary-file TestB.swift -sdk SDK
(SDKは/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk など)
ソース間に依存関係がある場合は,とりあえず全ソース名を並べてターゲットの前に-primary-file
を付けるのが無難です.
実行ファイル生成
各オブジェクトファイルをリンクします.
swiftc TestA.o TestB.o -o Test
これでTestという実行形式が出来上がります.
その他
- モジュール名(例えばMyTest)を付けたい場合は
-module-name MyTest
を追加します. - 他でインポート可能なモジュールを作りたい場合は,
-emit-module
を付けます..swiftmoduleというファイルが作られます.(生成したモジュールを他で使えるようにするのは少々手間がかかるので後ほど...記述するかも..)