Xcode 4 ne peut pas localiser les fichiers d'en-tête publics à partir de la dépendance statique de la bibliothèque

d'autres titres à l'aide de la recherche

  • Xcode ne peut pas trouver l'en-tête
  • manquant .h in Xcode
  • Xcode .h fichier non trouvé
  • lexicale ou de préprocesseur problème de fichier non trouvé

je travaille sur un projet d'application iOS qui vient de Xcode 3. J'ai maintenant déménagé à Xcode 4 mon projet construit un certain nombre de bibliothèques statiques.

ces bibliothèques statiques déclarent aussi les en-têtes publics et ces en-têtes sont utilisés par le code d'application. En Xcode 3.x les en-têtes ont été copiés (en phase de construction) sur le public headers directory , puis dans le projet d'application le public headers directory a été ajouté au headers search list .

sous Xcode 4 le répertoire de compilation est déplacé à ~/Library/Developer/Xcode/DerivedData/my-project .

le problème est comment faire référence à ce nouvel emplacement dans les en-têtes les paramètres de recherche? Il semble que:

  • public headers directory est relatif à DerivedData répertoire, mais
  • headers search l'annuaire est relatif à autre chose (peut-être l'emplacement du projet)

comment mettre en place une cible de bibliothèque statique pour le développement iOS dans Xcode 4 qui garantira que les fichiers d'en-tête sont mis à disposition des clients qui utilisent la bibliothèque statique en essayant de compiler comme un dépendance?

90
demandé sur jlehr 2011-04-05 00:18:04

17 réponses

chacune des solutions que j'ai vu à ce problème ont semblé soit inélégante (copier des en-têtes dans le projet de l'application) ou excessivement Simplifiée au point qu'ils ne fonctionnent que dans des situations triviales.

La réponse courte

ajouter le chemin suivant à votre chemin de recherche D'en-tête D'utilisateur

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

pourquoi ça marche?

tout d'abord, nous devons comprendre le problème. Dans des circonstances normales, c'est-à-dire lorsque vous exécutez, testez, profilez ou analysez, Xcode construit votre projet et place la sortie dans le répertoire Build/Products/ Configuration /Products, qui est disponible via la macro $BUILT_PRODUCTS_DIR .

la plupart des guides concernant les bibliothèques statiques recommandent de régler le chemin du dossier des en-têtes publics à $ TARGET_NAME , ce qui signifie que votre fichier lib devient $BUILT_PRODUCTS_DIR /libTargetName.a et vos en-têtes sont placés dans $BUILT_PRODUCTS_DIR /TargetName. Tant que votre application inclut $BUILT_PRODUCTS_DIR dans ses chemins de recherche, alors les importations fonctionneront dans les 4 situations indiquées ci-dessus. Toutefois, cela ne fonctionnera pas lorsque vous essayez d'archiver.

Archivage fonctionne un peu différemment

lorsque vous archivez un projet, Xcode utilise un dossier différent appelé ArchiveIntermediates. Dans ce dossier, vous trouverez /YourAppName/BuildProductsPath/Release-iphoneos/. C'est le dossier que $BUILT_PRODUCTS_DIR pointe lorsque vous faites une archive. Si vous regardez, vous verrez qu'il y est un lien symbolique vers votre bâti bibliothèque statique fichier mais un dossier avec les en-têtes est manquant.

pour trouver les en-têtes (et le fichier lib) vous devez aller à IntermediateBuildFilesPath/UninstalledProducts/. Rappelez-vous quand on vous a dit de mettre Skip Install à OUI pour les bibliothèques statiques? Eh bien, c'est l'effet que le paramètre a quand vous faites une archive.

note latérale: si vous ne le paramétrez pas pour sauter l'Installation, vos en-têtes seront placés dans un autre emplacement et le fichier lib sera copié dans votre archive, vous empêchant à partir de l'exportation d'une .fichier ipa que vous pouvez soumettre à l'App Store.

après beaucoup de recherches, je n'ai pas pu trouver de macro qui corresponde exactement au dossier Désinstallation des produits, d'où la nécessité de construire le chemin avec" $(BUILD_ROOT)/../ IntermediateBuildFilesPath / UninstalledProducts

résumé

