# [Documentation] Dissection de portage

## scout

Le but de ce cette documentation est d'expliquer ce qui se passe chronologiquement lors d'un emerge, en particulier pour que ceux qui feront leur premiers ebuild comprennent bien le phénomène de sandbox. Ils pourront être renvoyés vers cette documentation. Mon but n'est pas d'expliquer tous les réglages possibles, mais de faire comprendre sur un exemple comment le tout s'articule.

Les principaux fichiers de configuration

/etc

/etc/make.globals les valeurs par défaut des paramètres de portage

/etc/make.conf la configuration principale utilisée par portage, les paramètres supplantent ceux de make.globals lorsqu'ils sont réglés

/etc/portage répertoire où l'ont met les fichiers package.keywords package.use package.mask package.unmask qui modifient le calcul des dépendances et les versions des paquets installés par emerge.

/usr/portage répertoire où se trouvent tous les ebuilds, chacun dans un répertoire de catégorie

on y trouve aussi:

/usr/portage/distfiles là où sont les archives contenant les sources des programmes que l'on a emergé, ou tenté d'emerger

/usr/portage/profile et en particulier /usr/portage/profile/package.mask qui contient la liste des paquets masqués par défaut et /usr/portage/profile/{architecture}/virtuals expliqué plus loin

/usr/portage/packages qui contient les paquets binaires .tbz2 crées grâce à quickpkg, lors d'un emerge -b ou lors d'un emerge d'un paquet important si on a le paramètre buildsyspkg dans FEATURES (que je conseille de mettre (merci à TGL pour cette fonctionalité  :Smile:  ) )

/var

/var/cache/edb/

/var/cache/edb/world le fichier world (/var/lib/portage/world à partir de portage-2.0.51)

