Universal Binary Build

시작하기전에

MacOS 환경에서 Library 및 실행파일은 다양한 Architecture용으로 빌드된 목적물을 하나의 파일로 묶는 방법을 제공합니다. 이것을 Apple에서는 Universal Binary라고 하며 모든 개발결과물은 이러한 Universal Binary형태로 만들어 주어야 H/W에 구애받지 않고 사용할 수 있게 됩니다. 보통 i386, x86_64, ppc를 모두 지원하는 형태로 만들게 되는데 이에 대한 방법에 대하여 이 문서에서 정리합니다.

간단히 요약하자면 각 Archiecture별로 우선 빌드후 각 빌드된 Architecture별 결과물을 lipo명령어로 묶어주는 작업이 Universal Binary의 생성과정이라고 할 수 있습니다.

여기서 설명하는 내용을 이해하기 위해서는 gmake의 문법을 이해하고 있다는 가정하에 작성하였습니다. (참고: Make 기초사용법)

Universal Binary 만들기

  • Single Architecture만 지원하는 Makefile의 경우
    ##
    ##  Copyright (C) JAEHYUK CHO
    ##  All rights reserved.
    ##  Code by JaeHyuk Cho <mailto:minzkn@minzkn.com>
    ##
    
    .PHONY: all clean
    
    all: test
    clean:
            rm -f *.o test
    
    test: test.o libtest.a libtest.so libpthread.so
            gcc -o $(@) $(^)
    
    libtest.so: test_shared_api.o
            gcc -shared -dynamiclib -dylinker_install_name $(notdir $(@)) -o $(@) $(^)
    
    libtest.a: test_static_api.o
            ar rc $(@) $(^)
    
    %.o: %.c
            gcc -c -o $(@) $(<)
    


  • i386, x86_64, ppc를 지원하는 Universal Binary를 만드는 Makefile의 경우
    ##
    ##  Copyright (C) JAEHYUK CHO
    ##  All rights reserved.
    ##  Code by JaeHyuk Cho <mailto:minzkn@minzkn.com>
    ##
    
    UNIVERSAL_ARCH:=i386 x86_64#
    
    # iOS SDK가 설치된 경우
    UNIVERSAL_ARCH+=ppc#
    
    .PHONY: all clean
    
    all: test
    clean:
            rm -f *.o test $(foreach s_this_arch,$(UNIVERSAL_ARCH),*.o.$(s_this_arch) test.$(s_this_arch))
    
    test: test.o libtest.a libtest.so libpthread.so
    ifneq ($(UNIVERSAL_ARCH),)
            $(foreach s_this_arch,$(UNIVERSAL_ARCH),\
                gcc -o $(@).$(s_this_arch) $(^:%.o=%.o.$(s_this_arch));\
            )
            lipo -create $(UNIVERSAL_ARCH:%=$(@).%) -output $(@)
    else
            gcc -o $(@) $(^)
    endif
    
    libtest.so: test_shared_api.o
    ifneq ($(UNIVERSAL_ARCH),)
            $(foreach s_this_arch,$(UNIVERSAL_ARCH),\
                gcc -shared -dynamiclib -dylinker_install_name $(notdir $(@)) -o $(@).$(s_this_arch) $(^:%=%.$(s_this_arch));\
            )
            lipo -create $(UNIVERSAL_ARCH:%=$(@).%) -output $(@)
    else
            gcc -shared -dynamiclib -dylinker_install_name $(notdir $(@)) -o $(@) $(^)
    endif
    
    libtest.a: test_static_api.o
    ifneq ($(UNIVERSAL_ARCH),)
            $(foreach s_this_arch,$(UNIVERSAL_ARCH),\
                ar rc $(@).$(s_this_arch) $(^:%=%.$(s_this_arch));\
            )
            lipo -create $(UNIVERSAL_ARCH:%=$(@).%) -output $(@)
    else
            ar rc $(@) $(^)
    endif
    
    %.o: %.c
    ifneq ($(UNIVERSAL_ARCH),)
            $(foreach s_this_arch,$(UNIVERSAL_ARCH),\
                gcc -c -o $(@).$(s_this_arch) $(<);\
            )
            lipo -create $(UNIVERSAL_ARCH:%=$(@).%) -output $(@)
    else
            gcc -c -o $(@) $(<)
    endif
    





/*
[ FrontPage | PrintView | RawView | RSS ]

Copyright ⓒ MINZKN.COM
All Rights Reserved.

MINZKN
*/