Neste post veremos como compilar e preparar o ambiente na Cubieboard para desenvolvimento de aplicações utilizando o Qt na sua quinta versão.
A Cubieboard para quem ainda não conhece, basicamente é uma SBC (Single Board Computer) rodando no sistema SoC(System on Chip) AllWinner A10/A20 dependendo de sua versão. Para leigos, a Cubie é um computador muito pequeno que pode rodar sistemas linux embarcados completos, e através disso desenvolver diversas aplicações ao uso desse sistema. Seguem, por exemplo, as especificações da Cubieboard 1 A10:
- SoC: AllWinner A10
- CPU: Cortex-A8 @ 1 GHz CPU,
- GPU Mali-400 MP
- video acceleration: CedarX able to decode 2160p video
- display controller: unknown, supports HDMI 1080p
- 512 MiB (beta) or 1GiB (final) DDR3
- 4 GB NAND flash built-in, 1x microSD slot, 1x SATA port.
- 10/100 Ethernet connector
- 2x USB Host, 1x USB OTG, 1x CIR.
- 96 extend pin including I²C, SPI, LVDS
- Dimensions: 10 cm × 6 cm
Agora sem mais delongas, vamos ver como ao uso de uma Cubieboard, podemos compilar e preparar seu ambiente para desenvolvimento em Qt5.
Passo 1: Criando a imagem do Sistema no cartão SD.
Antes de escrever este tutorial efetuei diversos testes para escolher a imagem que melhor serviria ao projeto. Em primeiro momento, acabei usando a rootfs Linaro, porém a mesma não possuia o kernel adequado e algumas modificações deviam ser feitas que na maioria das vezes nos trazia problemas. Sendo assim apesar de ser um pouco mais lenta, acabei desenvolvendo o processo utilizando a Cubian. Um sistema Debian voltado para o uso na Cubie. Sua instalação é muito simples e pode ser feita como segue:
Acesse http://cubian.org/downloads/ e escolha a versão que mais lhe interessa, recomento porém a versão Nano.
Extraia a imagem:
Se a versão possuir a extensão bz2:
[shell]bzip2 -d PATH_TO_CUBIAN.bz2[/shell]
Se a versão possuir a extensão .7z
[shell]apt-get install p7zip-full
7z x PATH_TO_CUBIAN.7z[/shell]
Em seguida basta escrever a imagem no cartão com o uso do dd:
[shell]dd if=CAMINHO_DA_IMAGEM of=/dev/SEU_DISPOSITIVO bs=4096; sync[/shell]
Passo 2: Instalando as bibliotecas Mali.
As bibliotecas Mali são essenciais pois habilitam a aceleração de hardware e suporte a OpenGL por exemplo. Vale lembrar que este tutorial segue os passos para a instalação da versão Framebuffer. A versão X11 será mostrada como instalar em um outro tutorial.
Para instalar as mesmas, neste passo não usaremos o nosso host, mas sim o sistema da Cubie:
Passo 2.1, instalando a UMP(Unified Memory Provider) userspace library:
Instale as seguintes dependências:
[shell]apt-get install git build-essential autoconf libtool debhelper dh-autoreconf pkg-config automake[/shell]
Clone o repositório:
[shell]git clone https://github.com/linux-sunxi/libump.git
cd libump[/shell]
Compilando:
[shell]dpkg-buildpackage -b
dpkg -i ../libump_*.deb
autoreconf -i
./configure
make
make install[/shell]
Passo 2.2, instalando a Mali userspace driver:
Clone o repositório:
[shell]git clone –recursive https://github.com/linux-sunxi/sunxi-mali.git
cd sunxi-mali[/shell]
Configuração:
[shell]make config[/shell]
Após esse passo, certifique-se que ABI=”armhf” e que EGL_TYPE=”framebuffer”. Se você não obteve esses valores, rode novamente as configurações usando:
[shell] make config ABI=armhf EGL_TYPE=framebuffer[/shell]
Após isso a instalação pode ser feita:
[shell]make && make install[/shell]
Para verificar agora que nosso sistema está com as bibliotecas funcionando faça:
[shell]cd sunxi-mali
make test
test /test[/shell]
Feito isso você deve obter um triângulo colorido na tela. Se não obter, faça todos o passo 2 novamente. O triângulo é a indicação de que tudo funciona e podemos seguir em frente. Por garantia, faça um backup da imagem de seu cartão:
[shell]dd bs=1M if=/dev/seu_dispositivo of=/opt/cubiefb.img[/shell]
Passo 3: Cross-Compilando o Qt5.
Nesse passo já possuímos um cartão rodando na Cubie que dá suporte a framebuffer corretamente, agora de volta ao host, vamos cross-compilar o Qt.
AVISO: EM TODOS OS PASSOS, CHEQUE OS CAMINHOS CORRESPONDENTES
Baixe o Qt do site oficial na versão que preferir: (Recomento a 5.2.1 por já haver feito testes de estabilidade)
http://download.qt-project.org/archive/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.tar.xz
Se você está em um sistema 64 bits baixe os seguintes pacotes:
[shell]sudo apt-get install ia32-libs[/shell]
No Ubunuto 14.04 x64 esse pacote não existe mais, então instale os seguintes:
[shell]sudo apt-get install lib32z1 lib32ncurses5 lib32bz2-1.0 libstdc++6:i386[/shell]
Crie uma imagem de seu cartão :
[shell]dd bs=1M if=/dev/seu_dispositivo of=/opt/cubiefb.img[/shell]
Monte a imagem criada mas somente a partição do SO, para fazer isso você pode usar o parted:
[shell]parted /opt/cubiefb
unit B
p[/shell]
Isso irá mostrar as partições do cartão, use o byte inicial para a partição root. No meu caso como segue:
[shell] mount -o loop,offset=68157440 /opt/cubiefb img /opt/pasta_que_deseja_que_a_imagem_seja_montada[/shell]
Em seguida, baixe o Linaro gcc que será utilizado para compilarmos o Qt e extraia no seu ambiente de trabalho:
http://releases.linaro.org/14.09/components/toolchain/binaries/gcc-linaro-aarch64-linux-gnu-4.9-2014.09_linux.tar.xz
Você deve exportar para o path do sistema a pasta bin do GCC, incluindo a seguinte linha logo no inicio do seu bashrc:
export PATH=${PATH}:~/home/rafael/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin
Lembre-se que estes caminhos são para o meu host, e você deve adaptá-los. Em seguida, clone o repositório:
[shell]git clone git://gitorious.org/cross-compile-tools/cross-compile-tools.git
cd cross-compile-tools[/shell]
O comando a seguir irá fixar os caminhos das bibliotecas entre a imagem do cartão sd e o compilador:
[shell] ./fixQualifiedLibraryPaths /opt/PASTA_DA_IMAGEM_MONTADA /opt/CAMINHO_GCC_EXTRAIDO/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf-g++ [/shell]
Baixe o seguinte arquivo:
https://app.box.com/qt5-cubieboard-images/1/2053729450/17853572680/1
Esse arquivo é a especificação de dispositivo da Cubieboard para o Qt. Após baixado extraia o mesmo. Abra o arquivo qmake.conf e procure pelas linhas:
# Extra stuff (OpenGL, DirectFB, …)
QMAKE_INCDIR_EGL = /opt/qtwb/cubie-rootfs/usr/include/EGL
QMAKE_LIBDIR_EGL = /opt/qtwb/cubie-rootfs/usr/lib
QMAKE_INCDIR_OPENGL_ES2 = /opt/qtwb/cubie-rootfs/usr/include/GLES2
QMAKE_LIBDIR_OPENGL_ES2 = /opt/qtwb/cubie-rootfs/usr/lib
#QMAKE_INCDIR_OPENVG = $${QMAKE_INCDIR_EGL}
#QMAKE_LIBDIR_OPENVG = $${QMAKE_LIBDIR_EGL}
Observe que os caminhos listados acima são referentes a minha imagem montada. Você deve alterar os mesmos para o seu caminho da imagem montada anteriormente. Feito isso salve o arquivo e faça:
[shell]cp -R linux-cubieboard2-g++ ./qt-everywhere-opensource-src-5.2.1/qtbase/mkspecs/devices/[/shell]
Em seguida abra em seu editor de texto o arquivo que se encontra em: /qt-everywhere-opensource-src-5.2.1/qtbase/src/plugins/platforms/qeglfshooks_stub.cpp
Procure pela linha: EGLNativeWindowType QEglFSHooks::createNativeWindow
Altere seu conteúdo para:
[cpp]
EGLNativeWindowType QEglFSHooks::createNativeWindow(QPlatformWindow *platformWindow,
const QSize &size,
const QSurfaceFormat &format)
{
Q_UNUSED(platformWindow);
Q_UNUSED(size);
Q_UNUSED(format);
//return 0;
static struct mali_native_window native_window = {
.width = (short unsigned int)size.width(),
.height = (short unsigned int)size.height(),
};
return &native_window;
} [/cpp]
Após isso estamos prontos para compilar o Qt5. Entre no diretório pelo qual extraiu o Qt:
[shell] cd qt-everywhere-opensource-src-5.2.1/ [/shell]
Sete as seguintes configurações: (Novamente alertando para checarem todos os caminhos)
[shell]./configure -opengl es2 -device linux-cubieboard2-g++ -device-option CROSS_COMPILE=/home/rafael/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf- -sysroot /opt/pasta_onde_imagem_esta_montada -opensource -confirm-license -optimized-qmake -release -make libs -prefix /usr/local/qt5fb -no-pch -nomake examples -nomake tests -no-xcb -eglfs -v[/shell]
Perceba que os caminhos que devem ser configurados é do nosso compilador e da pasta pela qual a imagem está montada. Após as configurações serem geradas, você deve obter algo do tipo:
[shell]
Configure summary
Building on: linux-g++ (x86_64, CPU features: mmx sse sse2)
Building for: devices/linux-cubieboard2-g++ (arm, CPU features: neon)
Platform notes:
– Also available for Linux: linux-kcc linux-icc linux-cxx
qmake vars ………. styles += mac fusion windows QMAKE_CFLAGS_FONTCONFIG = -I/opt/qt5.cubieboard2A20.workbench/cubie2-rootfs/usr/include/freetype2 QMAKE_LIBS_FONTCONFIG = -L/opt/qt5.cubieboard2A20.workbench/cubie2-rootfs/usr/lib/arm-linux-gnueabihf -lfontconfig -lfreetype DEFINES += QT_NO_LIBUDEV DEFINES += QT_NO_XCB DEFINES += QT_NO_XKBCOMMON PRECOMPILED_DIR = .pch/release-shared OBJECTS_DIR = .obj/release-shared MOC_DIR = .moc/release-shared RCC_DIR = .rcc/release-shared UI_DIR = .uic/release-shared sql-drivers = sql-plugins = sqlite qmake switches ………
Build options:
Configuration ………. accessibility audio-backend c++11 clock-gettime clock-monotonic compile_examples concurrent cross_compile egl eglfs evdev eventfd fontconfig full-config getaddrinfo getifaddrs iconv icu inotify ipv6ifname large-config largefile linuxfb medium-config minimal-config mremap neon nis opengl opengles2 pcre png qpa qpa reduce_exports reduce_relocations release rpath shared small-config system-freetype system-zlib v8 xlib xrender
Build parts ………… libs
Mode ………………. release
Using C++11 ………… yes
Using PCH ………….. no
Target compiler supports:
iWMMXt/Neon ………. no/yes
Qt modules and options:
Qt D-Bus …………… no
Qt Concurrent ………. yes
Qt GUI …………….. yes
Qt Widgets …………. yes
JavaScriptCore JIT ….. yes (To be decided by JavaScriptCore)
QML debugging ………. yes
Use system proxies ….. no
Support enabled for:
Accessibility ………. yes
ALSA ………………. no
CUPS ………………. no
FontConfig …………. yes
Iconv ……………… yes
ICU ……………….. yes
Image formats:
GIF ……………… yes (plugin, using system library)
JPEG …………….. yes (plugin, using bundled copy)
PNG ……………… yes (in QtGui, using bundled copy)
Glib ………………. no
GStreamer ………….. no
GTK theme ………….. no
Large File …………. yes
libudev ……………. no
Networking:
getaddrinfo ………. yes
getifaddrs ……….. yes
IPv6 ifname ………. yes
OpenSSL ………….. no
NIS ……………….. yes
OpenGL …………….. yes (OpenGL ES 2.x)
OpenVG …………….. no
PCRE ………………. yes (bundled copy)
pkg-config …………. yes
PulseAudio …………. no
QPA backends:
DirectFB …………. no
EGLFS ……………. yes
KMS ……………… no
LinuxFB ………….. yes
XCB ……………… no
Session management ….. yes
SQL drivers:
DB2 ……………… no
InterBase ………… no
MySQL ……………. no
OCI ……………… no
ODBC …………….. no
PostgreSQL ……….. no
SQLite 2 …………. no
SQLite …………… yes (plugin, using bundled copy)
TDS ……………… no
udev ………………. no
xkbcommon ………….. no
zlib ………………. yes (system library)[/shell]
Onde bits importantes são:
QPA backends:
DirectFB …………. no
EGLFS ……………. yes
KMS ……………… no
LinuxFB ………….. yes
XCB ……………… no
Em seguida podemos compilar e instalar com:
[shell]make -j 5 && make install[/shell]
Onde o número depois do j pode ser alterado de acordo com o número de núcleos que possui para melhorar o desempenho da compilação.
Após o termino da compilação (que demorou por volta de 40 minutos em meu host i7), as bibliotecas serão adicionadas em /usr/local/qt5fb na imagem montada e o qmake será posto em /usr/local/qt5fb em seu host.
Faça novamente um backup como ensinado anteriormente de seu cartão.
Passo 4: Cross-Compilando Aplicativos Qt5.
Nesse ponto, tenha certeza que a imagem está desmontada ou desmonte-a usando:
[shell]umount /opt/cubian-img[/shell]
Em seguida, grave a imagem no cartão SD:
[shell]dd bs=1M if=/path/cubie.img of=<sd device>; sync[/shell]
IMPORTANTE: Para tudo funcionar corretamente nesta etapa, a imagem que geramos logo em seguida da compilação do Qt deve estar montada para que as bibliotecas geradas possam ser acessadas. Então após gravar a imagem no cartão, monte-a novamente como já foi ensinado anteriormente.
Agora vamos configurar o Qt Creator para compilar os projetos adequadamente. Com o Qt aberto, acesse a aba, Tools e em seguida Options. No Menu lateral busque por Build & Run
Na aba Compilers, adicione o GCC Linaro que baixamos anteriormente.
Na aba Qt Versions, adicione o qmake gerado pela compilação, em /usr/local/qt5fb/bin/qmake
A aba Kits, crie um novo, selecionando o Compiler adicionado, a versão do Qt adicionada e na opção Device type selecione Generic Linux Device, bastanto agora aplicar as modificações e clicar em Ok.
Agora você já pode compilar projetos Qt para a Cubieboard usando o kit configurado. Basta compilar usando o kit gerado, copiar o projeto para o cartão SD e testar na Cubie.
Ultimo detalhe, para rodar os apps na Cubie, use
[shell] ./seuapp -platform eglfs[/shell]
e tudo funcionará perfeitamente.
Um bom exemplo para se testar se tudo ocorreu perfeitamente é o Qt5 CinematicExperience, que mostra a que taixa de FPS a aplicação esta rodando e possui vários efeitos e animações, certificando-se de que tudo está funcionando. Você pode baixar o exemplo aqui:
http://quitcoding.com/download/Qt5_CinematicExperience_rpi_1.0.tgz
Então agora já sabemos como Compilar o Qt5 em sua versão framebuffer para rodar na Cubieboard, em breve também teremos o tutorial para a versão X11 que sofre poucas alterações no tutorial. Quaisquer dúvidas ou sugestões deixem nos comentários e tentarei ajudá-lo.
Excelente post, me ajudou muito. Obrigado
Genio, lo voy a probar… muchas gracias por el aporte