Inclut un en-tête non modulaire à l'intérieur du module de cadre

143

J'utilise Xcode 6,

1) Tout d'abord, je crée une bibliothèque dynamique (CoreLibrary). Cette bibliothèque contient le fichier RequestPoster.h.

2) Ensuite, j'ai créé un Cocoa Touch Framework et ajouté cette bibliothèque dynamique (CoreLibrary).

3) Ensuite, ce framework est ajouté à mon projet et il donne une erreur dans le fichier RequestPoster.h (CoreLibrary).

Erreur: inclure un en-tête non modulaire dans la classe de module de structure

ifaddrs.h, arpa / inet.h, sys / types.h>

Ces fichiers sont introuvables dans le projet.

Dev
la source

Réponses:

190

Essayez d'aller dans Paramètres de construction sous «Cible» et définissez «Autoriser les inclusions non modulaires dans les modules de structure» sur OUI.

La vraie réponse est que l'emplacement des importations doit être modifié par le propriétaire de la bibliothèque. Ces fichiers ifaddrs.h, arpa / inet.h, sys / types.h sont importés dans un fichier .h dans un framework, ce que Xcode n'aime pas. Le responsable de la bibliothèque doit les déplacer vers un fichier .m. Voir par exemple ce problème sur GitHub, où AFNetworking a résolu le même problème: https://github.com/AFNetworking/AFNetworking/issues/2205

bovins
la source
2
Dans le cas où l'en-tête avec une erreur utilise un type des en-têtes importés, qu'est-ce qui est recommandé? Par exemple, si l'en-tête module.h dans module déclare une fonction prenant un paramètre de type ifaddrs, ils sont tenus d'importer ifaddrs.h.
Ayush Goel
Mais que faire s'ils sont inclus dans le système, comme /usr/include/libproc.h?
Ben Leggiero
3
Pourriez-vous s'il vous plaît expliquer quel est l'impact du changement: Autoriser les
inclusions
Je pense que la meilleure réponse serait peut-être d'en faire un en-tête modulaire, plutôt que de faire taire cette erreur. J'imagine facilement qu'Apple supprime l'option d'autoriser les en-têtes non modulaires dans un module.
Ben Leggiero le
170

Assurez-vous que les fichiers d'en-tête sont accessibles au public dans le cadre des en-têtes publics du framework.

Goto Framework -> Target -> Build Phases et faites glisser pour déplacer les fichiers d'en-tête pertinents du projet vers Public. J'espère que cela pourra aider!

Capture d'écran

Long Pham
la source
3
Cela m'a aidé à inclure du code Objective C dans un framework Swift, merci!
Vadim
1
Vous pouvez également apporter cette modification à l'appartenance cible de projet à public dans votre fichier en utilisant la fenêtre Inspecteur de fichiers à droite de l'écran principal de XCode.
Pigpocket
Si vous importez la bibliothèque dans un mélange de swift / objc, vous devez vous assurer que l'en-tête de pontage est également public. Erreur que j'ai faite!
Nick H247 le
74

Vous pouvez définir Autoriser les inclusions non modulaires dans les modules de structure dans les paramètres de construction de la cible affectée sur OUI. Voici le paramètre de construction que vous devez modifier:

Élément de paramètres de construction que vous devez modifier

REMARQUE : vous devez utiliser cette fonctionnalité pour découvrir l'erreur sous-jacente, que j'ai trouvée fréquemment causée par la duplication d'inclusions globales entre crochets angulaires dans des fichiers avec une relation dépendante, c'est-à-dire:

#import <Foo/Bar.h> // referred to in two or more dependent files

Si la définition de l' option Autoriser les inclusions non modulaires dans les modules de trame sur OUI entraîne un ensemble d'erreurs «X est une référence ambiguë» ou quelque chose de ce genre, vous devriez être en mesure de rechercher les doublons incriminés et de les éliminer. Après avoir nettoyé votre code, redéfinissez Autoriser les inclusions non modulaires dans les modules de trame sur NON .

revprez
la source
1
Ok, c'étaient les chevrons qui causaient le problème! J'ai eu ce problème avec une importation CocoaPods et je l'ai corrigé en modifiant l'importation pour utiliser des guillemets au lieu de crochets angulaires.
Michael Forrest
Oups, non, non. J'ai découvert qu'il était cassé après avoir nettoyé mon projet: - /
Michael Forrest
2
Je ne trouve aucun avertissement de «référence ambiguë». Quels sont les inconvénients de la laisser sur OUI ?
Nicolas Miari
28

J'ai eu le même problème et je l'ai résolu en rendant simplement le fichier d'en-tête public. [problème]

