신속한 컴파일러 오류 : "프레임 워크 모듈 내부의 비 모듈 식 헤더"


204

이제 ObjC 프레임 워크를 Swift로 마이그레이션하고 싶습니다. 다음과 같은 오류가 발생했습니다.

include of non-modular header inside framework module 'SOGraphDB'

참조는 프로토콜을 정의하는 헤더 파일에 대한 것이며 일부 클래스에서는이 헤더 파일을 사용하여이 프로토콜을 사용합니다.

모듈 기능과 관련이있는 것 같지만 현재 해결 방법이 명확하지 않습니다. 솔루션을 알고 있습니까?

최신 정보:

이것은 스위프트 컴파일러 오류입니다.

업데이트 2 :

빠른 수정 (그러나 근본 원인을 해결하지는 않음)은 다음 설정을 yes로 설정하는 것입니다. CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES


3
"CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES"에 대한 새로운 빌드 설정이있는 것 같습니다
Stephan

1
누구든지 이것을 공개 및 모듈 형 포함에서 보았습니까? 나는 바닐라 (cocoapods) 프로젝트에서 이것을 본다 : github.com/CocoaPods/CocoaPods/issues/3092 and dropbox.com/s/trhe5vwhzoa9bf5/…
Chris Conover

누구든지 이것을 자동으로 활성화하는 빠른 스크립트를 만들었습니까?
fatuhoku

@fatuhoku yeah
funroll

이 솔루션 중 어느 것도 나를 위해 일한 적이 없으며 내 경우에는 볼트와 같은 것으로 보입니다. 삭제하면 문제가 해결되었습니다. stackoverflow.com/a/33114309/3324388
Aggressor

답변:


316

헤더가 공개되어 있습니까?

프로젝트 탐색기에서 헤더 파일을 선택하십시오. 그런 다음 xcode의 오른쪽 섹션에서 대상 옆에 드롭 다운이 있음을 알 수 있습니다. "프로젝트"에서 "공용"으로 변경하십시오. 이것은 나를 위해 일했습니다.

공개 헤더


이 답변은 내가 말한 것과 동일합니다.
Stephan

또한 프레임 워크의 헤더 빌드 단계로 이동하여 공개, 프로젝트 및 비공개 헤더를 신속하게 확인할 수 있습니다.
호세 이바네즈

나는이 간단한 작업이 여기에 오기 전에 한 시간 이상 이것으로 싸웠을 때 해결책이 될 수 있다고 생각하지 않았습니다. 보라, 이것은 정확히 해결책이었고 즉시 작동했습니다.
TMc

1
이 헤더를 내부에 넣으 려면 어떻게해야 합니까?
Raphael

2
이것은 또한 내 문제를 해결합니다! 필자의 경우 다른 포드에 의존하는 내 포드는 모듈 식 문제로 인해 가져올 수 없습니다. 그래서 공개 모드를 사용하여 다른 포드의 대상으로 일부 헤더를 포함 시켰습니다. 그리고 그것은 문제를 해결합니다!
Chen Li Yong

135

이것은 예상되는 컴파일러 동작이며 매우 좋은 이유입니다.

이 문제를 겪고있는 사람들의 대다수는 C와 Objective C 헤더를 전환 하고 응용 프로그램의 Bridging Header 와 동일한 동작을 기대하는 프레임 워크의 우산 헤더에 추가 Application Target하기 Framework Target시작한 후에 발생한다고 생각합니다 . 엄브렐러 헤더는 실제로 혼합 된 신속한 obj-c 프레임 워크 용으로 지정되었으며 목적은 프레임 워크가 objective-c 또는 c에있는 외부 세계에 API를 노출시키는 것입니다. 그것은 우리가 넣은 헤더가 공개 범위에 있어야 함을 의미합니다.

프레임 워크의 일부가 아닌 Objective-C / C 헤더를 프레임 워크의 신속한 코드에 노출하는 장소로 사용해서는 안됩니다. 이 경우 이러한 헤더는 프레임 워크 모듈의 일부로 외부에 노출되기 때문에 모듈성을 깨뜨리기 때문에 수행하지 않는 경우가 많습니다. (그래서 프레임 워크 모듈에 비 모듈 식 포함 허용이 기본값으로 NO 인 이유 )