/var/cache/edb/virtuals le fichier virtuals (n'existe plus à partir de portage-2.0.51)

Le fichier virtuals sert au calcul des dépendances. Par exemple fluxbox qui a besoin d'un serveur X peut se contenter de Xorg ou de Xfree indiféremment, il y a ainsi dans l'ebuild de fluxbox une dépendance sur virtual/x11. Si une ligne "virtual/x11 x11-base/xorg-x11" est présente dans le fichier virtuals, alors la dépendance est bien présente. cette ligne est rajoutée au fichier virtuals lors de emerge xorg-x11 car l'ebuild de xorg-x11 contient une ligne PROVIDE="virtual/x11". Enfin si on essaye d'emerger fluxbox sans avoir emergé un serveur X au préalable, aucune ligne virtual/x11 n'est présente dans le fichier virtuals et emerge décider d'installer un paquet qui "fournit" virtual/x11, et il choisit ce paquet grâce au fichier /usr/portage/profile/{architecture}/virtuals qui contient les paquets à installer par défaut

Si emerge -upD world a tout le temps envie de vous réinstaller des sources de noyau dont vous ne voulez plus c'est qu'il faut nettoyer à la main ce fichier ...

/var/db/pkg contient toutes les informations sur les paquets installés sur votre système, en particulier l'ebuild, les USE et les CFLAGS au moment de l'installation, le fichier CONTENTS qui contient la liste des fichiers installés par le paquet, et encore d'autres infos. La plupart des autres fichiers de conf peuvent être reconstruit si on les perd ou casse, mais pas ce répertoire.

Le fichier ebuild

Lors de "emerge fluxbox" emerge choisit par exemple d'utiliser /usr/portage/x11-wm/fluxbox/fluxbox-0.9.9.ebuild

voilà /usr/portage/x11-wm/fluxbox/fluxbox-0.9.9.ebuild pour référence:

```
# Copyright 1999-2004 Gentoo Foundation

# Distributed under the terms of the GNU General Public License v2

# $Header: /var/cvsroot/gentoo-x86/x11-wm/fluxbox/fluxbox-0.9.9.ebuild,v 1.16 2004/09/16 02:29:12 pvdabeel Exp $

inherit eutils

IUSE="nls xinerama truetype kde gnome"

DESCRIPTION="Fluxbox is a lightweight windowmanager for X featuring tabs."

SRC_URI="mirror://sourceforge/fluxbox/${P}.tar.gz"

HOMEPAGE="http://www.fluxbox.org"

# Please note that USE="kde gnome" simply adds support for

# the respective protocols, and does not depend on external libraries.

RDEPEND="virtual/x11

        truetype? ( media-libs/freetype )

        nls? ( sys-devel/gettext )"

DEPEND=">=sys-devel/autoconf-2.52

                ${RDEPEND}"

PROVIDE="virtual/blackbox"

SLOT="0"

LICENSE="MIT"

KEYWORDS="x86 ppc sparc amd64 alpha hppa ~ia64 mips ppc64 macos ppc-macos"

src_unpack() {

        unpack ${A}

        cd ${S}

        # upstream tell us we probably want to apply this if there's any chance

        # anyone will ever try to compile using gcc 3.4.

        epatch ${FILESDIR}/${PN}-0.9.9-gcc3.4.patch

}

src_compile() {

        export PKG_CONFIG_PATH=/usr/X11R6/lib/pkgconfig:/usr/lib/pkgconfig

        econf \

                `use_enable nls` \

                `use_enable xinerama` \

                `use_enable truetype xft` \

                `use_enable kde` \

                `use_enable gnome` \

                --sysconfdir=/etc/X11/${PN} \

                ${myconf} || die "configure failed"

        emake || die "make failed"

}

src_install() {

        dodir /usr/share/fluxbox

        make DESTDIR=${D} install || die "make install failed"

        dodoc README* AUTHORS TODO* COPYING

        dodir /usr/share/xsessions

        insinto /usr/share/xsessions

        doins ${FILESDIR}/${PN}.desktop

        dodir /etc/X11/Sessions

        echo "/usr/bin/startfluxbox" > ${D}/etc/X11/Sessions/fluxbox

        fperms a+x /etc/X11/Sessions/fluxbox

}
```

Si vous voulez une vraie référence sur les ebuilds allez voir man 5 ebuild

Un ebuild c'est:

3 lignes de commentaires génrées automatiquement lorsqu'un developpeur uploade un paquet

inherit quelquechose pour charger des fonctionnalités en plus dans l'ebuild. Les plus courants et utiles sont:

eutils petits outils dont epatch

flag-o-matic pour enlever/changer des CFLAGS

cvs pour télécharger les sources d'une cvs

kde pour compiler quelquechose pour kde

gnome2 pour compiler quelquechose pour gnome2

    ces eclass sont des scripts situés dans /usr/portage/eclass

des affectations de variables en particulier

IUSE liste des drapeaux USE utilisés par l'ebuild

SRC_URI pour récupérer les sources (sauf pour le cvs)

DEPEND: la liste des dépendances

SLOT pour savoir si plusieurs paquets peuvent cohabiter avec des versions différentes. par défaut SLOT="0" pour signaler qu'une seule version du paquet doit être installée à un instant T. un exemple très riche est gcc:

(je rappelle que etcat fait partie du paquet gentoolkit)

```
p4 sys-apps # etcat -v gcc

[ Results for search key           : gcc ]

[ Candidate applications found : 24 ]

 Only printing found installed programs.

*  sys-devel/gcc :

        [M I] 2.95.3-r8 (2.95)

        [M  ] 3.1.1-r2 (3.1)

        [   ] 3.2.3-r4 (3.2)

        [M  ] 3.3 (3.2)

        [M~ ] 3.3.1-r5 (3.2)

        [M  ] 3.3.2 (3.2)

        [M~ ] 3.3.2-r1 (3.2)

        [M~ ] 3.3.2-r2 (3.2)

        [M~ ] 3.3.2-r3 (3.2)

        [M~ ] 3.3.2-r4 (3.2)

        [   ] 3.3.2-r5 (3.2)

        [M~ ] 3.3.2-r7 (3.2)

        [M  ] 3.3.3_pre20040408-r1 (3.2)

        [M  ] 3.3.3_pre20040426 (3.2)

        [M~ ] 3.3.3 (3.2)

        [M~ ] 3.3.3-r3 (3.2)

        [M~ ] 3.3.3-r5 (3.2)

        [   ] 3.3.3-r6 (3.2)

        [  I] 3.3.4-r1 (3.2)

        [M~ ] 3.3.4-r2 (3.2)

        [M~ ] 3.4.1 (3.4)

        [M~ ] 3.4.1-r2 (3.4)

        [M~ ] 3.4.1-r3 (3.4)

        [M~ ] 3.4.2-r1 (3.4)
```

Le slot présent dans l'ebuild est ici affiché entre parenthèses. On voit que j'ai en même temps gcc-2.95.3-r8 et gcc-3.3.4-r1 d'installés, ce qui n'est possible que car ils sont dans des slots différents. Après il y a gcc-config pour changer d'un compilateur à l'autre ... gimp est un autre exemple, mais là il n'y a pas de gimp-config  :Smile:  et la distinction se fait en appelant l'exécutable par gimp-1.2 ou gimp-2.0

KEYWORDS pour signaler si le paquet est stable ou en test (avec un ~ )       

d'autres qui sont nécéssaires, mais mieux expliquées ailleurs, comme par exemple dans le Ebuild Howto

des fonctions telles src_compile() ou src_install() qui on déjà des valeurs par défaut si on ne spécifie rien dans l'ebuild. un ebuild peut ainsi ne pas contenir de src_compile() si jamais la procédure par défaut spécifiée par portage marche bien.

Ce que emerge fait

lors d'un emerge fluxbox (par exemple ...)

quel fichier ebuild utiliser ? on prend l'ebuild qui convient le mieux: l'ebuild ayant le numéro de version le plus élevé, non masqué et avec le bon keyword, et dans les overlay si il y a ambiguité

/usr/portage/x11-wm/fluxbox/fluxbox-0.9.9.ebuild est choisi

quelles sont les dépendances ? là emerge regarde les variables DEPEND pour les dépendances nécéssaires à la compilation et RDEPEND pour les dépendances nécéssaires à l'exécution de fluxbox (les Runtime dependancies)

```
RDEPEND="virtual/x11

        truetype? ( media-libs/freetype )

        nls? ( sys-devel/gettext )"

DEPEND=">=sys-devel/autoconf-2.52

                ${RDEPEND}"
```

donc il nous faut autoconf, un serveur X, et si USE (de make.conf) contient truetype, alors il faut freetype, si USE contient nls, il faut gettext

On verra plus loin que USE n'influence pas que les dépendances

on installe les dépendances si ce n'est pas déja fait

à cet instant on est prêt à installer fluxbox-0.9.9, et emerge fait comme si on exécutait la commande

```
ebuild /usr/portage/x11-wm/fluxbox/fluxbox-0.9.9.ebuild merge
```

(en gros, car en réalité ce n'est que l'étape principale du processus: par exemple le ebuild blabla merge ne nettoie pas les fichiers objets intermédiaires tout seul il faut faire un ebuild blabla clean, contrairement à emerge qui lui nettoie si on lui laisse son comportement par défaut)

lors de cette commande, la partie de compilation des sources, si elle a le droit de lire presque partout, est restreinte en écriture au répertoire /var/tmp/portage/fluxbox-0.9.9/ (en gros, car plus précisément il y a d'autres répertoires authorisés en écriture, d'autres où l'on fait croire que l'on a le droit d'écrire, etc ... je vous conseille d'emerger sandboxshell pour être plus familier avec ces concepts)

 *man 1 ebuild wrote:*   

> merge  Normally, to merge an ebuild, you need to fetch, unpack, compile, install and qmerge.

 

clean emerge nettoie les anciens essais de compilation: il vide le répertoire /var/tmp/portage/fluxbox-0.9.9/work/fluxbox-0.9.9

fetch récupération des fichiers listés dans SRC_URI pour les mettre dans /usr/portage/distfiles

setup execute la fonction pkg_setup() si elle est présente dans l'ebuild (c'est rare)