pour votre bibliothèque statique, assurez-vous que vous sautez l'installation et que vos en-têtes publics sont placés dans $TARGET_NAME.

pour votre application, définissez vos chemins de recherche d'en-tête d'utilisateur à " $(BUILT_PRODUCTS_DIR)", qui fonctionne bien pour les constructions régulières, et " $(BUILD_ROOT)/../ IntermediateBuildFilesPath / UninstalledProducts", qui fonctionne pour les constructions d'archives.

123
répondu Colin 2012-03-01 02:29:15

j'ai rencontré ce même problème lors du développement de ma propre bibliothèque statique et bien que la réponse de Colin ait été très utile, j'ai dû la modifier un peu pour travailler de manière cohérente et simple lors de l'exécution et de l'archivage de projets sous Xcode 4 en utilisant un espace de travail.

ce qui est différent de ma méthode est que vous pouvez utiliser un chemin d'en-tête utilisateur unique pour toutes vos configurations de construction.

ma méthode est la suivante:

créer un espace de travail

  1. sous Xcode 4, allez à File, New, Workspace.
  2. de Finder vous pouvez alors glisser dans le .xcodeproj projets pour la bibliothèque statique que vous souhaitez utiliser, et la nouvelle application, vous êtes de construction qui utilise la bibliothèque. Voir Apple Docs pour plus d'informations sur la configuration des espaces de travail: https://developer.apple.com/library/content/featuredarticles/XcodeConcepts/Concept-Workspace.html

Projet De Bibliothèque Statique Paramètres

  1. assurez-vous que tous les en-têtes de la bibliothèque statique sont configurés pour copier vers"Public". Ceci est fait sous les paramètres de la cible de bibliothèque statique > phases de construction. Dans la phase" copier les en-têtes", assurez-vous que tous vos en-têtes sont dans la section" Public".
  2. ensuite, allez dans les paramètres de Construction, trouvez" public Headers Folder Path " et tapez un chemin pour votre bibliothèque. Je choisis d'utiliser ceci:

include / LibraryName

J'ai adopté Ceci de L'utilisation avec RestKit et j'ai trouvé qu'il fonctionne mieux avec toutes mes bibliothèques statiques. Ce que cela fait est de dire à Xcode de copier tous les en-têtes que nous avons déplacés dans la section des en-têtes "publics" à l'étape 1 dans le dossier que nous spécifions ici qui réside dans le dossier des données dérivées lors de la construction. Comme avec RestKit, j'aime utiliser un seul dossier" include " pour contenir chaque bibliothèque statique que j'utilise dans un projet.

Je n'aime pas non plus utiliser les macros ici car cela nous permettra d'utiliser un chemin de recherche d'en-tête utilisateur unique plus tard lorsque nous configurerons le projet en utilisant la bibliothèque statique.

  1. trouvez" Skip Install " et assurez-vous que C'est oui.

paramètres pour le projet en utilisant la bibliothèque statique

  1. Ajouter à la bibliothèque statique comme un cadre de Phases de construction > Lien Binaire Avec Bibliothèques et ajouter le libLibraryName.un fichier pour une bibliothèque statique que vous souhaitez utiliser.
  2. suivant assurez-vous que le projet est défini pour rechercher les chemins de recherche des utilisateurs. Ceci est fait sous Paramètres de construction > toujours rechercher les chemins D'Utilisateur et s'assurer que son jeu à Oui.
  3. dans la même zone trouver des chemins de recherche D'en-tête D'Utilisateur et ajouter:

    " $(PROJECT_TEMP_DIR)/../ Produits désinstallés / incluent "

  4. "

indique à Xcode de rechercher des bibliothèques statiques dans le dossier de compilation intermédiaire que Xcode crée pendant le processus de compilation. Ici, nous avons le dossier "include" que nous utilisons pour nos emplacements de bibliothèque statique que nous configurons à l'étape 2 pour les paramètres du projet de bibliothèque statique. C'est l'étape la plus importante pour obtenir Xcode pour trouver correctement vos bibliothèques statiques.

configurer l'espace de travail

