Vous cherchez une commande «cmake clean» pour effacer la sortie CMake


419

Tout comme make cleansupprime tous les fichiers produits par un makefile, je voudrais faire de même avec CMake. Trop souvent, je me retrouve à parcourir manuellement des répertoires supprimant des fichiers comme cmake_install.cmakeet CMakeCache.txt, et les CMakeFilesdossiers.

Existe-t-il une commande comme cmake cleansupprimer automatiquement tous ces fichiers? Idéalement, cela devrait suivre la structure récursive définie dans le CMakeLists.txtfichier du répertoire courant .

Réponses:


487

Il n'y en a pas cmake clean.

Je construis généralement le projet dans un dossier unique comme "build". Donc, si je le veux make clean, je peux juste rm -rf build.

Le dossier "build" dans le même répertoire que la racine "CMakeLists.txt" est généralement un bon choix. Pour construire votre projet, vous donnez simplement à cmake l'emplacement du CMakeLists.txt comme argument. Par exemple: cd <location-of-cmakelists>/build && cmake ... (De @ComicSansMS)


101
C'est ce qu'on appelle la «construction hors source» et devrait être la voie à suivre préférée. Cela évite les conflits de noms et autres
arne

17
+1 pour les versions hors source. Cela devient vital lors de la construction de plusieurs architectures. Par exemple, vous ne pouvez pas créer à la fois des binaires 64 bits et 32 ​​bits avec une génération en source, car cela nécessite deux hiérarchies de cache CMake distinctes.
ComicSansMS

9
Vous pouvez placer le dossier où vous le souhaitez, mais un dossier de génération dans le même répertoire que le CMakeLists.txt racine est généralement un bon choix. Pour construire, donnez simplement à cmake l'emplacement du CMakeLists.txt comme argument. Par exemple:cd <location-of-cmakelists>/build && cmake ..
ComicSansMS

64
Il devrait vraiment y avoir un nettoyage net. Tous ceux qui ont déjà utilisé cmake, même s'ils ont l'habitude de faire des builds en dehors de la source, ont accidentellement exécuté cmake dans le mauvais répertoire et il est très difficile de nettoyer manuellement.
pavon

24
@DevSolar Mais l'inverse n'est pas vrai; ce n'est pas parce qu'un fichier n'est pas sous contrôle de version qu'il est généré par cmake et qu'il est sûr de le supprimer. Choisir quels fichiers non versionnés sont en cours de travail que vous devez conserver et lesquels sont cmake cruft est une douleur, surtout lorsque la plupart des fichiers cmake sont des copies / de même nom pour vos fichiers.
pavon

84

La FAQ officielle de CMake indique:

Certaines arborescences de build créées avec les autotools GNU ont une cible "make distclean" qui nettoie la build et supprime également les Makefiles et d'autres parties du système de build généré. CMake ne génère pas de cible "make distclean" car les fichiers CMakeLists.txt peuvent exécuter des scripts et des commandes arbitraires; CMake n'a aucun moyen de suivre exactement quels fichiers sont générés dans le cadre de l'exécution de CMake. Fournir une cible distclean donnerait aux utilisateurs la fausse impression que cela fonctionnerait comme prévu. (CMake génère une cible "make clean" pour supprimer les fichiers générés par le compilateur et l'éditeur de liens.)

Une cible "make distclean" n'est nécessaire que si l'utilisateur effectue une génération en source. CMake prend en charge les builds in-source, mais nous encourageons fortement les utilisateurs à adopter la notion de build out-of-source. L'utilisation d'une arborescence de génération distincte de l'arborescence source empêchera CMake de générer des fichiers dans l'arborescence source. Parce que CMake ne modifie pas l'arborescence source, il n'est pas nécessaire d'avoir une cible distclean. On peut démarrer une nouvelle construction en supprimant l'arborescence de construction ou en créant une arborescence de construction distincte.


A l'origine, tel qu'introduit et utilisé par les autotools GNU, la cible 'distclean' est destinée à préparer l'arborescence source pour tarer et créer une distribution tar. Un tel fichier tar peut être téléchargé et décompressé par les utilisateurs, puis exécuter 'configure' et 'make' sans avoir besoin des outils automatiques (aclocal, automake, autoconf, etc.). source qui peut être construite sans avoir installé cmake. Cependant, cela ne fonctionne pas lorsque le générateur était un générateur à cible unique (comme la cible 'make'), car la configuration avec cmake se produit pendant
Carlo Wood

