'2013/08'에 해당되는 글 2건

  1. 2013.08.29 iPhone Static Framework 1
  2. 2013.08.28 library끼리 duplicated symbol error발생 시 2
iOS2013. 8. 29. 02:10


아이폰 코드공유의 문제점

모두다 알다시피 애플은 개발자에세 아이폰용 프레임웍을 만들 수 있는 기회를 제공하지 않는다. 하지만 많은 경우 서로 다른 프로젝트나 개발자들에게 코드를 배포해야 하는 경우가 있다.

대안

몇가지 코드공유나 배포를 위한 방안이 있다. 

첫번째는 코드자체를 공유 및 배포 가능하게 하는것이다. 이 방법은 XCode가 관련 매커니즘을 제공하지만 개발자가 디펜던시나 헤더파일 경로등을 추가로 해주어야 하는 불편함이 있다.

두번째는 코드가 아니라 static library로 배포하는것이다. 잘 알려진 방법이고 리눅스/유닉스 개발자를 비롯해서 아주 많은 개발자들에게 익숙한 방법이다. 하지만 몇가지 불편함이 있는데.  static library는 C/C++코드로 작성이 되어지고 Objective-C의 property나 category를 사용할 수 없다. category를 static library에 추가하려면 명시적으로 링커옵션을 주어야 한다.

-ObjC

-all_load

개발자가 위 옵션을 깜박하면 런타임에러가 발생하게 된다."unrecognized selector sent to instance"


Static Framework

가장 좋은 방법은 'static framework'라고 생각한다. 이 방법은 컴파일러에게 이 라이브러리가 일반적인 아이폰 프레임웍인것처럼 인식하도록 하는 것이다. 공유하고 싶은 static library가 있다면 아주 쉽게 framework으로 만들 수 있다. 그리고 이런 프레임웍은 개발자에게 프로젝트에 추가하는것 말고 추가로 아무것도 시키지 않는다.


어떻게 만들지??

XCode에서 프레임웍으로 빌드하는 방법을 제공하지 않으므로 XCode MacOS framework template로 빌드해야 한다. 일반적인 프레임웍과 동일한 구조를 가지며 몇가지 추가적인 절차가 있다.

1. simulator와 device용을 하나로 만듦

2. framework bundle에 이전 단계에서 프레임웍 번들로 추가한다.

쉽게 작업하기 위해 쉘스크립트를 사용할것이다. lipo유틸을 사용할것인데 이 유틸은 라이브러리 여러개를 하나로 묶어주는 유틸리티이다. 마지막에 이 파일은 프레임웍번들에 복사되고 전용 링크가 생성될것이다.

FRAMEWORK=”${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework”
lipo \”${BUILD_DIR}/${CONFIGURATION}-iphoneos/libDev.a” “${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib Sim.a” -create -output “${FRAMEWORK}/Versions/Current/${PRODUCT_NAME}”cd “${FRAMEWORK}” && ln -sf “Versions/Current/${PRODUCT_NAME}” ./

위 스크립트는 프로젝트의 빌드페이즈에 스크립트로 추가된다.
위 과정을 거치면 이젠 코드를 포함하는 프레임웤을 쉽게 공유할 수 있다.


Posted by 삼스
iOS2013. 8. 28. 23:01


3rd party library를 사용하다보면 서로 같은 심볼을 사용하게 되어서 아래와 같은 링크에러가 나는 경우가 종종 있다.

ld: duplicate symbol .objc_class_name_CJSONScanner in /Users/myappOne/TapjoyConnect/Frameworks/libTapjoyConnectSimulatorRewardInstall_Ads_Pinch.a(CJSONScanner.o) and /Developer/Projects/BuildOutput/Debug-iphonesimulator/OtherLibrary_d.a(CJSONScanner.o)
이 경우 해결 방법을 정리하겠다.

2개의 3rd party library가 있고 소스가 없는 상황을 가정한다.
libtool, lipo, ar명령으로 라이브러리를 extract하고 recombine한다.

먼저 라이브러리가 어떤 아키텍쳐를 지원하는지 확인한다.

$ lipo -info libTapjoy.a
Architectures in the fat file: libTapjoy.a are: armv6 i386

armv6와 i386를 지원하는것을 알 수 있다. 여기서 armv6를 extract한다.

$ lipo -extract_family armv6 -output libTapjoy-armv6.a libTapjoy.a
$ mkdir armv6
$ cd armv6
$ ar -x ../libTapjoy-armv6.a

같은 방법으로 다른 라이브러리의 동일아키텍쳐를 extract하는데 같은 디렉토리에 한다. 그리고 다음과 같이 다시 recombine한다.

$ libtool -static -o ../lib-armv6.a *.o

아키텍쳐별로 이 과정을 마친 후 다시 lipo로 합친다.

$ cd ..
$ lipo -create -output lib.a lib-armv6.a lib-i386.a




Posted by 삼스