Meego Harmattanのアプリケヌション開発

この投皿は、 「Smart Posts for Smart Posts」ずいうコンテストに参加しおいたす。



画像

この蚘事では、Meego Harmattanの䟋でQtComponentsを䜿甚しお゜フトりェアを開発した経隓をHabrasocietyず共有したいず思いたす。 Ubuntu Oneを䜿甚しお同期するノヌト゚ディタヌを䜜成したす。







すべおの開発はスクラッチボックスを䜿甚しお実行され、maddeず比范しおいく぀かの利点がありたすが、Linuxシステムでのみ機胜したす。

䞻な利点の䞭で、アセンブリはchrootで実行され、アヌメルの堎合ぱミュレヌションにqemuが䜿甚されるこずに泚意しおください。 条件は可胜な限り戊闘に近いです。 これにより、クロスコンパむルを蚭定する䜙分な手間が省けたす。 さらにプラスは、apt-getの存圚です。これは、アセンブリに必芁なすべおの䟝存関係をむンストヌルできたす。これは、helloworldよりも難しいアプリケヌションを䜜成するずきに間違いなく必芁になりたす。

スクラッチボックスをむンストヌルしお構成する





scratchboxをむンストヌルするには、このスクリプトをルヌトからダりンロヌドしお実行し、将来その指瀺に埓う必芁がありたす。

# ./harmattan-sdk-setup.py
      
      





むンストヌル埌、ナヌザヌがsboxグルヌプに正垞に远加されるようにログむンする必芁がありたす。

次のコマンドを䜿甚しおスクラッチボックスを起動したす。

 $ /scratchbox/login
      
      





むンストヌラヌが正垞に機胜した堎合、次のようなプロンプトが衚瀺されたす。

 [sbox-HARMATTAN_ARMEL: ~] >
      
      





ログむンが誓う堎合は、scratchboxのルヌトにあるrun_me_first.shスクリプトを実行しおみおください。 sb_menuを䜿甚しお、目的のタヌゲットを遞択できたす。 残りのスクラッチボックスの䜿甚ガむドはこちらにありたす。



cmakeプロゞェクトの䜜成





コレクタヌずしお、私は通垞のqmakeを䜿甚したせんが、䟝存関係を探すこずができるより匷力なcmakeを䜿甚し、倚数の構成オプションを備えおおり、クロスプラットフォヌム開発により適しおいたす。 この蚘事では、アセンブリシステムの分析に぀いおは詳しく説明したせんので、理解を深めるために、この蚘事を読むこずをお勧めしたす 。

唯䞀のマむナス点は、cmakeがSymbianの䜿甚方法を知らないこずです。そのため、今のずころ、このプラットフォヌムを忘れるか、このプラットフォヌム専甚のアセンブリ甚に特別なプロゞェクトを手動で蚘述できたす。 Cmakeは残りの郚分を簡単に凊理できるので、将来はこのアプリケヌションをデスクトップシステムに、堎合によっおはAndroidに、さらにはiOSに移怍する予定です。

このプロゞェクトは、gitサブモゞュヌルを䜿甚しおメむンリポゞトリに接続されおいる倚数の䟝存ラむブラリで構成されおいたす。各ラむブラリには、独自のcmakeプロゞェクトがありたす。 これらはすべおサヌドパヌティのディレクトリにあり、メむンプロゞェクトに接続されおいるため、harmattanリポゞトリにない䞻芁な䟝存関係がすぐにアセンブリに反映されたす。



サヌドパヌティラむブラリのリスト



これに加えお、アセンブリに必芁な倖郚ラむブラリもありたすが、メむンのHarmattanのカブに存圚し、qcaはそれらを参照し、すぐにむンストヌルし、cmakeもむンストヌルしたす

 [sbox-HARMATTAN_ARMEL: ~] > apt-get install libqca2-dev cmake
      
      





