忍者ブログ
プログラミングとか日常とかの覚書っぽいなにか
[36] [35] [34] [33] [32] [31] [30] [29] [28] [27] [26]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

Xcodeで外部ライブラリのソースを丸ごとプロジェクトに追加して使うことがありますが、この場合、そのプロジェクトのヘッダファイルがどこにあっても単にヘッダファイル名を(相対パスもなしに) #import に指定できることに疑問を感じました。

例えばVisual Studioなら、プロジェクト設定の「追加のインクルードディレクトリ」にライブラリのヘッダファイルがあるディレクトリをあらかじめ指定しておくか、適切に間接パスまたは直接パスの形式で #include を指定しないと、ヘッダが見つからないというコンパイルエラーが発生することでしょう。
コマンドラインでもオプション指定か環境変数による指定がありますし。

確かに、Xcodeにもプロジェクトの「Build Settings」の中に、追加の検索パスを指定する「Search Paths」の項目が存在します。……が、その項目には特にプロジェクトディレクトリのパスが指定されていたりはしませんでした。

というわけで、どういう条件で #include / #import が可能になるのか、以下のように実験してみました。

まずはプロジェクトを新規作成。例として testapp という名前で作成するとディレクトリ構成が以下のようになります。

作成したプロジェクトのファイル/ディレクトリ構成

[testapp]
    testapp.xcodeproj
    [testapp]
        AppDelegate.h
        AppDelegate.m
        main.m
        (略)

次に、プロジェクトとは別の場所にソースファイルを以下のように準備しておきます。

追加するソースのファイル/ディレクトリ構成

[testlib]
    testlib1.h  ・・・★
    testlib1.m  ・・・★
    [testlib2]  ・・・★
        testlib2.h
        testlib2.m
        [testlib3]
            testlib3.h
            testlib3.m

上記の★マークのファイル3つをFinder上でまとめて選択し、それをXcodeのProject Navigator上のtestappフォルダ(プロジェクト名と同じ名前のグループフォルダ)に放り込みます。

「Add to targets」で対象プロジェクト名にチェックボックスにチェックを入れておいてください。入れないと追加するソースファイル(.m)がビルド対象に含まれません。(ヘッダ(*.h)が含まれてるとデフォルトではチェックされないらしい。)
また、ここでは「Copy items into destination group's folder (if needed)」のチェックをONにして、「Create groups for any added folders」ラジオボタンを選択しておきます。

プロジェクトにソースファイルを追加すると、全体のファイル構成が以下のようになっています。

追加後のプロジェクトのファイル/ディレクトリ構成

[testapp]
    testapp.xcodeproj
    [testapp]
        AppDelegate.h
        AppDelegate.m
        main.m
        (略)
        testlib1.h
        testlib1.m
        [testlib2]
            testlib2.h
            testlib2.m
            [testlib3]
                testlib3.h
                testlib3.m

この構成で AppDelegate.m および testlib2.m からヘッダファイルを#importで取り込めるか試してみました。

AppDelegate.m の中で
#importの記述 結果
#import "testlib1.h" OK
#import "testlib2.h" OK
#import "testlib3.h" OK
#import "./testlib1.h" OK
#import "./testlib2.h" NG
#import "testlib2/testlib2.h" OK
#import "testlib2/testlib3/testlib3.h" OK
#import "testlib3/testlib3.h" NG


testlib2.m の中で
#importの記述 結果
#import "testlib1.h" OK
#import "testlib2.h" OK
#import "testlib3.h" OK
#import "./testlib1.h" NG
#import "./testlib2.h" OK
#import "testlib3/testlib3.h" OK
#import "testlib2/testlib3/testlib3.h" OK


さらに、Finder上で testlib3 ディレクトリに新しいヘッダファイル testlib4.h を作成(ただし、プロジェクトには含めない)。

追加後のプロジェクトのファイル/ディレクトリ構成2

[testapp]
    testapp.xcodeproj
    [testapp]
        AppDelegate.h
        AppDelegate.m
        main.m
        (略)
        testlib1.h
        testlib1.m
        [testlib2]
            testlib2.h
            testlib2.m
            [testlib3]
                testlib3.h
                testlib3.m
                testlib4.h ・・・★ファイル追加(Xcodeのプロジェクトには含めない)


AppDelegate.m の中で
#importの記述 結果
#import "testlib4.h" NG
#import "testlib2/testlib3/testlib4.h" OK

testlib2.m の中で
#importの記述 結果
#import "testlib4.h" NG
#import "testlib3/testlib4.h" OK
#import "testlib2/testlib3/testlib4.h" NG

ということで、どうやらXcodeの場合、通常の #include のルールの他に、「プロジェクトに含まれているヘッダファイルをパス指定なしで #import 可能」であるようです。

では、同じ名前のファイルがあったらどうなるのでしょうか?
今度は以下のようにファイル testlib3.h を testlib1.h に名前変更して試してみます。

[testapp]
    testapp.xcodeproj
    [testapp]
        AppDelegate.h
        AppDelegate.m
        main.m
        (略)
        testlib1.h ・・・(1)
        testlib1.m
        [testlib2]
            testlib2.h
            testlib2.m
            [testlib3]
                testlib1.h ・・・(2) ★testlib3.hから名前変更
                testlib3.m


AppDelegate.m の中で
#importの記述 結果
#import "testlib1.h" (1)のファイルが読み込まれる

testlib2.m の中で
#importの記述 結果
#import "testlib1.h" (1)のファイルが読み込まれる

testlib3.m の中で
#importの記述 結果
#import "testlib1.h" (2)のファイルが読み込まれる


以上から、プロジェクトに同じ名前のヘッダファイルがあった場合には、

1. 同じディレクトリ内にある場合は、それが読み込まれる
2. 同じディレクトリ内にない場合は、プロジェクト内の浅いディレクトリにあるものが読み込まれる?

となっているっぽい。

……と最初は思ったのですが、さらにディレクトリを作っていろいろ試すと、同じファイル名が(#importを書いているソースとは別の)複数のディレクトリにある場合にどれが優先して読み込まれるのかがよくわからなくなってしまいました。
必ずしも上のディレクトリのものとは限らないようですし、アルファベット順というわけでもなく……。プロジェクトに追加された順? プロジェクトいったん閉じて再度開いたらまた順序が変わっているような……?

この辺りはさらなる調査の余地がありそうです。
何はともあれ、同じ名前のヘッダを含めないようにするか、せめて(同じディレクトリにないヘッダを読むのであれば)相対パスを指定するようにした方がよさそうな。

拍手

PR

コメント
グッチ バッグ
お世話になります。とても良い記事ですね。
【2012/10/17 19:39】 NAME[グッチ バッグ] WEBLINK[URL] EDIT[]
無題
とてもわかりやすい記事で参考になりました。
【2012/12/11 22:46】 NAME[ハリス] WEBLINK[] EDIT[]


コメントフォーム
お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード
  Vodafone絵文字 i-mode絵文字 Ezweb絵文字


忍者ブログ [PR]
プロフィール
HN:
はむぱい
職業:
ソフト作ったりしてる人
Twitter
最新CM
[06/09 replica rolex oyster perpetual datejust]
[06/09 bracelets imitation cartier love]
[06/09 replica the oyster perpetual datejust]
[06/09 datejust rolex oyster perpetual]
[06/09 replica gold love bangle]
カレンダー
11 2017/12 01
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
ブログ内検索
あ~いい漢字