Ici, nous voulons configurer l'espace de travail afin qu'il construira la bibliothèque statique quand nous construirons notre application. Cela se fait en modifiant le schéma utilisé pour notre application.

  1. assurez-vous que vous avez sélectionné le schéma qui créera votre demande.
  2. de la liste déroulante de scheme, choisissez Editer Scheme.
  3. sélectionnez Build en haut de la liste à gauche. Ajouter une nouvelle cible en appuyant sur le + sur le volet du milieu.
  4. Vous devriez voir la bibliothèque statique montrez-vous pour la bibliothèque que vous essayez de relier. Choisissez la bibliothèque statique iOS.
  5. cliquez à la fois Run et Archive. Cela indique au schéma de compiler les bibliothèques pour la bibliothèque statique chaque fois que vous construisez votre application.
  6. faites glisser la bibliothèque statique au-dessus de votre cible d'application. Cela permet aux bibliothèques statiques de compiler avant votre cible d'application.

commencer à utiliser la bibliothèque

Maintenant, vous devriez être en mesure d'importer votre bibliothèque statique en utilisant

import <LibraryName/LibraryName.h>

cette méthode permet de contourner la difficulté d'avoir des chemins d'en-tête utilisateurs différents pour différentes configurations, de sorte que vous ne devriez pas avoir de problème de compilation pour les archives.

pourquoi ça marche?

tout dépend de ce chemin:

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

parce que nous configurons notre bibliothèque statique pour utiliser "Skip Install", les fichiers compilés sont déplacés vers Dossier "désinstaller des projets" dans le répertoire de compilation temporaire. Notre chemin ici se résout aussi au dossier "include" que nous avons configuré pour notre bibliothèque statique et que nous utilisons pour notre chemin de recherche d'en-tête d'utilisateur. Les deux travaillant ensemble permettent à Xcode de savoir où trouver notre bibliothèque pendant le processus de compilation. Étant donné que ce répertoire de compilation temporaire existe pour les configurations de débogage et de publication, vous n'avez besoin que d'un seul chemin pour Xcode pour rechercher des bibliothèques statiques.

84
répondu gdavis 2017-07-02 05:50:24

le projet Xcode 4 ne parvient pas à compiler une bibliothèque statique

question connexe: "fichier d'édition lexical ou préprocesseur introuvable" dans Xcode 4

les erreurs peuvent inclure; fichiers d'en-tête manquants, "édition lexicale ou préprocesseur "

Solutions:

  1. vérifier que les" chemins d'en-tête de l'utilisateur "sont corrects
  2. définir "toujours rechercher des chemins d'utilisateur" à Oui
  3. créer un appel de groupe" en-têtes D'indexation "dans votre projet et de faire glisser les en-têtes à ce groupe, ne pas ajouter à des cibles lorsqu'on vous le demande.
16
répondu rjstelling 2017-05-23 11:53:49

ce fut un fil très utile. En recherchant pour ma propre situation, J'ai trouvé Qu'Apple a un document de 12 pages daté de septembre 2012 intitulé "L'utilisation de bibliothèques statiques dans iOS."Voici le lien pdf: http://developer.apple.com/library/ios/technotes/iOSStaticLibraries/iOSStaticLibraries.pdf

c'est beaucoup plus simple que la plupart de la discussion sur Internet, et avec quelques petits mods pour expliquer comment les bibliothèques externes que j'utilise sont configuré, il fonctionne bien pour moi. La partie la plus importante est probablement:

si votre cible de bibliothèque a une phase de construction de "en-têtes de Copie" , vous devriez supprimer; copie des en-têtes de phases de construction ne fonctionnent pas correctement avec statique les cibles de la bibliothèque lors de l'exécution de l'action "Archive" dans Xcode.

de nouvelles cibles de bibliothèque statiques créées avec Xcode 4.4 ou plus tard viendront avec une phase de copie de fichiers correctement configurée pour les en-têtes, donc vous devriez vérifier pour voir si vous avez déjà un avant d'en créer un. Si vous ne le faites pas, appuyez sur "Ajouter Phase de compilation" au bas de l'éditeur cible et choisissez " Ajouter des fichiers de copie."Divulguer les nouveaux fichiers de copie phase et définir la Destination à " Répertoire des produits."Mettre le Subpath pour inclure/${NOM_PRODUIT}. Cela permet de copier des fichiers dans un dossier nommé après votre bibliothèque( prise du paramètre de construction PRODUCT_NAME), à l'intérieur un dossier nommé include, dans votre répertoire des produits construits. Le inclure le dossier à l'intérieur de l'accumulation des produits de répertoire par défaut en-tête chemin de recherche pour les applications, donc c'est un endroit approprié pour mettre les fichiers d'en-tête.

