Incluir cabeçalho não modular dentro do módulo de estrutura

143

Estou usando o Xcode 6,

1) Em primeiro lugar, estou criando uma biblioteca dinâmica (CoreLibrary). Esta biblioteca contém o arquivo RequestPoster.h.

2) Criei um Cocoa Touch Framework e adicionei esta biblioteca dinâmica (CoreLibrary).

3) Em seguida, essa estrutura é adicionada ao meu projeto e gera erro no arquivo RequestPoster.h (CoreLibrary).

Erro: inclusão do cabeçalho não modular na classe do módulo de estrutura:

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

Esses arquivos não foram encontrados no projeto.

Dev
fonte

Respostas:

190

Tente ir para Configurações de compilação em "Destino" e defina "Permitir inclusões não modulares nos módulos da estrutura" para SIM.

A resposta real é que o local das importações precisa ser alterado pelo proprietário da biblioteca. Esses arquivos ifaddrs.h, arpa / inet.h, sys / types.h estão sendo importados em um arquivo .h em uma estrutura, da qual o Xcode não gosta. O mantenedor da biblioteca deve movê-los para um arquivo .m. Veja, por exemplo, este problema no GitHub, onde a AFNetworking corrigiu o mesmo problema: https://github.com/AFNetworking/AFNetworking/issues/2205

bcattle
fonte
2
Caso o cabeçalho com erro esteja usando um tipo dos cabeçalhos importados, o que é recomendado? Por exemplo, se o cabeçalho module.h no módulo declara uma função que aceita um parâmetro do tipo ifaddrs, eles são obrigados a importar ifaddrs.h.
Ayush Goel
Mas e se eles incluírem o sistema, como /usr/include/libproc.h?
Ben Leggiero
3
Você poderia por favor explicar o que é o impacto da mudança: Permitir não-modular Inclui no Quadro Módulos
NR 5
Acho que talvez a melhor resposta envolva torná-lo um cabeçalho modular, em vez de basicamente silenciar esse erro. Posso facilmente imaginar a Apple removendo a opção de permitir cabeçalhos não modulares em um módulo.
Ben Leggiero 24/07
170

Verifique se os arquivos de cabeçalho estão disponíveis publicamente como parte dos cabeçalhos públicos da estrutura.

Vá para Framework -> Target -> Build Fhases e arraste para mover os arquivos de cabeçalho relevantes de Project para Public. Espero que ajude!

Captura de tela

Long Pham
fonte
3
Isso me ajudou a incluir o código do Objective C em uma estrutura Swift, obrigado!
Vadim
1
Você também pode fazer essa alteração na Associação de Destino de Projeto para Pública em seu arquivo usando a janela Inspetor de Arquivos à direita da tela principal do XCode.
Pigpocket
Se a importação da biblioteca para uma combinação de swift / objc, também é necessário garantir que o cabeçalho da ponte seja público. Erro que cometi!
Nick H247 16/04
74

Você pode definir YES para Permitir inclusões não modulares nos Módulos da estrutura em Configurações de compilação do destino afetado. Esta é a configuração de compilação que você precisa editar:

Item Configurações de compilação que você precisa editar

NOTA : Você deve usar esse recurso para descobrir o erro subjacente, que eu acho frequentemente causado pela duplicação de inclusões globais com colchetes angulares em arquivos com algum relacionamento dependente, ou seja:

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

Se definir Permitir inclusões não modulares nos módulos de quadros como YES resultar em um conjunto de erros "X é uma referência ambígua" ou algo do tipo, você poderá rastrear as duplicatas incorretas e eliminá-las. Depois de limpar seu código, defina Permitir inclusões não modulares nos módulos de quadros novamente para NÃO .

revprez
fonte
1
Ok, foram os colchetes angulares que causaram o problema! Eu tive esse problema com uma importação do CocoaPods e a corrigi, alterando a importação para usar aspas em vez de colchetes angulares.
Michael Forrest
Opa, não, não foi. Descobriu que estava quebrado depois que eu limpo o meu projeto: - /
Michael Forrest
2
Não consigo encontrar nenhum aviso de 'referência ambígua'. Quais são as desvantagens de deixá-lo definido como SIM ?
Nicolas Miari 13/09/16
28

