iOS Framework의 duplicate symbol 에러 해결하기

Xcode 프로젝트를 개발하다 보면 다양한 Framework를 사용하게 됩니다. 애플에서 기본적으로 제공하는 Framework부터 외부의 개발사가 제공하는 Dynamic 혹은 Static 형태의 Framework를 접하게 되는데요. 프로젝트의 Build Settings – Other Linker Flags-ObjC 또는 -all_load 설정이 존재하게 되면 이 프레임워크들 사이에 사용하고 있는 라이브러리들이 충돌을 일으키게 됩니다.

이때에 접하게 되는 에러가 다음과 같은 duplicate symbol 오류입니다.

스크린샷 2015-08-23 오후 1.01.16

만약의 위의 충돌이 나고 있는 한쪽이 내 프로젝트라면 해당 Class/Library를 제거하면 간단히 해결될 문제이지만 차용하고 있는 두개의 Framework들 사이에 발생하고 있다면 굉장히 난감한 상황이 됩니다. 이경우 한쪽을 분해하여 해당 라이브러리를 제거한 뒤에 사용하는 방법이 있습니다.

위의 경우에는 Unity 프로젝트에서 기본이 되는 라이브러리 libiPhone-lib.aPPAppPlatformKit.framework간에 ioapi.o 라는 라이브러리가 충돌이 나는 경우이며 PPAppPlatformKit.framework에서 ioapi.o를 제거하는 방향으로 해결해 보도록 하겠습니다.

요즘의 프레임워크는 일명 Universal Framework 혹은 Fat Framework라는 이름으로 다양한 아키텍쳐를 동시에 지원하도록 Archiving 되어 제공됩니다. 우선 위의 충돌이 나고 있는 프레임워크로 접근하여 어떤 아키텍쳐들을 지원하고 있는지 확인해 보겠습니다.

lipo를 사용하여 해당 Framework는 armv7arm64 두가지 아키텍쳐를 지원하고 있다는것을 확인하였습니다. 이제 묶여있는 현재의 Framework를 아키텍쳐별로 분리해보도록 하겠습니다.

lipo의 -thin 명령을 사용하여 PPAppPlatformKit.armv7PPAppPlatformKit.arm64 두개로 분리하는데 성공하였습니다. 이번에는 분리해낸 각각의 바이너리들이 현재 충돌나고 있는 ioapi.o를 포함하고 있는지 확인해보도록 하겠습니다.

ioapi.o가 포함되어있는것을 확인하였습니다. 이제 바이너리에서 해당 오브젝트를 제거해보겠습니다.

아키텍쳐별 바이너리에서 각각 ioapi.o를 제거하였습니다. 이제 다시 하나로 합쳐보도록 하겠습니다.

Framework로부터 중복되어 충돌나고 있는 오브젝트를 정상적으로 제거하였습니다. 이제부턴 해당 오류가 발생하지 않을것입니다.

  • YEOSIM

    duplicate symbol _main in:

    /Users/mac21/Library/Developer/Xcode/DerivedData/OpneCV-djvaucrethgvgdaeqbypncairski/Build/Intermediates/OpneCV.build/Debug-iphoneos/OpneCV.build/Objects-normal/arm64/PhotoUnit.o

    /Users/mac21/Library/Developer/Xcode/DerivedData/OpneCV-djvaucrethgvgdaeqbypncairski/Build/Intermediates/OpneCV.build/Debug-iphoneos/OpneCV.build/Objects-normal/arm64/main.o

    ld: 1 duplicate symbol for architecture arm64

    clang: error: linker command failed with exit code 1 (use -v to see invocation)

    검색하다가 블로그 보게 되었습니다
    저는 이렇게 에러가 뜨더라구요 어떤 파일이 겹친건지. 아실 수 있을까요?
    초보라서.. 답변 주시면 감사하겠습니다 ^^

    • 아이

      PhotoUnit.o랑 main.o인가 보네요.

  • JungTek Hwang

    안녕하세요? 혹시 답변을 들을 수 있을까요?

    lipo -i 명령어로 지원하는 아키텍쳐를 확인 후
    각 아키텍쳐별로 분리까지는 했습니다.
    하지만 분리된 framework 내부에 존재하는 objectd의 목록보기가 실패했습니다.
    실행하니 아래와 같이 에러가 나네요.

    ar -t My_Framework.armv7
    ar: My_Framework.armv7: Inappropriate file type or format

    구글링을 해도 적절한 답을 얻지 못했는데 혹시 아시면 답변 부탁드립니다.^^