同じワークスペース内で作ったSwiftモジュールを使う
こういう感じの構成で、libの中をPokemonKitとしてモジュールにして、sourcesをアプリにしたいと思った。
app $ tree . ├── Makefile ├── README.md ├── build.ninja ├── lib │ └── pokemon.swift └── sources └── main.swift
モジュールにしなければ、swiftc lib/pokemon.swift sources/main.swift -o build/main
で済む話だし、どこかのGitリポジトリのライブラリを持ってくるのであればSwiftPMを使えばいい話である。
どうしてもSwiftPMを使いたくないというケースも考慮して、一応このまま突き進もう。
module = swiftc -emit-module -module-name PokemonKit -o build/PokemonKit module-obj = swiftc -emit-library -emit-object -module-name PokemonKit app-obj = swiftc -I build/ -emit-object executable = swiftc lib = lib/pokemon.swift app = sources/main.swift rule kit command = $module -o build/PokemonKit $in && mv build/PokemonKit build/PokemonKit.swiftmodule && $module-obj $in -o $out rule app-obj command = $app-obj $in -o $out rule app command = $executable $in -o $out build build/pokemon.o: kit $lib build build/main.o: app-obj $app build build/main: app build/pokemon.o build/main.o default build/main
ninja-buildを使って見た。これで差分ビルドにも対応している。
-emit-module の時にswiftdocも一緒に生成するのだが、出力場所を指定する方法がわからなかった。仕方ないので -o をえいやで指定すると .swiftmoduleのサフィクスがつかなかったので、自分でリネームする処理を入れた。惜しい。
ビルド方法は以下のようになっている。
$ cat Makefile emitted = build/* .PHONY: clean build clean: rm $(emitted) build: ninja -j 1
ninja -j 1
で並列にビルドしないようにしている点がポイントである。
こうしないと、pokemon.oとmain.o を同時に作ろうとして失敗する。
ビルドした状態。
app $ tree . ├── Makefile ├── README.md ├── build │ ├── PokemonKit.swiftdoc │ ├── PokemonKit.swiftmodule │ ├── main │ ├── main.o │ └── pokemon.o ├── build.ninja ├── lib │ └── pokemon.swift └── sources └── main.swift
動かしてみよう。
app $ ./build/main [ATTACK] Pikachu:Lv.1:Scratch! [ATTACK] Bulbasaur:Lv.5:Scratch! [ATTACK] Pikachu:Lv.11:ThunderShock! [ATTACK] Pikachu:Lv.4:Scratch! [ATTACK] Pikachu:Lv.20:ThunderShock!
ちなみにコードはこんな感じである。
import PokemonKit let a = PokeDeck(pokemons: [ Pikachu(level: 1), Bulbasaur(level: 5), Pikachu(level: 11), Pikachu(level: 4), Pikachu(level: 20) ]) for pokemon in a.pokemons { do { try pokemon.attack(move: ElectricMove.ThunderShock) } catch { try! pokemon.attack(move: NormalMove.Scratch) } }
無駄に凝ってしまった。
記事にしてしまったし一応コードをアップしておいた。ご参考まで。
https://github.com/toshi0383/PokemonAttackDemo