Objective-C / C 라이브러리를 프레임 워크 스위프트 코드에 노출 시키려면 해당 라이브러리에 대해 별도의 스위프트 모듈을 정의해야합니다. 그런 다음 표준 스위프트를 import YourLegacyLibrary사용할 수 있습니다.

libxml2프레임 워크에 포함하는 몇 가지 일반적인 시나리오에서이를 설명하겠습니다 .

1. 먼저 module.modulemap다음과 같은 파일 을 작성해야합니다 .

OSX 프레임 워크의 경우 :

module SwiftLibXML2 [system] {
  header "/usr/include/libxml2/libxml/xpath.h"
  export *
}

iOS 프레임 워크의 경우 :

module SwiftLibXML2 [system] {
  header "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/include/libxml2/libxml/xpath.h"
  export *
}

그것은 swift 모듈 내에서 헤더와 참조하는 다른 헤더를 마무리하여 swift가 이러한 C 인터페이스에 대한 신속한 바인딩을 생성 할 수 있도록하는 것입니다.

2. xcode 프로젝트 디렉토리에 폴더 SwiftLibXML2를 만들고이 모듈을 넣습니다.

3. 에서 빌드 설정 , 추가 $(SDKROOT)/usr/include/libxml2헤더 검색 경로

4. 에서 빌드 설정 , 추가 $(SRCROOT)/SwiftLibXML2가져 오기 경로

5. 아래에서 프로젝트의 일반 탭을 추가 libxml2.tbd링크 된 프레임 워크 및 라이브러리 .

이제 필요한 곳에서이 모듈을 가져옵니다.

import SwiftLibXML2

(보다 완전한 module.map 예제를 보려면에서 Darwin의 module.modulemap을 참조하는 것이 좋습니다 .Xcode /usr/include/module.modulemap명령 줄 도구가 설치되어 있어야합니다 .OS X El Capitan에 / usr / include 누락 참조 )


1
파일 이름 module.map은 더 이상 사용되지 않으며 module.modulemap clang.llvm.org/docs/Modules.html#attributes
Hyperbole

import SwiftLibXML2Objective-C 방법 감사!
Itachi

다른 obj-c 가져 오기와 같은 방식으로 : #import <libxml / xpath.h>이지만 3-5 단계를 수행했는지 확인하십시오.
ambientlight

이 작업을 수행했지만 시스템간에 빌드 아티팩트를 이동할 수 없습니다. Objective-C (하위) 모듈은 절대 경로를 사용하여 분명히 링크되어 제공 한 프레임 워크를 사용하는 앱을 컴파일 할 때 오류가 발생합니다.
Raphael

오류는 빌드 프로세스와 관련이있을 가능성이 높습니다. 모듈을 지원하는 llvm 언어가 다른 언어와 상호 작용할 수 있도록 모듈 정의 일뿐입니다. 그 자체로 빌드 아티팩트에 영향을 줄 수 있다고 생각하지 않습니다. 잘못되었습니다
ambientlight

55

빠른 수정 사항을 자동으로 적용하여 Pods.xcodeproj매번 수동으로 변경할 필요가 없습니다 pod install.

이 스 니펫을 Podfile 끝에 추가하십시오.

post_install do |installer|
  installer.pods_project.build_configuration_list.build_configurations.each do |configuration|
    configuration.build_settings['CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES'] = 'YES'
  end
end

29

나를위한 해결책은 대상-> 빌드 설정-> 프레임 워크 모듈의 비 모듈 형 포함 스위치를 YES로 전환하는 것입니다!


Cocoapods와 함께 일했습니다. 포드 설치 후 다른 답변에서 마술을 할 필요가 없습니다
brainray

