web-dev-qa-db-ja.com

Xcode 4は、静的ライブラリの依存関係からパブリックヘッダーファイルを見つけることができません

検索を支援する代替タイトル

  • Xcodeはヘッダーを見つけることができません
  • Xcodeに.hがありません
  • Xcode .hファイルが見つかりません
  • 字句またはプリプロセッサの問題ファイルが見つかりません

私はXcode 3から来たiOSアプリケーションプロジェクトに取り組んでいます。現在、Xcode 4に移動し、私のプロジェクトは多くの静的ライブラリをビルドしています。

これらの静的ライブラリもパブリックヘッダーを宣言し、それらのヘッダーはアプリケーションコードで使用されます。 Xcode 3.xでは、ヘッダーが(ビルドフェーズとして)public headers directoryにコピーされ、アプリケーションプロジェクトでpublic headers directoryheaders search listに追加されました。

Xcode 4では、ビルドディレクトリは~/Library/Developer/Xcode/DerivedData/my-projectに移動します。

問題は、ヘッダー検索設定でこの新しい場所をどのように参照するのですか?のようだ:

  • public headers directoryDerivedDataディレクトリに相対的ですが、
  • headers searchディレクトリは、他のもの(おそらくプロジェクトの場所)に関連しています。

Xcode 4でiOS開発用の静的ライブラリターゲットを設定するには、依存関係としてコンパイルするときに静的ライブラリを使用するクライアントがヘッダーファイルを使用できるようにしますか?

91
rjstelling

Xcode 4プロジェクトが静的ライブラリのコンパイルに失敗する

関連質問: Xcode 4 の「字句またはプリプロセッサの問題ファイルが見つかりません」

エラーには以下が含まれる可能性があります;ヘッダーファイルの欠落、「字句またはプリプロセッサの問題」

ソリューション:

  1. 「ユーザーヘッダーパス」が正しいことを確認します
  2. [常にユーザーパスを検索する]を[はい]に設定します
  3. プロジェクトに「Indexing headers」というグループコールを作成し、ヘッダーをこのグループにドラッグします。DO NOTプロンプトが表示されたらターゲットに追加します。
16
rjstelling

この問題に対して私が見た解決策はそれぞれ、洗練されていない(アプリケーションのプロジェクトにヘッダーをコピーする)か、些細な状況でしか機能しない程度に単純化されているかのいずれかです。

短い答え

次のパスをser Header Search Pathsに追加します

「$(BUILD_ROOT)/../ IntermediateBuildFilesPath/UninstalledProducts」

なぜこれが機能するのですか?

まず、問題を理解する必要があります。通常の状況、つまり、実行、テスト、プロファイル、または分析の場合、Xcodeはプロジェクトをビルドし、出力をBuild/Products /Configuration/ Productsディレクトリ。これは、$ BUILT_PRODUCTS_DIRマクロを介して利用できます。

静的ライブラリに関するほとんどのガイドでは、Public Headers Folder Path$ TARGET_NAMEに設定することを推奨しています。つまり、libファイルは$ BUILT_PRODUCTS_DIR/libTargetName.aになります。ヘッダーは$ BUILT_PRODUCTS_DIR/TargetNameに配置されます。アプリの検索パスに$ BUILT_PRODUCTS_DIRが含まれている限り、インポートは上記の4つの状況で機能します。ただし、アーカイブしようとすると、これは機能しません。

アーカイブの動作は少し異なります

プロジェクトをアーカイブすると、XcodeはArchiveIntermediatesと呼ばれる別のフォルダーを使用します。そのフォルダー内に/ YourAppName/BuildProductsPath/Release-iphoneos /があります。これは、アーカイブを行うときに$ BUILT_PRODUCTS_DIRが指すフォルダーです。そこを見ると、ビルドされた静的ライブラリファイルへのシンボリックリンクがあることがわかりますが、ヘッダーのあるフォルダーがありません。

ヘッダー(およびlibファイル)を見つけるには、IntermediateBuildFilesPath/UninstalledProducts /に移動する必要があります。静的ライブラリのSkip InstallをYESに設定するように言われたときのことを覚えていますか?これは、アーカイブを作成するときに設定が持つ効果です。

サイドノート:インストールをスキップするように設定しない場合、ヘッダーはさらに別の場所に配置され、libファイルがアーカイブにコピーされるため、App Storeに送信できる.ipaファイルをエクスポートできません。

多くの検索の後、UninstalledProductsフォルダーに正確に対応するマクロが見つからなかったため、「$(BUILD_ROOT)/../ IntermediateBuildFilesPath/UninstalledProducts」でパスを作成する必要があります。

概要

静的ライブラリの場合、インストールをスキップし、パブリックヘッダーが$ TARGET_NAMEに配置されていることを確認してください。

