Xcode에서 "링크 된 프레임 워크"대신 "임베디드 바이너리"를 언제 사용해야합니까?


140

라이브러리와 이진 링크 VS Embed Frameworks에 설명 된 두 옵션의 차이점에 대한 좋은 질문이 있습니다. .

둘 다 사용할 수있는 옵션이있는 것 같습니다. 임베디드 바이너리를 더 잘 사용해야하는 경우 또는 링크 된 프레임 워크보다 어떤 경우를 사용해야합니까?

이 문제를보다 명확하게 해결하기위한 확실한 예가 있습니까? 감사


답변:


239

링크 된 질문은 "바이너리와 바이너리 링크"기능을 참조하며 이는 내장 바이너리와 약간 다릅니다.

"라이브러리와 바이너리 연결"은 링크와 관련하여 예상되는 것을 의미합니다. 바이너리가 정적 라이브러리, 동적 라이브러리 또는 프레임 워크인지에 관계없이 컴파일 후 링크 타임에 오브젝트 코드에 링크됩니다.

정적 라이브러리와의 연결을 생각할 때, 링커 는 라이브러리에서 코드를 복사 합니다 (예 :libFoo.a 출력 바이너리로 . 출력 파일의 크기는 커지지 만 런타임에 외부 종속성을 해결할 필요는 없습니다. 정적 라이브러리와 관련하여 프로그램을 실행하는 데 필요한 모든 것은 프로그램이 작성된 후에 존재합니다.

동적 라이브러리 (.dylib 또는 시스템 제공 프레임 워크)를 사용하면 프로그램을 실행할 때 링크하는 라이브러리가 시스템의 동적 라이브러리 로더 경로에 존재하게됩니다. 이렇게하면 모든 타사 외부 라이브러리를 바이너리로 복사하는 오버 헤드가 없으며 해당 라이브러리에 연결된 컴퓨터의 모든 다른 프로그램에서 찾을 수 있으므로 디스크 공간을 최소화하면서도 공간을 절약 할 수 있습니다 시스템이 라이브러리를 캐시하는 방법과 위치에 따라 잠재적으로 메모리 공간.

프레임 워크는 동적 라이브러리와 매우 유사하지만 디렉토리 구조 (이미지, 오디오, 기타 프레임 워크 등)에 리소스를 포함 할 수 있습니다. 방금 있도록 프레임 워크에 연결해야 할 수도 있으므로이 경우에는 간단한 정적 라이브러리 또는 .dylib 파일을 잘라하지 않습니다 제대로 실행하는 데 필요한 것을 찾을 수 있습니다.

타사 프레임 워크 (예 : github에서 다운로드하여 직접 빌드 한 것)에 연결하면 실행하려는 시스템에 없을 수 있습니다. 이 경우 프레임 워크에 링크 할뿐만 아니라 "프레임 워크 복사"단계를 사용하여 프레임 워크를 응용 프로그램 번들에 포함시킵니다. 프로그램이 실행될 때 런타임 로더 (일명 리졸버)는 시스템 로더 경로와 함께 번들 내부를보고 내장 된 프레임 워크를 찾은 다음 링크하여 앱이 실행하는 데 필요한 코드를 갖도록합니다.

마지막으로, 적절하게 "임베디드 바이너리"란 파일 복사 단계를 통해 애플리케이션 번들에 임베드 한 실행 파일이며 호출 popen()또는 이와 유사한 방식으로 사용자 자신을 실행 합니다. 내장 바이너리는 프로그램에서 호출 할 수 있지만 연결되어 있지 않습니다. /bin디렉토리의 프로그램과 같은 완전히 외부 엔티티 입니다.

실제로, 시스템 제공 라이브러리 및 프레임 워크의 경우 링크를 제공하기 만하면됩니다.

내장 된 리소스가 필요하지 않은 (즉, 프레임 워크가 필요하지 않은) 빌드 한 라이브러리를 연결해야하는 경우 정적 라이브러리에 연결하면됩니다. 프로그램에 동일한 라이브러리 코드를 사용하려는 여러 모듈이있는 경우이를 프레임 워크 또는 동적 라이브러리로 변환하고 링크하면 공간이 절약되고 편리 할 수 ​​있습니다 (특히 메모리 사용이 중요한 경우).

마지막으로 프레임 워크에는 리소스뿐만 아니라 헤더 및 / 또는 라이센스 파일도 포함될 수 있습니다. 프레임 워크를 사용하여 이러한 파일을 전달하는 것은 실제로 편리한 배포 메커니즘이므로 종종 프레임 워크를 통합하여 바이너리와 함께 태그를 지정할 수 있습니다 (예 : 라이센스 요구 사항으로 인해 필수).

--- 편집하다 ---

Adam Johns는 다음 질문을 의견으로 올렸습니다.

이것은 좋은 대답입니다. 그러나 여전히 약간 혼란스러워하는 것이 있습니다. 바이너리를 직접 실행한다는 것은 무엇을 의미합니까? 단순히 임베디드 프레임 워크의 코드를 사용한다는 의미입니까? popen ()을 언급했지만 내 앱이 popen ()을 호출하고 있다는 것을 알고 있습니까? 나는 그것이 무엇을 의미하는지 정말로 모른다.

임베디드 바이너리 는 오디오 파일이나 이미지와 같은 번들의 또 다른 리소스 파일 이라고 말하고 있지만 파일은 실행 가능한 명령 줄 도구입니다. 이 popen()기능을 사용하면 ( man popen터미널에서 자세한 내용을 읽을 수 있음) 실행중인 다른 프로그램에서 임의의 프로그램을 실행할 수 있습니다. 이 system()기능은 다른 방법입니다. 다른 것들도 있고 여기에 포함 된 바이너리의 이해를 좀 더 명확하게 이해할 수있는 역사적인 예가 있습니다.

아시다시피, Mac OS X에서 응용 프로그램을 시작하면 현재 사용자의 사용자 ID로 시작됩니다. 대부분의 일반적인 설치에서 기본 사용자는 데스크탑 admin사용자이며 사용자에게 부여 501됩니다.

Unix 기반 운영 체제에서는 root사용자 (사용자 ID 0) 만 전체 파일 시스템에 대한 전체 액세스 권한을 갖습니다. 데스크탑 사용자가 시작한 설치 프로그램이 권한있는 디렉토리 (예 : 드라이버)에 파일을 설치해야하는 경우가 있습니다. 이 경우, 응용 프로그램은 root제한된 디렉토리에 쓸 수 있도록 권한을 사용자 에게 에스컬레이션해야합니다 .

OS X 10.7을 통해 운영 체제에서이를 용이하게하기 위해 Apple은 Authorization Services API 에서 AuthorizationExecuteWithPrivileges () 함수를 제공했습니다 (이제는 더 이상 사용되지 않지만 여전히 유용한 예입니다).

AuthorizationExecuteWithPrivileges()as로 실행할 명령 줄 도구의 경로를 인수로 사용했습니다 root. 명령 행 도구는 설치 로직을 실행하기 위해 작성한 실행 가능한 쉘 스크립트 또는 컴파일 된 바이너리입니다. 이 도구는 다른 리소스 파일과 마찬가지로 응용 프로그램 번들 안에 설치되었습니다.

호출되면 OS는 사용자의 암호를 묻는 인증 대화 상자를 표시하고 (이전에 본 적이 있습니다!) 입력하면 root앱 대신 프로그램을 실행합니다 . 이 프로세스는 단독 으로 프로그램을 실행하는 것과 비슷 popen()하지만 popen()단독으로 권한 상승의 이점을 제공하지는 않습니다.


62
이런 것들을 어떻게 아십니까?
이안 워버튼

56
@IanWarburton 저는 20 년 이상 Apple 운영 체제를 프로그래밍 해 왔으며 여기저기서 약간의 혼란을 겪었습니다. :)
par

