13
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Qt を使った Auto Grade Linux アプリ開発方法

Posted at

Qt 初心者が Qt を使った AGL アプリを作成する手順の記録。Linux GUI に慣れてないので、Qt アプリの作成を Mac OS で行い、クロスビルドから wgt の作成までを Ubuntu 16.04 LTS を使った。

ソースコード: https://github.com/propella/agl-hello

Qt インストール方法

簡単なアプリの作成

簡単なアプリのソース

自分が思いついた一番簡単な Qt の GUI のプロジェクトファイルは以下のようになった。

# agl-hello.pro

QT += widgets
TARGET = agl-hello
TEMPLATE = app
SOURCES += main.cpp
CONFIG += debug

pro ファイルは qmake というツールの設定ファイルで、qmake は pro ファイルから Makefile 等を生成する。代入形式で定義する。リストは空白区切り。

  • QT : プログラムで使う Qt Module
    • QT にはデフォルトで coregui 等の基本的な値がセットされているため、追加するには += を使う。
  • TARGET : 出来上がるファイルの名前。デフォルトで project name と同じになる。
  • TEMPLATE : アプリを作る時は app, ライブラリの時は lib
  • SOURCES : ソースコードを記述する。
  • CONFIG : デバッグしたい時 debug を追加
  • pro ファイルのデバッグには message が便利。

以下プログラムソースコード。

// main.cpp

# include <QApplication>
# include <QLabel>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QLabel label("Hello, World!");
    label.setWindowFlags(Qt::FramelessWindowHint);
    label.show();
    return a.exec();
}

ここで setWindowFlags(Qt::FramelessWindowHint) で FramelessWindowHint を指定するのがポイント。これが無いとなぜか AGL HomeScreen から表示出来なかった。

ビルド方法

Qt Creator を使う場合

  • File > Open File or Project > agl-hello.pro を選択
  • Configure Project でデフォルトのまま Configure Project を押す。いつの間にか qthello.pro.user が出来ている。
  • 再生ボタンで実行
  • ../build-qthello-Desktop_Qt_5_9_1_clang_64bit-Debug にビルド用フォルダが出来ている。

Terminal を使う場合

~/Qt/5.9.1/clang_64/bin/qmake
make

クロスビルド用 Docker 環境の作成

AGL SDK Quick Setup に、Docker を使ったクロスビルド環境の作成が紹介されている。Docker 無しで Ubuntu 16.04 の上に直接 SDK をインストールしても動くので、面倒ならこのステップは省略出来る。

この docker image は特定のディレクトリ構成で使うように出来ているので、~/ssd 及び ~/devel を作成する

mkdir ~/ssd ~/devel
chmod a+w ~/ssd ~/devel

すると以下のようにコンテナ内からホストにアクセス出来る。

container host 用途
/xdt ~/ssd/xdt_$ID SDK インストール場所
/home/devel/mirror ~/ssd/localmirror_$ID 作業場所
/home/devel/share ~/devel/docker/share ダウンロードファイル置き場

docker image をダウンロードして設定

wget https://download.automotivelinux.org/AGL/snapshots/sdk/docker/docker_agl_worker-3.0.tar.xz
sudo docker load -i docker_agl_worker-3.0.tar.xz
docker images
git clone https://git.automotivelinux.org/AGL/docker-worker-generator
cd docker-worker-generator
./contrib/create_container 0 docker.automotivelinux.org/agl/worker:3.0

コンテナにログイン (パスワードは devel) なぜか TERM=screen が無いと、screen 経由で vi が上手く動かない。

TERM=screen ssh -p 2222 devel@localhost

コンテナ内からは uid: 1664 / gid: 1664 の devel というユーザでホストとファイル共有する。以下のように設定するとホストとファイル交換が出来る。(linux 詳しく無いので間違ってるかも)

ホスト

sudo groupadd --gid 1664 devel
sudo useradd --uid 1664 --gid 1664 devel

コンテナ

sudo groupadd --gid 1002 tyamamiya
sudo gpasswd -a devel tyamamiya

SDK のインストール

AGL のターゲット向け SDK はどこからか拾ってくるか、自分で作る場合は AGL の build ディレクトリで agl-demo-platform-crosssdk をビルドする。

bitbake agl-demo-platform-crosssdk

SDK は tmp/deploy/sdk/poky-agl-glibc-x86_64-agl-demo-platform-crosssdk-aarch64-toolchain-3.99.1+snapshot.sh のような場所に出来る。Docker を使っている場合はこれを ~/devel/docker/share に置いてコンテナと共有し、コンテナの install_sdk でインストールする。

Docker を使わない場合はこのファイルを直接実行すればインストーラが起動する。

host

mv tmp/deploy/sdk/poky-agl-glibc-x86_64-agl-demo-platform-crosssdk-aarch64-toolchain-3.99.1+snapshot.sh ~/devel/docker/share/

container

install_sdk ~/share/poky-agl-glibc-x86_64-agl-demo-platform-crosssdk-aarch64-toolchain-3.99.1+snapshot.sh 

実機で動くかテストしてみる。(デバイスのホスト名が device とする)

$ source /xdt/sdk/environment-setup-aarch64-agl-linux
$ cat <<EOT > hello.c
#include <stdio.h>
int main() { printf("Hello world\n"); return 0; }
EOT
$ $CC -o hello hello.c
$ scp hello root@device:.
$ ssh root@device ./hello
Hello world

アプリを Widget にする

クロスコンパイルしてデバイス上に表示する

サンプルアプリをコンテナの ~/mirror にコピーする。SDK を source すると qmake が使えるようになるので、そのままコンテナでビルドし、デバイス上で動く事を確認する。