3
이 단계를 수행했습니다. 잠시 동안 작동했습니다. 이제 작동하지 않습니다 ... 포드 설치 단계도 포함했습니다. 그러나 이제는 다시 실패하고 있습니다. 내가 확인해야 할 것이 있습니까? 헤더를 공개로 변경하기위한 옵션으로 GoogleMobileAds.Framework가 표시되지 않습니다.
Michael Rowe

이것은 나를 위해 작동하지 않았습니다. 여전히 구문 분석 오류가 발생했습니다. Xcode 7.3.1
C0D3 2016 년

이 변경 작업을 수행 한 후 XCode를 다시 시작해야했습니다.
존 파울러

1
이 설정을 변경하면 어떤 영향이 있습니까?
nr5

15

나는이 문제를 해결했다고 생각합니다. 프레임 워크에서 sqlite3을 사용하는 모델 코드가 있습니다. 필자의 경우 범인은 <sqlite3.h>였습니다.

문제는 내 Module / Module.h 헤더에서 <sqlite3.h>를 가져온 공용 헤더를 가져 왔다는 것입니다. 해결책은 모든 sqlite3_xxx 유형을 숨기고 공개 .h에서 보이지 않도록하는 것입니다. sqlite3에 대한 모든 직접 참조는 비공개 또는 프로젝트 가시성으로 만들어졌습니다. 예를 들어, 나는 sqlite3_stmt 포인터가 매달려있는 공개 싱글 톤을 가지고있었습니다. 나는 그것들을 이제는 그 공용 헤더에서 앞으로 선언하는 별도의 클래스로 옮겼습니다. 이제 만들 수 있습니다.

또한 CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES 설정이 작동하지 않았습니다. 프레임 워크와 종속 프로젝트 모두에서 설정을 시도했습니다. 이유는 확실하지 않지만이 해결 방법이 필요했습니다.


이것은 완전히 도움이되었습니다! 제 경우에는 도달 가능성이었습니다.
Daniel Brim

4
내 프레임 워크 모듈에 SSZipArchive를 포함하려고 할 때 이것이 내 문제에 대한 해결책이라고 확신합니다. 공개 헤더가 <zlib.h>를 중요하게하고 동일한 오류가 발생합니다. 답변의 일부만 이해하기 때문에 소스 코드를 작동시키기 위해 고군분투하고 있기 때문에 어딘가에 소스 코드를 게시 할 수 있습니까? 감사합니다!
Bruce

15

에서 스위프트 :

1. 아래에서 언급 한대로 Xcode 프로젝트 및 대상의 빌드 설정을 수정하십시오.

프레임 워크 모듈에 비 모듈 식 포함 허용 : 아니요

비트 코드 활성화 : 예

2. GoogleMaps iOS SDK에서 사용할 수있는 최신 버전을 사용하십시오 (CocoaPod를 사용하여 사용).

Google지도 (1.10.4)

3. 문제가있는 가져 오기에 주석을 답니다.

//import GoogleMaps

4. 문제가있는 가져 오기를 추가하여 브리징 헤더 파일을 작성하거나 수정하십시오.

[귀하의 Xcode 프로젝트 이름] -Bridging-Header.h

// Use this file to import your target's public headers 
// that you would like to expose to Swift.
#import <GoogleMaps/GoogleMaps.h>

5. Xcode 프로젝트를 정리하고 다시 빌드하십시오.


1
이것은 많은 도움이됩니다! GoogleMobilAds 프레임 워크 (Cocoapod 포함)와 함께 작동
bluenowhere

제목 파일을 만드는 방법에 대한 자세한 내용은 다음을 참조하십시오. stackoverflow.com/a/51227304/529663
lenooh

6

이 답변은 구식입니다.

프레임 워크를 가져올 때 루트 헤더와 종속성을 공유하는 모든 헤더 파일 을 가져와야 합니다 . 이것이 항상 작동하도록하는 가장 쉬운 방법은 프레임 워크의 "Headers"폴더에있는 모든 헤더를 공용 헤더 경로로 가져 오는 것입니다.

여기에 이미지 설명을 입력하십시오

Swift 컴파일러는이 정보를 사용하여 얽 히지 않은 심볼의 맵과 관련 유형 정보를 생성합니다.