1
@JustAMartin 의미 link하지만 복사 파일 단계를 통해 포함 해야하는 것이 맞습니다 (그렇지 않으면 어떻게 사용합니까?). 써드 파티 프레임 워크 또는 임베디드 바이너리를 사용하는 목적은 엔티티가 제공하는 코드를 실행하는 것입니다. 임베디드 바이너리를 사용하면 연결이 필요하지 않습니다. 런타임에 바이너리에 대한 경로를 구성한 다음 수동으로 실행하십시오. 프레임 워크를 사용하면 앱을 빌드 할 때 컴파일 타임 링커에서 링크 한 다음 (타사 프레임 워크 인 경우) 복사 파일 단계를 통해 임베드 한 다음 마지막으로 앱을 실행할 때 런타임 링커에서 다시 링크합니다. .

1
@JustAMartin에 대한 답변은 명확하지 않습니다. 써드 파티 프레임 워크 또는 임베디드 바이너리를 사용하는 목적은 엔티티가 제공하는 코드를 실행하는 것입니다. 현재 임베디드 바이너리는 타사 프레임 워크가 될 수도 있습니다. 나는 당신이 여기서 무엇을 의미하는지 이해하려고 노력하고 있습니다 ... AFA, 임베디드 바이너리는 임베디드 프레임 워크의 바이너리가 앱 번들에 도입 될 것이며, 동일한 프레임 워크를 연결하면 동일한 바이너리에 넣을 것입니다 앱의 것. 만약 내가 잘못 ... 제발 올바른
hariszaman