... en cours d'exécution cmake. Faire une distribution qui ne peut pas être configurée, ne fait même pas de tests de plate-forme, etc., est inutile. Par conséquent, il n'existe pas de cible «distclean» pour cmake. cmake doit exister sur la machine de l'utilisateur final.
Carlo Wood

63

En ces jours de Git partout, vous pouvez oublier CMake et son utilisation git clean -d -f -x, qui supprimera tous les fichiers qui ne sont pas sous contrôle de source.


14
Cette -xoption cependant. C'est une excellente astuce du gitmétier. Bien que personnellement je fais encore un fonctionnement à sec d' abord, git clean -d -f -x -n. De temps en temps, je garde un fichier de commodité que j'utilise pour un projet avec le dossier du projet sous gitcontrôle, mais ce n'est pas quelque chose que je veux partager avec d'autres, donc je ne le fais pas git addpour le projet. Cela ferait sauter ce type de fichier si je ne faisais pas attention à ajouter une -e <pattern>option. Sur cette note, ce serait bien d' gitavoir un .gitcleanignorefichier. :)
CivFan

1
@CivFan vous pouvez essayer d'utiliser chattr +i $filename(nécessite des autorisations root, ne permet pas de modifier le fichier après cela). De cette façon, git ne pourra pas supprimer ce fichier même s'il essaie de le faire comme rm -f.
Ruslan

3
Cela suppose des builds en source, ce qui doit être évité par lui-même.
Slava

c'était une solution simple (et je ne me souviens pas de ce que ces drapeaux signifient, mais c'est juste une machine de développement lol).
matanster

1
Mais qu'en est-il des fichiers nouvellement ajoutés que l'utilisateur a oubliés git add?
yugr

50

Je l'ai googlé pendant une demi-heure et la seule chose utile que j'ai trouvée a été d'invoquer l' findutilitaire:

# Find and then delete all files under current directory (.) that:
#  1. contains "cmake" (case-&insensitive) in its path (wholename)
#  2. name is not CMakeLists.txt
find . -iwholename '*cmake*' -not -name CMakeLists.txt -delete

Assurez-vous également d'invoquer make clean(ou le générateur CMake que vous utilisez) avant cela.

:)


36
Je déconseille d'utiliser cette approche si le répertoire dans lequel vous travaillez est sous contrôle de version: lorsque j'ai essayé cette approche avec svn, il a supprimé certains des fichiers de travail des référentiels.
début le

8
Il pourrait y avoir d'autres fichiers correspondant à cmake donc ce n'est vraiment pas une approche universelle. Cela devrait faire: rm -rf CMakeFiles; rm -rf CMakeCache.txt; rm -rf cmake_install.cmake;
honza_p

1
Je supprimerais -exec rm -rf {} \ + et utiliserais simplement -delete.
Edgar Aroutiounian

3
Voté, car cette commande peut potentiellement supprimer certains fichiers utilisateur. Je préfère la commande honza_p, pas vraiment plus longue, plus simple et moins risquée.
Adrien Descamps

1
@AdrienDescamps: sauf qu'il laisse encore des déchets liés à cmake dans les sous-répertoires. Je faisais rm -rf CMakeFiles ; rm -rf */CMakeFiles ; rm -rf */*/CMakeFiles ; rm -rf */*/*/CMakeFileset je n'avais toujours pas fini ...
SF.

35

Vous pouvez utiliser quelque chose comme:

add_custom_target(clean-cmake-files
   COMMAND ${CMAKE_COMMAND} -P clean-all.cmake
)

// clean-all.cmake
set(cmake_generated ${CMAKE_BINARY_DIR}/CMakeCache.txt
                    ${CMAKE_BINARY_DIR}/cmake_install.cmake
                    ${CMAKE_BINARY_DIR}/Makefile
                    ${CMAKE_BINARY_DIR}/CMakeFiles
)

foreach(file ${cmake_generated})

  if (EXISTS ${file})
     file(REMOVE_RECURSE ${file})
  endif()

