Xcodeのビルド時イベントでdotnetコマンドを使うときの注意点まとめ
Photo by Christopher Gower on Unsplash
どうもみなさんこんにちは。イプシロンソフトウェアで代表をしております、渡部です。Xcodeで開発を行っていて、ビルド前の処理としてスクリプト等を書くことってよくありますよね。簡単なシェルスクリプトだったり、RubyやPythonなどのスクリプトもあるかと思います。今回はXcodeからdotnetコマンドを起動して処理を行わせる際の各種注意点をまとめました。このようなスクリプト言語は何を使ってもよいかと思うのですが、ビルド環境のプラットフォームで正しく動作することと、本人が書き慣れているかという点が選択の基準になりますよね。C#でちょっとした処理を書いた場合にどうなるかという点について見てければと思います。
注意点1 : 問題になりがちな環境変数があるので注意する
Xcodeからスクリプトを動かしたりする際には、ビルド時の情報が環境変数という形で各種渡された状態で実行されます。例えばCMakeで作られたXcodeのプロジェクトがあったとします。Xcodeのビルド時のイベントとしてツール起動をCMakeのadd_custom_targetで設定している場合、add_custom_targetで指定したコマンド名は環境変数 TARGETNAME として外部スクリプトに渡されます。このTARGETNAMEがdotnetをビルドする際に問題を引き起こす可能性があります。その場合はdotnetコマンドを実行してあげる前に特定の環境変数を無効にしたうえで実行すると問題がなくなるようです。
unset TARGETNAME && ....参考
注意点2 : dotnetコマンドはフルパスで書く
.NETをインストールするとdotnetコマンドが使えるようになります。シェルにもパスが通るのでターミナルからdotnetと打つだけでコマンドが実行できるようになります。しかしながらXcodeからビルド時イベントとしてdotnetコマンドを実行しようとするとパスが通っていないような挙動になってしまいます。なのでdotnetとコマンドを書かずにフルパスで書いてあげるのがよいみたいです。
/usr/local/share/dotnet/dotnet ...注意点3 : レガシービルドシステムは使わない
Xcodeはレガシービルドシステムというのが一時期サポートされていました。レガシービルドシステムを使っていると、Xcodeのイベントから実行したdotnetコマンドが終了しなくなってしまうという問題があります。とはいえ、レガシービルドシステムは Xcode 14.0.1で廃止されたので2025年現在では使える状況にはなくなっているかと思うのですが、まだ古い環境を使っている場合は早めに乗り換えるとよいかと思います。
参考
注意点4 : シンボリックリンク使用時の注意
あるあるな話としてビルドサーバーのストレージ容量が増えて来た際に、ビルドサーバーにストレージを増設することがあるかと思います。その際にビルド用のオリジナルのディレクトリから新しいストレージにシンボリックリンクを貼ることによりマシンの設定変更を最低限に抑える、ということってよくやりますよね。ただ、Xcodeからビルド時のイベントでdotnetを動かしている場合、ビルドするパスにシンボリックリンクが含まれていると正しく動作しないことに注意してください。具体的には以下の条件を満たしたときに問題が起こります。
- Xcodeのビルド時のイベントでdotnetコマンドを実行している
- dotnet run --project によってソースコードから直接実行しようとしている
- .NETのプロジェクトが外部のパッケージ(NuGetなど)に依存している
- ソースコードの場所にシンボリックリンクが含まれており、実態のパスは違う場所にある
この場合、以下のようにreadlinkコマンドで本当のパスをdotnetコマンドに渡してあげれば問題が解決できるようです。
/usr/local/share/dotnet/dotnet run --project `readlink -f /path/to/csharp_proj`まとめ
ネイティブアプリの開発を行っていると、特にマルチプラットフォームの開発を行っているとこのあたりのビルドシステムをどうやって整えてあげるかって悩みどころですよね。サーバーの開発だとDockerが出てから以降、このような環境依存の問題はだいぶ減ったと言えるかと思いますが、クライアントの開発は「これだ!」と呼べるものがないような印象で、まだまだ悩みはつきないところです。