それを䜿甚できるようにするには、ラむブラリヘッダヌファむルずラむブラリファむル自䜓を含むディレクトリを芋぀けおリンクできる特別なcmakeファむルを䜜成する必芁がありたす。

 include(FindLibraryWithDebug) if(QCA2_INCLUDE_DIR AND QCA2_LIBRARIES) # in cache already set(QCA2_FOUND TRUE) else(QCA2_INCLUDE_DIR AND QCA2_LIBRARIES) if(NOT WIN32) find_package(PkgConfig) pkg_check_modules(PC_QCA2 QUIET qca2) set(QCA2_DEFINITIONS ${PC_QCA2_CFLAGS_OTHER}) endif(NOT WIN32) find_library_with_debug(QCA2_LIBRARIES WIN32_DEBUG_POSTFIX d NAMES qca HINTS ${PC_QCA2_LIBDIR} ${PC_QCA2_LIBRARY_DIRS} ${QT_LIBRARY_DIR}) find_path(QCA2_INCLUDE_DIR QtCrypto HINTS ${PC_QCA2_INCLUDEDIR} ${PC_QCA2_INCLUDE_DIRS} ${QT_INCLUDE_DIR}} PATH_SUFFIXES QtCrypto) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(QCA2 DEFAULT_MSG QCA2_LIBRARIES QCA2_INCLUDE_DIR) mark_as_advanced(QCA2_INCLUDE_DIR QCA2_LIBRARIES) endif(QCA2_INCLUDE_DIR AND QCA2_LIBRARIES)
      
      





ほずんどの䟝存関係の怜玢は、同じスタむルで蚘述されおいたす。 Harmattanを含むpgkconfigを備えたシステムでは、すべおがシンプルで明確です。そうでないシステムでは、$ QTDIRディレクトリを調べたす。 cmakeがラむブラリを自動的に怜出しなかった堎合、倉数QCA2_INCLUDE_DIR QCA2_LIBRARIESを手動で蚭定するこずを提案したす。 このアプロヌチにより、パッケヌゞマネヌゞャヌのないシステムでの䜜業が楜になりたす。

cmakeには、このプログラムたたはそのプログラムがビルドされおいるプラ​​ットフォヌムを刀別できる倉数がありたす。䟋えば

 if(WIN32) .... elseif(APPLE) ... elseif(LINUX) ... endif()
      
      





残念ながら、cmakeはHarmattanに぀いお䜕も知りたせん。最も簡単な解決策は、-DHARMATTAN = ONスむッチでcmakeを開始するこずです。 これでHARMATTAN倉数が定矩され、次のように蚘述できたす。

 if(HARMATTAN) add_definitions(-DMEEGO_EDITION_HARMATTAN) #  ,         . endif()
      
      





これらの同じ倉数を䜿甚しお、むンストヌルするGUI実装を決定できたす。

 if(HARMATTAN) set(CLIENT_TYPE meego) message(STATUS "Using meego harmattan client") else() set(CLIENT_TYPE desktop) list(APPEND QML_MODULES QtDesktop) message(STATUS "Using desktop client") endif() set(QML_DIR "${CMAKE_CURRENT_SOURCE_DIR}/qml/${CLIENT_TYPE}") ... install(DIRECTORY ${QML_DIR} DESTINATION ${SHAREDIR}/qml)
      
      





開発では、ほずんどの堎合、harmattanクむックコンポヌネントずアセンブリ䞭の-DHARMATTANスむッチを備えたQtSDKで十分です。 scratchboxでは、最終バヌゞョンを倚少収集するのが理にかなっおいたす。



Tomboy Notes APIを実装するC ++プラグむン





API自䜓を別のqmlモゞュヌルに取り蟌むこずにしたした。このモゞュヌルはimportディレクティブを介しお利甚できたす。 これは、GUIむンタヌフェヌスのさたざたな実装を䜜成するために䟿利です。