endforeach(file)

Je crée généralement une commande "make clean-all" en ajoutant un appel à "make clean" à l'exemple précédent:

add_custom_target(clean-all
   COMMAND ${CMAKE_BUILD_TOOL} clean
   COMMAND ${CMAKE_COMMAND} -P clean-all.cmake
)

N'essayez pas d'ajouter la cible "propre" comme dépendance:

add_custom_target(clean-all
   COMMAND ${CMAKE_COMMAND} -P clean-all.cmake
   DEPENDS clean
)

Parce que "nettoyer" n'est pas une vraie cible dans CMake et cela ne fonctionne pas.

De plus, vous ne devez pas utiliser ce "clean-cmake-files" comme dépendance de quoi que ce soit:

add_custom_target(clean-all
   COMMAND ${CMAKE_BUILD_TOOL} clean
   DEPENDS clean-cmake-files
)

Parce que, si vous faites cela, tous les fichiers CMake seront effacés avant la fin de tout nettoyer, et make vous enverra une erreur lors de la recherche "CMakeFiles / clean-all.dir / build.make". En conséquence, vous ne pouvez pas utiliser la commande clean-all avant "n'importe quoi" dans n'importe quel contexte:

add_custom_target(clean-all
   COMMAND ${CMAKE_BUILD_TOOL} clean
   COMMAND ${CMAKE_COMMAND} -P clean-all.cmake
)

Ça ne marche pas non plus.


Existe-t-il un moyen de remplir automatiquement cmake_generated? Peut-être, en combinant cela avec la réponse de yuri.makarevich? Actuellement, cela ne supprimera pas les fichiers dans les sous-répertoires de $ {CMAKE_BINARY_DIR}.
foxcub

Ne fonctionne pas pour Ninja ou Visual studio. Je ne recommanderais pas une telle approche.
usr1234567

23

Le simple fait de publier des rm CMakeCache.txtœuvres pour moi aussi.


1
Seule la suppression des variables liées dans CMakeCache.txt fonctionne aussi pour moi.
Yorkwar

La suppression de CMakeCache.txt puis l'exécution de «cmake --build / build-path» provoque «Erreur: impossible de charger le cache».
nenchev

1
@nenchev, vous devez exécuter à cmake /build-pathnouveau.
Samaursa

@Samaursa cmake --build relance cmake si nécessaire, cette méthode casse le répertoire de construction et cmake se plaint. Ma réponse plus bas vous indique de supprimer le répertoire CMakeFiles /, ce qui provoque une reconstruction propre et cmake se réexécute automatiquement.
nenchev

2
@nenchev Je vois ce que tu veux dire et je suis d'accord.
Samaursa

9

C'est peut-être un peu dépassé, mais comme c'est le premier hit lorsque vous google cmake clean , j'ajouterai ceci:

Puisque vous pouvez démarrer une construction dans le répertoire de construction avec une cible spécifiée avec

cmake --build . --target xyz

vous pouvez bien sûr courir

cmake --build . --target clean

pour exécuter la cleancible dans les fichiers de génération générés.


8

Je suis d'accord que la construction hors source est la meilleure réponse. Mais pour les moments où vous devez simplement faire une construction en source, j'ai écrit un script Python disponible ici , qui:

  1. Fonctionne "make clean"
  2. Supprime des fichiers générés par CMake spécifiques dans le répertoire de niveau supérieur tels que CMakeCache.txt
  3. Pour chaque sous-répertoire qui contient un répertoire CMakeFiles, il supprime CMakeFiles, Makefile, cmake_install.cmake.
  4. Supprime tous les sous-répertoires vides.