$ git clone git@github.com:propella/agl-hello.git
$ cd agl-hello
$ source /xdt/sdk/environment-setup-aarch64-agl-linux
$ qmake
$ make
$ scp agl-hello root@device:.

AGL 起動時に Home Screen が表示される場合、そのままでは普通の Qt アプリが動かないので weston.ini を編集して ivi-shell.so を無効にする。

$ vi /etc/xdg/weston/weston.ini

# shell=ivi-shell.so (shell=ivi-shell.so をコメントアウト)

$ systemctl restart weston
$ ~/agl-hello

AGL デバイスの画面に寂しく Hello World! が表示されれば成功。終わったら weston.ini の設定を戻して systemctl restart weston する。

Wiget を作成する。

AGL のアプリは W3C Widget 仕様に基づいて作成した wgt ファイルだ。SDK 内に wgt ファイルを作るためのツールがある。パッケージを作るためには以下のファイルが必要。

  • config.xml : 今から作ります
  • アイコンファイル : なんでも良い
  • 実行ファイル
<?xml version="1.0" encoding="UTF-8"?>
<widget xmlns="http://www.w3.org/ns/widgets" id="poi" version="0.1">
  <name>Hello World</name>
  <icon src="icon.png"/>
  <content src="agl-hello" type="application/x-executable"/>
  <description>A Simple Hello World</description>
  <author>Takashi Yamamiya</author>
  <feature name="urn:AGL:widget:required-permission">
    <param name="http://tizen.org/privilege/internal/dbus" value="required" />
  </feature>
  <license>MIT</license>
</widget>

AGL App Framework は widget の id 属性でアプリを識別します。今回何故か poi という ID にしてみました。本来 ID はアプリを表す名前であるべきですが、現時点 (AGL 3.0) では HomeScreen の実装が不十分で、プリインストールされた決め打ちの ID のアイコンしか表示されません。今回は問題のある HomeScreen を騙すために、poi という既に存在するアプリの ID を流用します。

これらをまとめて適当なディレクトリに置きます。SDK の wgtpkg-pack コマンドで wgt ファイルを作成し、デバイスに転送します。

mkdir root
cp config.xml root/
cp icon.png root/
cp agl-hello root/
wgtpkg-pack -f -o agl-hello.wgt root
scp agl-hello.wgt root@device:.

デバイス側では afm-util コマンドを使ってアプリの登録削除を行います。

afm-util uninstall poi@0.1 # 既存の poi アプリを削除
afm-util install agl-hello.wgt # 作成した Hello World を poi 名前で登録

これで AGL Home Screen から POINT OF INTEREST のアイコンを押すと Hello World が表示されます。起動中にアプリの入れ替えは出来ないようなので、うまくいかない時はリブートして下さい。

afm-util には便利な機能が沢山あって Quick Tutorial に詳しい紹介があります。私がよく使うのは以下です。

  • afm-util uninstall (id@バージョン) # 既存の poi アプリを削除
  • afm-util install (wgt ファイル) # 作成した Hello World を poi 名前で登録
  • afm-util runners # 起動中のアプリを確認
  • afm-util terminate (runid) # runid で起動しているアプリを停止
  • systemctl --user restart HomeScreen # HomeScreen 再起動
    • アプリの入れ替えには役に立たないが、インストールしていない状態がからインストールした時にこのコマンドでアイコンを表示し直せる。

CMake で Widget ファイルを作成する

折角なのでこれらの作業を自動化するために cmake を使う。https://git.automotivelinux.org/apps/hvac 等の他のアプリを見ると qmake だけでも自動化出来るようだが、たまたま参考にした poi が cmake を使っていたので cmake になってしまった。

# CMakeLists.txt

cmake_minimum_required(VERSION 2.8.11)

project(agl-hello)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC ")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)

find_package(Qt5Widgets REQUIRED)
qt5_add_resources(agl_hello_QRC )
add_executable(agl-hello main.cpp ${agl_hello_SRC} ${agl_hello_QRC})
target_link_libraries(agl-hello Qt5::Core Qt5::Widgets)

install (TARGETS agl-hello DESTINATION bin)

configure_file(config.xml.in config.xml)
add_custom_command(
        OUTPUT agl-hello.wgt
        DEPENDS agl-hello
        COMMAND rm -rf package
        COMMAND mkdir -p package/root
        COMMAND cp config.xml package/root/
        COMMAND cp ${CMAKE_CURRENT_SOURCE_DIR}/icon.png package/root/icon.png
        COMMAND cp agl-hello package/root/agl-hello
        COMMAND wgtpkg-pack -f -o package/agl-hello.wgt package/root
)
add_custom_target(widget ALL DEPENDS agl-hello.wgt)

qmake から cmake への変換は http://doc.qt.io/qt-5/cmake-manual.html に詳しく書いてあるが、ポイントは以下

  • set(CMAKE_INCLUDE_CURRENT_DIR ON) # 良くわからないがとりあえず入れておく。
  • set(CMAKE_AUTOMOC ON) # 良くわからないがとりあえず入れておく。
  • find_package(Qt5Widgets REQUIRED) # qt5_ 関連のマクロが使えるようになる。
  • qt5_add_resources(agl_hello_QRC ) # この例では使ってないが、リソースファイルをビルドしたい時に使う。
  • target_link_libraries(agl-hello Qt5::Core Qt5::Widgets) # cmake の QT と同様の内容を記述

これで結局ビルド手順は以下のようになる。

cmake
make

package/agl-hello.wgt に Widget が出来る。

AGL Recipe の書き方

ここまで行くとあとはレシピを書くだけだが、力尽きたので今度書く。

基本 cmake_qt5, pkgconfig, aglwgt を inherit するだけでパッケージのインストールまで行われる。

13
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?