開発プロセスで最も困難な郚分は、OAuthを䜿甚しお承認を実装するこずでした。その間に、いく぀かの異なるラむブラリの実装が列挙され、珟時点ではQOauthに萜ち着きたした。 このラむブラリの説明が蚘茉されたHabréの蚘事があるので、すぐに差し迫った問題の解決に進みたす。 たず最初に、非垞に切望されおいるトヌクンを取埗する必芁がありたす。

これはトリッキヌなビゞネスではありたせん。アドレスにリク゚ストを送信し、httpsを介した基本認蚌のリク゚ストが届くのを埅ちたす。

 UbuntuOneApi::UbuntuOneApi(QObject *parent) : QObject(parent), m_manager(new QNetworkAccessManager(this)), m_oauth(new QOAuth::Interface(this)) { ... connect(m_manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(onAuthenticationRequired(QNetworkReply*,QAuthenticator*))); } ... void UbuntuOneApi::requestToken(const QString &email, const QString &password) { m_email = email; m_password = password; QUrl url("https://login.ubuntu.com/api/1.0/authentications"); url.addQueryItem(QLatin1String("ws.op"), QLatin1String("authenticate")); url.addQueryItem(QLatin1String("token_name"), QLatin1Literal("Ubuntu One @ ") % m_machineName); qDebug() << url.toEncoded(); QNetworkRequest request(url); QNetworkReply *reply = m_manager->get(request); reply->setProperty("email", email); reply->setProperty("password", password); connect(reply, SIGNAL(finished()), SLOT(onAuthReplyFinished())); } ... void UbuntuOneApi::onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *auth) { auth->setUser(reply->property("email").toString()); auth->setPassword(reply->property("password").toString()); }
      
      





お気づきかもしれたせんが、QNetworkAccessManagerの暙準であるauthenticationRequired信号は認蚌に䜿甚されたす。通垞の道具でログむンずパスワヌドを芚えおいるだけです。 䟿利で、䞍必芁な詳现でむンタヌフェヌスを詰たらせたせん。

完了するず、応答は目的のトヌクンずその他の重芁な情報を含むjson圢匏で返信されたす。 これは、k8jsonラむブラリが必芁な堎所です。

  QNetworkReply *reply = static_cast<QNetworkReply*>(sender()); QVariantMap response = Json::parse(reply->readAll()).toMap(); if (response.isEmpty()) { emit authorizationFailed(tr("Unable to recieve token")); } m_token = response.value("token").toByteArray(); m_tokenSecret = response.value("token_secret").toByteArray(); m_oauth->setConsumerKey(response.value("consumer_key").toByteArray()); m_oauth->setConsumerSecret(response.value("consumer_secret").toByteArray()); QUrl url("https://one.ubuntu.com/oauth/sso-finished-so-get-tokens/" + reply->property("email").toString()); connect(get(url), SIGNAL(finished()), SLOT(onConfirmReplyFinished()));
      
      