アプリの場合、ユーザーヘッダーの検索パスを「$(BUILT_PRODUCTS_DIR)」に設定します。これは通常のビルドで正常に機能し、「$(BUILD_ROOT)/../ IntermediateBuildFilesPath/UninstalledProducts」はアーカイブビルドで機能します。

125
Colin

独自の静的ライブラリを開発するときにこの同じ問題に遭遇しましたが、Colinの答えは非常に役に立ちましたが、ワークスペースを使用してXcode 4でプロジェクトを実行およびアーカイブするときに一貫して動作するように少し修正する必要がありました。

私の方法の違いは、すべてのビルド構成に単一のユーザーヘッダーパスを使用できることです。

私の方法は次のとおりです。

ワークスペースを作成する

  1. Xcode 4で、[ファイル]、[新規]、[ワークスペース]に移動します。
  2. Finderから、使用する静的ライブラリと、ライブラリを使用する作成中の新しいアプリの両方の.xcodeprojプロジェクトにドラッグできます。ワークスペースの設定の詳細については、Apple Docs)を参照してください: https://developer.Apple.com/library/content/featuredarticles/XcodeConcepts/Concept-Workspace.html

静的ライブラリプロジェクトの設定

  1. すべての静的ライブラリのヘッダーが「パブリック」にコピーするように設定されていることを確認してください。これは、静的ライブラリターゲット>ビルドフェーズの設定で行われます。 [ヘッダーのコピー]フェーズで、すべてのヘッダーが[パブリック]セクション内にあることを確認します。
  2. 次に[ビルド設定]に移動し、[パブリックヘッダーフォルダーパス]を見つけて、ライブラリのパスを入力します。私はこれを使用することを選択します:

include/LibraryName

RestKitでの使用からこれを採用しましたが、すべての静的ライブラリで最適に機能することがわかりました。これは、手順1で「パブリック」ヘッダーセクションに移動したすべてのヘッダーを、ビルド時に派生データフォルダー内にあるここで指定したフォルダーにコピーするようにXcodeに指示します。 RestKitと同様、単一の「include」フォルダーを使用して、プロジェクトで使用している各静的ライブラリを含めるのが好きです。

また、静的ライブラリを使用してプロジェクトを構成するときに、単一のユーザーヘッダー検索パスを使用できるようになるため、ここでマクロを使用するのも好きではありません。

  1. 「スキップインストール」を見つけて、これがYESに設定されていることを確認します。

静的ライブラリを使用したプロジェクトの設定

  1. [ビルドフェーズ]> [ライブラリとバイナリをリンク]でフレームワークとして静的ライブラリを追加し、使用する静的ライブラリのlibLibraryName.aファイルを追加します。
  2. 次に、プロジェクトがユーザー検索パスを検索するように設定されていることを確認します。これは、[ビルド設定]> [ユーザーパスを常に検索]で行い、[はい]に設定されていることを確認します。
  3. 同じ領域で、ユーザーヘッダーの検索パスを見つけて追加します。

    「$(PROJECT_TEMP_DIR)/../ UninstalledProducts/include」

これにより、Xcodeは、ビルドプロセス中にXcodeが作成する中間ビルドフォルダー内の静的ライブラリを検索します。ここには、ステップ2で静的ライブラリプロジェクト設定用に設定した静的ライブラリの場所に使用している「include」フォルダがあります。これは、Xcodeで静的ライブラリを正しく見つけるための最も重要な手順です。

ワークスペースを構成する

ここでは、アプリをビルドするときに静的ライブラリがビルドされるようにワークスペースを構成します。これは、アプリで使用されるスキームを編集することで行われます。

  1. アプリケーションを作成するスキームが選択されていることを確認してください。
  2. スキームのドロップダウンから、スキームの編集を選択します。
  3. 左側のリストの上部にある[ビルド]を選択します。中央のペインで+を押して、新しいターゲットを追加します。
  4. リンクしようとしているライブラリの静的ライブラリが表示されるはずです。 iOS静的ライブラリを選択します。
  5. [実行]と[アーカイブ]の両方をクリックします。これにより、アプリをビルドするたびに静的ライブラリのライブラリをコンパイルするようにスキームに指示します。
  6. アプリケーションターゲットの上に静的ライブラリをドラッグします。これにより、アプリケーションのターゲットの前に静的ライブラリがコンパイルされます。

ライブラリの使用を開始

これで、次を使用して静的ライブラリをインポートできるはずです。

import <LibraryName/LibraryName.h>

この方法では、構成ごとに異なるユーザーヘッダーパスを用意する必要があるため、アーカイブのコンパイルに問題はありません。

なぜこれが機能するのですか?

すべてこのパスに依存します。