이것은 Framework 파일을 갖는 목적을 무효화하는 것처럼 보이지만 그것은 나를 위해 일했습니다. Chartboost와 RevMob은 최근에 lib 대신 프레임 워크 파일을 사용하기 시작했습니다. 헤더에서 내 앱 헤더로 모든 것을 복사하면 문제가 해결됩니다.
Jason Short

이것이 유일한 해결책입니까? 나는 6 개의 프레임 워크를 가지고 있으며 각 프레임 워크에는 약 20 개의 헤더가 있습니다. 혼란을 일으킨다. 다른 대안?
vivin

1
가능성이 높습니다. 이것은 Xcode 버그의 해결 방법이므로 더 이상 관련이 없습니다.
seo

6

하지마

#import "MyOtherFramework.h"

하다

#import <MyOtherFramework/MyOtherFramework.h>

3

헤더 파일이 대상에 할당되었지만 프로젝트 표시 만 표시되었으며 공개로 변경하면이 오류가 해결되었습니다.


정확히 어떻게 할 수 있습니까? 내 TwitterKit 헤더 파일에 문제가 있어요
비 노드 Sobale

2

나는 이것이 오래된 질문이라는 것을 알고 있지만, 같은 문제가 있었고 위의 아무것도 도움이되지 않았습니다. 그래서 내 대답이 누군가에게 도움이되기를 바랍니다. 제 경우에는 문제가 ALWAYS_SEARCH_USER_PATHS 설정에있었습니다. 그것이 NO 프로젝트로 설정되었을 때 빌드되고 작동했습니다. 그러나 포드 중 하나가 YES로 설정 해야하는 한 오류가 발생했습니다.

프레임 워크 모듈 내에 비 모듈 식 헤더 포함

몇 잔의 커피와 하루 종일 연구 한 결과 Xcode 7.1 Beta 2 릴리스 노트 의 알려진 문제에 따르면 :

• 이전에 컴파일 한 프레임 워크에 대해 "프레임 워크 모듈 내에 비 모듈 식 헤더 포함"오류가 발생하면 "항상 검색 사용자 경로"빌드 설정이 "아니오"로 설정되어 있는지 확인하십시오. 레거시 이유로 인해 기본값은 "예"입니다. (22784786)

나는 XCode 7.3을 사용하고 있었지만이 버그는 아직 수정되지 않은 것 같습니다.


이것이 나를 도왔습니다! NO로 전환 한 후 일부 가져 오기를 변경해야했지만 이제 필요한 프레임 워크를 가져올 수있었습니다!
Pavel Gurov

2

빌드 설정 전환 > 프레임 워크 모듈에서 비 모듈 식 포함 허용을 YES! 나를 위해 동일한 문제를 해결했습니다.


2

문제에 대한 경험을 추가하고 싶습니다.

요약하면 다음과 같습니다.

  • @ambientlight의 답변은 훌륭하며 대부분의 문제를 해결합니다.
  • 비 모듈 식 헤더를 허용하는 것도 또 다른 솔루션입니다 (위의 답변 중 일부 참조).
  • 프레임 워크의 헤더를 공개로 표시하고 (노출하려는 헤더 만) 우산 헤더로 가져옵니다.

위의 답변에 2 가지 추가 사항이 있습니다.

  • 가능한 경우 정방향 선언을 사용하는 대신 프레임 워크를 직접 가져 오는 헤더의 프로젝트 가져 오기를 신중하게 확인하십시오. 헤더 파일을 다른 헤더 파일에 포함시키는 것은 좋지 않습니다. 제대로 수행하지 않으면 하나의 헤더가 여러 번 포함되어 링커 문제가 발생할 수 있으므로 때때로 문제가 발생합니다.
  • 업데이트 : 라이브러리의 아키텍처와 연결하려는 대상의 아키텍처가 일치하는지 확인하십시오.
  • 마지막으로 위의 모든 작업을 수행 한 후에도 계속 그 오류에 부딪 쳤습니다. 그래서 나는 조금 더 파고 (애플 개발자 포럼에서 찾았지만 링크를 잃어 버렸습니다 : () 우산 헤더에 헤더를 포함하지 않으면이 문제 <framework/headerName.h>"headerName.h"사라집니다.

나는 이것을 마지막으로 시도했지만 지금까지 더 이상이 문제를 경험하지는 않았지만이 솔루션은 최고의 답변 중 일부를 적용 한 경우에만 유효하다고 생각합니다 (참고 : 예를 들어 서로 호환되는 것은 아닙니다) 모듈 방식 및 비 모듈 식 헤더 허용).