1
임베디드 프레임 워크를로드하는 새로운 Xcode 매직이있을 수 있습니다. 그 기능이 필요했던 지 오래되었습니다. 더 많은 일을 탐험하고 싶다면 여기에 새 질문을 게시하십시오.

35

한마디로

  • 시스템 라이브러리, 링크;
  • 타사 라이브러리를 포함시킵니다.

왜?

  • 시스템 라이브러리를 내장하려고하면 팝업 목록에서 찾을 수 없습니다.
  • 타사 라이브러리를 연결하면 충돌이 발생할 수 있습니다.

7

Dependency관리 의 일부입니다 [정보]

에 섹션 Xcode 11만 포함되어 있습니다 Frameworks, Libraries, and Embedded Content.General 탭을

링크 이진

Build Phases -> Link Binary With Libraries의 거울입니다 General -> Linked Frameworks and Libraries.

정적 라이브러리 및 프레임 워크

Static Library or Static Framework이 섹션에 를 추가하면 Frameworks 그룹 [정보] ( Project Navigator -> <workspace/project> -> Frameworks)에 나타나고 프로젝트에 대한 참조가 추가됩니다. 그런 다음에 사용됩니다 Static Linker. Static Linker컴파일시 라이브러리의 모든 코드를 실행 가능 객체 파일에 포함 / 복사 합니다. Static linker와 함께 작동Build Settings -> <Library/Framework> Search Paths

Static Library

Static Framework

  • Build Settings -> Framework Search Paths. static framework이 섹션에를 추가하지 않으면 컴파일 오류가 발생합니다. [No such module]

이진 포함

정적 라이브러리 및 정적 프레임 워크

삽입은 대한 이해가없는 것 Static Library그리고 Static Framework그들로부터 기호가 실행 가능한 바이너리로 컴파일되어 있기 때문이다. Xcode static library에서는 Embed 섹션 아래에 a를 놓을 수 없습니다 .

다이나믹 프레임 워크

Build Phases -> Embed Frameworks의 거울입니다 General -> Embedded Binaries. 임베딩은 실제로 프레임 워크 사본 을 애플리케이션 번들에 추가합니다. 결과적으로 프레임 워크가 Embed섹션에 추가 / 제거 될 때 자동으로 Linked섹션에 추가 / 제거됩니다 . 기본적으로 번들 폴더는 Frameworks있지만 Destination필드를 사용하여 변경할 수 있습니다 . 또한을 지정할 수 있습니다 Subpath.

Dynamic linker :dyld에서 로드 또는 런타임 찾기 위해 노력할 것입니다 임베디드 프레임 워크를 사용하여 @rpath[정보] 는 오류가 발생합니다 발견되지 않는 경우 [dyld을 : 도서관로드되지]

[링크와 내장 사용시]

[어휘]

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