[xcode4] Xcode 4는 정적 라이브러리 종속성에서 공용 헤더 파일을 찾을 수 없습니다.

검색에 도움이되는 대체 제목

  • Xcode에서 헤더를 찾을 수 없습니다.
  • Xcode에서 .h 누락
  • Xcode .h 파일을 찾을 수 없습니다.
  • 어휘 또는 전 처리기 문제 파일을 찾을 수 없습니다.

저는 Xcode 3에서 가져온 iOS 애플리케이션 프로젝트에서 작업하고 있습니다. 이제 Xcode 4로 이동했습니다. 제 프로젝트는 여러 정적 라이브러리를 빌드합니다.

이러한 정적 라이브러리는 또한 공용 헤더를 선언하며 해당 헤더는 애플리케이션 코드에서 사용됩니다. Xcode 3.x에서는 헤더가 (빌드 단계로)에 복사 된 public headers directory다음 애플리케이션 프로젝트 public headers directory에서 headers search list.

Xcode 4에서 빌드 디렉토리는 ~/Library/Developer/Xcode/DerivedData/my-project.

문제는 헤더 검색 설정에서이 새 위치를 어떻게 참조합니까? 다음과 같이 보입니다.

  • public headers directory 에 상대적이다 DerivedData디렉토리에 이지만
  • headers search 디렉토리가 다른 항목 (아마도 프로젝트 위치)에 상대적입니다.

종속성으로 컴파일하려고 할 때 정적 라이브러리를 사용하는 클라이언트가 헤더 파일을 사용할 수 있도록 Xcode 4에서 iOS 개발 용 정적 라이브러리 대상을 어떻게 설정해야합니까?



답변

이 문제에 대해 내가 본 각 솔루션은 우아하지 않은 것처럼 보였거나 (헤더를 응용 프로그램의 프로젝트에 복사) 사소한 상황에서만 작동 할 정도로 지나치게 단순화되었습니다.

짧은 대답

사용자 헤더 검색 경로에 다음 경로를 추가하십시오.

“$ (BUILD_ROOT) /../ IntermediateBuildFilesPath / UninstalledProducts”

왜 이것이 작동합니까?

먼저 문제를 이해해야합니다. 실행, 테스트, 프로파일 링 또는 분석과 같은 정상적인 상황에서 Xcode는 프로젝트를 빌드 하고 $ BUILT_PRODUCTS_DIR 매크로 를 통해 사용할 수 있는 Build / Products / Configuration / Products 디렉토리에 출력을 저장합니다 .

정적 라이브러리와 관련된 대부분의 가이드에서는 공용 헤더 폴더 경로$ 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 /로 이동해야합니다. 정적 라이브러리에 대해 설치 건너 뛰기 를 YES 로 설정하라는 지시를 받았던 때를 기억 하십니까? 이것이 아카이브를 만들 때 설정이 갖는 효과입니다.

참고 : 설치를 건너 뛰도록 설정하지 않으면 헤더가 다른 위치에 저장되고 lib 파일이 아카이브에 복사되어 App Store에 제출할 수있는 .ipa 파일을 내보낼 수 없습니다. .

많은 검색 끝에 UninstalledProducts 폴더에 정확히 해당하는 매크로를 찾을 수 없었기 때문에 “$ (BUILD_ROOT) /../ IntermediateBuildFilesPath / UninstalledProducts”로 경로를 구성해야합니다.

요약

정적 라이브러리의 경우 설치를 건너 뛰고 공개 헤더가 $ TARGET_NAME에 배치되었는지 확인하세요.

앱의 경우 사용자 헤더 검색 경로를 일반 빌드에 대해 잘 작동하는 “$ (BUILT_PRODUCTS_DIR)”과 아카이브 빌드에 대해 작동하는 “$ (BUILD_ROOT) /../ IntermediateBuildFilesPath / UninstalledProducts”로 설정합니다.


답변

자체 정적 라이브러리를 개발할 때 동일한 문제가 발생했으며 Colin의 답변이 매우 도움이되었지만 작업 공간을 사용하여 Xcode 4에서 프로젝트를 실행하고 보관할 때 일관되고 간단하게 작동하도록 약간 수정해야했습니다.

