Comment utiliser CCache avec CMake?

90

Je voudrais faire ce qui suit: Si CCache est présent dans PATH, utilisez "ccache g ++" pour la compilation, sinon utilisez g ++. J'ai essayé d'écrire un petit script my-cmake contenant

    CC="ccache gcc" CXX="ccache g++" cmake $*

mais cela ne semble pas fonctionner (l'exécution de make n'utilise toujours pas ccache; j'ai vérifié cela en utilisant CMAKE_VERBOSE_MAKEFILE sur).

Mise à jour:

Selon ce lien, j'ai essayé de changer mon script en

     cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*

mais cmake renonce à se plaindre qu'un test a échoué lors de l'utilisation du compilateur ccache (ce à quoi on peut s'attendre).

amit
la source
4
Pourquoi ne liez-vous pas simplement gcc à ccache? Et si vous distribuez ceci, je pense que l'utilisateur lui-même aurait fait le lien symbolique s'il avait installé ccache et voulait qu'il soit utilisé ..
int3
1
@ int3 Oui, cela fonctionnerait probablement (je ne savais pas que ccache avait le compilateur comme argument optionnel). Cependant, il serait plus propre d'être plus explicite.
amit

Réponses:

67

J'ai personnellement /usr/lib/ccachedans mon $PATH. Ce répertoire contient des tas de liens symboliques pour chaque nom possible à partir duquel le compilateur pourrait être appelé (comme gccet gcc-4.3), tous pointant vers ccache.

Et je n'ai même pas créé les liens symboliques. Ce répertoire est pré-rempli lorsque j'installe ccache sur Debian.

Nicolás
la source
11
Notez que ce chemin ccache doit être placé avant le chemin où se trouve votre véritable compilateur $PATHpour qu'il fonctionne. Quelque chose commeexport PATH = /usr/lib/ccache:$PATH
Gui13
6
@ Gui13: Mieux que mettre à jour le PATH serait de dire explicitement à cmake où se trouve le gcc qu'il doit utiliser, par exemple cmake -DCMAKE_CXX_COMPILER = / usr / lib / ccache / bin / g ++
cib
3
Après brew install ccache, j'ai /usr/local/Cellar/ccache/3.2.1/libexec/.
cdunn2001
96

Il est maintenant possible de spécifier ccache comme lanceur pour les commandes de compilation et les commandes de lien (depuis cmake 2.8.0). Cela fonctionne pour Makefile et Ninja Generator. Pour ce faire, définissez simplement les propriétés suivantes:

find_program(CCACHE_FOUND ccache)
if(CCACHE_FOUND)
    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
    set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) # Less useful to do it for linking, see edit2
endif(CCACHE_FOUND)

Il est également possible de définir ces propriétés uniquement pour des répertoires ou des cibles spécifiques.

Pour Ninja, cela est possible depuis la version 3.4. Pour XCode, Craig Scott donne une solution de contournement dans sa réponse.

Edit: Grâce au commentaire d'uprego et de Lekensteyn, j'ai édité la réponse pour vérifier si ccache est disponible avant de l'utiliser comme lanceur et pour quels générateurs est-il possible d'utiliser un lanceur de compilation.

Edit2: @Emilio Cobos a recommandé d'éviter de faire cela pour la partie de liaison car ccache n'améliore pas la vitesse de liaison et peut gâcher d'autres types de cache comme sccache

Babcool
la source
De nombreux sites conseillent implicitement d'utiliser des guillemets doubles comme dans find_program(CCACHE_FOUND "ccache"), je ne sais pas lequel est le plus portable, mon kilométrage s'est parfaitement bien passé sans avoir besoin des doubles guillemets.
1737973
5
Il est intéressant de noter que cela ne fonctionne actuellement que pour les générateurs Makefile (à partir de cmake 3.3.2). Voir la page de manuel de cmake-properties.
Lekensteyn
1
Il est à noter que cela entre en conflit avec le paramètre CTEST_USE_LAUNCHERS. Ces propriétés sont également définies ici: github.com/Kitware/CMake/blob/master/Modules/…
purpleKarrot
Je pense que vous voudrez peut-être changer le code pour celui-ci (sauf, supprimer le texte de l'intérieur deendif() ) . Les améliorations sont: 1. Il y a une option de configuration pour le désactiver, et 2. Il s'avère que les couleurs disparaissent de GCC / Clang dans le backend Make lorsqu'elles sont utilisées de cette façon. Le ninjabackend fonctionne autour de lui en ajoutant une -fdiagnostics-coloroption, il est donc conseillé de le faire également pour le makebackend.
Hi-Angel
94

Depuis CMAKE 3.4, vous pouvez faire:

-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
Jacob
la source
1
Et -DCMAKE_CXX_COMPILER_LAUNCHER=ccache. Ceux-ci fonctionnent à merveille! Je ne sais pas pourquoi cmake insiste sur la recherche clangde /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc(donc l'astuce du lien symbolique ne fonctionne pas), plutôt que de $PATH, mais votre réponse fonctionne quand même.
cdunn2001
2
Cela devrait être la meilleure réponse. Fini les problèmes de variable de chemin et de liens symboliques du compilateur!
ilya b.
1
J'ai essayé ceci, mais cela me donne juste l'erreur "ccache: error: invocation récursive (le nom du binaire ccache doit être" ccache ")". En regardant la trace verbeuse, il essaie d'exécuter "/ usr / local / bin / ccache ccache / usr / bin / c ++" ...
Chris Dodd
3
Comment interagit-il avec RULE_LAUNCH_COMPILE?
Trass3r
10

A partir de CMake 3.1, il est possible d'utiliser ccache avec le générateur Xcode et Ninja est pris en charge à partir de CMake 3.4. Ninja honorera RULE_LAUNCH_COMPILEtout comme le générateur Unix Makefiles (donc la réponse de @ Babcool vous y conduit aussi pour Ninja), mais faire fonctionner le cache pour le générateur Xcode demande un peu plus de travail. L'article suivant explique la méthode en détail, en se concentrant sur une implémentation générale qui fonctionne pour les trois générateurs CMake et en ne faisant aucune hypothèse sur la configuration des liens symboliques ccache ou du compilateur sous-jacent utilisé (il laisse toujours CMake décider du compilateur):

https://crascit.com/2016/04/09/using-ccache-with-cmake/

L'essentiel général de l'article est le suivant. Le début de votre CMakeLists.txtfichier doit être configuré comme ceci:

cmake_minimum_required(VERSION 2.8)

find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
    # Support Unix Makefiles and Ninja
    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
endif()

project(SomeProject)

get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
if(RULE_LAUNCH_COMPILE AND CMAKE_GENERATOR STREQUAL "Xcode")
    # Set up wrapper scripts
    configure_file(launch-c.in   launch-c)
    configure_file(launch-cxx.in launch-cxx)
    execute_process(COMMAND chmod a+rx
                            "${CMAKE_BINARY_DIR}/launch-c"
                            "${CMAKE_BINARY_DIR}/launch-cxx")

    # Set Xcode project attributes to route compilation through our scripts
    set(CMAKE_XCODE_ATTRIBUTE_CC         "${CMAKE_BINARY_DIR}/launch-c")
    set(CMAKE_XCODE_ATTRIBUTE_CXX        "${CMAKE_BINARY_DIR}/launch-cxx")
    set(CMAKE_XCODE_ATTRIBUTE_LD         "${CMAKE_BINARY_DIR}/launch-c")
    set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
endif()

Les deux fichiers de modèle de script launch-c.inet launch-cxx.inressemblent à ceci (ils doivent être dans le même répertoire que le CMakeLists.txtfichier):

launch-c.in:

#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_C_COMPILER}" "$@"

launch-cxx.in:

#!/bin/sh
export CCACHE_CPP2=true
exec "${RULE_LAUNCH_COMPILE}" "${CMAKE_CXX_COMPILER}" "$@"

Ce qui précède est utilisé RULE_LAUNCH_COMPILEseul pour Unix Makefiles et Ninja, mais pour le générateur Xcode, il repose sur l'aide du CMAKE_XCODE_ATTRIBUTE_...support des variables de CMake . Le réglage des CCet CXXattributs de contrôle définis par l' utilisateur Xcode la commande du compilateur et LDet LDPLUSPLUSpour la commande de liaison est pas, pour autant que je peux dire, une caractéristique documentée des projets Xcode, mais il ne semble travailler. Si quelqu'un peut confirmer qu'il est officiellement pris en charge par Apple, je mettrai à jour l'article lié et cette réponse en conséquence.

Craig Scott
la source
J'avais également besoin set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}")de l'article mentionné.
Jörn Reimerdes
Merci pour le rappel, j'ai mis à jour la réponse pour inclure les paramètres LD et LDPLUSPLUS.
Craig Scott
ccache ne prend pas en charge les compilateurs VS, vous ne pouvez donc pas l'utiliser pour cela. Il existe un projet appelé clcache qui vise à fournir les mêmes fonctionnalités pour VS, mais je ne peux pas commenter son fonctionnement.
Craig Scott
9

Je n'aimais pas définir un lien symbolique de g++à ccache. Et cela CXX="ccache g++"n'a pas fonctionné pour moi car certains cas de test cmake voulaient avoir juste le programme de compilation sans attributs.

J'ai donc utilisé un petit script bash à la place:

#!/bin/bash
ccache g++ "$@"

et l'a enregistré en tant qu'exécutable dans /usr/bin/ccache-g++.

Ensuite, C a configuré cmake pour l'utiliser /usr/bin/ccache-g++comme compilateur C ++. De cette façon, cela passe les cas de test cmake et je me sens plus à l'aise que d'avoir des liens symboliques que je pourrais oublier dans 2 ou 3 semaines et ensuite peut-être me demander si quelque chose ne fonctionne pas ...

Jonas
la source
5

À mon avis, le meilleur moyen est de créer un lien symbolique gcc, g ++ vers ccache, mais si vous souhaitez utiliser dans cmake, essayez ceci:

export CC="ccache gcc" CXX="ccache g++" cmake ...
Nadir SOUALEM
la source
5

J'ai vérifié les travaux suivants (source: ce lien ):

        CC="gcc" CXX="g++" cmake -D CMAKE_CXX_COMPILER="ccache" -D CMAKE_CXX_COMPILER_ARG1="g++" -D CMAKE_C_COMPILER="ccache" -D CMAKE_C_COMPILER_ARG1="gcc" $*

Mise à jour : j'ai réalisé plus tard que même cela ne fonctionnait pas. Curieusement, cela fonctionne à chaque fois (les autres fois, cmake se plaint).

amit
la source
4

Permettez-moi d’ajouter un élément important qui n’a pas été mentionné auparavant.

Lors du démarrage d'un système de construction minimaliste à partir de l'image docker ubunutu: 18.04, j'ai trouvé que l'ordre d'installation fait une différence.

Dans mon cas, ccache a bien fonctionné lors de l'appel gcc, mais n'a pas réussi à intercepter les appels du même compilateur par les autres noms: ccet c++. Pour installer complètement ccache, vous devez vous assurer que tous les compilateurs sont installés en premier, ou ajouter un appel aux liens symboliques update-ccache pour être sûr.

sudo apt-get install ccache build-essential # and everyhting ... sudo /usr/sbin/update-ccache-symlinks export PATH="/usr/lib/ccache/:$PATH"

... puis (en raison des liens symboliques mis à jour), les appels à cc et c ++ sont également pris!

Jürgen Weigert
la source
Merci que je ne savais pas update-ccache-symlinks, je créais un c++lien avec un script pour un projet et cela fonctionnait mais pas pour un autre projet (je ne sais toujours pas pourquoi, le lien était bien), update-ccache-symlinksrésolu.
Alex