Merci pour ça. Je voudrais ajouter une ligne à votre script qui se tait makelorsqu'il n'y a pas de Makefileprésence en raison d'un nettoyage préalable (c'est-à-dire, rend ce script idempotent). Ajoutez simplement la ligne (correctement espacée): if os.path.isfile(os.path.join(directory,'Makefile')):juste avant la ligne 24: args = [et bien sûr, indentez le reste du corps de la fonction après la ligne qui vient d'être ajoutée. Cela n'effectuera que make ... cleansi a Makefileest présent dans le répertoire en cours de nettoyage. Sinon, le script est parfait!
Michael Goldshteyn

4

Une solution que j'ai trouvée récemment consiste à combiner le concept de construction hors source avec un wrapper Makefile.

Dans mon fichier CMakeLists.txt de niveau supérieur, j'inclus les éléments suivants pour empêcher les builds en source:

if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} )
    message( FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt." )
endif()

Ensuite, je crée un Makefile de niveau supérieur et j'inclus les éléments suivants:

# -----------------------------------------------------------------------------
# CMake project wrapper Makefile ----------------------------------------------
# -----------------------------------------------------------------------------

SHELL := /bin/bash
RM    := rm -rf
MKDIR := mkdir -p

all: ./build/Makefile
    @ $(MAKE) -C build

./build/Makefile:
    @  ($(MKDIR) build > /dev/null)
    @  (cd build > /dev/null 2>&1 && cmake ..)

distclean:
    @  ($(MKDIR) build > /dev/null)
    @  (cd build > /dev/null 2>&1 && cmake .. > /dev/null 2>&1)
    @- $(MAKE) --silent -C build clean || true
    @- $(RM) ./build/Makefile
    @- $(RM) ./build/src
    @- $(RM) ./build/test
    @- $(RM) ./build/CMake*
    @- $(RM) ./build/cmake.*
    @- $(RM) ./build/*.cmake
    @- $(RM) ./build/*.txt

ifeq ($(findstring distclean,$(MAKECMDGOALS)),)
    $(MAKECMDGOALS): ./build/Makefile
    @ $(MAKE) -C build $(MAKECMDGOALS)
endif

La cible par défaut allest appelée en tapant makeet appelle la cible./build/Makefile .

La première chose que la cible ./build/Makefilefait est de créer le buildrépertoire en utilisant $(MKDIR), qui est une variable pour mkdir -p. Le répertoire buildest l'endroit où nous effectuerons notre build out-of-source. Nous fournissons l'argument -ppour nous assurer que mkdircela ne nous crie pas pour essayer de créer un répertoire qui peut déjà exister.

La deuxième chose que la cible ./build/Makefilefait est de changer de répertoire en buildrépertoire et d'appeler cmake.

De retour à la allcible, nous invoquons $(MAKE) -C build, où se $(MAKE)trouve une variable Makefile générée automatiquement pour make. make -Cchange le répertoire avant de faire quoi que ce soit. Par conséquent, utiliser $(MAKE) -C buildéquivaut à faire cd build; make.

Pour résumer, appeler ce wrapper Makefile avec make allou makeéquivaut à faire:

mkdir build
cd build
cmake ..
make 

La cible distcleaninvoque cmake .., puis make -C build clean, et enfin, supprime tout le contenu du buildrépertoire. Je pense que c'est exactement ce que vous avez demandé dans votre question.

La dernière partie du Makefile évalue si la cible fournie par l'utilisateur est ou non distclean. Sinon, il changera de répertoire en buildavant de l'invoquer. C'est très puissant car l'utilisateur peut taper, par exemple make clean, et le Makefile le transformera en un équivalent de cd build; make clean.

En conclusion, ce wrapper Makefile, en combinaison avec une configuration CMake de construction hors source obligatoire, fait en sorte que l'utilisateur n'ait jamais à interagir avec la commande cmake. Cette solution fournit également une méthode élégante pour supprimer tous les fichiers de sortie CMake du buildrépertoire.

PS Dans le Makefile, nous utilisons le préfixe @pour supprimer la sortie d'une commande shell, et le préfixe @-pour ignorer les erreurs d'une commande shell. Lors de l'utilisation rmdans le cadre de la distcleancible, la commande retournera une erreur si les fichiers n'existent pas (ils peuvent avoir été supprimés déjà en utilisant la ligne de commande avec rm -rf build, ou ils n'ont jamais été générés en premier lieu). Cette erreur de retour forcera notre Makefile à quitter. Nous utilisons le préfixe @-pour éviter cela. Il est acceptable si un fichier a déjà été supprimé; nous voulons que notre Makefile continue et supprime le reste.

Une autre chose à noter: Ce Makefile ne peut pas fonctionner si vous utilisez un nombre variable de variables CMake pour construire votre projet, par exemple, cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar". Ce Makefile suppose que vous appelez CMake de manière cohérente, soit en tapant, cmake ..soit en fournissant cmakeun nombre cohérent d'arguments (que vous pouvez inclure dans votre Makefile).

Enfin, le crédit là où le crédit est dû. Ce wrapper Makefile a été adapté du Makefile fourni par le modèle de projet d'application C ++ .


4

Bien sûr, les builds hors source sont la méthode incontournable pour les Makefiles Unix, mais si vous utilisez un autre générateur tel que Eclipse CDT, il préfère que vous construisiez en source. Dans ce cas, vous devrez purger les fichiers CMake manuellement. Essaye ça:

find . -name 'CMakeCache.txt' -o -name '*.cmake' -o -name 'Makefile' -o -name 'CMakeFiles' -exec rm -rf {} +

Ou si vous avez activé globstar avec shopt -s globstar, essayez plutôt cette approche moins dégoûtante:

rm -rf **/CMakeCache.txt **/*.cmake **/Makefile **/CMakeFiles

Hier, mon choix était de cloner le dépôt dans un nouveau dossier, de mettre à jour CMakeLists.txt pour construire à partir du sous-dossier build. Cela a pris un peu plus de temps que ces commandes mais je n'ai dû le faire qu'une seule fois :)
Tien Do