unpack décompression des fichiers dans ${WORKDIR} c'est à dire /var/tmp/portage/fluxbox-0.9.9/work

ou execution de la fonction src_unpack() de l'ebuild, typiquement elle est définie lorsqu'il faut appliquer des patchs (voir l'exemple plus haut)

compile execute la fonction src_compile() de l'ebuild.

Au début de cette fonction, on est dans ${S} c'est à dire /var/tmp/portage/fluxbox-0.9.9/work/fluxbox-0.9.9 et on effecture un ./configure puis un make à ceci près qu'il vaut mieux utiliser econf et emake, qui sont des fonctions définies par portage. En effet econf est un configure auquel on a rajouté des options pour changer les répertoires d'installation de manière à ce qu'ils correspondent à ceux définis par gentoo et emake c'est make avec les options de MAKEOPTS (défini dans make.conf)

ici intervienent pour la deuxième fois les drapeaux USE puisqu'ils conditionnent le econf. ainsi un `use_enable kde` est remplacé par un --enable-kde si kde est dans les USE, et par --disable-kde sinon.

install par défaut on effectue un make DESTDIR=${D} install (ici ${D}=/var/tmp/portage/fluxbox-0.9.9/image/ ) qui a pour effet de copier les fichiers compilés dans ${S} vers ${D} comme si ${D} était /

Je m'explique: grace à l'affectation de DESTDIR, le fichier /var/tmp/portage/fluxbox-0.9.9/work/fluxbox-0.9.9/src/fluxbox, crée lors de emake, sera copié vers /var/tmp/portage/fluxbox-0.9.9/image/usr/bin/fluxbox, lors du make DESTDIR=${D} install

en effet, un simple make install échouerait car /usr/bin n'est pas en écriture à ce moment précis. il est donc nécéssaire de patcher les programmes qui ne reconnaissent pas la variable DESTDIR pour leur faire installer les fichier quand même au bon endroit, c'est à dire dans la sandbox (par exemple  l'ebuild pour darksnow de Corto et moi)

preinst execute la fonction pkg_preinst() si elle est présente dans l'ebuild (c'est rare)

qmerge c'est lors de cette étape que les fichiers sont recopiés de ${D} vers / mais ils ne sont pas recopiés bêtement: le md5 de chaque fichier est calculé et enregistré avec son chemin final et sa date dans le fichier /var/db/pkg/${CATEOGRY}/${PN}-[version-rev]/CONTENTS c'est à dire /var/db/pkg/x11-wm/fluxbox-0.9.9/CONTENTS

ces données sont utilisées lors de emerge unmerge

petit traitement spécial pour les fichiers qui atterissent dans un répertoire protégé tel /etc (paramètre CONFIG_PROTECT, présent dans make.globals).

postinst execute la fonction pkg_postinst() si elle est présente dans l'ebuild - c'est très souvent ici que des messages sont affochés à la fin de l'installation. On utilise einfo pour afficher ces petits messages

clean on vide le répertoire /var/tmp/portage/fluxbox-0.9.9

on rajoute "catégorie/paquet" au fichier world (et éventuellement au virtuals si ce paquet a une variable PROVIDE)

emerge unmerge

emerge unmerge lit ce fichier CONTENTS et supprime les fichier qui y sont répertoriés lorsque leur dates et leur md5 correspondent à celui donné dans la liste, et le laisse sinon; et un "emerge -u" revient à emerger la nouvelle version puis à unmerger l'ancienne.

il execute les fonctions pkg_prerm pkg_postrm de l'ebuild si elles sont présentes. Vous remarquerez que le vieil ebuild est gardé dans /var/db/pkg/x11-wm/fluxbox-0.9.9/fluxbox-0.9.9.ebuild

C'est pourquoi etcat -v n'affiche pas toujours toutes les versions des paquets installés sur votre système, etcat -v n'affiche que les versions des paquets installés sur votre système et disposant d'un ebuild présent dans /usr/portage, or les vieux fichiers ebuild sont enlevés de /usr/portage périodiquement.

Ainsi les binaires installés par la nouvelle version du paquet ne sont pas désinstallés par le emerge unmerge de l'ancienne version du paquet.

C'est pas beau portage ?   :Very Happy: 

(merci à sireyessire pour la relecture)

Ce document est sous licence FDL

----------

## sireyessire

cool, merci scout.

Petit rajout, le fichier /var/cache/edb/world va être déplacé vers /var/lib/portage

et le /var/cache/edb/virtuals sera supprimé (car recalculé en live) dans le portage version 2.0.51 

 *changelog wrote:*   

> MAJOR CHANGES in 2.0.51:
> 
>     1. /var/cache/edb/virtuals is no longer used at all. It's calculated now.
> 
>     2. /var/cache/edb/world is now /var/lib/portage/world.
> ...

 

----------

## scout

Wow, je savais pas .... je met à jour le howto

----------

## zdra

WAW ! j'en ai la larme à l'oeuille !! c'est si beau !! B R A V O !!!   :Very Happy: 

----------

## gulivert

Trop bon cette doc, merci pour ton grand travail.   :Wink: 

----------

## kernelsensei

SUPERR !! Merci pour cette belle doc !!

----------

## ghoti

Oui, il était utile d'avoir une si belle synthèse !  :Smile: 

Mais quand tu parlais de "disséquer", j'ai cru que tu comptais faire une traduction de l'article "My poor Portage deconstruction"  :Laughing: 

----------

## scout

 *ghoti wrote:*   

> Mais quand tu parlais de "disséquer", j'ai cru que tu comptais faire une traduction de l'article "My poor Portage deconstruction" 

 

J'ai regardé ton lien et j'ai compris pourquoi t'avais peur  :Very Happy: 

[EDIT] en fait j'avais hésité pour le titre à mettre quelquechose du genre "[portage] documentation sur son fonctionnement", dites moi si c'est plus pertinent

[EDIT2] j'ai enlevé quelques fautes de frappe et les "pipo" qui restaient (en fait j'avais fait un ebuild "pipo" pour tester mes dires  :Wink:  )

