XcodeGenの導入でつまずいたところ

今私の中でちょっとアツいのがXcodeGenで、まあアツいんでアツいうちに導入するか〜って昨日ぐらいに重い腰を上げました。

結構スムーズに書けたんですが、いくつかつまずいたので、その点をピックアップ。ちなみに書くときに参考にしたのは XcodeGen/ProjectSpec.md at master · yonaskolb/XcodeGen · GitHub です。ここ見れば大体書いてある。

Xcode上でTestingのHost Applicationが設定されていない(ように見える)

テストターゲットの指定の仕方は:

targets:
  SampleApp:
    scheme:
      testTargets:
        - SampleAppTests
  SampleAppTests:
    # ...

でOKで、実際これでテストの設定がされたSampleAppのスキームが出力されます。ただし、SampleAppのPRODUCT_NAMEを.xcconfigファイルなり:

targets:
  SampleApp:
    settings:
      PRODUCT_NAME: Sample

のように設定してしまうと、Xcode上でSampleAppTestsのHost Applicationを見ても設定されていないように見えます。

f:id:takkkun:20190313163418p:plain

原因なんですが、TEST_HOSTに設定される値は変更前のPRODUCT_NAME(= SampleApp)、ただ実際のPRODUCT_NAMEは変更されている(= Sample)からです。要は食い違っているということですね。

解消するには:

targets:
  SampleApp:
    productName: Sample
    settings:
      PRODUCT_NAME: Sample

と、productNameキーで指定してあげれば大丈夫です。なお、productNameキーで指定しても、実際にPRODUCT_NAMEが変わるわけではない(あくまでXcodeGenのコード中で扱う値が変わるだけ)ので、別途設定する必要はあります。

か、TEST_HOSTを自前で設定してあげれば大丈夫ですね(最初こっちでやってた)。

R.swiftなどで生成されるコードがコンパイルの対象にならない

project.ymlで設定したsourcesは、xcodegenを行ったタイミングで取り込まれているみたいで、その後に追加されたファイルはコンパイルの対象になりません。ですので、R.swiftなどのように、コンパイル直前にコードを生成するものと組み合わせると、その生成物はコンパイル対象に入らず、大量のコンパイルエラーに見舞われます。

じゃあもう1回xcodegenすればって、まあそうなんですけど、めんどくさい(というかだいたい新たにgit cloneしたタイミングでこの問題が起きるので、そこでコケさせたくない)ので、自動でコンパイル対象になっていてほしいです。

ので、project.yamlで:

targets:
  SampleApp:
    sources:
      - path: Source
      - path: Source/R.generated.swift
        optional: true
    preBuildScripts:
      - name: R.swift
        script: # ...

と、してあげます。sourcesに指定されたフォルダなどはxcodegen時にあるかどうかチェックされるんですが、optional: trueとしておくと、なくてもスルーしてくれるようになります。これで実際のビルド時はR.generated.swiftが生成されるので、問題なくビルドできます。

ただpreBuildScriptsで生成されたものをいちいちsourcesに書かないといけないので、やや面倒……。もう少し良い方法ある?