4

essayez d'utiliser: cmake --clean-first path-of-CMakeLists.txt-file -B output-dir

--clean-first: Construisez la cible propre d'abord, puis construisez.
(Pour nettoyer uniquement, utilisez --target clean.)


Cette capture d'écran montre uniquement du texte . Pourtant, vous en prenez une capture d'écran, brisant la réponse pour quiconque vient ici avec un lecteur d'écran. Veuillez déposer cette image, faire un copier / coller de texte et passer la minute pour formater correctement cette entrée.
GhostCat

3

Dans le cas où vous transmettez des -Dparamètres à CMake lors de la génération des fichiers de build et que vous ne souhaitez pas supprimer l'intégralité du répertoire build /:

Supprimez simplement le répertoire CMakeFiles / dans votre répertoire de construction.

rm -rf CMakeFiles/
cmake --build .

Cela provoque CMake à réexécuter et les fichiers système de génération sont régénérés. Votre build commencera également à zéro.


1

Pour simplifier le nettoyage lors de l'utilisation de build "out of source" (c'est-à-dire que vous construisez dans le buildrépertoire), j'utilise le script suivant:

$ cat ~/bin/cmake-clean-build
#!/bin/bash

if [ -d ../build ]; then
    cd ..
    rm -rf build
    mkdir build
    cd build
else
    echo "build directory DOES NOT exist"
fi

Chaque fois que vous devez nettoyer, vous devez source ce script à partir du buildrépertoire:

. cmake-clean-build

Agréable et sûr. Comme je peux avoir le répertoire de construction ouvert dans le gestionnaire de fichiers, je suggère de remplacer la cd .. ; rm ; mkdir ; cdséquence par cd .. ; rm -rf build/*.
Mostafa Farzán

0

Si vous avez des définitions personnalisées et que vous souhaitez les enregistrer avant le nettoyage, exécutez ce qui suit dans votre répertoire de génération:

sed -ne '/variable specified on the command line/{n;s/.*/-D \0 \\/;p}' CMakeCache.txt