Si vous travaillez sur plusieurs modules dans votre projet. Ensuite, votre fichier d'en-tête doit être public pour être utilisé dans d'autres parties des projets. Ce dont vous avez besoin est de sélectionner ce fichier d'en-tête et dans la vue Utilitaires du projet. Modifiez le fichier de Projet / Privé à Public. Voir l'image ci-dessous:

Modification de la portée du fichier d'en-tête

Saad
la source
Cela se produit en particulier lorsque vous dupliquez un en-tête public existant, l'appartenance d'en-tête dupliquée est changée en "projet"
Jeremie
non ce n'est pas obligatoire pour la duplication. Cela peut se produire en raison de différents cas, par exemple si vous importez complètement un projet en tant que bibliothèque dans votre projet et que vous essayez ensuite de modifier les classes privées. Vous connaissez le fichier d'en-tête et l'écrivez mais l'accès n'est pas public pour tous les projets.
Saad
23

"Inclut un en-tête non modulaire à l'intérieur du module de structure"

Lorsque vous obtenez cette erreur, la solution dans certaines circonstances peut être de simplement marquer le fichier que vous essayez d'importer comme "public" dans l'inspecteur de fichiers "Adhésion cible". La valeur par défaut est "Projet", et lorsqu'elle est définie de cette façon, elle peut provoquer cette erreur. C'était le cas avec moi lorsque j'ai essayé d'importer les en-têtes de Google Analytic dans un framework, par exemple.

John Bushnell
la source
Cette réponse m'a beaucoup aidé dans mon problème similaire. Je ne savais pas que les fichiers d'en-tête du framework pouvaient être ajoutés à la cible. Dans les projets d'application, les en-têtes ne font jamais partie d'une cible.
bio du
20

En fait, un moyen plus simple de résoudre ce problème consiste à déplacer l' #importinstruction vers le haut du .mfichier (au lieu de l'avoir dans votre .hfichier d' en- tête). De cette façon, il ne se plaindra pas qu'il inclut un fichier d'en-tête non modulaire. J'ai eu ce problème où Allow non-module includesréglé sur YESne fonctionnait PAS pour moi, donc en le déplaçant vers le fichier d'implémentation, il a cessé de se plaindre. C'est en fait la méthode préférée pour importer et inclure de toute façon des fichiers d'en-tête. Une fois que vous avez fait cela, la réinitialisation NOdevrait fonctionner.