[EDIT3] y'a encore d'autres trucs à corriger, où les phrases sont pas bien françaises  :Very Happy:  je ferais ça bientôt

----------

## jpwalker

Pour ma part, le titre me convient. Et un grand merci à toi, cette doc est très bien faite et très compréhensible, bravo (ça manquait)   :Wink: 

----------

## sireyessire

 *scout wrote:*   

> 
> 
> [EDIT3] y'a encore d'autres trucs à corriger, où les phrases sont pas bien françaises  je ferais ça bientôt

 

et après tu te permets de criiquer mes changements de langue intempestifs  :Twisted Evil:  ....  :Mr. Green: 

----------

## Longfield

vraiment très très instructif ... merci beaucoup pour cette doc !!!!

ça fait plaisir de voir comment ça tourne derrière ...

----------

## jpwalker

Salut,

J'aimerais créer un instantané de portage à partir de mon installation (pour un ami n'ayant pas encore le net). Si j'ai bien compris, il suffit que je copie

```
/usr/portage

/etc/portage

/var/cache/edb

/var/db/pkg
```

et que je les recopies au même endroit ?? Y a t il une commande permettant de créer se genre de choses automatiquement ?

Merci

----------

## LoganX02

Bravo, enfin quelque chose de clair sur le fonctionnement de portage  :Very Happy: 