Eu tive o mesmo problema e resolvi-o apenas tornando público o arquivo de cabeçalho. [problema]

Se você estiver trabalhando em vários módulos em seu projeto. Em seguida, seu arquivo de cabeçalho precisa ser público para ser usado em outras partes dos projetos. O que você precisa é selecionar esse arquivo de cabeçalho e, na visualização Utilitários do projeto. Altere o arquivo de Projeto / Privado para Público. Veja a imagem abaixo:

Alterando o escopo do arquivo de cabeçalho

Saad
fonte
Isto acontece em particular quando você duplicar um cabeçalho pública existente, a associação de cabeçalho duplicado é alterado para "projeto"
Jeremie
não, não é obrigatório para a duplicação. Isso pode ocorrer devido a casos diferentes, por exemplo, se você importar algum projeto como biblioteca completamente em seu projeto e tentar modificar as classes privadas. Você conhece o arquivo de cabeçalho e o escreve, mas o acesso não é público para todo o projeto.
Saad
23

"Incluir cabeçalho não modular dentro do módulo de estrutura"

Quando você recebe esse erro, em algumas circunstâncias, a solução pode ser simplesmente marcar o arquivo que você está tentando importar como "público" no inspetor de arquivos "Associação de Destino". O padrão é "Projeto" e, quando definido dessa maneira, pode causar esse erro. Esse foi o meu caso ao tentar importar os cabeçalhos do Google Analytic para uma estrutura, por exemplo.

John Bushnell
fonte
Essa resposta me ajudou muito no meu problema semelhante. Eu não sabia que os arquivos de cabeçalho da estrutura podem ser adicionados ao destino. Nos projetos de aplicativos, os cabeçalhos nunca fazem parte de um destino.
bio
20

Na verdade, uma maneira mais fácil de corrigir isso é mover a #importinstrução para a parte superior do .marquivo (em vez de tê-la em seu .harquivo de cabeçalho). Dessa forma, não irá reclamar que está incluindo um arquivo de cabeçalho não modular. Eu tive esse problema em Allow non-module includesdefinir a YESfez não trabalho para mim, por isso, movê-lo para o arquivo de implementação, ele parou de reclamar. De fato, essa é a maneira preferida de importar e incluir arquivos de cabeçalho. Depois de fazer isso, configurá-lo novamente NOdeve funcionar.

Idealmente, devemos tentar almejar ter Allow non-module includesdefinido NO. Definir isso YESna maioria dos casos significa que você está fazendo algo errado. A configuração se traduz em "Permitir a importação de arquivos de cabeçalho aleatórios no disco que não fazem parte do módulo". Isso se aplica a poucos casos de uso na prática e, portanto, essa configuração deve sempre ser NO(ou seja, o valor padrão).

estranhas
fonte
10

Caso você esteja desenvolvendo sua própria estrutura:

Por que isso está acontecendo?

Se algum dos arquivos de cabeçalho público que você mencionou no module.modulemap tiver instruções de importação que não são mencionadas no modulemap, isso fornecerá o erro. Como ele tenta importar algum cabeçalho que não é declarado como modular (em module.modulemap), ele quebra a modularidade da estrutura.

Como posso corrigir isso?

Apenas inclua o cabeçalho que deu o erro no seu module.modulemap e construa novamente!

POR QUE NÃO apenas definir permitir não modular para SIM?

Porque não é realmente uma solução aqui, com isso você diz ao seu projeto "que essa estrutura deveria ser modular, mas não é. Use-a de alguma forma, não me importo". Isso não resolve o problema de modularidade da sua biblioteca.

Para mais informações, verifique esta postagem no blog ou consulte os documentos clang .

Mert Celik
fonte
como você configurou o module.modulemap com a estrutura de projetos de cacau, tentei permitir que minha biblioteca funcionasse com projetos somente Swift, mas como uma dependência da biblioteca, o module.modulemap não está funcionando, o cocoapod é gerando automaticamente o mapa do módulo, mas parece não funcionar, você enfrentou algo semelhante?
Amadeu Cavalcante Filho
8

Se você precisar disso para os destinos do CocoaPods, adicione estas linhas em 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
fonte
7