내 방법의 차이점은 모든 빌드 구성에 단일 사용자 헤더 경로를 사용할 수 있다는 것입니다.

내 방법은 다음과 같습니다.

작업 공간 만들기

  1. Xcode 4에서 File, New, Workspace로 이동합니다.
  2. 그런 다음 Finder에서 사용하려는 정적 라이브러리와 라이브러리를 사용하는 빌드중인 새 앱에 대한 .xcodeproj 프로젝트를 드래그 할 수 있습니다. 작업 영역 설정에 대한 자세한 내용은 Apple Docs를 참조하십시오. https://developer.apple.com/library/content/featuredarticles/XcodeConcepts/Concept-Workspace.html

정적 라이브러리 프로젝트 설정

  1. 모든 정적 라이브러리의 헤더가 “공용”으로 복사되도록 설정되어 있는지 확인하십시오. 이는 정적 라이브러리 대상> 빌드 단계의 설정에서 수행됩니다. “헤더 복사”단계에서 모든 헤더가 “공개”섹션 내에 있는지 확인합니다.
  2. 다음으로 빌드 설정으로 이동하여 “공용 헤더 폴더 경로”를 찾아 라이브러리 경로를 입력하십시오. 나는 이것을 사용하기로 선택한다 :

include / LibraryName

RestKit과 함께 사용하여 이것을 채택했으며 모든 정적 라이브러리에서 가장 잘 작동한다는 것을 알았습니다. 이것이하는 일은 Xcode가 1 단계에서 “Public”헤더 섹션으로 이동 한 모든 헤더를 빌드 할 때 Derived Data 폴더 내에있는 여기에서 지정한 폴더로 복사하도록 지시하는 것입니다. RestKit과 마찬가지로 저는 프로젝트에서 사용하는 각 정적 라이브러리를 포함하기 위해 단일 “include”폴더를 사용하는 것을 좋아합니다.

또한 정적 라이브러리를 사용하여 프로젝트를 구성 할 때 나중에 단일 사용자 헤더 검색 경로를 사용할 수 있기 때문에 여기서 매크로를 사용하는 것을 좋아하지 않습니다.

  1. “Skip Install”을 찾아 이것이 YES로 설정되어 있는지 확인하십시오.

정적 라이브러리를 사용한 프로젝트 설정

  1. Build Phases> Link Binary With Libraries 아래에서 정적 라이브러리를 프레임 워크로 추가하고 사용할 정적 라이브러리에 대해 libLibraryName.a 파일을 추가합니다.
  2. 다음으로 프로젝트가 사용자 검색 경로를 검색하도록 설정되어 있는지 확인하십시오. 이는 빌드 설정> 항상 사용자 경로 검색에서 수행되며 YES로 설정되어 있는지 확인하십시오.
  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"

“Skip Install”을 사용하도록 정적 라이브러리를 구성하기 때문에 컴파일 된 파일은 임시 빌드 디렉토리 내의 “UninstalledProjects”폴더로 이동됩니다. 여기서 경로는 정적 라이브러리에 대해 설정하고 사용자 헤더 검색 경로에 사용하는 “include”폴더로도 확인됩니다. 두 가지가 함께 작동하면 Xcode가 컴파일 과정에서 라이브러리를 찾을 수있는 위치를 알 수 있습니다. 이 임시 빌드 디렉토리는 디버그 및 릴리스 구성 모두에 존재하므로 정적 라이브러리를 검색하려면 Xcode에 대한 단일 경로 만 필요합니다.


답변

Xcode 4 프로젝트가 정적 라이브러리를 컴파일하지 못함

관련 질문 : Xcode 4의 “어휘 또는 전 처리기 문제 파일을 찾을 수 없음”

오류에는 다음이 포함될 수 있습니다. 헤더 파일 누락, “어휘 또는 전 처리기 문제”