----------

## scout

 *jpwalker wrote:*   

> J'aimerais créer un instantané de portage à partir de mon installation (pour un ami n'ayant pas encore le net). Si j'ai bien compris, il suffit que je copie
> 
> ```
> /usr/portage
> 
> ...

 

Je ne connais pas de commande faisant ceci automatiquement et ce n'est pas forcément la peine de copier /usr/portage puisqu'il est en grande partie reconstitué par un emere sync. mais bon si tu le copies t'es sur que ça marche  :Wink: 

----------

## Pachacamac

Merci beaucoup scout. Belle doc.

Mais heu c'est quoi portage ?? lol

----------

## jpwalker

 *scout wrote:*   

>  *jpwalker wrote:*   J'aimerais créer un instantané de portage à partir de mon installation (pour un ami n'ayant pas encore le net). Si j'ai bien compris, il suffit que je copie
> 
> ```
> /usr/portage
> 
> ...

 

Merci  :Wink: 

 *Pachacamac wrote:*   

> Merci beaucoup scout. Belle doc.
> 
> Mais heu c'est quoi portage ?? lol

 

Mdr  :Laughing: 

----------

## dyurne

juste une petite question qui m'intrigue a propos du emerge unmerge.

exemple :

récemment la nouvelle version de xfce (4.2 ) est sortie j'ai lancé mon emerge -u world sous xfce (4.0) et tout s'est très bien déroulé. 

il a installé la 4.2 et désinstallé la 4.0 alors que j'étais en train de l'utiliser.

après l'installation je coupe mon serveur x puis je le redemarre et je me retrouve bien avec xfce4.2.

ma question est donc la suivante comment fait il pour supprimer xfce4.0 alors que je suis en train de m'en servir ?

----------

## zdra