Allow Non-modular Includes in Framework Modulessó funciona no código objc. Não trabalhe rápido.

Após um período de pesquisa, eu descobri que o swift pode passar o parâmetro de aviso para clang, então defina OTHER_SWIFT_FLAGSpara -Xcc -Wno-error=non-modular-include-in-framework-moduleinibir o erro de importação rápido.

apenas para alguém que tem o mesmo problema

SolaWing
fonte
6

Eu tive o mesmo problema e nada de cima me ajudou. Então, espero que minha resposta seja útil para alguém. No meu caso, o problema estava na configuração ALWAYS_SEARCH_USER_PATHS. Quando foi definido como NO, o projeto foi construído e funcionou bem. Mas, na medida em que um dos pods exigia que fosse definido como SIM, eu estava recebendo um erro

Incluir cabeçalho não modular dentro do módulo de estrutura

Depois de tomar algumas xícaras de café e pesquisar o dia inteiro, descobri que, de acordo com problemas conhecidos das notas de versão do Xcode 7.1 Beta 2 :

• Se você receber um erro informando "Incluir cabeçalho não modular dentro do módulo da estrutura" para uma estrutura compilada anteriormente, verifique se a configuração de compilação "Sempre pesquisar caminhos do usuário" está definida como "Não". O padrão é "Sim" apenas por motivos herdados. (22784786)

Eu estava usando o XCode 7.3, mas parece que esse bug ainda não foi corrigido.

iyuna
fonte
6

Finalmente, acho que colocar o 'import xxx.h' na implementação em vez da interface pode resolver o problema.E se você usar o Cocoapods para gerenciar o seu projeto.Você pode adicionar

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

no seu arquivo 'xxx.podspec'.

贺彦文
fonte
6

Se você vir esse erro em um cabeçalho guarda - chuva ao criar uma estrutura dinâmica , importe seu arquivo como:

#import "MyFile.h"

e não como #import <MyFramework/MyFile.h>.

Misha Karpenko
fonte
2

Também deparei com esse problema e originalmente pensei que era um problema do CocoaPods, mas era um problema nas configurações de criação de aplicativos em que alguém (provavelmente eu) havia definido ${PODS_ROOT}nos Caminhos de pesquisa de cabeçalho e definido como uma recursivepesquisa. Isso permitiu encontrar cabeçalhos que não foram projetados para serem usados ​​na criação do aplicativo. Depois de definir isso para usar, non-recursivetudo estava bem. usar a recursivepesquisa é um truque terrível para tentar encontrar os cabeçalhos adequados. Lição aprendida.

ucangetit
fonte
Posso confirmar que esse também foi o meu problema.
Wilson Muñoz
Eu tive esse problema com o PersonalizedAdConsent e isso foi corrigido. Obrigado!
Steven Elliott
1

Isso foi meio que um problema chato para mim. Nenhuma sugestão pareceu ajudar meu caso particular, pois eu precisava incluir os cabeçalhos "não modulares" no meu arquivo de cabeçalho de arquivo individual. O trabalho que usei foi colocar a chamada de importação no arquivo de cabeçalho do prefixo.

Greg
fonte
0

Acabei movendo o Umbrella Header para o final da lista de Headers depois de verificar as soluções acima, e funcionou no Xcode 9.3.

alfwatt
fonte
0

Eu resolvi removendo a Modulespasta da estrutura.

  • Navegue até o local da estrutura presente no App Project usando o finder

  • Vá para dentro da Test.frameworkpasta (no caso acima será CoreLibrary.framework) e apague a Modulespasta.

  • Limpe e re Construa o aplicativo, ele resolverá o problema.

Vittal Pai
fonte
0

No meu caso, esqueci de adicionar os arquivos .he .m na seção "s.source_files" do arquivo .podspecs.

depois de adicionar isso, ele funciona bem.

insira a descrição da imagem aqui

Muhammad Ahmed Baig
fonte
0

tente em @import FrameworkNamevez de#import "FrameworkName.h"

Ke Yang
fonte
-5

Consegui limpar dezenas desses erros usando o Git clean. Aqui está o comando: git clean -dffx && git reset --hard

Matt Bearson
fonte