"$(PROJECT_TEMP_DIR)/../UninstalledProducts/include"

「スキップインストール」を使用するように静的ライブラリを構成するため、コンパイルされたファイルは一時ビルドディレクトリ内の「UninstalledProjects」フォルダーに移動されます。ここでのパスは、静的ライブラリ用にセットアップし、ユーザーヘッダーの検索パスに使用する「include」フォルダーにも解決されます。この2つが連携することで、Xcodeはコンパイルプロセス中にライブラリの場所を認識できます。この一時的なビルドディレクトリはデバッグ構成とリリース構成の両方に存在するため、Xcodeが静的ライブラリを検索するための単一のパスのみが必要です。

85
gdavis

これは非常に役立つスレッドでした。私自身の状況を調査してみると、Appleには2012年9月の「iOSでの静的ライブラリの使用」という12ページのドキュメントがあります。PDFリンクは次のとおりです。 http:/ /developer.Apple.com/library/ios/technotes/iOSStaticLibraries/iOSStaticLibraries.pdf

インターネットでの議論の大部分よりもはるかに簡単で、使用している外部ライブラリの設定方法を説明する小さなmodがあれば、うまく機能します。最も重要な部分はおそらく次のとおりです。

ライブラリターゲットに「ヘッダーのコピー」ビルドフェーズがある場合は、削除する必要があります。 Xcodeで「アーカイブ」アクションを実行するときに、コピーライブラリのビルドフェーズが静的ライブラリターゲットで正しく機能しません。

Xcode 4.4以降で作成された新しい静的ライブラリターゲットには、ヘッダーのファイルのコピーフェーズが適切に構成されているため、作成する前に既に存在するかどうかを確認する必要があります。そうでない場合は、ターゲットエディターの下部にある[ビルドフェーズの追加]を押し、[コピーファイルの追加]を選択します。新しいコピーファイルビルドフェーズを公開し、宛先を[製品ディレクトリ]に設定します。 $ {PRODUCT_NAME}。これにより、ビルドされた製品ディレクトリ内のincludeという名前のフォルダー内の、(PRODUCT_NAMEビルド​​設定から取得された)ライブラリーにちなんだ名前のフォルダーにファイルがコピーされます。ビルド製品ディレクトリ内のincludeフォルダーは、アプリケーションのデフォルトのヘッダー検索パスにあるため、これはヘッダーファイルを置くのに適した場所です。

多くの既存の状況では、Appleのアプローチでは十分ではないと確信しています。静的ライブラリの庭の道を旅し始めたばかりの人のために、これをここに投稿します。これは、単純な場合の最適な出発点かもしれません。

15
Michael J.

http://developer.Apple.com/library/ios/#technotes/iOSStaticLibraries/Articles/creating.html

Per Apple documention:

ライブラリには、そのライブラリのクライアントがインポートする必要がある1つ以上のヘッダーファイルがあります。クライアントにエクスポートするヘッダーを構成するには、ライブラリプロジェクトを選択してプロジェクトエディターを開き、ライブラリターゲットを選択してターゲットエディターを開き、ビルドフェーズタブを選択します。ライブラリターゲットに「ヘッダーのコピー」ビルドフェーズがある場合は、削除する必要があります。 Xcodeで「アーカイブ」アクションを実行するときに、コピーライブラリのビルドフェーズが静的ライブラリターゲットで正しく機能しません。

4
dmarnel

詳細については、Jonah Wlliamのソリューション(中途半端)とGitHubモデル(コメント)をご覧ください。 http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/

3
d1bru

私の場合、ワークスペースにはいくつかの静的ライブラリプロジェクトがあり、そのうちの1つにはヘッダーファイルを含む依存関係があります。問題は建築の順序にあった。 [ビルド]セクションの[スキーム]ページの編集で、並列化オプションの選択を解除し、依存関係に従ってターゲットの順序を調整し、問題によって解決しました

2
Vamshi

$(OBJROOT)/ UninstalledProducts/exactPathToHeadersHeader Search Paths。に追加します

何らかの理由で再帰チェックボックスが機能しなかったため、残りのパスをヘッダーのある場所に追加する必要がありました。

XcodeのLog Navigator(ブレークポイントナビゲーターの右側のタブ)で、ビルド履歴を確認できます。実際のビルドの失敗を選択した場合、詳細を展開してsetenv PATHを表示し、ヘッダーファイルへのパスが存在することを確認できます。

2
Collin

私がバカなのかを示すリスクがある...私は、XCodeが午後中ずっと.hファイルを見つけるのを拒否することに苦しんでいます。

それから実現しました。

「XCode 4」を使用していたため、「インテリジェントに」すべてのプロジェクトを「XCode 4 projects」というフォルダーのサブフォルダーに入れることにしました。