ah mon avis ça tient de la puissance de unix: un fichier n'est supprimé que si il n'a plus de nom (/usr/...) ET si il n'est plus utilisé par aucun processus. Evidement si il n'a plus de nom, les processus ne peuvent plus l'ouvrir et donc le fichier sera réellement supprimé dès que tt les processus ayant fait un open() sur le fichier passent par le close().

Donc (à mon avis, je suis pas sur) portage supprime tt les fichiers mais ils restent utilisable par xfce car ils sont encore ouvert et donc pas réellement supprimé. La nouvelle version de xfce remplace donc les nom des anciens fichiers, mais pas les inodes ! et donc apres un relancement de xfce, il va relacher tt les fichiers et ils seront réellement supprimé, puis au redémarage il va réouvrir les nouveau nom et donc charger la nouvelle version de tout les programmes.

----------

## kwenspc

@zdra : c'est bien compliqué tout ça.

moi je pense juste que comme xfce était déjà chargé en mémoire, il n'avait plus besoin d'utiliser les fichiers sur le dur le concernant puisque il était complètement en mémoire. Du coup tu sors, le process xfce4.0 est detruit. tu recharges et là à la place d'xfce 4.0 c'est l'éxecutable d'xfce 4.2...et voilà.

non?

bon j'imagine qu'un gourou du noyau pourrait mieux nous expliquer cela, mais je trouve mon explication plus logique. (enfin en même temps c'est ma logique hien...donc qui peut s'avérer TRES foireuse)

----------

## zdra

Les deux sont liés, c'est encore en mémoire parce que le fichier existe encore. lorsque tu fais un read() sur un fichier à priori il n'y a que le kenrel qui sait si il va devoir chercher les info en mémoire cache, en buffer, ou sur disque... et le kernel gere en permanence pour optimiser l'utilisation de la mémoire.

----------

## kwenspc

AAAAH ok je vois maintenant pourquoi tu parlais d'inode, mais c'est l'inverse : le fichier existe encore parcqu'il est encore chargé en mémoire (enfin dans le cas où ce dernier aurait été supprimé du disque, il n'apparait plus sur le système de fichier mais sa correspondance inode "match" toujours parce qu'il existe encore en mémoire quelque part,ram ou swap.) du coup il est toujours utilisable tant que le progrmame qui l'utilise ne s'est pas arreté.

c'est un peu comme si tu ouvrais un fichier avec un éditeur (donc il est chargé en mémoire), genre SciTE, tu supprime à la mano le fichier du disque (donc il existe plus sur le système de fichier) dès lors il semble qu'il ai disparu mais pourtant il est toujours là dans l'editeur. bon c'ets un peu tiré par les cheuveux mais c'est ce qui ce passe en gros avec l'exemple du xfce 4.0 à xfce 4.2.  non?

----------

## zdra

non le fichier existe encore sur disque aussi (il me semble) !! Un teste, prend un divX de 640Mo (impossible qu'il rentre en mémoire) tu l'ouvre avec mplayer et pendant la lecture tu faire:

rm divx.avi

echo "nouveau fichier" > divx.avi

cat divx.avi

tu verras que le divX continura a etre lu jusqu'au bout se le moindre probleme ! puisque le fichier ne sera réellement supprimé que quand mplayer fera un close() du fichier. Et malgré que le divx existe encore meme sur disque, si tu crée un nouveau fichier du meme nom c'est comme si c'était un autre fichier... parce que c'est un autre inode !

----------

## kwenspc

ok je comprends mieux avec cet exemple   :Smile: 

----------

## mic006fr

Quelqu'un avait d'ailleurs donné un exemple de script sur ce forum, qui créait un fichier, lancait un thread qui remplissait ce fichier (avec du random, des 0, peu importe), puis supprimait le fichier.

Le fichier n'existait donc plus en apparence, pas moyen de le trouver avec du (diskusage) par exemple et de le supprimer (il l'est déjà), mais le disque était plein, car le thread maintenait le fichier ouvert et continuait de le remplir...

Si quelqu'un se souvient et peut donner le lien...

----------

## zdra

```

dd if=/dev/random of=file &

rm file

```

par exemple  :Wink: 

----------

## dyurne

merci jeunes gens, vous avez répondu a ma question.

----------