次のステップは、トヌクンを受け取ったずいう事実の確認を送信するこずです最埌の行に泚意を払っおください。 その結果、答えは倧䞈倫です。

 void UbuntuOneApi::onConfirmReplyFinished() { QNetworkReply *reply = static_cast<QNetworkReply*>(sender()); QByteArray data = reply->readAll(); if (data.contains("ok")) { emit hasTokenChanged();
      
      





そのような単語が答えに含たれおいる堎合、すべお、あなたは喜んでゞャンプし、トヌクンが最終的に受信されたこずを瀺す信号を送信し、メモで䜜業を開始できたすが、そこにはありたせんでした tomboy apiずの互換性のために、ノヌトサヌバヌはWebブラりザヌを介した認蚌を必芁ずしたす。 これたでのずころ、この問題を回避するこずができず、歯を磚くために、「このナヌザヌがメモにアクセスできるようにする」ボタンを含むりィンドりをWebkitアプリケヌションに远加する必芁がありたした。 このWebkitにQNetworkAccessManagerぞのポむンタを䞎え、認蚌が正垞に完了するず、認蚌に必芁なデヌタを含む倧切なCookieの所有者になりたす。

たた、ナヌザヌがナヌザヌ名ずパスワヌドを再床入力する必芁がないように、これらのフィヌルドにDOMツリヌを入力したす。

  QWebFrame *frame = page()->mainFrame(); QWebElement email = frame->findFirstElement("#id_email"); email.setAttribute("value", m_email); QWebElement pass = frame->findFirstElement("#id_password"); pass.setAttribute("value", m_password); QWebElement submit = frame->findFirstElement("#continue"); submit.setFocus();
      
      





受け取ったCookieを保存するこずを忘れないでください。

 void Notes::onWebAuthFinished(bool success) { if (success) { QNetworkCookieJar *jar = m_api->manager()->cookieJar(); QList<QNetworkCookie> cookies = jar->cookiesForUrl(m_apiRef); QSettings settings; settings.beginWriteArray("cookies", cookies.count()); for (int i = 0; i != cookies.count(); i++) { settings.setArrayIndex(i); settings.setValue("cookie", cookies.at(i).toRawForm()); } settings.endArray(); sync(); } }
      
      





サヌバヌがリク゚ストを正垞に凊理するには、ヘッダヌに以前に受け取ったトヌクンが含たれおいる必芁がありたす。 これは、QOauthが䟿利な堎所です。

 QNetworkReply *UbuntuOneApi::get(const QUrl &url) { QByteArray header = m_oauth->createParametersString(url.toEncoded(), QOAuth::GET, m_token, m_tokenSecret, QOAuth::HMAC_SHA1, QOAuth::ParamMap(), QOAuth::ParseForHeaderArguments); QNetworkRequest request(url); request.setRawHeader("Authorization", header); return m_manager->get(request); }
      
      





これで、軜いハヌトで、 tomboy apiの実装を開始できたす。

qmlからの䜜業を簡単にするために、各ノヌトを個別のQObjectずしお提瀺するこずにし、Qtラボのオヌプンスペヌスで芋぀かったQObjectListModelを介しおノヌトのリストを実装したした。 各ノヌトには独自のGUIDがあり、どのノヌトを䜿甚できるかがわかりたす。 Guidはクラむアント偎で生成されたす;このため、QtにはQUuidクラスに察応するメ゜ッドがありたす。したがっお、新しいノヌトを䜜成する際に、䞀意の識別子を生成する必芁がありたす。この識別子は今埌参照したす。

 Note::Note(Notes *notes) : QObject(notes), m_notes(notes), m_status(StatusNew), m_isMarkedForRemoral(false) { QUuid uid = QUuid::createUuid(); m_guid = uid.toString(); m_createDate = QDateTime::currentDateTime(); }
      
      





メモ付きの基本アクション



これらのアクションに基づいお、APIを蚭蚈し、ノヌトのモデルでsyncメ゜ッドを䜜成し、ノヌト自䜓でメ゜ッドを保存、削陀したす。 そしおもちろん、タむトルずコンテンツのプロパティを実装したす

 class Note : public QObject { Q_OBJECT Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged) Q_PROPERTY(QString content READ content WRITE setContent NOTIFY textChanged) Q_PROPERTY(int revision READ revision NOTIFY revisionChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(QDateTime createDate READ createDate NOTIFY createDateChanged) ...
      
      





たた、qmlの状態で䜿甚できるノヌトステヌタスプロパティを远加するこずをお勧めしたす。

  Q_ENUMS(Status) public: enum Status { StatusNew, StatusActual, StatusOutdated, StatusSyncing, StatusRemoral };
      
      





これを行うには、転送甚のメタ情報を生成するマゞックマクロQ_ENUMSを䜿甚したす。 これで、qmlコヌドで数倀を取埗し、盞互に比范できたす。

  State { name: "syncing" when: note.status === Note.StatusSyncing
      
      





䟿利で読みやすく、高速。 それでも、文字列ではなく数倀が比范されたす

デフォルトでは、QObjectListModelでは、デリゲヌトからのモデル芁玠は名前オブゞェクトによっおアクセスできたすが、これはあたり私に合わないので、モデルから継承し、ObjectRoleロヌルの名前をメモに倉曎したした。

 NotesModel::NotesModel(QObject *parent) : QObjectListModel(parent) { QHash<int, QByteArray> roles; roles[ObjectRole] = "note"; setRoleNames(roles); }
      
      







次に、qmlモゞュヌル自䜓の䜜成を怜蚎したす。 API実装をqmlのむンポヌトで䜿甚するには、QDeclarativeExtensionPluginから継承するモゞュヌルにクラスを䜜成し、その䞭にregisterTypesメ゜ッドを実装しお、すべおのメ゜ッドずクラスを登録する必芁がありたす。

 void QmlBinding::registerTypes(const char *uri) { Q_ASSERT(uri == QLatin1String("com.ubuntu.one")); qmlRegisterType<UbuntuOneApi>(uri, 1, 0, "Api"); qmlRegisterType<ProgressIndicatorBase>(uri, 1, 0, "ProgressIndicatorBase"); qmlRegisterUncreatableType<Notes>(uri, 1, 0, "Notes", tr("Use Api.notes property")); qmlRegisterUncreatableType<Account>(uri, 1, 0, "Account", tr("Use Api.account property")); qmlRegisterUncreatableType<Note>(uri, 1, 0, "Note", tr("")); qmlRegisterUncreatableType<NotesModel>(uri, 1, 0, "NotesModel", tr("")); } Q_EXPORT_PLUGIN2(qmlbinding, QmlBinding)
      
      





あなたはおそらく断蚀に気づき、尋ねたいず思うでしょう。 そしお、このuriはどこから来たのですか たた、モゞュヌルが存圚するディレクトリの名前から取埗されたす。 ぀たり、Qtは次のモゞュヌルを探したす。

 $QML_IMPORTS_DIR/com/ubuntu/one/
      
      





しかし、それだけではありたせん。 Qtがモゞュヌルを芋぀けおむンポヌトするには、ディレクトリにバむナリプラグむン、qml、jsファむルがリストされた正しく構成されたqmldirファむルが含たれおいる必芁がありたす。

 plugin qmlbinding
      
      







Meego Harmattan甚のqmlむンタヌフェむスの開発





Meegoのアプリケヌションの倧郚分はPageStackWindow芁玠で、これは奇劙なこずに、ペヌゞのスタックです。 ペヌゞはpushメ゜ッドを䜿甚しおスタックにプッシュされ、popを​​䜿甚しおポップされたす。 ペヌゞの1぀を゜ヌスずしお割り圓おる必芁がありたす。 各ペヌゞには独自のツヌルバヌがありたす。 同じペヌゞに耇数のペヌゞを割り圓おるこずができたす。

 import QtQuick 1.1 import com.nokia.meego 1.0 import com.ubuntu.one 1.0 //    notes API PageStackWindow { id: appWindow initialPage: noteListPage Api { //,  API id: api Component.onCompleted: checkToken() onHasTokenChanged: checkToken() function checkToken() { if (!hasToken) loginPage.open(); else api.notes.sync(); } } ...
      
      





ここで、必芁なすべおのペヌゞず、メモを远加するボタンずアクションを含むメニュヌがある暙準ツヌルバヌを䜜成したす。

 ... LoginPage { id: loginPage onAccepted: api.requestToken(email, password); } NoteListPage { id: noteListPage notes: api.notes } NoteEditPage { id: noteEditPage } AboutPage { id: aboutPage } ToolBarLayout { id: commonTools visible: true ToolIcon { iconId: "toolbar-add" onClicked: { noteEditPage.note = api.notes.create(); pageStack.push(noteEditPage); } } ToolIcon { platformIconId: "toolbar-view-menu" anchors.right: (parent === undefined)? undefined: parent.right onClicked: (menu.status === DialogStatus.Closed)? menu.open(): menu.close() } } Menu { id: menu visualParent: pageStack MenuLayout { MenuItem { text: qsTr("About") onClicked: {menu.close(); pageStack.push(aboutPage)} } MenuItem { text: qsTr("Sync") onClicked: api.notes.sync(); } MenuItem { text: api.hasToken ? qsTr("Logout") : qsTr("Login") onClicked: { if (api.hasToken) api.purge(); else loginPage.open(); } } } }
      
      







次に、NoteListPage.qmlに実装されおいるNoteListPageの䟋を䜿甚しお、別のペヌゞがどのようなものかを芋おみたしょう。

 import QtQuick 1.1 import com.nokia.meego 1.0 import com.ubuntu.one 1.0 Page { id: noteListPage property QtObject notes: null tools: commonTools //  ,   main.qml PageHeader { //  .           id: header text: qsTr("Notes:") } ListView { id: listView anchors.top: header.bottom anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom anchors.margins: 11 clip: true focus: true model: notes.model delegate: ItemDelegate { title: note.title //      subtitle: truncate(note.content, 32) onClicked: { noteEditPage.note = note; pageStack.push(noteEditPage); //    } function truncate(str, n, suffix) { str = str.replace(/\r\n/g, ""); if (suffix === undefined) suffix = "..."; if (str.length > n) str = str.substring(0, n) + suffix; return str; } } } ScrollDecorator { flickableItem: listView } }
      
      





結果はずおもかわいいペヌゞです





ログむンりィンドりには、Sheetオブゞェクトを䜿甚したした。これは、䞊郚からポップアップするペヌゞです。 通垞、それを利甚しお、ナヌザヌは情報を求められたす。

 import QtQuick 1.0 import com.nokia.meego 1.0 import "constants.js" as UI //     - js   .      namespace'  qml'. Sheet { id: loginPage property alias email: loginInput.text //.   ,           loginInput.text property alias password: passwordInput.text content: Column { // sheet' anchors.topMargin: UI.MARGIN_DEFAULT anchors.horizontalCenter: parent.horizontalCenter Image { id: logo source: "images/UbuntuOneLogo.svg" } Text { id: loginTitle width: parent.width text: qsTr("Email:") font.pixelSize: UI.FONT_DEFAULT_SIZE color: UI.LIST_TITLE_COLOR } TextField { id: loginInput width: parent.width } Text { id: passwordTitle width: parent.width text: qsTr("Password:") font.pixelSize: UI.FONT_DEFAULT_SIZE color: UI.LIST_TITLE_COLOR } TextField { id: passwordInput width: parent.width echoMode: TextInput.Password } } acceptButtonText: qsTr("Login") rejectButtonText: qsTr("Cancel") }
      
      





この玠晎らしさはすべお次のようになりたす。



線集およびペヌゞに぀いおは、メモのリストに戻るための戻るボタンを実装する必芁がありたす。 CommonToolsはこれにはもはや適切ではなく、独自のツヌルバヌが必芁です。

  ToolBarLayout { id: aboutTools visible: true ToolIcon { iconId: "toolbar-back" onClicked: { pageStack.pop() } } }
      
      







ランチャヌアむコン





アプリケヌションに起動アむコンを蚭定するには、すべおのlinuxoids .desktopファむルに銎染みのあるファむルを䜜成したす。

 [Desktop Entry] Name=ubuntuNotes Name[ru]=ubuntuNotes GenericName=ubuntuNotes GenericName[ru]=ubuntuNotes Comment=Notes editor with sync Comment[ru]=    Exec=/usr/bin/single-instance /opt/ubuntunotes/bin/ubuntuNotes %U Icon=/usr/share/icons/hicolor/80x80/apps/ubuntuNotes.png StartupNotify=true Terminal=false Type=Application Categories=Network;Qt;
      
      





Execセクションに泚意しおください。このように、アプリケヌションを数回起動するこずはできたせん。 アプリケヌションに矎しいスプラッシュを持たせたい堎合は、invokerナヌティリティを䜿甚できたす。

 Exec=/usr/bin/invoker --splash=/usr/share/apps/qutim/declarative/meego/qutim-portrait.png --splash-landscape=/usr/share/apps/qutim/declarative/meego/qutim-landscape.png --type=e /usr/bin/qutim
      
      





もちろん、矎しいアむコンではなく、すべおの写真を別の堎所に蚭定するこずも忘れないでください。赀い四角が衚瀺されたす。



ビルドdebパッケヌゞ





アセンブリには、暙準のdpkg-buildpackageず通垞のdebianが䜿甚されたす。これは䟿宜䞊debian_harmattanず呌ばれ、アセンブリの前にシンボリックリンクdebian_harmattan> debianが蚭定されたす。 制埡セクションはdebianパッケヌゞの暙準であり、その䜜成に぀いおはすでにHabréの倚くの蚘事で詳しく説明されおいたす。 この䞀連の蚘事を読むこずをお勧めしたす。



制埡ファむルの内容

 Source: ubuntunotes Section: user/network Priority: extra Maintainer: Aleksey Sidorov <gorthauer87@ya.ru> Build-Depends: debhelper (>= 5),locales,cmake, libgconf2-6,libssl-dev,libxext-dev,libqt4-dev,libqca2-dev,libqca2-plugin-ossl, libqtm-dev Standards-Version: 3.7.2 Package: ubuntunotes Section: user/network Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends},libqca2-plugin-ossl Description: TODO XSBC-Maemo-Display-Name: ubuntuNotes XSBC-Bugtracker: https://github.com/gorthauer/ubuntu-one-qml Package: ubuntunotes-dbg Section: debug Priority: extra Architecture: any Depends: ${misc:Depends}, qutim (= ${binary:Version}) Description: Debug symbols for ubuntuNotes Debug symbols to provide extra debug info in case of crash.
      
      





倉曎ログを維持するために、devscriptsパッケヌゞからdchプログラムをむンストヌルするのは適切です。 䜿い方はずおも簡単です。

 $ dch - i
      
      





ルヌルファむルは、debhelper'ovの䜿甚のおかげで、非垞に簡単でした。

 #!/usr/bin/make -f %: dh $@ override_dh_auto_configure: dh_auto_configure -- -DCMAKE_INSTALL_PREFIX=/opt/ubuntunotes -DHARMATTAN=ON override_dh_auto_install: dh_auto_install --destdir=$(CURDIR)/debian/ubuntunotes
      
      





同じファむルは、最小限の倉曎でほずんどすべおのプロゞェクトに適しおいたす。

パッケヌゞの䜜成も簡単です。

 $ ln -s ./debian_harmattan ./debian $ dpkg-buildpackage -b
      
      







おわりに





これで、結果のパッケヌゞを安党にむンストヌルしお実行し、高速で応答性の高いむンタヌフェヌスを楜しむこずができたす。 自己アセンブリの゜ヌスコヌドはgithubからダりンロヌドできたす。 コンパむル枈みのdebパッケヌゞもありたす 。 この蚘事が、Harmattanの初心者デベロッパヌの助けになり、最初のアプリケヌションの䜜成をより早く始めるこずを願っおいたす。 将来的には、おそらく私はHabrasocietyにcmakeを䜿うこずの埮劙さをより良く説明しようずするでしょう。倚くの人はすでに圌に関する蚘事がないこずに䞍満を蚀っおいたす。



All Articles