ビルド設定ファイルでXcodeの検索パスを変更する

開発しているアプリによっては、自身で管理していないSDKなどの使用が必要となることがあります。SDKのインストールパスは大体同じ場合が多いと思いますが、任意の場所にインストール可能な場合、マシンや開発者によってインストール先が異なる場合もあります。

そのようなときに、プロジェクトファイルに直接、検索パスを設定してしまうと、Gitからプロジェクトファイルをプルするたびに、検索パスを自分の設定に合わせて変更しなければいけなくなってしまいます。逆に自分がコミットするときには、プロジェクトファイルを含めないように自分で注意しなければいけなくなってしまいます。

この記事ではこのような事態を回避するための方法を解説します。

目次

ビルド設定ファイルの作成

プロジェクトファイルに設定される値が、環境依存になることが問題の原因です。回避するには、マシンごとに設定値が変わるようにビルド設定ファイルを作成します。

ビルド設定ファイルの作成方法と、それをプロジェクトに適用する方法については、以下の記事を参照してください。

上記の記事を参考に、次の3つのビルド設定ファイルを作成します。

  • Debug.xcconfig
  • Release.xcconfig
  • SearchPath.xcconfig

名前の通り、デバッグビルドにDebug.xcconfig、リリースビルドにRelease.xcconfigを設定します。次にDebug.xcconfigRelease.xcconfigに以下のように記述します。

#include "SearchPath.xcconfig"

検索パスの変更

iOSアプリやmacOSアプリの場合、検索パスというと次の3つが一般的に使われます。

  • フレームワーク検索パス
  • ヘッダーファイル検索パス
  • ライブラリ検索パス

検索パスはビルド設定のSearch Pathsの中に設定項目がまとまっています。

検索パス
検索パス

フレームワーク検索パス

フレームワーク検索パスはリンカーがフレームワークとリンクするときに、フレームワークを検索するディレクトリパスです。ビルド設定のSearch PathsFramework Search Pathsに設定します。

ヘッダーファイル検索パス

ヘッダーファイル検索パスは、C言語、C++、Objective-C/C++のコードから、ヘッダファイルをインクルードするときに、コンパイラがヘッダーファイルを検索するディレクトリパスです。ビルド設定のSearch PathsHeader Search Pathsに設定します。

ライブラリ検索パス

ライブラリ検索パスは、リンカーが共有ライブラリおよびスタティックライブラリとリンクするときに、ライブラリを検索するディレクトリパスです。ビルド設定のSearch PathsLibrary Search Pathsに設定します。

ビルド設定ファイルを使った変更方法

ビルド設定ファイルを使って、検索パスを指定するには、ビルド設定ファイルで以下の設定にディレクトリパスを設定します。

検索パス ビルド設定ファイルの設定
フレームワーク検索パス FRAMEWORK_SEARCH_PATHS
ヘッダーファイル検索パス HEADER_SEARCH_PATHS
ライブラリ検索パス LIBRARY_SEARCH_PATHS
検索パスの設定

検索パスには複数のディレクトリパスをスペース区切りで指定可能です。ディレクトリパスにスペースが含まれる場合は、クオーテーションマークで囲みます。

本記事では、SearchPath.xcconfigファイル内に記述します。たとえば、次のように記述します。

FRAMEWORK_SEARCH_PATHS = /usr/local/share/mydevice-sdk/frameworks $(inherited)
HEADER_SEARCH_PATHS = /usr/local/share/mydevice-sdk/includes $(inherited)
LIBRARY_SEARCH_PATHS = /usr/local/share/mydevice-sdk/libs $(inherited)

$(inherited)を使って、デフォルトや上位で設定している値も継承して使用するようにしましょう。

また、この例では$(inherited)よりも前に自分の設定を書くことで、継承したディレクトリよりも、ビルド設定ファイルで指定するディレクトリを優先するように指定しています。本例では、デバイスのSDKを利用するシナリオを想定しています。原則として重複は避けた方が良いものの、SDKがデフォルトで提供するヘッダーファイルと同名のファイルをSDK側で提供している場合、そのファイルがSDK専用にカスタマイズされている可能性があります。このような場合、SDK側のファイルを優先して使用すべきです。そのため、本例ではSDK側の設定を優先するようにしています。

Gitの管理対象から除外する

しかし、これだけではマシン固有の設定になりません。SearchPath.xcconfigファイルは、各マシンごとに異なると想定しています。そのため、SearchPath.xcconfig.gitignoreに記述し、Gitの管理対象から除外しましょう。

そのようにすることで、必ず、マシン毎(クローン毎)にSearchPath.xcconfigファイルを、作ることを強制できます。

ただし、この「作成を強制する」方式にはCI(継続的インテグレーション)との組み合わせた場合に問題が発生する、可能性があるという弱点があります。

CI用のファイルはどうするか?

このようにして、SearchPath.xcconfigをGitからクローンした環境毎に作成することを強制すると、困ってしまうのがCI(継続的インテグレーション)はどうするかです。

ビルド設定ファイルは、複数回同じ設定項目を設定すると、後から書いた方が優先されるという特徴が有ります。それを利用して次のようにデフォルト値を定義してしまうという方法があります。

STEP
「SearchPath-default.xcconfig」を作成します。
STEP
「SearchPath-default.xcconfig」内で、検索パスのデフォルト値を定義します。

この定義はCIによって使われます。

STEP
「Debug.xcconfig」と「Release.xcconfig」に、次のように記述して、「SearchPath-default.xcconfig」を読み込んだ後、「SearchPath.xcconfig」を読み込むようにします。
#include "SearchPath-default.xcconfig"
#include? "SearchPath.xcconfig"

これにより、SearchPath.xcconfigの作成を強制することはできなくなりますが、ローカル環境ではSearchPath.xcconfigを作成し、SearchPath-default.xcconfigに記述された設定を上書きすることが可能になります。

SearchPath.xcconfigでは#include?という、?が付いたインクルード文を使用します。この#include?は、対象のファイルが存在しなくてもビルドエラーにはならず、ファイルが存在する場合にのみインクルードします。

上書きする必要がないときは、SearchPath.xcconfigは作成せずにビルドし、CIとは別のディレクトリにSDKを置いているときにはSearchPath.xccconfigを作成して、設定を上書きして運用できるようになります。

デバッグ版とリリース版を分ける

デバッグ版とリリース版とで、ライブラリやフレームワークも切り替えたい場合があります。SDKがデバッグ版のライブラリとリリース版のライブラリを提供しているというときです。

このような場合は、SearchPath.xcconfigファイルもデバッグ用とリリース用を作成します。たとえば、次のようなファイル名にします。

  • SearchPath-debug.xcconfig
  • SearchPath-release.xcconfig

次に、Debug.xcconfigRelease.xcconfigで、読み込むファイルを変更します。

Debug.xcconfigには次のように記述します。

#include "SearchPath-debug.xcconfig"

Release.xcconfigには次のように記述します。

#include "SearchPath-release.xcconfig"

Xcodeでビルド設定を確認すると、期待通り、デバッグ用とリリース用で異なる検索パスが正しく設定されていることを確認できます。

検索パス
検索パス

著書紹介

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。Appleプラットフォーム向けの開発を専門としているソフトウェアエンジニア。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, Medium, LinkedIn
-
Representative of RK Kaihatsu. Software Engineer Specializing in Development for the Apple Platform. Specializing in contract software development, technical writing, and serving as a tech workshop lecturer. note, Medium, LinkedIn

目次