# Aide pour compilation croisée

## Anard

Bonjour,

Je cherche à installer un Raspberry 3B+ sous Gentoo (idéalement en arm64). Les temps de compilation étant probablement très longs sur ce type de matériel, je voudrais utiliser mon installation Gentoo sur PC fixe pour la création de la carte SD (et plus tard pour ses mises à jour).

J'ai beaucoup lu les "Embbeded handbook" et les différents sujets sur la compilation croisée mais je crois qu'il y a beaucoup de concepts que je comprends mal.

Bref j'ai d'abord tenté d'utiliser qemu pour créer ma clé. J'ai extrait l'image stage 3 sur ma carte SD (montée sur /mnt/gentoo), ainsi que le noyau et les firmware nécessaires dans /mnt/gentoo/boot.

J'ai pu ensuite chrooter dans mon /mnt/gentoo et lancer `emerge -auDN @world` avec qemu. Ca a fonctionné pour une bonne partie des paquets mais certains autres refusent de compiler car portage cherche x86_64-pc-linux-gnu-gcc qu'il ne trouve pas (en effet il est censé utiliser aarch64-rpi-linux-gnu-gcc).

Je cherche donc à utiliser une autre méthode en utilisant uniquement crossdev mais je comprends mal la méthode.  J'ai donc créé ma chaîne de compilation sous /usr/aarch64-rpi-linux-gnu

J'aimerais que portage utilise mon PC fixe pour la compilation et qu'il installe de lui même les binaires, fichiers de cconfiguration, docs etc dans /mnt/gentoo/

J'ai essayé de modifier les valeurs de ROOT et PORTAGE_CONFIGROOT avec différentes valeurs pour cela mais n'ai pour le moment obtenu aucun résultat probant.

Je cherche à compiler mon système avec la commande 

