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






배너 신청 문의

 
작성일 : 14-07-02 17:14
[QT/X11] Qt App을 Mac Appstore에 올리기
 글쓴이 : korone
조회 : 7,913   추천 : 0  
   http://www.podovat.com/?p=195 [1411]
이글은 제가 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 198
번호 제   목 글쓴이 날짜 조회 추천
198 [QT/Win32] MFC에서 Qt 사용하기 팁. (3) devilqoo 09-10 3406 0
197 [QT/X11] QML 모델을 C++ 코드로 구현하는 방법 중 하나 (1) 구름님 12-03 5063 0
196 [QT/X11] QWT for qt android (1) 구름님 03-07 6537 1
195 [QT/Embedded] QTcpSocket사용 시 플러그 뽑힘 증상 체크 방법 요원009 11-13 10660 0
194 [QT/Win32] QML 에서 CustomModule 을 import 하여 사용하기 tmdwn 05-18 6144 0
193 [QT/Embedded] Qt update함수/repaint함수 사용법좀 알려주세여.. (1) 잉농 05-14 5919 0
192 [QT/Embedded] C++ Exception을 활용한 런타임 콜스택 정보 얻기 (1) korone 04-01 6258 0
191 [QT/Embedded] Qt 5.4.1 raspberry Pi 프로그램 개발하기 (5) 구름님 03-31 20902 1
190 [QT/Win32] Qt 다국어 처리 (2) korone 03-17 12559 0
189 [QT/Win32] signal to signal devilqoo 02-13 5573 0
188 [QT/Win32] Qt x64 바이너리 제공 사이트 (1) 인라이… 02-12 5518 1
187 [QT/Embedded] 우분투 Qt5 크로스 컴파일 (14/11/26 2차 수정) (9) 김아무… 11-12 15516 0
186 [QT/Embedded] Qt 5.3.2에서 Mouse Double Click시 이벤트 문제 (2) korone 11-11 5570 0
185 [QT/Embedded] QtWinExtras korone 11-11 5612 0
184 [QT/Win32] Qt 코딩 스타일 (편집 편) (4) devilqoo 10-22 10103 0
183 [QT/Win32] Qt와 C++11 (2) devilqoo 10-12 10460 1
182 [QT/Win32] Qt 에서의 이벤트 처리 (5) devilqoo 10-09 9989 0
181 [QT/Win32] QList와 QVector의 비교. (2) devilqoo 10-02 7227 0
180 [QT/Win32] Qt에서 사용되는 컨테이너들을 정리해 보았습… (4) devilqoo 10-01 8189 0
179 [QT/X11] qmake DEFINES 변수에 공백문자가 포함된 값을 설… (1) 별님 09-25 5195 0
178 [QT/Win32] 데이터 압축 관련 qCompress(), qUncompress() (9) 구름님 09-16 5804 0
177 [QT/Win32] QML 로 One-Source Multi-Platform (iOS, Android) 실행 tmdwn 09-03 7260 0
176 [QT/Win32] QML 로 iOS Application 제작하기 tmdwn 09-02 7216 0
175 [QT/Win32] QML 로 Android Application 제작하기 (4) tmdwn 09-02 7673 2
174 [QT/X11] qt에서 메모리 조작하기. (2) 나무나… 07-25 8046 0
173 [QT/Win32] Q_DECLARE_FLAGS 매크로 (2) 구름님 07-11 6500 2
172 [QT/Win32] Q_PROPERTY 매크로 (6) 구름님 07-09 8932 2
171 [QT/Win32] Q_INTERFACE 매크로에 대해.. (4) 구름님 07-08 6307 2
170 [QT/Win32] windeployqt.exe라는 프로그램이 있습니다. (4) 구름님 07-07 12581 1
169 [QT/X11] Qt App을 Mac Appstore에 올리기 (3) korone 07-02 7914 0
 1  2  3  4  5  6  7  


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