Idéalement, nous devrions essayer et viser à nous y Allow non-module includesmettre NO. Définir ceci sur YESdans la plupart des cas signifie que vous faites quelque chose de mal. Le paramètre se traduit par «Autoriser l'importation de fichiers d'en-tête aléatoires sur le disque qui ne font pas autrement partie du module». Cela s'applique à très peu de cas d'utilisation dans la pratique, et donc ce paramètre doit toujours être NO(c'est-à-dire la valeur par défaut).

des temps étranges
la source
10

Dans le cas où vous développez votre propre framework:

Pourquoi cela arrive-t-il?

Si l'un des fichiers d'en-tête publics que vous avez mentionnés dans votre module.modulemap contient des instructions d'importation qui ne sont pas mentionnées dans modulemap, cela vous donnera l'erreur. Puisqu'il essaie d'importer un en-tête qui n'est pas déclaré comme modulaire (dans module.modulemap), il rompt la modularité du framework.

COMMENT puis-je résoudre ce problème?

Incluez simplement l'en-tête qui a donné l'erreur à votre module.modulemap et reconstruisez à nouveau!

POURQUOI PAS simplement définir autoriser non modulaire sur OUI?

Parce que ce n'est pas vraiment une solution ici, avec cela, vous dites à votre projet "ce framework était censé être modulaire mais ce n'est pas le cas. Utilisez-le d'une manière ou d'une autre, je m'en fiche." Cela ne résout pas le problème de modularité de votre bibliothèque.

Pour plus d'informations, consultez ce billet de blog ou reportez-vous à la documentation de clang .

Mert Celik
la source
comment avez-vous configuré le module.modulemap avec le framework de projets cacao, j'ai essayé de laisser ma bibliothèque pouvoir travailler avec des projets Swift uniquement, mais comme une dépendance de la bibliothèque, le module.modulemap ne fonctionne pas, le cocoapod est générer automatiquement le modulemap, mais cela semble ne pas fonctionner, avez-vous rencontré quelque chose de similaire?
Amadeu Cavalcante Filho
8

Si vous en avez besoin pour les cibles CocoaPods, ajoutez ces lignes dans Podfile:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      target.build_settings(config.name)['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
    end
  end
end
k06a
la source
7

Allow Non-modular Includes in Framework Modulesne fonctionne qu'en code objc. ne fonctionne pas rapidement.

Après une période de recherche, j'ai trouvé que swift peut passer le paramètre d'avertissement à clang, donc réglé OTHER_SWIFT_FLAGSpour -Xcc -Wno-error=non-modular-include-in-framework-moduleinhiber l'erreur d'importation rapide.

juste pour quelqu'un qui a le même problème

SolaWing
la source
6

J'ai eu le même problème et rien d'en haut ne m'a aidé. J'espère donc que ma réponse sera utile à quelqu'un. Dans mon cas, le problème était dans le paramètre ALWAYS_SEARCH_USER_PATHS. Quand il a été réglé sur AUCUN projet construit et a fonctionné correctement. Mais dans la mesure où l'un des pods exigeait qu'il soit réglé sur OUI, je recevais une erreur

Inclut un en-tête non modulaire à l'intérieur du module de cadre

Après quelques tasses de café et toute la journée de recherche, j'ai découvert que, selon les problèmes connus des notes de publication de Xcode 7.1 Beta 2 :

• Si vous obtenez une erreur indiquant «Inclure un en-tête non modulaire dans le module de structure» pour un framework qui a déjà été compilé, assurez-vous que le paramètre de construction «Toujours rechercher les chemins utilisateur» est défini sur «Non». La valeur par défaut est "Oui" uniquement pour des raisons héritées. (22784786)

J'utilisais cependant XCode 7.3, mais il semble que ce bogue n'ait pas encore été corrigé.

iyuna
la source
6

le même problème rend fou.Enfin, je trouve que mettre le 'import xxx.h' dans la mise en œuvre au lieu de l'interface peut résoudre le problème.Et si vous utilisez Cocoapods pour gérer votre projet, vous pouvez ajouter

s.user_target_xcconfig = {'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'OUI'}

dans votre fichier 'xxx.podspec'.

贺彦文
la source
6

Si vous voyez cette erreur dans un en- tête parapluie lors de la création d'un framework dynamique , assurez-vous d'importer votre fichier comme:

#import "MyFile.h"

et pas comme #import <MyFramework/MyFile.h>.

Misha Karpenko
la source
2

Je suis également tombé sur ce problème et je pensais à l'origine qu'il s'agissait d'un problème CocoaPods, mais c'était un problème dans les paramètres de construction des applications où quelqu'un (probablement moi) avait défini les ${PODS_ROOT}chemins de recherche d'en-tête et l'avait défini comme une recursiverecherche. Cela lui permettait de trouver des en-têtes qui n'étaient pas destinés à être utilisés lors de la création de l'application. Une fois que j'ai réglé cela pour utiliser non-recursivetout allait bien. utiliser la recursiverecherche est un terrible hack pour essayer de trouver les en-têtes appropriés. Leçon apprise.

ucangetit
la source
Je peux confirmer que c'était aussi mon problème.
Wilson Muñoz
J'ai eu ce problème avec PersonalizedAdConsent et cela l'a résolu. Merci!
Steven Elliott
1

C'était un peu un problème ennuyeux pour moi. Aucune suggestion n'a semblé aider mon cas particulier, car je devais inclure les en-têtes "non modulaires" dans mon fichier d'en-tête de fichier individuel. Le travail autour que j'ai utilisé consistait à coller l'appel d'importation dans le fichier d'en-tête de préfixe.

Greg
la source
0

J'ai fini par déplacer l'en-tête Umbrella en bas de la liste des en-têtes après avoir vérifié les solutions ci-dessus, et cela a fonctionné dans Xcode 9.3.

Alfwatt
la source
0

Je l'ai résolu en supprimant le Modulesdossier du cadre.

  • Accédez à l'emplacement de votre framework qui est présent dans le projet d'application à l'aide du Finder

  • Allez dans le Test.frameworkdossier (dans le cas ci-dessus, ce sera CoreLibrary.framework) & Supprimer le Modulesdossier.

  • Nettoyez et reconstruisez l'application, cela résoudra le problème.

Vittal Pai
la source
0

Dans mon cas, j'ai oublié d'ajouter les fichiers .h et .m dans la section "s.source_files" du fichier .podspecs.

après avoir ajouté cela fonctionne bien.

entrez la description de l'image ici

Muhammad Ahmed Baig
la source
0

essayer @import FrameworkNameau lieu de#import "FrameworkName.h"

Ke Yang
la source
-5

J'ai pu effacer des dizaines de ces erreurs en utilisant Git clean. Voici la commande: git clean -dffx && git reset --hard

Matt Bearson
la source