커뮤니티 | 큐티/임베디드/큐토피아 | PODO | SDL | 마이크로윈도우 | 리눅스프로그래밍 | 기타 | 포인트순위 | 최근게시물최근게시물 RSS  
korone.net에 다루었으면 하는것은요?
 
 
 
 
 
364
882
3,878
3,960,898
  현재접속자 : 77 (회원 0)






배너 신청 문의

 
작성일 : 14-07-02 17:14
[QT/X11] Qt App을 Mac Appstore에 올리기
 글쓴이 : korone
조회 : 7,691   추천 : 0  
   http://www.podovat.com/?p=195 [1365]
이글은 제가 podovat.com의 blog 올린글(http://www.podovat.com/?p=195)에서 퍼온것입니다.

Qt App을 Mac Appstore에 올리기

*** Qt settings ***
기본적으로 Qt의 기본설정파일이 ~/Application Support/Preferences/com.trolltech.plist 에 생성되는데
이것은 Mac App Store의 정책(설정 파일은 반드시 응용프로그램의 번들 식별자(이름, 회사이름)와 같아야함)을 위반한다.
이 문제점을 해결하기 위해서 Qt 4.8.1부터 다음의 두가지 상황에 대해
Global Qt 설정을 응용프로그램의 Local 설정파일에 저장을 한다.

1. 응용프로그램이 샌드박스로 실행하거나
2. info.plist에 "ForAppStore"값을 "yes"로 설정해야 한다.

위와같은 상황에서 응용프로그램읜 번들 식별자가 설정 파일이 되고, Global Qt 설정은 해당파일의
"QtLibrarySettings"라는 파일로 저장된다.
만약에 샌드박스 형태로 사용할 경우, 설정파일이 정상적으로 생성되고
그렇지 않은경우 info.plist 파일에 "ForAppStore"키에 "yes"값을 넣어야지 제대로 동작을 한다.


*** 샌드박스에서 파일 저장 다이얼로그 ***
샌드박스 내에서는 파일 저장 다이얼로그의 기본 파일명이 비어 있지 않아야 제대로 동작된다.
다음과 같이 기본 파일명을 넣어주어야 한다.
QString fileSavePath = QFileDialog::getSaveFileName(this, "Save file", "default filename");
또는 직접 QFileDialog객체를 생성했다면 다음과 같이 처리 하면 된다.
QFileDialog *fileSaveDialog = new QFileDialog(this);
fileSaveDialog->setAcceptMode(QFileDialog::AcceptSave);
fileSaveDialog->selectFile("default filename");
참고) 파일 열기 다이얼로그는 특별한 문제가 없음


*** 데이타, 캐시 위치 ***
만약 QDesktopServices::storageLocation()함수를 이용해 DataLocation 또는 CacheLocation을
얻기위해 사용하는 경우, iTunes Connect의 값과 같은 응용프로그램 과 조직(organization)이름을
사용해야 한다.
만약 일치하지 않는경우, 소스코드에서 다음과 같이 application이름과 조직(organization)이름을
지정해 주면 된다.
단, 이름 지정은 QApplication객체가 생성되기 전에 해 주어야 한다.
QApplication::setOrganizationName("MyCompany");
QApplication::setApplicationName("MyApp");
참고) iTunes Connect에서는 지역화(localized)된 application이름과 조직(organization)이름을  허용하지 않기 때문에, 위 함수를 통해 이름을 지정하는데 주의를 해야 한다.