je suis sûr que dans de nombreuses situations existantes, L'approche D'Apple pourrait ne pas être suffisante. Je poste ceci ici pour tous ceux qui commencent juste leur voyage sur le chemin statique de jardin de bibliothèque - ceci peut être le meilleur point de départ pour des cas simples.

14
répondu Michael J. 2012-12-27 21:15:57

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

par Pomme documentation:

Votre bibliothèque aura un ou plusieurs fichiers d'en-tête que les clients de la bibliothèque besoin d'importer. Pour configurer quels en-têtes sont exportés vers les clients, sélectionnez votre projet de bibliothèque pour ouvrir l'éditeur de projet, sélectionnez la bibliothèque cible pour ouvrir l'éditeur cible, et sélectionnez l'onglet phases de construction. Si votre cible de bibliothèque a une phase de compilation "Copy Headers", vous devez la supprimer; les phases de compilation des en-têtes de copie ne fonctionnent pas correctement avec les cibles de bibliothèque statiques lors de l'exécution de l'action" Archive " dans Xcode.

4
répondu dmarnel 2013-07-15 15:21:26

jetez un oeil à la solution de Jonah Wlliam (à mi-chemin) et le modèle GitHub (dans les commentaires) pour un aperçu. http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/

3
répondu d1bru 2011-04-07 20:18:38

Ajouter $(OBJROOT)/UninstalledProducts/exactPathToHeaders à la en-Tête de Chemins de Recherche.

pour une raison quelconque, la case à cocher récursive n'a pas fonctionné pour moi et j'ai dû ajouter le reste du chemin à l'endroit où se trouvent les en-têtes.