해결책 :

  1. “사용자 헤더 경로”가 올바른지 확인하십시오.
  2. “항상 사용자 경로 검색”을 예로 설정
  3. 프로젝트에서 “인덱싱 헤더”라는 그룹 호출을 생성하고 헤더를이 그룹으로 드래그합니다 . 메시지가 표시 될 때 대상에 추가 하지 마십시오 .


답변

이것은 매우 유용한 스레드였습니다. 내 상황을 조사하다가 2012 년 9 월에 “iOS에서 정적 라이브러리 사용”이라는 제목으로 12 페이지 분량의 문서가 Apple에 있음을 발견했습니다. 다음은 pdf 링크입니다. http://developer.apple.com/library/ios/technotes/iOSStaticLibraries/iOSStaticLibraries.pdf

대부분의 인터넷 토론보다 훨씬 간단하며 사용중인 외부 라이브러리가 구성되는 방식을 설명하기위한 몇 가지 작은 모드를 사용하면 잘 작동합니다. 가장 중요한 부분은 다음과 같습니다.

라이브러리 대상에 “헤더 복사”빌드 단계가있는 경우이를 삭제해야합니다. 복사 헤더 빌드 단계는 Xcode에서 “아카이브”작업을 수행 할 때 정적 라이브러리 대상에서 올바르게 작동하지 않습니다.

Xcode 4.4 이상으로 생성 된 새로운 정적 라이브러리 타겟은 헤더에 대해 적절하게 구성된 Copy Files 단계와 함께 제공되므로 생성하기 전에 이미 존재하는지 확인해야합니다. 그렇지 않은 경우 대상 편집기 하단의 “Add Build Phase”를 누르고 “Add Copy Files”를 선택합니다. 새 파일 복사 빌드 단계를 공개하고 대상을 “제품 디렉토리”로 설정합니다. / $ {PRODUCT_NAME}을 포함하도록 하위 경로를 설정합니다. 이렇게하면 빌드 된 제품 디렉토리 내의 include라는 폴더 안에있는 라이브러리 (PRODUCT_NAME 빌드 설정에서 가져옴) 이름의 폴더에 파일이 복사됩니다. 빌드 제품 디렉토리 내의 포함 폴더는 애플리케이션의 기본 헤더 검색 경로에 있으므로 헤더 파일을 배치하기에 적합한 위치입니다.

기존의 많은 상황에서 Apple의 접근 방식으로는 충분하지 않을 수 있습니다. 나는 정적 도서관 정원 경로에서 막 여행을 시작하는 모든 사람을 위해 여기에 게시합니다. 이것은 간단한 경우에 가장 좋은 출발점이 될 수 있습니다.


답변

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

Apple 문서에 따라 :

라이브러리에는 해당 라이브러리의 클라이언트가 가져와야하는 하나 이상의 헤더 파일이 있습니다. 클라이언트로 내보낼 헤더를 구성하려면 라이브러리 프로젝트를 선택하여 프로젝트 편집기를 열고 라이브러리 대상을 선택하여 대상 편집기를 열고 빌드 단계 탭을 선택하십시오. 라이브러리 대상에 “헤더 복사”빌드 단계가있는 경우 삭제해야합니다. Xcode에서 “아카이브”작업을 수행 할 때 복사 헤더 빌드 단계가 정적 라이브러리 대상에서 올바르게 작동하지 않습니다.


답변

통찰력을 얻으려면 Jonah Wlliam의 솔루션 (중간) 및 GitHub 모델 (댓글)을 살펴보십시오.
http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/


답변

추가 $ (OBJROOT을) / UninstalledProducts / exactPathToHeaders 받는 헤더 검색 경로.

어떤 이유로 재귀 확인란이 작동하지 않았고 헤더가있는 위치에 나머지 경로를 추가해야했습니다.

Xcode의 로그 네비게이터 (중단 점 네비게이터 오른쪽에있는 탭)에서 빌드 히스토리를 볼 수 있습니다. 실제 빌드 실패를 선택하면 세부 정보를 확장하여 setenv PATH 를보고 헤더 파일의 경로가 있는지 확인할 수 있습니다.