Créez ensuite un nouveau répertoire de build (ou supprimez l'ancien répertoire de build et recréez-le) et enfin exécutez cmakeavec les arguments que vous obtiendrez avec le script ci-dessus.


0

Si vous courez

cmake .

il régénérera les fichiers CMake. Ce qui est nécessaire si vous ajoutez un nouveau fichier à un dossier source sélectionné par * .cc, par exemple.

Bien que ce ne soit pas un "nettoyage" en soi, il "nettoie" les fichiers CMake en régénérant les caches.


Il ne nettoie pas wrt. l'état de compilation: si 500 fichiers sur 1200 ont été compilés, après "cmake". il continuera simplement avec les 700 derniers fichiers.
Peter Mortensen

0

J'utilise le script shell suivant à de telles fins:

#!/bin/bash

for fld in $(find -name "CMakeLists.txt" -printf '%h ')
do
    for cmakefile in CMakeCache.txt cmake_install.cmake CTestTestfile.cmake CMakeFiles Makefile
    do
        rm -rfv $fld/$cmakefile
    done
done

Si vous utilisez Windows, utilisez Cygwin pour ce script.


0

C'est drôle de voir que cette question reçoit autant d'attentions et de solutions compliquées, ce qui montre en effet une douleur de ne pas avoir une méthode propre avec cmake.

Eh bien, vous pouvez certainement cd buildfaire votre travail, puis faire un rm -rf *quand vous avez besoin de nettoyer. Cependant, rm -rf *c'est une commande dangereuse étant donné que beaucoup de gens ne savent souvent pas dans quel répertoire ils se trouvent.

Si vous cd .., rm -rf buildet puis mkdir buildet puis cd build, c'est tout simplement trop de frappe.

Donc, une bonne solution est de rester en dehors du dossier de construction et de dire à cmake le chemin:
à configurer: cmake -B build
à construire: cmake --build build
à nettoyer: rm -rf build
à recréer le dossier de construction: vous n'avez même pas besoin de le mkdir buildconfigurer avec cmake -B buildet cmake le créera


0

cmakecuit principalement un Makefile, on pourrait ajouter rmà la PHONY propre .

Par exemple,

[root@localhost hello]# ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  CMakeLists.txt  hello  Makefile  test
[root@localhost hello]# vi Makefile
clean:
        $(MAKE) -f CMakeFiles/Makefile2 clean
        rm   -rf   *.o   *~   .depend   .*.cmd   *.mod    *.ko   *.mod.c   .tmp_versions *.symvers *.d *.markers *.order   CMakeFiles  cmake_install.cmake  CMakeCache.txt  Makefile

-1

J'ai ceci dans mon fichier shell rc ( .bashrc, .zshrc):

t-cmake-clean() {
    local BUILD=$(basename $(pwd))
    cd ..
    rm -rf $BUILD
    mkdir $BUILD && cd $BUILD
}

Vous êtes censé l'utiliser uniquement pour les versions hors source. Disons que vous avez un répertoire nommé build/à cet effet. Ensuite, il vous suffit de courir t-cmake-cleanà l'intérieur.


-3

J'ai utilisé la réponse de zsxwing avec succès pour résoudre le problème suivant:

J'ai une source que je construis sur plusieurs hôtes (sur une carte Linux Raspberry Pi, sur une machine virtuelle Linux VMware, etc.)

J'ai un script Bash qui crée des répertoires temporaires basés sur le nom d'hôte de la machine comme ceci:

# Get hostname to use as part of directory names
HOST_NAME=`uname -n`

# Create a temporary directory for cmake files so they don't
# end up all mixed up with the source.

TMP_DIR="cmake.tmp.$HOSTNAME"

if [ ! -e $TMP_DIR ] ; then
  echo "Creating directory for cmake tmp files : $TMP_DIR"
  mkdir $TMP_DIR
else
  echo "Reusing cmake tmp dir : $TMP_DIR"
fi

# Create makefiles with CMake
#
# Note: switch to the temporary dir and build parent 
#       which is a way of making cmake tmp files stay
#       out of the way.
#
# Note 2: to clean up cmake files, it is OK to
#        "rm -rf" the temporary directories

echo
echo Creating Makefiles with cmake ...

cd $TMP_DIR

cmake ..

# Run makefile (in temporary directory)

echo
echo Starting build ...

make

-8

Créez un répertoire de construction temporaire, par exemple, build_cmake ,. Par conséquent, tous vos fichiers de construction seront dans ce dossier.

Ensuite, dans votre fichier CMake principal, ajoutez la commande ci-dessous.

add_custom_target(clean-all
    rm -rf *
)

Par conséquent, lors de la compilation,

cmake ..

Et pour nettoyer faire:

make clean-all

11
belle façon de supprimer tout votre projet si quelqu'un construit accidentellement in-source au lieu de out-of-source

3
Oui. cette méthode ne doit être utilisée qu'avec la "construction hors source"
Natesh

6
Terrible recommandation. Ne devrait pas exister comme réponse.
Anne van Rossum

@AnnevanRossum conviennent
zevarito
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.