Xcodeのヘッダーマップについて一言

C / Objective C / C ++言語ファミリにはプリプロセッサが必要です。 プリプロセッサは、コンパイラにテキストを送信する前に、コンパイルされたソースを自分自身に渡します。 おそらく、プリプロセッサの仕事の最も重要な部分は、 #include<->ディレクティブを指定されたファイルの内容に置き換えることです。 通常、相対パスを示します(例: stdio.hsys/stat.h )。 論理的な疑問が生じます-プリプロセッサはどのようにヘッダーファイルを見つけるのですか?

古典的な答えは次のとおりです。プリプロセッサは、INCLUDE_PATHのパスを最初から順番に繰り返し処理します。 includeディレクティブからの相対パスは、INCLUDE_PATHからの(sic)フォルダーを基準にして解決されます。 ファイルが見つからない場合は、次のINCLUDE_PATH要素に進みます。 INCLUDE_PATHを使い果たすと、コンパイラーはエラーを報告します。

しかし、Appleはいつものように調整を行っています。 Xcodeでビルドする場合、いわゆる ヘッダーマップ 。 これは、プロジェクト内のすべてのヘッダーファイルのインデックスです。 Xcodeがfoobar.hを「認識」している場合、このファイルはファイルシステム上の実際の場所に関係なく、名前( #include<foobar.h> )で簡単に利用できます。

これは優れたソリューションです-意図したとおりに機能する限り。 残念ながら、ヘッダーマップメカニズムの文書化は不十分であり、問​​題の迅速な解決には寄与しません。 このギャップを埋めようとします。


ヘッダーマップ

定義
ヘッダーマップは、Xcodeによって生成されるインデックスファイルです。 ファイルの名前は現在のターゲットにちなんで付けられ、拡張子は「 .hmap 」です。 インデックスは、文字列のキーと値のペアのセットです。 インデックスは、 includeディレクティブの引数によってヘッダーファイルへのフルパスと一致するために使用されます。 インデックス検索では大文字と小文字は区別されません。 インデックス検索は、INCLUDE_PATHよりも優先されます。 これは、アセンブリを高速化するために行われます。

デフォルトでは、ヘッダーマップはアクティブです。 無効にするには、プロジェクト構成で変数USE_HEADERMAP=NOを作成する必要があります。

しかし、プロジェクトが同じ名前の複数のヘッダーファイルを使用している場合はどうでしょうか。 デフォルト設定では、これらのファイルの1つだけがインデックスに追加されます-これは予測できません。 プロジェクト内のファイル名が大文字と小文字を区別しないシステムヘッダーファイルと一致する場合も同じ問題が発生します(例: Time.h )。


ヘッダーマップを表示


診断には、生成されたヘッダーマップを調べると役立つ場合があります。 これは、一般的な部分文字列の最適化が混乱しているバイナリファイルです。 親切な人がテキスト形式に変換するためのプログラムを書いたのは良いことです。

 python headermap.py build/hmap.build/Debug/primary.build/primary.hmap 

ここで、 primaryはターゲットの名前です。

 bar.h /Users/nickz/hmap/bar.h foo.h /Users/nickz/hmap/foo.h primary/foo.h /Users/nickz/hmap/foo.h 

foo.hbar.hですべてが多かれ少なかれ明確な場合、 primary/foo.hは質問を投げかけます。 判明したように、Xcodeは現在のターゲットのメンバーであるヘッダーファイル用にこのようなレコードを作成します。 (Xcodeでターゲットメンバーシップをヘッダーファイルにするためには、コピーヘッダービルドフェーズを追加する必要があります。)

PRODUCT_NAMEはプレフィックスとして使用されます。変更すると、古いプレフィックスが引き続きヘッダーマップに表示されます(3.2.5に表示され、新しいバージョンで修正される可能性があります)。 これは、プロジェクトの開閉によって処理されます。


設定


USE_HEADERMAP = [はい] /いいえ
オン/オフ

HEADERMAP_INCLUDES_FLAT_ENTRIES_FOR_TARGET_BEING_BUILT = [はい] /いいえ
アクティブなターゲットのメンバーであるヘッダーファイルをヘッダーマップに含めます。 3.2.5では無視されます。

HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = [はい] /いいえ
アクティブなターゲットのメンバーであるヘッダーファイルをヘッダーマップに含めます。 ファイルには接頭辞$(PRODUCT_NAME)/ます。 設定値がYES場合、そのようなレコードはあらゆるタイプの目的で作成されます。 それ以外の場合、ターゲットタイプがフレームワークの場合のみ。

HEADERMAP_INCLUDES_PROJECT_HEADERS = [はい] /いいえ
目標に関係なく、プロジェクトのすべてのヘッダーファイルをヘッダーマップに含めます。 3.2.5では無視されます。

設定の完全なリスト

Source: https://habr.com/ru/post/J144834/


All Articles