Fer canvis i proves localment¶
En aquesta pàgina trobareu informació sobre com desenvolupar programari de sistema, incloent-hi com muntar-lo, compilar-lo de forma creuada i fer-lo disponible a d’altres usuaris. La major part del programari ja instal·lat al vostre dispositiu Ubports es distribueix a la imatge del dispositiu en forma d’un paquet Debian. Aquest format s’utilitza a diverses distribucions Linux (com ara Debian, Ubuntu, Mint) i hi ha disponible un volum important de documentació en altres llocs sobre com treballar sobre ell, per això no el cobrirem aquí. Per una altra part, quasi sempre us trobareu amb la necessitat de modificar programari existent, més que desenvolupar paquets nous des de zero; per aquesta raó, aquesta guia és sobretot sobre recompilar un paquet Ubports existent.
Hi ha essencialment tres maneres de desenvolupar el programari del sistema Ubuntu Touch localment:
Compilació creuada amb un compilador creuat¶
sbuild utilitza un entorn de construcció basat en chroot més mínim, mentre que crossbuilder utilitza un contenidor LXD amb paquets més preinstal·lats. Quan es construeix amb un constructor creuat, es poden perdre les dependències de construcció preinstal·lades, que serien capturades per sbuild. El crossbuilder pot ser més ràpid per a construccions posteriors, ja que el contenidor LXD persisteix. sbuild instal·la totes les dependències de construcció en cada execució. Sbuild crea automàticament un fitxer de registre i executa lintian en els paquets construïts per tal de detectar qualsevol problema. L’ús de LXD per crossbuilder també permet una inspecció més fàcil, depuració i modificació manual de l’entorn de construcció. crossbuilder també pot desplegar automàticament paquets de construcció en un dispositiu connectat a través d’ADB.
Examinarem l’ús de crossbuilder i builds al dispositiu utilitzant theaddress-book-app <https://gitlab.com/ubports/core/address-book-app>the (l’aplicació Contactes) com a exemple.
Només recomanem desenvolupar paquets utilitzant un dispositiu amb Ubuntu Touch instal·lat des del canal devel. Això assegura que esteu provant els canvis contra l’estat més actual del codi Ubuntu Touch.
Preparant un paquet per a una construcció¶
Cal invocar sbuild o crossbuilder des d’un arbre font de paquets debianitzat (és a dir, les fonts de paquets amb un subdirectori debian), els paquets UBports consisteixen majoritàriament en repositoris git que contenen paquets nadius o no nadius. Els paquets nadius es poden construir directament i es pot utilitzar el següent script per preparar un paquet no natiu per a una construcció:
#!/bin/sh
PATH=/bin:/usr/bin
die() {
if [ $# -gt 0 ]; then
printf "%s\n" "$1" >&2
fi
exit 1
}
if [ ! -d "./debian" ]; then
die "not in a debianized package directory"
fi
if [ -f "./debian/ubports.source_location" ]; then
{
read -r src_url && \
read -r src_filename
} < "./debian/ubports.source_location" || \
die "failed to parse ubports.source_location"
case ${src_url} in
http://*|https://*|ftp://*)
;;
*)
die "invalid url: \"${src_url}\""
;;
esac
src_filename="$(basename "${src_filename}")"
wget -O "../${src_filename}" "${src_url}" || \
die "failed to download source archive"
fi
Construint paquets en un chroot utilitzant sbuild¶
.sbuild <https://tracker.debian.org/pkg/sbuild> a és una eina per construir paquets Debian des del codi font en un entorn aïllat utilitzant un chroot creat per .schroot <https://wiki.debian.org/Schroot>.. S’assembla molt al procés de construcció de paquets del sistema IC d’UBports mitjançant l’ús d’un entorn de construcció aïllat amb un conjunt mínim de paquets preinstal·lats. Això detecta les dependències de construcció que manquen i sbuild també detectarà problemes amb els paquets resultants executant el .lintian <https://lintian.debian.org/manual/lintian.html>..
Hi ha tres tipus d’edificis utilitzant sbuild:
Compilació nativa: aquest tipus de compilació s’utilitza quan l’arquitectura de l’amfitrió coincideix amb l’arquitectura de destinació.
Compilació creuada.: aquest tipus de compilació s’utilitza quan l’arquitectura de l’amfitrió no coincideix amb l’arquitectura de destinació. Aquest mètode pot fallar a causa de dependències d’arquitectura estrangeres que no són instal·lables. En aquest cas cal utilitzar un altre mètode.
Compilació d’arquitectura creuada de Qemu - aquest mètode permet realitzar una compilació nativa falsa sobre una arquitectura d’amfitrió que no coincideix amb l’arquitectura de destinació, evitant problemes de dependència de l’arquitectura estrangera. L’inconvenient d’aquest mètode és la velocitat lenta, causada per la sobrecàrrega de les traduccions binàries d’arquitectura. Consulteu l’enllaç per a més informació sobre qemu.
Prerequisits¶
Es requereix un sistema amfitrió que funcioni bé Debian 11 (Bullseye) o més tard o Ubuntu 20.04 (Focal Fossa) o més tard. Una manera fàcil i performant de configurar Debian o Ubuntu en altres distribucions és executar-lo en un contenidor utilitzant .LXD <https://linuxcontainers.org/lxd/getting-started-cli/#installing-a-package>..
Un contenidor LXD requereix la configuració següent per permetre que debootstrap utilitzi la crida del sistema mknod per crear pseudo dispositius com /dev/null dins d’un chroot:
lxc config set <container> security.syscalls.intercept.mknod true
Se suposa que l’usuari que està construint paquets està autoritzat a executar ordres amb privilegi de superusuari utilitzant sudo.
sbuild utilitza schroot per gestionar chroots que al seu torn utilitza debootstrap per crear el chroot. Els paquets requerits estan instal·lats amb:
sudo apt install sbuild schroot devscripts debhelper dh-migrations ccache
Un sistema Debian o Ubuntu també es pot instal·lar dins d’una màquina virtual, però això ve amb una despesa de rendiment.
Configuració de l’sbuild¶
Cal afegir un usuari sense privilegis al grup sbuild per tal d’obtenir el privilegi necessari per construir paquets:
sudo sbuild-adduser <username>
L’usuari de construcció pot configurar sbuild creant un fitxer ~/.sbuildrc de la següent manera:
cat >~/.sbuildrc <<'EOF'
# directory containing the build logs
$log_dir = "$HOME/logs";
1;
EOF
Per a més personalitzacions, vegeu el fitxer d’exemple a /usr/share/doc/sbuild/examples/example.sbuildrc.
Creeu el directori ~/logs si no existeix encara:
mkdir ~/logs
Weblate de l’UBports¶
La construcció d’alguns dels mòduls d’Ubuntu Touch requereix paquets del repositori de paquets d’UBports que s’instal·laran a la màquina amfitriona.
En aquest cas, cal afegir el repositori de paquets UBports a la màquina amfitriona. Inicialitzeu primer les variables chroot_repo i chroot_distro com es mostren a la secció Compilació nativa i després afegiu el repositori utilitzant:
wget 'http://repo.ubports.com/keyring.gpg' -O - | sudo tee "/usr/share/keyrings/ubports-keyring.gpg" >/dev/null
printf 'deb [signed-by=/usr/share/keyrings/ubports-keyring.gpg] %s %s main\n' "${chroot_repo}" "${chroot_distro}" | sudo tee "/etc/apt/sources.list.d/ubports.list" >/dev/null
Instal·lació d’un paquet:
sudo apt update
sudo apt install click-dev gobject-introspection
Construcció nativa¶
Per tal de crear un chroot basat en Ubuntu 20.04 (Focal Fossa) amb l’arquitectura amd64 sota el directori /srv/chroot/ubports-${chroot_distro}-amd64 (chroot_base es pot canviar si cal) es poden definir les següents variables per al seu ús posterior per les ordres reals:
chroot_distro=focal
chroot_base=/srv/chroot/ubports-${chroot_distro}-amd64
chroot_repo=http://repo2.ubports.com/
Per a crear un chroot basat en Ubuntu 16.04 (Xenial Xerus) amb l’arquitectura amd64, definiu les següents variables:
chroot_distro=xenial
chroot_base=/srv/chroot/ubports-${chroot_distro}-amd64
chroot_repo=http://repo.ubports.com/
Connecteu el dispositiu al vostre ordinador i executeu les ordres següents:
sudo sbuild-createchroot --components=main,restricted,universe --extra-repository="deb http://archive.ubuntu.com/ubuntu/ ${chroot_distro}-updates main restricted universe" --include=ccache "${chroot_distro}" "${chroot_base}" http://archive.ubuntu.com/ubuntu/
El repositori de paquets d’UBports s’ha d’afegir amb:
wget 'http://repo.ubports.com/keyring.gpg' -O - | sudo tee "${chroot_base}/usr/share/keyrings/ubports-keyring.gpg" >/dev/null
printf 'deb [signed-by=/usr/share/keyrings/ubports-keyring.gpg] %s %s main\n' "${chroot_repo}" "${chroot_distro}" | sudo tee "${chroot_base}/etc/apt/sources.list.d/ubports.list" >/dev/null
La sincronització dels fitxers d’índex de paquets i les actualitzacions de paquets posteriors es poden realitzar utilitzant:
sudo sbuild-update -u -d ${chroot_distro}
Es pot iniciar una construcció des de dins del directori de codi font de paquets desbianitzats utilitzant:
sbuild -d ${chroot_distro}
Compilació creuada¶
L’única diferència amb la construcció nativa ve en l’ordre per a iniciar la construcció que és la següent:
sbuild --host=arm64 --build=amd64 -d "${chroot_distro}"
Construcció d’arquitectura creuada de Qemu¶
Per simplificar la configuració de chroot, utilitzem mk-sbuild del paquet ubuntu-dev-tools. El paquet qemu-user-static permet l’execució d’executables de destinació no nadius com els nadius.
Instal·la els paquets amb les ordres següents:
sudo apt install ubuntu-dev-tools qemu-user-static
Per tal de crear un chroot basat en Ubuntu 20.04 (Focal Fossa) amb l’arquitectura arm64 sota el directori /var/lib/schroot/chroots/ubports-${chrootdistro}-arm64 (chroot_base es pot canviar si cal) es poden definir les següents variables per al seu ús posterior per les ordres reals:
chroot_arch=arm64
chroot_distro=focal
chroot_base=/var/lib/schroot/chroots/ubports-${chroot_distro}-${chroot_arch}
chroot_repo=http://repo2.ubports.com/
Per a crear un chroot basat en Ubuntu 16.04 (Xenial Xerus) amb l’arquitectura arm64, definiu les següents variables:
chroot_arch=arm64
chroot_distro=focal
chroot_base=/var/lib/schroot/chroots/ubports-${chroot_distro}-${chroot_arch}
chroot_repo=http://repo.ubports.com/
Connecteu el dispositiu al vostre ordinador i executeu les ordres següents:
mk-sbuild --arch=${chroot_arch} ${chroot_distro} --name ubports-${chroot_distro}
El repositori de paquets d’UBports s’ha d’afegir amb:
wget 'http://repo.ubports.com/keyring.gpg' -O - | sudo tee "${chroot_base}/usr/share/keyrings/ubports-keyring.gpg" >/dev/null
printf 'deb [signed-by=/usr/share/keyrings/ubports-keyring.gpg] %s %s main\n' "${chroot_repo}" "${chroot_distro}" | sudo tee "${chroot_base}/etc/apt/sources.list.d/ubports.list" >/dev/null
La sincronització dels fitxers d’índex de paquets i les actualitzacions de paquets posteriors es poden realitzar utilitzant:
sudo sbuild-update --arch=${chroot_arch} -u -d ubports-${chroot_distro}
Es pot iniciar una construcció des de dins del directori de codi font de paquets desbianitzats utilitzant:
sbuild --build=${chroot_arch} --host=${chroot_arch} -d ubports-${chroot_distro}
Compilació de la documentació¶
Si la construcció ha tingut èxit, els paquets binaris es col·locaran al directori pare. El registre de construcció es col·locarà dins de ~/logs. En cas que la construcció fallés, el chroot es pot inspeccionar utilitzant:
sudo sbuild-shell ${chroot_distro}
Notificacions d’inserció¶
S’estan emmagatzemant les baixades dels paquets¶
Per tal d’estalviar amplada de banda i temps, és molt aconsellable emmagatzemar a la memòria cau els paquets descarregats utilitzant apt-cacher-ng. Es pot instal·lar amb:
apt install apt-cacher-ng
Llavors cal configurar Chroots perquè apt dins del chroot utilitzi apt-cacher-ng al servidor intermediari:
printf 'Acquire::http { Proxy "http://localhost:3142"; }\n' | sudo tee "${chroot_base}/etc/apt/apt.conf.d/proxy" >/dev/null
Resultats de la compilació de memòria cau¶
ccache és una memòria cau de compilador que accelera la compilació repetida del mateix codi font en memòria cau dels fitxers d’objecte resultants. La memòria cau real s’emmagatzema en el sistema amfitrió i es munta «bind» a sbuild chroots amb un ganxo schroot:
ccache_dir=/var/cache/ccache-sbuild
sudo install --group=sbuild --mode=2775 -d "${ccache_dir}"
sudo env CCACHE_DIR="${ccache_dir}" ccache --max-size 4G
printf '%s %s none rw,bind 0 0\n' "${ccache_dir}" "${ccache_dir}" | sudo tee -a /etc/schroot/sbuild/fstab >/dev/null
Per tal de fer ús de ccache inside un chroot sbuild cal crear un script d’embolcall:
cat >"${ccache_dir}/sbuild-ccache.sh" <<EOF
#!/bin/sh
export CCACHE_DIR=$ccache_dir
export CCACHE_UMASK=002
export CCACHE_COMPRESS=1
unset CCACHE_HARDLINK
export PATH=/usr/lib/ccache:\$PATH
exec "\$@"
EOF
chmod +x "${ccache_dir}/sbuild-ccache.sh"
Per a utilitzar aquest script d’embolcall, s’ha d’afegir la següent línia a la configuració d’un chroot schroot a /etc/schroot/chroot.d/:
command-prefix=/var/cache/ccache-sbuild/sbuild-ccache.sh
Més informació¶
Els detalls tècnics estan disponibles a les pàgines del manual sbuild(1) i sbuild-createchroot(8) i al wiki de Debian.
Compilació creuada amb un compilador creuat¶
Crossbuilder és un script que automatitza la configuració i l’ús d’un entorn crossbuild per a paquets Debian. És adequat per a desenvolupadors amb qualsevol dispositiu, ja que la compilació de codi es produeix en el vostre ordinador d’escriptori en lloc del dispositiu de destinació. Això fa que Crossbuilder sigui la forma recomanada de desenvolupar canvis no trivials a Ubuntu Touch.
Nota
Crossbuilder requereix una distribució Linux amb lxd instal·lat i el conjunt d’ordres sense privilegis disponible. En altres paraules, heu de poder executar l’ordre lxc.. Si esteu executant Ubuntu al vostre amfitrió, Crossbuilder us configurarà lxd.
Comenceu instal·lant Crossbuilder al vostre amfitrió:
cd ~
git clone https://github.com/ubports/crossbuilder.git
És un script d’intèrpret d’ordres, així que no us cal compilar-lo. Us acal en canvi afegir el seu directori a la vostra variable d’entorn PATH, per poder-lo executar des de qualsevol directori:
echo 'export PATH="$HOME/crossbuilder:$PATH"' >> ~/.bashrc
# and add it to your current session:
source ~/.bashrc
Ara que Crossbuilder està instal·lat, podem utilitzar-lo per configurar LXD:
crossbuilder setup-lxd
Si aquesta és la primera vegada que utilitzeu LXD, és possible que hàgiu de reiniciar el vostre amfitrió una vegada que tot s’hagi completat.
Després de configurar LXD, es pot iniciar una construcció per a UBports basada en Ubuntu 20.04 (Focal Fossa) utilitzant l’arquitectura arm64 des de dins del directori font de paquets debianized utilitzant:
distro=20.04
arch=arm64
crossbuilder --lxd-image="ubuntu:${distro}" --architecture="${arch}" build
Per construir contra una versió diferent d’UBports o canvi d’arquitectura distro i arch segons sigui necessari.
El Crossbuiler us ho farà tot: crearà el contenidor LXD, descarregarà la imatge de desenvolupament, instal·larà totes les dependències de desenvolupament del vostre paquet, realitzarà la compilació i finalment, si el vostre dispositiu està connectat a l’amfitrió, copiarà els paquets al destí i els instal·larà. Els primers dos passos (la creació de la imatge LXD i l’obtenció de les dependències) poden portar alguns minuts, però sols s’executaran el primer cop que llenceu el crossbuilder per a un nou paquet.
Per a desplegar el paquet acabat de construir en un dispositiu local (vegeu Accés a la consola via adb per obtenir més informació sobre la connexió amb el vostre dispositiu), podeu utilitzar:
crossbuilder --lxd-image="ubuntu:${distro}" --architecture="${arch}" --password="password-or-0000-if-not-set" deploy
Ara, cada cop que canvieu el codi font al vostre repositori git, els mateixos canvis estaran disponibles dins del contenidor, i la propera vegada que escriviu l’ordre crossbuiler, sols es recompilaran els fitxers que han canviat. Això fa que el desenvolupament iteratiu sigui tremendament ràpid.
Si les dependències de construcció han canviat, es pot utilitzar la següent ordre per actualitzar el contenidor en conseqüència (distro i arch s’han d’establir com a dalt):
crossbuilder --lxd-image="ubuntu:${distro}" --architecture="${arch}" dependencies
Mentre que el crossbuilder no crea fitxers de registre per al procés de construcció, la utilitat script es pot utilitzar amb aquesta finalitat:
script -c "crossbuilder --lxd-image=\"ubuntu:${distro}\" --architecture=\"${arch}\" build" build.log
Quan ja no es necessita un contenidor de construcció, potser s’elimina usant:
crossbuilder --lxd-image="ubuntu:${distro}" --architecture="${arch}" delete
Proves unitàries¶
El crossbuilder no executa proves unitàries de forma predeterminada; això és així tant per motius de rapidesa, com perquè el contenidor creat pel crossbuilder no se suposa que ha d’executar programes nadius (del destí); les eines de desenvolupament (qmake/cmake, make, gcc, etc.) s’executen totes a l’arquitectura de l’amfitrió, sense cap emulació (un altre cop, per motius de rapidesa). Tanmateix, l’emulació qemu està disponible a dins del contenidor, de manera que hauria de ser possible executar proves unitàries a dins del contenidor. Podeu fer això obtenint un intèrpret d’ordres dins del contenidor:
crossbuilder --lxd-image="ubuntu:${distro}" --architecture="${arch}" shell
i després trobeu les proves unitàries i executeu-les. Tingueu present que l’emulació no és perfecta, així que és molt probable que les proves fallin tot i que haurien tingut èxit en altres casos, si s’executen en un entorn apropiat. Per aquesta raó, probablement és aconsellable no preocupar-se sobre les proves unitàries quan es treball amb el crossbuilder, i executar-les sols quan no s’estigui compilant de forma creuada.
Compilació al propi dispositiu¶
Aquest és el sistema més ràpid i fàcil de desenvolupar petits canvis i provar-los a pràcticament temps real. Depenent dels recursos del vostre dispositiu, tanmateix, podria no ser possible seguir aquest camí: si no teniu suficient espai lliure al vostre sistema de fitxers arrel no podreu instal·lar totes les dependències de compilació del paquet; o, la memòria RAM del vostre dispositiu pot ser insuficient per al compilador. Suposant que teniu sort i no us trobeu amb aquestes restriccions, i que no us importa reinstal·lar el vostre dispositiu (per netejar tots els paquets de desenvolupament que heu instal·lat), si us plau continueu llegint.
Avís
Aquest mètode és limitat. Molts dispositius no tenen prou espai d’imatge lliure per instal·lar els paquets necessaris per construir components d’Ubuntu Touch. La instal·lació de paquets té el risc de danyar el programari del vostre dispositiu, fent-lo inutilitzable. Si això passa, podeu reinstal·lar Ubuntu Touch.
En aquest exemple, construirem i instal·larem l’aplicació de llibre d’adreces. Totes les ordres que es mostren aquí s’han d’executar al vostre dispositiu Ubuntu Touch a través d’un intèrpret d’ordres remot.
Podeu obtenir un intèrpret d’ordres al dispositiu utilitzant Accés a la consola via adb o Accés a la consola via adb. Torneu a muntar la lectura-escriptura del sistema de fitxers arrel per començar:
sudo mount / -o remount,rw
A continuació instal·leu tots els paquets que calen per recompilar el component que voleu modificar (la aplicació Contactes, per exemple):
sudo apt update
sudo apt build-dep address-book-app
sudo apt install fakeroot
Addicionalment, probablement voleu instal·lar git per obtenir el codi font de la vostra aplicació al dispositiu i després tornar a pujar els vostres canvis al repositori:
sudo apt install git
Un cop hàgiu acabat, podeu recuperar la font d’una app (en el nostre exemple, la llibreta d’adreces) i passar al seu directori:
git clone https://gitlab.com/ubports/core/address-book-app.git
cd address-book-app
Ara ja podeu compilar el paquet:
DEB_BUILD_OPTIONS="parallel=2 debug" dpkg-buildpackage -rfakeroot -b
L’ordre dpkg-buildpackage imprimirà els noms dels paquets generats. Instal·leu aquests paquets amb dpkg:
sudo dpkg -i ../<package>.deb [../<package2>.deb ...]
Noteu, tanmateix, que potser no us cal instal·lar tots els paquets: generalment, podeu saltar-vos tots els paquets els noms dels quals acaben en -doc o dev, atès que no contenen codi usat pel dispositiu.
Passos següents¶
Ara que heu fet canvis amb èxit i els heu provat localment, esteu llestos per a carregar-los a GitHub. Passeu a la pàgina següent per aprendre sobre l’ús de l’IC d’UBports per construir i proporcionar paquets de desenvolupament!