フォルダー名のスペースがめちゃくちゃになったのは、XCode big-time!

このフォルダーの名前を「XCode_4_Projects」に変更すると、私の人生に喜びがもたらされ(宣誓は減ります)ます。

もう一度思い出してください、what今年は?

おそらく誰かがApple開発者...

1
Mike Gledhill

Xcode 7では上記の答えはどれもうまくいきませんでしたが、良いアイデアをくれました。 Xcode 7で苦労している人のために、ユーザーヘッダー検索パスに次を追加することでこれを修正しました(引用符を含む)

"$(BUILT_PRODUCTS_DIR)/usr/local/include"

相対URL部分を変更するusr/local/include静的ライブラリの[パブリックヘッダーフォルダパス]設定の内容に応じて

1
Evol Gate

これらの答えはどれも私にとってはうまくいきませんでした。これが何をしたかです。 ユーザーヘッダー検索パスビルド設定に次を正確に追加します(二重引用符を含むコピーアンドペースト)。

"$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts/include/"

他の回答と比較して、「/ include /」サブディレクトリが追加されていることに注意してください。他のユーザーが指摘しているように、「再帰」オプションは何もしないようですので、無視してください。

次の形式で静的ライブラリヘッダーファイルをインポートすると、私のプロジェクトは正常にアーカイブできるようになりました。

#import "LibraryName/HeaderFile.h"

notAlways Search User Paths設定を有効にする必要があります。山括弧(#import <LibraryName/HeaderFile.h>)、しかし、それがシステム/フレームワークヘッダーでないなら、とにかくそれをそうするべきではありません。

1
devios1

次のパスをユーザーヘッダーの検索パスに追加します。

$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts

これは確認済みです!

1
yirenjun

これが私にとって同じ問題を解決したものです。

App TargetとiMessage Extension Targetがあります。次に、App Targetがリンクする2つのSDK(自分のSDK)がありました。

問題は、私のiMessageターゲットも私の2つのSDK(個別のプロジェクト)を使用していましたが、Build Phases-> Link Binary With Librariesでリンクしていませんでした。 2つのSDKをiMessageターゲットに追加して、Appターゲットに一致させる必要がありましたが、今ではアーカイブします。

したがって、話の教訓は次のとおりです。拡張機能など、複数のターゲットがある場合は、すべてのターゲットが必要なライブラリにリンクしていることを確認してください。シミュレータおよびデバイスにビルドおよびデプロイできましたが、アーカイブできませんでした。

0
FranticRock

これを行うにはさまざまな複雑な方法があり、このスレッドではいくつかの非常にスマートなソリューションが提案されています。

これらすべてのソリューションの主な問題は、ライブラリの移植性が大幅に低下することです。

  • ライブラリを使用して新しいプロジェクトを開始し、iTunes用にアーカイブする必要があるたびに、それは設定の地獄です。
  • プロジェクトをチームや顧客と共有する必要があるたびに、何らかの理由(コンテキスト、Xcodeバージョン、その他)で壊れる可能性があります。

最終的には、Apple(WWDCビデオ)で推奨されているように、常に-フレームワークを使用することを選択しました。

それはとても簡単で、最後に同じ仕事をします!

動作すると思われる別の非常にエレガントなソリューションは、プライベートココアポッドを使用することです。 Cocoapodsは、すべての構成作業、ヘッダーのコピーなどを行います。

Frameworks rock!

0
Moose

これは関連する問題であるため、この質問に至ったので、ドキュメントのために厳密にソリューションを追加します。これにより、さらに多くの汗をかくことができます

DropboxSDK.hファイルが見つかりません

IOS向けにVESをコンパイルしようとした数日後、私は最終的にこの問題に遭遇しました。 DropboxSDK.hは間違いなくsearch headersに届きました。framework headers検索パスに追加したり、included .hに直接追加したり、あらゆる種類の取得しようとする長さDropboxSDK.hが見つかりました。

解決

[〜#〜] explicity [〜#〜]DropboxSDK.frameworkファイルをXcodeのProject Navigationにドラッグし、Copy Files if neededがオンになっていることを確認します。また、必要に応じてターゲットがチェックされていることを確認してください。

警告

build phasesで明示的なフレームワークの場所を設定しても機能しませんでした。 ドラッグ .frameworkをXcodeに入れ、ファイルがプロジェクトにコピーされていることを確認する必要がありました。

#mbp2015#xcode7#ios9

0
Jacksonkr

更新:Xcode 9

Xcode 9を使用した場合、上記の回答は機能しませんでしたが、この answer は完全に機能しました。 「ヘッダー検索パス」に$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/includeを追加しましたが、Xcodeは静的ライブラリのヘッダーを問題なくリンクしました。

0