sous le log Navigator dans Xcode (l'onglet à la droite du break points navigator), vous pouvez voir l'historique de construction. Si vous sélectionnez l'échec de construction réelle, vous pouvez étendre ses détails pour voir le chemin setenv et vérifier pour s'assurer que le chemin vers vos fichiers d'en-tête est là.

2
répondu Collin 2012-04-15 04:24:26

ajouter le chemin suivant à votre tête D'utilisateur"

$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts

C'est vérifié!

1
répondu yirenjun 2012-05-30 08:15:29

au risque de montrer quel idiot je suis... Je souffre de Xcode refusant de trouver la mienne .h dossiers tout l'après-midi.

puis j'ai réalisé.

parce que j'utilisais" XCode 4", j'avais" intelligemment " décidé de mettre tous mes projets dans un sous-dossier d'un dossier appelé " Xcode 4 projects ".

ces espaces dans le nom de dossier ont foiré Xcode big-time !

renommé ce dossier à " XCode_4_Projects " a apporté la joie (et moins jurer) de nouveau dans ma vie.

Rappelez-moi, quelle année est-ce ?

peut-être que quelqu'un pourrait le dire aux développeurs Apple...

1
répondu Mike Gledhill 2013-05-08 13:47:08

aucune de ces réponses n'a fonctionné pour moi. Voici ce que fait. Ajoutez exactement ce qui suit (copier-coller, y compris les doubles guillemets) à votre chemin de recherche de L'en-tête de L'utilisateur paramètre de construction:

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

notez l'ajout du sous-répertoire "/include/ " par rapport à d'autres réponses. Comme d'autres utilisateurs l'ont fait remarquer, l'option "récursive" ne semble rien faire, donc vous pouvez l'ignorer.

My projet a maintenant été en mesure d'archiver avec succès lors de l'importation statique des fichiers d'en-tête de bibliothèque dans la forme suivante:

#import "LibraryName/HeaderFile.h"

Vous ne pas besoin d'activer le Toujours à la Recherche de Chemins de l'Utilisateur , à moins que vous y compris votre bibliothèque statique en-têtes avec des crochets ( #import <LibraryName/HeaderFile.h> ), mais vous ne devriez vraiment pas faire de cette façon de toute façon si ce n'est pas un système ou un cadre d'en-tête.

1
répondu devios1 2015-03-30 21:22:59

Aucune des réponses ci-dessus a fonctionné pour moi sur Xcode 7 mais ils m'ont donné une bonne idée. Pour les gars luttant sur Xcode 7, j'ai obtenu ce corrigé en ajoutant ce qui suit aux chemins de recherche D'en-tête D'utilisateur (inclure des citations)

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

modifier la partie relative de L'URL usr/local/include en fonction de ce qu'il y a dans le paramètre' Public Header Folder Path 'de la bibliothèque statique

1
répondu Evol Gate 2015-11-05 04:12:00

dans mon cas, mon espace de travail avait quelques projets de bibliothèques statiques et l'un d'eux a une dépendance incluant des fichiers d'en-tête avec l'autre. La question était à l'ordre de construction . Dans la page Editer Scheme sous la section construire, j'ai désélectionné l'option parallelize et arrangé l'ordre des cibles selon les dépendances et il résolu par problème

1
répondu Vamshi 2016-02-10 11:50:20

C'est une question connexe qui m'a conduit à cette question donc j'ajoute ma solution strictement pour la documentation / il pourrait sauver une autre âme des heures de sueur

DropboxSDK.h fichier non trouvé

après des jours à essayer de faire compiler VES pour iOS, j'ai finalement rencontré ce numéro. le DropboxSDK.h était certainement dans la portée de search headers Je l'ai même ajouté au framework headers chemin de recherche, include D le .h directement et est allé à toutes sortes de grandes longueurs pour essayer d'obtenir DropboxSDK.h trouvé.

Solution

EXPLICITY faites glisser le fichier DropboxSDK.framework dans Project Navigation de Xcode et assurez-vous que Copy Files if needed est coché. Assurez-vous également que votre cible est vérifiée au besoin.

Avertissement

Réglage de la cadre explicite emplacement dans build phases ne fonctionne pas pour moi. J'ai eu à glisser .cadre dans Xcode et assurez-vous que les fichiers copiés sur mon projet.

#mbp2015 #xcode7 #ios9

0
répondu Jacksonkr 2016-05-14 22:35:19

il y a plusieurs façons complexes de le faire, et certaines solutions très intelligentes sont proposées dans ce fil.

le principal problème de toutes ces solutions est qu'elles diminuent sérieusement la portabilité de votre bibliothèque.

  • chaque fois que vous avez besoin de commencer un nouveau projet en utilisant votre bibliothèque et de l'archiver pour iTunes, c'est un enfer de configuration.
  • chaque fois que vous avez besoin de partager votre projet avec votre équipe ou vos clients, il peut pause pour n'importe quelle raison (contexte, Version Xcode, peu importe.. )

mon choix a finalement été d'utiliser simplement des Framework - toujours - comme recommandé par Apple ( vidéos WWDC ).

C'est tellement plus facile et fait le même travail à la fin !

une autre solution assez élégante qui semble fonctionner est d'utiliser des Cocoapods privés. Cocoapods fait tout le travail de configuration, copie de l'en-tête et ainsi de suite.

Les cadres de rock !

0
répondu Moose 2016-07-27 15:02:46

voici ce qui a résolu le même problème pour moi.

J'ai une application cible, et une Extension cible iMessage. Puis j'ai eu 2 SDK (les miens), contre lesquels la cible de L'application est liée.

le problème était: ma cible iMessage utilisait aussi les 2 SDK de la mine (projets séparés), mais il ne liait pas contre eux dans les Phases de construction --> lien binaire avec les bibliothèques. J'ai dû ajouter mes 2 SDK à la cible iMessage là-bas, pour correspondre à ma cible App, et maintenant c'archives.

ainsi la morale de l'histoire est: si vous avez plusieurs cibles, telles que des extensions, assurez-vous que toutes vos cibles sont liées contre les bibliothèques dont ils ont besoin. Il a été capable de construire et de déployer sur simulateur et appareil, mais pas D'Archives.

0
répondu FranticRock 2017-08-18 17:40:19

Économisez-vous la peine et faites cela = créez un nouveau compte d'utilisateur sur votre Mac -- ouvrez le projet sous le nouveau compte d'utilisateur-- tous les problèmes disparaissent. Gagnez votre temps et gardez votre bon sens. tous ces gars réponses ne l'aide pas!!

Bonne Chance

-17
répondu Max 2013-04-02 04:47:19