```
ARCH=arm64 CROSS_COMPILE="aarch64-rpi-linux-gnu-" emerge -auDN @world
```

 mais les valeurs de ROOT et PORTAGE_CONFIGROOT ne lui conviennent pas si elles ne correspondent pas au même répertoire (ce qui me semblait logique était  ROOT="/mnt/gentoo/" et PORTAGE_CONFIGROOT="/usr/${CHOST}/"

Voici mon make.conf actuel :

http://dpaste.com/HY8RVX78P

Et voici le aarch64-rpi-linux-gnu-emerge --info :

http://dpaste.com/FFE43G8LD

Bref, je crois qu'il y a quelque chose que je ne comprends pas dans le principe même de la compilation croisée...  :Razz: 

Pourriez-vous m'aider à configurer tout cela correctement pour installer un Gentoo ARM64 sur ma carte SD ?

Merci beaucoup.

----------

## netfab

Salut,

 *Anard wrote:*   

> 
> 
> Je cherche à compiler mon système avec la commande 
> 
> ```
> ...

 

Si tu as créé ton environnement de cross-compilation avec crossdev, ce dernier a dû te créer une série de liens symboliques.

Que donne :

```

# ls -l /usr/bin/aarch64-rpi-linux*

```

Dans cette liste de commandes, tu dois avoir un emerge. C'est cette commande qui'il faut utiliser, tu n'as pas a définir des variables d'environnement comme tu le fais.

Je n'ai pas de raspberry, mais à l'époque où je compilais sur mon coreI5 pour un environnement crossdev pour une cubieboard2, voici la commande que j'utilisais pour effectuer les mises à jour :

```

# armv7a-hardfloat-linux-gnueabi-emerge -avuDN --keep-going world

```

Une fois les paquets construits, il ne restait (pratiquement) qu'à les déployer, modulo quelques bugs/bizarreries sur lesquels j'étais tombé à l'époque.

Edit : je n'avais pas vu ta commande aarch64-rpi-linux-gnu-emerge --info.

Que se passe t'il si tu essayes de construire tes paquets avec :

```

# aarch64-rpi-linux-gnu-emerge -avuDN @world

```

Edit 2 : je ne pense pas que la variable ROOT doit être définie dans ton make.conf.

----------

## netfab

Pour être clair, une fois que ton environnement dans /usr/aarch64-rpi-linux-gnu est installé et configuré, tu dois pouvoir construire et installer le paquet app-misc/foo de cette manière :

```

# aarch64-rpi-linux-gnu-emerge -av1 --buildpkg app-misc/foo

```

Une fois cette commande terminée, le paquet a été construit et installé dans /usr/aarch64-rpi-linux-gnu. Un tbz2 a aussi créé et stocké dans ton répertoire de packages.

Après, si tu veux redéployer ce paquet sur ta carte SD (préalablement montée dans /mnt/gentoo) :

```

# ROOT=/mnt/gentoo aarch64-rpi-linux-gnu-emerge -av1k app-misc/foo

```

----------

## Anard

Cool merci beaucoup pour ta réponse. ... mais ça reste encore confus dans ma tête.   :Very Happy: 

Tout d'abord la réponse d'emerge :

https://dpaste.com/ATE9E9UM8

Ca semble bien vouloir se passer hormis la dépendance circulaire dont la résolution est indiquée.

Ceci dit :

Je ne me rappelle plus si j'ai décompressé le stage 3 (ni portage-latest) dans /usr/aarch64-rpi-linux-gnu/. Comment sait-il ce qu'il doit mettre à jour ? Il faudrait donc que je copie le /var/lib/portage/world de la carte SD dans  /usr/aarch64-rpi-linux-gnu/ ? Peut-être quelques autres fichiers...

J'avais cru comprendre l'idée de préparer les paquets sur l'hôte avec --buildpkg (ou --buildpkgonly ?) puis de l'installer sur la carte SD avec --usepkgonly. Mais alors lorsque je mets à jour le système complet, une commande comme la précédente (-auDN @world) ne risque-t-elle pas de détruire mon système hôte ? Où va-t-il installer les paquets ?

Aussi en construisant un paquet seul avec --buildpkg et --usepkg, tu as utilisé --oneshot dans les deux commandes. Dans quelle commande doit-il être supprimé pour ajouter le paquet au world ? Si je ne me suis pas trompé au premier point, je dirais à la compilation côté hôte...   :Confused: 

Dans ces conditions, qu'ai-je besoin sur ma carte SD ? En dehors du /boot où se trouve le noyau, est-ce que je peux supprimer toute la partition / et y décompresser un stage3 neuf sans y décompresser portage-latest ? En fait je ne visualise pas bien ce que contient le stage3  :Smile: 

Finalement, je ne vois pas eselect ou eclean dans /usr/bin/aarch64-rpi-linux*. Comment faire eselect news read, eselect profile set X ou autre pour mon raspberry ?

Je vois bien que je ne comprend pas tout ce que je fais et je crains de détruire mon système par erreur. J'ai donc besoin de bien comprendre dans quelle mesure et dans quelle situation l'environnement de crossdev protège (ou non) mon système hôte.

Merci.

PS : pour le dernier point, je viens d'essayer :

```
# ROOT=/usr/aarch64-rpi-linux-gnu/ eselect news list

News items:

  [1]   N  2016-06-19  L10N USE_EXPAND variable replacing LINGUAS

  [2]   N  2019-05-23  Change of ACCEPT_LICENSE default

  [3]   N  2021-01-30  Python preference to follow PYTHON_TARGETS

  [4]   N  2021-07-20  Perl 5.34 upgrade now stable

  [5]   N  2021-10-18  migrating from glibc[crypt] to libxcrypt in stable

# ROOT=/usr/aarch64-rpi-linux-gnu/ eselect profile list

Available profile symlink targets:

  [1]   default/linux/amd64/17.1 (stable)

  [2]   default/linux/amd64/17.1/selinux (stable)

  [3]   default/linux/amd64/17.1/hardened (stable)

  [4]   default/linux/amd64/17.1/hardened/selinux (stable)

  [5]   default/linux/amd64/17.1/desktop (stable)

[...]

  [37]  default/linux/amd64/17.0/musl/hardened/selinux (exp)

```

Pour la première commande, il travaille bien sur aarch64-... (les news sont toutes lues sur l'hôte)

Mais pour la seconde, il me liste les profils amd64 (hôte). En revanche, aucun n'est sélectionné.

 :Confused: 

----------

## Anard

Bien, pour la seconde commande, ça fonctionne comme ceci :

```
PORTAGE_CONFIGROOT=/usr/aarch64-rpi-linux-gnu/ eselect profile list 
```

Concernant la mise à jour du système entier, je suis en train de tenter un emerge -ukDN @world

Ce qui me semble étrange, c'est que certains paquets ne semblent pas être destinés à ma cible :

```
[ebuild  N     ] dev-libs/re2-0.2021.11.01:0/9::gentoo to /usr/aarch64-rpi-linux-gnu/ USE="icu" 400 KiB

[ebuild   R    ] net-libs/nodejs-14.17.6:0/14::gentoo  USE="icu inspector* npm snapshot ssl system-icu system-ssl -debug -doc -lto -pax-kernel -systemtap -test" CPU_FLAGS_X86="sse2" 0 KiB

[ebuild  N     ] media-libs/audiofile-0.3.6-r4:0/1::gentoo to /usr/aarch64-rpi-linux-gnu/ USE="flac" 0 KiB
```

nodejs n'est pas destiné à /usr/aarch64-rpi-linux-gnu comme ses copains...   :Confused: 

----------

## netfab

 *Quote:*   

> 
> 
> Je ne me rappelle plus si j'ai décompressé le stage 3 (ni portage-latest) dans /usr/aarch64-rpi-linux-gnu/.
> 
> 

 

Je pense que tout ce qui est dans /usr/arch64-rpi-linux-gnu a été créé/installé par crossdev.

 *Quote:*   

> 
> 
> Comment sait-il ce qu'il doit mettre à jour ?
> 
> 

 

Comme n'importe quel autre système gentoo, aarch64-rpi-linux-gnu-emerge utilise les repertoires suivants :

 - /usr/arch64-rpi-linux-gnu/etc/portage

 - /usr/arch64-rpi-linux-gnu/var/db/pkg

 - /usr/arch64-rpi-linux-gnu/var/lib/portage

 *Quote:*   

> 
> 
> Il faudrait donc que je copie le /var/lib/portage/world de la carte SD dans /usr/aarch64-rpi-linux-gnu/ ? Peut-être quelques autres fichiers...
> 
> 

 

C'est ce que je faisais à l'époque : je dupliquais la configuration entre la carte SD et l'environnement de cross-compilation.

Je compilais sur le système hôte, et je déployais ensuite les paquets sur la carte SD.

 *Quote:*   

> 
> 
> Mais alors lorsque je mets à jour le système complet, une commande comme la précédente (-auDN @world) ne risque-t-elle pas de détruire mon système hôte ? Où va-t-il installer les paquets ? 
> 
> 

 

Si tu utilises emerge, tu mets à jour ton sytème hôte.

Si tu utilises aarch64-rpi-linux-gnu-emerge, tu mets à jour ton environnement /usr/arch64-rpi-linux-gnu.

 *Quote:*   

> 
> 
> Aussi en construisant un paquet seul avec --buildpkg et --usepkg, tu as utilisé --oneshot dans les deux commandes. Dans quelle commande doit-il être supprimé pour ajouter le paquet au world ?
> 
> 

 

Cela dépend de quel world tu parles.

Si tu veux l'ajouter à /usr/aarch64-rpi-linux-gnu/var/lib/portage/world, la première commande.

Sinon, la deuxième pour le world de la carte SD.

 *Quote:*   

> 
> 
> En dehors du /boot où se trouve le noyau, est-ce que je peux supprimer toute la partition / et y décompresser un stage3 neuf sans y décompresser portage-latest ?
> 
> 

 

Oui, tu peux. En ce qui concerne l'arbre portage, tant que tu es dans la phase de création de la carte SD, tu peux utiliser le même arbre que le système hôte.

Après, une fois que ton système sur la carte SD sera autonome, et que tu auras booté sur ton Raspberry, tu n'es pas obligé d'y décompresser un arbre : si tu es sur le même réseau, tu peux monter ton arbre par NFS depuis ton système hôte, et utiliser emerge sur ton rasp pour installer les paquets précompilés.

La commande suivante : 

```

# ROOT=/mnt/gentoo aarch64-rpi-linux-gnu-emerge -av1k app-misc/foo

```

Je ne l'utilisais que pendant la phase de création de la carte SD, la phase d'installation de gentoo.

Une fois que le système était autonome, je me connectais par SSH sur le cubieboard2 pour monter l'arbre portage par NFS, et déployer les paquets précompilés avec la commande emerge habituelle.

Étant donné que les configurations (etc/portage, world, ...) de la carte SD et du système de cross-compilation étaient les mêmes, emerge -k sur le cubieboard2 retrouvait les paquets précompilés par le système hôte.

Tu dois cependant savoir que certains paquets (dev-lang/perl par exemple) ne sont pas cross-compilables. Tu seras obligé de le compiler sur le RASP.

Il me semble que j'avais configuré distcc des 2 côtés, de façon à ce que le cubieboard2 fasse appel au système hôte pour l'aider à compiler.

 *Quote:*   

> 
> 
> Ce qui me semble étrange, c'est que certains paquets ne semblent pas être destinés à ma cible
> 
> 

 

Pour éviter ce genre de bizarreries, je me souviens que je mettais toujours à jour mon système hôte avant de mettre à jour l'environnement de cross-compilation. Quelle était la commande ?

----------

## Anard

Merci pour ces réponses instructives.

J'ai essayé de lancer la mise à jour globale du stage3 après avoir copié depuis mon hôte mon /var/lib/portage/world vers /usr/aarch64-rpi-linux-gnu/var/lib/portage/world. Puis effectué quelques modifs pour l'adapter (certains paquets ne me seront pas utiles sur raspberry et certains sont indisponibles sous arm64).

Bref, l'upgrade s'est arrêté sur une erreur de compilation de sqlite :

```
imack /usr/aarch64-rpi-linux-gnu # aarch64-rpi-linux-gnu-emerge -avbuDN @world

[...]

/usr/libexec/gcc/aarch64-rpi-linux-gnu/ld: /usr/aarch64-rpi-linux-gnu/usr/lib/../lib64/libicuuc.so: undefined reference to `__once_proxy@GLIBCXX_3.4.11'

/usr/libexec/gcc/aarch64-rpi-linux-gnu/ld: /usr/aarch64-rpi-linux-gnu/usr/lib/../lib64/libicui18n.so: undefined reference to `__gxx_personality_v0@CXXABI_1.3'

/usr/libexec/gcc/aarch64-rpi-linux-gnu/ld: /usr/aarch64-rpi-linux-gnu/usr/lib/../lib64/libicui18n.so: undefined reference to `operator delete(void*, unsigned long)@CXXABI_1.3.9'

collect2: error: ld returned 1 exit status

make: *** [Makefile:666: sqlite3] Error 1

 * ERROR: dev-db/sqlite-3.35.5::gentoo failed (compile phase):

 *   emake failed

[...]

```

Il semble en fait rencontrer de nombreux soucis avec les fichiers en .so sans forcément s'arrêter de compiler. La compilation de plusieurs paquets se termine par ce genre de message :

```
strip: aarch64-rpi-linux-gnu-strip --strip-unneeded -N __gentoo_check_ldflags__ -R .comment -R .GCC.command.line -R .note.gnu.gold-version

   /usr/lib64/libasyncns.so.0.3.1

 * QA Notice: Unresolved soname dependencies:

 * 

 *    /usr/lib64/libasyncns.so.0.3.1: ld-linux-aarch64.so.1 libc.so.6 libpthread.so.0 libresolv.so.2

 * 

```

Une centaine de paquets avaient quand même été compilés, j'ai donc voulu tenter de les installer sur la carte SD (désormais montéee sur /mnt/raspi ce qui est plus parlant) :

```
imack /usr/aarch64-rpi-linux-gnu # ROOT=/mnt/raspi aarch64-rpi-linux-gnu-emerge -aukDN @world

!!! Error: SYSROOT (currently /usr/aarch64-rpi-linux-gnu/) must equal / or ROOT (currently /mnt/raspi/).

Traceback (most recent call last):

  File "/usr/lib/python-exec/python3.9/emerge", line 51, in <module>

    retval = emerge_main()

  File "/usr/lib/python3.9/site-packages/_emerge/main.py", line 1277, in emerge_main

    emerge_config = load_emerge_config(action=myaction, args=myfiles, opts=myopts)

  File "/usr/lib/python3.9/site-packages/portage/proxy/objectproxy.py", line 31, in __call__

    return result(*args, **kwargs)

  File "/usr/lib/python3.9/site-packages/_emerge/actions.py", line 2876, in load_emerge_config

    emerge_config.trees = portage.create_trees(trees=emerge_config.trees, **kwargs)

  File "/usr/lib/python3.9/site-packages/portage/__init__.py", line 655, in create_trees

    settings = config(

  File "/usr/lib/python3.9/site-packages/portage/package/ebuild/config.py", line 471, in __init__

    locations_manager.set_root_override(make_conf.get("ROOT"))

  File "/usr/lib/python3.9/site-packages/portage/package/ebuild/_config/LocationsManager.py", line 401, in set_root_override

    raise InvalidLocation(self.sysroot)

portage.exception.InvalidLocation: /usr/aarch64-rpi-linux-gnu/

```

Ca ne lui plait pas vraiment...

----------