*** info.plist와 프로그램 아이콘 ***
qmake가 생성하는 info.plist파일은 Mac App Store에서 필요로 하는 키가 존재하지 않는다.
따라서 프로그램 이름등으로 새로운 plist를 지정(예, MyAppInfo.plist) 하여 만들고 qmake에 의해서
덮어쓰지 않도록 하기 위해 다음과 같은 설정내용을 pro 파일에 기록을 한다.
QMAKE_INFO_PLIST = MyAppInfo.plist
plist파일의 생성은 "Submitting to the Mac App Store"라는 애플 공식 문서를 참고 한다.
(https://developer.apple.com/library/mac/#releasenotes/General/SubmittingToMacAppStore/_index.html)
근데, 이것은 내용이 너무 복잡해서, 다음의 URL에서 복사를 해 오는게 편하다.
(http://hartcw.com/francis/qt-and-the-mac-app-store/)

아이콘은 pro파일에 다음과 같이 쓰면 된다.
ICON = MyApp.icns
mac 아이콘 포맷은 icns는 png파일을 이용해서 변환할 수 있는데,
http://iconverticons.com/ 에서 자동으로 변환시키는 웹기반 도구를 제공한다.


*** 디버그 심볼 ***
Mac App Store에 올리기 위해서는 디버그 심볼 정보를 생성해야 한다.
pro 파일에 다음과 같이 추가를 한다.
QMAKE_CFLAGS += -gdwarf-2
QMAKE_CXXFLAGS += -gdwarf-2
디버그 심볼은 dsymutil 이라는 명령을 이용해서 추출해 낼 수 있다.
dsymutil MyApp.app/Contents/MacOS/MyApp -o MyApp.app.dSYM

*** 코드 사이닝 ***
코드사이닝을 하기전에 macdeployqt(~/QtSDK/Desktop/Qt/4.8.1/gcc/bin/macdeplyqt)를 이용해 번들내에 Qt Frameworks와 플러그인을 복사를 한다.
작성하는 프로그램에서 사용하고 있지 않는 Qt Frameworks와 플러그인을 제거해서 용량을 줄이도록 한다.
이제 Qt Framework, plug-in, 응용프로그램을 모두 사이닝한다.
이 작업은 굳이 App Store의 승인이 없어도 되는데, 언사인되었다는 경고가 발생한다.
애플 공식 사이트에서 코드 사인에 필요한 인증서를 얻어서 다음과 같이 사인을 한다.

Qt Framework의 사인은 다음과 같이 하고
codesign -s "3rd Party Mac Developer Application: Developer Name" MyApp.app/Contents/Frameworks/QtCore.framework/Versions/4/QtCore
응용프로그램의 사인은 다음과 같이 한다.
codesign -s "3rd Party Mac Developer Application: Developer Name" --entitlements MyEntitlements.plist MyApp.app

만약 샌드박스를 사용하지 않는경우 "--entitlements MyEntitlements.plist" 옵션을 제거할 수 있다.
코드사인과 관련된 문서는 Apple's Code Signing Guide(http://developer.apple.com/library/mac/#documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html) 와 Apples Technical Note 2206(https://developer.apple.com/library/mac/#technotes/tn2206/_index.html)을 참조한다.

*** 인스톨 패키지 만들기 ***
다음과같이  productbuild명령을 이용해서 인스톨 패키지를 만든다.
productbuild --component MyApp.app /Applications --sign "3rd Party Mac Developer Installer: Developer Name" MyApp.pkg

만들어진것을 테스트 하려면 다음과 같은 명령을 입력한다.

sudo installer -store -pkg MyApp.pkg -target /

*** 프로젝트 파일 예제 ***
다음의 pro파일은 위의 과정에 나온 것에 대한 예제이다.
macx {
    # Name of the application signing certificate
    APPCERT = \"3rd Party Mac Developer Application: <yourcompany>\"
    # Name of the installer signing certificate
    INSTALLERCERT = \"3rd Party Mac Developer Installer: <yourcompany>\"
   
    # Bundle identifier for your application
    BUNDLEID = com.yourcompany.MyApp
   
    # Name of the entitlements file (only needed if you want to sandbox the application)
    ENTITLEMENTS = Entitlements.plist
   
    ICON = MyApp.icns
     QMAKE_CFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
    QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO
    QMAKE_OBJECTIVE_CFLAGS_RELEASE =  $$QMAKE_OBJECTIVE_CFLAGS_RELEASE_WITH_DEBUGINFO
    QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
    QMAKE_INFO_PLIST = MyAppInfo.plist
    OTHER_FILES += MyAppInfo.plist \
                 $${ENTITLEMENTS}
    codesign.depends  += all
    codesign.commands += macdeployqt $${TARGET}.app;
   
    # Remove unneeded frameworks (uncomment and change to suit your application)
    #codesign.commands += rm -r $${TARGET}.app/Contents/Frameworks/QtDeclarative.framework;
   
    # Remove unneeded plug-ins (uncomment and change to suit your application)
    #codesign.commands += rm -r $${TARGET}.app/Contents/PlugIns/accessible;
   
    # Extract debug symbols
    codesign.commands += dsymutil $${TARGET}.app/Contents/MacOS/$${TARGET} -o $${TARGET}.app.dSYM;
   
    # Sign frameworks and plug-ins (uncomment and change to suit your application)
    #codesign -s "$APPCERT" -i $BUNDLEID $${TARGET}.app/Contents/Frameworks/QtCore.framework/Versions/4/QtCore
    #codesign -s "$APPCERT" -i $BUNDLEID $${TARGET}.app/Contents/PlugIns/imageformats/libqjpeg.dylib
   
    # Sign the application bundle, using the provided entitlements
    codesign.commands += codesign -f -s $${APPCERT} -v --entitlements $${ENTITLEMENTS} $${TARGET}.app;
    product.depends += all
   
    # Build the product package
    product.commands += productbuild --component $${TARGET}.app /Applications --sign $${INSTALLERCERT} $${TARGET}.pkg;
    QMAKE_EXTRA_TARGETS += codesign product copyfiles
}

위의 내용을 pro 파일에 복사를 하고 인증에 관련된 이름, plist file 이름등등을 본인의 환경에 맞게 수정을 한다.
응용프로그램을 빌드 했다면, 다음과 같이 코드사인을 하고
(macdeployqt가 path아 안걸려 있다면 다음과 같이 PATH를 추가한다.
export PATH=$PATH:$HOME/QtSDK/Desktop/Qt/4.8.1/gcc/bin)
make codesign

다음과 같이 product 패키지를 만든다.
make product

이제 테스트를 하기에 앞서 이미 실행중인지를 확인하고, 다음과 같은 명령을 이용해서 테스트를 해본다.
(이때 주의 해야할 것은 현재 디렉토리에 MyApp.app 디렉토리가 있는경우 /Applications에 설치되지 않고 현재 디렉토리에 설치되므로
Launchpad에서 표시되기 위해서는 현재 디렉토리의 MyApp.app 디렉토리를 삭제한 후에 다음의 명령을 실행한다.)
sudo installer -store -pkg MyApp.pkg -target /

이제 Mac App Store에 올리기 위해 작업이 모두 끝났다.



*** 참고 URL ***
- http://www.digia.com/en/Blogs/Qt-blog/Pasi_Matilainen/Dates/2012/4/How-to-Publish-Qt-Applications-in-the-Mac-App-Store/
- https://developer.apple.com/library/mac/#releasenotes/General/SubmittingToMacAppStore/_index.html
- http://hartcw.com/francis/qt-and-the-mac-app-store/
Qt Professional Service(http://podovat.com)



devilqoo 14-07-03 11:00
 
어서 빨리 앱을 만들어 보고 싶어지는 글입니다. -ㅅ-b
구름님 14-07-03 11:33
 
에궁.. 뭔말인지 한개도 몰겠어요 ㅜㅜ
설이아… 14-07-03 19:07
 
올.. 좋은 자료!!
 
 

Total 220
번호 제   목 글쓴이 날짜 조회 추천
220 자신이 해야 할 일을 결정하는 사람은 세상에… rqyuspv875 10-21 5 0
219 산다는것 그것은 치열한 전투이다. -로망로랑… rqyuspv875 10-21 3 0
218 인간의 삶 전체는 단지 한 순간에 불과하다 . … rqyuspv875 10-21 3 0
217 source 삶이 그대를 속일지라도 슬퍼하거나 노… rqyuspv875 10-21 3 0
216 내일은 내일의 태양이 뜬다 피할수 없으면 즐… wyltqme425 10-20 9 0
215 인생이란 학교에는 불행 이란 훌륭한 스승이 … wyltqme425 10-20 6 0
214 최고에 도달하려면 최저에서 시작하라.-P.시… wyltqme425 10-20 2 0
213 해야 할 것을 하라. 모든 것은 타인의 행복을 … wyltqme425 10-20 3 0
212 평생 살 것처럼 꿈을 꾸어라.그리고 내일 죽… wyltqme425 10-20 10 0
211 이룰수 없는 꿈을 꾸고 이길수 없는 적과 싸… wyltqme425 10-20 7 0
210 만약 우리가 할 수 있는 일을 모두 한다면 우… wyltqme425 10-20 16 0
209 꿈을 계속 간직하고 있으면 반드시 실현할 때… wyltqme425 10-20 7 0
208 사막이 아름다운 것은 어딘가에 샘이 숨겨져 … wyltqme425 10-20 4 0
207 자신의 본성이 어떤것이든 그에 충실하라 . … wyltqme425 10-20 3 0
206 아래에 비교하면 남음이 있다.-명심보감[쇼미… wyltqme425 10-20 7 0
205 nephew 삶이 있는 한 희망은 있다 -키케로유혜… wyltqme425 10-20 7 0
204 고통이 남기고 간 뒤를 보라! 고난이 지나면 … rqyuspv875 10-20 7 0
203 진짜 문제는 사람들의 마음이다.그것은 절대… rqyuspv875 10-20 9 0
202 지금이야 말로 일할때다. 지금이야말로 싸울… rqyuspv875 10-20 6 0
201 도저히 손댈 수가 없는 곤란에 부딪혔다면 과… rqyuspv875 10-20 19 0
200 우선 무엇이 되고자 하는가를 자신에게 말하… rqyuspv875 10-20 9 0
199 longer 자신감 있는 표정을 지으면 자신감이 생… rqyuspv875 10-20 3 0
198 [QT/Win32] MFC에서 Qt 사용하기 팁. (3) devilqoo 09-10 3059 0
197 [QT/X11] QML 모델을 C++ 코드로 구현하는 방법 중 하나 (1) 구름님 12-03 4758 0
196 [QT/X11] QWT for qt android (1) 구름님 03-07 6311 1
195 [QT/Embedded] QTcpSocket사용 시 플러그 뽑힘 증상 체크 방법 요원009 11-13 10251 0
194 [QT/Win32] QML 에서 CustomModule 을 import 하여 사용하기 tmdwn 05-18 5872 0
193 [QT/Embedded] Qt update함수/repaint함수 사용법좀 알려주세여.. (1) 잉농 05-14 5738 0
192 [QT/Embedded] C++ Exception을 활용한 런타임 콜스택 정보 얻기 (1) korone 04-01 6070 0
191 [QT/Embedded] Qt 5.4.1 raspberry Pi 프로그램 개발하기 (5) 구름님 03-31 20192 1
 1  2  3  4  5  6  7  8  


About korone.net | Copyright 2003 korone.net. All rights reserved.