1

프로젝트에 자체 프레임 워크를 포함시킬 때이 정확한 문제가 발생했습니다. sqlite3.h의 모든 가져 오기를 public .h 파일이 아닌 .m 파일로 가져 와서 수정했습니다. 다른 라이브러리가 Xcode와 비슷한 문제를 표시 할 수 있다고 가정합니다.


1

Facebook 4.02 SDK 및 FBSDKCoreKit에 특정 문제가있었습니다.

모든 단계를 수행했지만 비 모듈 식 헤더에 대해서는 여전히 오류가 발생했습니다. 프레임 워크에서 특정 헤더 만 끌어서 단계-> 헤더 섹션을 작성했습니다.

그런 다음 맨 위에있는 프로젝트 탐색기에서 헤더 사본을 자동으로 작성했습니다.

빌드 단계-> 헤더에서 제거하고 새 파일을 삭제하고 정상적으로 작동했습니다.

재설정 또는 무언가처럼.


1

필자의 경우 (Xcode 9 beta 6-Swift 4-Cocoapods 사용) Podfile.lockPods 디렉토리를 삭제 하고 pod install다시 실행 하면 해결되었습니다.


1

swift2에서 swift3으로 프로젝트를 업데이트 한 후이 문제가 발생했습니다. XCode 8.3.2를 사용하여 코드를 업데이트하고 "프레임 워크 모듈 내부의 비 모듈 식 헤더"오류를 제거 할 수 없습니다. 다른 버전의 XCode (버전 9.0.1)에서 동일한 프로젝트를 열었을 때 오류가 나타나지 않았습니다.


0

가장 일반적 으로이 오류는 선택한 답변으로 인해 발생하지만 프레임 워크 파일을 새 프로젝트 폴더로 드래그 할 때 실수 로이 오류가 한 번 발생했습니다. 나는 프레임 워크를 삭제하기 위해 클릭했지만 실수로 실제로 파일을 완전히 삭제하지 않고 프레임 워크에 대한 '참조 제거'만 눌러야했습니다. 이 시점에서 Finder에서 프로젝트 폴더를 열면 'CoreLocation'및 'AudioToolbox'와 같은 파일이 나타납니다. 프로젝트 폴더에서 이러한 파일을 삭제하고 프로젝트를 정리하면 문제가 해결되었습니다.


0

비 모듈 식 포함을 가져 오도록 허용 한 후 Objective-C Bridging 헤더를 사용하여 해당 모듈을 가져 오려고 시도 할 수 있습니다.

#import <YandexMobileMetrica/YandexMobileMetrica.h>

0

Modules프레임 워크에서 폴더를 제거하여 해결했습니다 .

  • 파인더를 사용하여 앱 프로젝트에있는 프레임 워크 위치를 탐색하십시오.

  • Test.framework폴더 내부 (위의 경우 SOGraphDB.framework) 및 Modules폴더 삭제로 이동하십시오 .

  • 앱을 정리하고 다시 빌드하면 문제가 해결됩니다.


-1

Parse 프레임 워크를 가져 오는 데이 문제가있었습니다. 내가 고칠 수있는 유일한 방법은 마지막 커밋 이후의 모든 변경 사항을 버리고 (간단히 프레임 워크 삭제 및 프로젝트 정리가 작동하지 않음) Parse를 다른 필요한 프레임 워크와 함께 다시 새로 추가 한 것입니다 (SDK를 새로 다운로드 한 후).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.