Wie verwende ich CCache mit CMake?

88

Ich möchte Folgendes tun: Wenn CCache in PATH vorhanden ist, verwenden Sie "ccache g ++" zum Kompilieren, andernfalls verwenden Sie g ++. Ich habe versucht, ein kleines my-cmake-Skript zu schreiben, das Folgendes enthält

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

aber es scheint nicht zu funktionieren (das Ausführen von make verwendet immer noch keinen Ccache; ich habe dies mit CMAKE_VERBOSE_MAKEFILE aktiviert).

Aktualisieren:

Über diesen Link habe ich versucht, mein Skript in zu ändern

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

cmake klagt jedoch darüber, dass ein Test bei Verwendung des Compiler-Ccaches fehlgeschlagen ist (was zu erwarten ist).

amit
quelle
4
Warum verknüpfen Sie gcc nicht einfach mit ccache? Und wenn Sie dies verteilen, würde ich denken, dass der Benutzer selbst den Symlink gemacht hätte, wenn er Ccache installiert hätte und wollte, dass er verwendet wird.
Int3
1
@ int3 Ja, wahrscheinlich würde das funktionieren (mir war nicht bewusst, dass ccache den Compiler als optionales Argument hat). Es wäre jedoch sauberer, expliziter zu sein.
Amit

Antworten:

64

Ich persönlich habe /usr/lib/ccachein meinem $PATH. Dieses Verzeichnis enthält viele Symlinks für jeden möglichen Namen, von dem aus der Compiler aufgerufen werden kann (wie gccund gcc-4.3), die alle auf ccache verweisen.

Und ich habe nicht einmal die Symlinks erstellt. Dieses Verzeichnis wird vorgefüllt, wenn ich ccache auf Debian installiere.

Nicolás
quelle
11
Beachten Sie, dass dieser Ccache-Pfad vor dem Pfad platziert werden muss, in dem sich Ihr realer Compiler befindet, $PATHdamit er funktioniert. So etwas wieexport PATH = /usr/lib/ccache:$PATH
Gui13
6
@ Gui13: Besser als das Aktualisieren des Pfads wäre es, cmake explizit mitzuteilen, wo sich das verwendete gcc befindet, z. B. cmake -DCMAKE_CXX_COMPILER = / usr / lib / ccache / bin / g ++
cib
3
Nachher habe brew install ccacheich /usr/local/Cellar/ccache/3.2.1/libexec/.
cdunn2001
96

Es ist jetzt möglich, ccache als Starter für Kompilierungsbefehle und Verknüpfungsbefehle anzugeben (seit cmake 2.8.0). Das funktioniert für Makefile und Ninja Generator. Legen Sie dazu einfach die folgenden Eigenschaften fest:

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)

Es ist auch möglich, diese Eigenschaften nur für bestimmte Verzeichnisse oder Ziele festzulegen.

Für Ninja ist dies seit Version 3.4 möglich. Für XCode gibt Craig Scott eine Problemumgehung in seiner Antwort.

Bearbeiten: Dank des Kommentars von uprego und Lekensteyn habe ich die Antwort bearbeitet, um zu überprüfen, ob ccache verfügbar ist, bevor ich ihn als Launcher verwende, und für welche Generatoren ein Compile-Launcher verwendet werden kann.

Edit2: @Emilio Cobos hat empfohlen, dies für den Verknüpfungsteil zu vermeiden, da der Ccache die Verknüpfungsgeschwindigkeit nicht verbessert und mit anderen Cache-Typen wie sccache in Konflikt geraten kann

Babcool
quelle
Viele Websites raten implizit zur Verwendung von Doppelzitaten wie in find_program(CCACHE_FOUND "ccache"). Ich weiß nicht, welches tragbarer ist. Mein Kilometerstand war ohne die Notwendigkeit von Doppelzitaten einwandfrei.
1737973
5
Es ist erwähnenswert, dass dies derzeit nur für Makefile-Generatoren funktioniert (ab cmake 3.3.2). Siehe die Handbuchseite von cmake-properties.
Lekensteyn
1
Es ist anzumerken, dass dies im Widerspruch zur Einstellung CTEST_USE_LAUNCHERS steht. Diese Eigenschaften werden auch hier festgelegt: github.com/Kitware/CMake/blob/master/Modules/…
lilaKarrot
Ich denke, Sie möchten vielleicht den Code in diesen ändern (außer Text aus dem Inneren von entfernenendif() ) . Die Verbesserungen sind: 1. Es gibt eine Konfigurationsoption, um es zu deaktivieren, und 2. Es stellt sich heraus, dass Farben aus GCC / Clang im Make-Backend verschwinden, wenn sie auf diese Weise verwendet werden. Das ninjaBackend umgeht es, indem es eine -fdiagnostics-colorOption hinzufügt. Daher ist es ratsam, dies auch für das makeBackend zu tun .
Hi-Angel
86

Ab CMAKE 3.4 können Sie:

-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
Jacob
quelle
1
Und -DCMAKE_CXX_COMPILER_LAUNCHER=ccache. Diese funktionieren wunderbar! Ich weiß nicht, warum cmake darauf besteht, clangvon zu finden /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc(der Symlink-Trick funktioniert also nicht) und nicht von $PATH, aber Ihre Antwort funktioniert trotzdem.
cdunn2001
2
Dies sollte die beste Antwort sein. Kein Durcheinander mehr mit Pfadvariablen und Compiler-Symlinks!
ilya b.
1
Ich habe es versucht, aber es gibt mir nur den Fehler "ccache: error: Rekursiver Aufruf (der Name der ccache-Binärdatei muss" ccache "sein)". Mit Blick auf die ausführliche Ablaufverfolgung wird versucht, "/ usr / local / bin / ccache ccache / usr / bin / c ++" auszuführen ...
Chris Dodd
3
Wie interagiert es mit RULE_LAUNCH_COMPILE?
Trass3r
10

Ab CMake 3.1 ist es möglich, ccache mit dem Xcode-Generator zu verwenden, und Ninja wird ab CMake 3.4 unterstützt. Ninja wird RULE_LAUNCH_COMPILEgenau wie der Unix Makefiles-Generator ehren (also bringt Sie die Antwort von @ Babcool auch für Ninja dorthin), aber Ccache für den Xcode-Generator zum Laufen zu bringen, erfordert etwas mehr Arbeit. Der folgende Artikel erläutert die Methode im Detail, wobei der Schwerpunkt auf einer allgemeinen Implementierung liegt, die für alle drei CMake-Generatoren funktioniert, und keine Annahmen zum Einrichten von Ccache-Symlinks oder des verwendeten zugrunde liegenden Compilers getroffen werden (CMake kann weiterhin den Compiler bestimmen):

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

Der allgemeine Kern des Artikels lautet wie folgt. Der Anfang Ihrer CMakeLists.txtDatei sollte ungefähr so ​​eingerichtet sein:

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()

Die beiden Skriptvorlage Dateien launch-c.inund launch-cxx.insieht wie folgt aus (sie im selben Verzeichnis wie das sein sollte CMakeLists.txtDatei):

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}" "$@"

Das Obige wird RULE_LAUNCH_COMPILEallein für Unix Makefiles und Ninja verwendet, aber für den Xcode-Generator ist es auf die Hilfe der CMake- CMAKE_XCODE_ATTRIBUTE_...Variablenunterstützung angewiesen . Die Einstellung der CCund CXXbenutzerdefinierten Xcode Attribute den Compiler - Befehl und steuern LDund LDPLUSPLUSfür den Linker - Befehl nicht, soweit ich das beurteilen kann, ein dokumentiertes Merkmal von Xcode - Projekten, aber es zu funktionieren scheint. Wenn jemand bestätigen kann, dass es offiziell von Apple unterstützt wird, werde ich den verlinkten Artikel und diese Antwort entsprechend aktualisieren.

Craig Scott
quelle
Ich brauchte auch das set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}")aus dem genannten Artikel.
Jörn Reimerdes
Vielen Dank für die Erinnerung, ich habe die Antwort so aktualisiert, dass sie LD und LDPLUSPLUS enthält.
Craig Scott
ccache unterstützt keine VS-Compiler, daher können Sie es nicht dafür verwenden. Es gibt ein Projekt namens clcache, das die gleiche Funktionalität für VS bereitstellen soll, aber ich kann nicht beurteilen , wie gut es funktioniert.
Craig Scott
8

Ich wollte keinen Symlink von g++bis setzen ccache. Und CXX="ccache g++"hat bei mir nicht funktioniert, da einige cmake-Testfälle nur das Compiler-Programm ohne Attribute haben wollten.

Also habe ich stattdessen ein kleines Bash-Skript verwendet:

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

und speicherte es als ausführbare Datei in /usr/bin/ccache-g++.

Anschließend hat C cmake für die Verwendung /usr/bin/ccache-g++als C ++ - Compiler konfiguriert . Auf diese Weise besteht es die cmake-Testfälle und ich fühle mich wohler als Symlinks, die ich in 2 oder 3 Wochen vergessen könnte, und frage mich dann vielleicht, ob etwas nicht funktioniert ...

Jonas
quelle
5

Meiner Meinung nach ist es am besten, gcc, g ++ mit ccache zu verknüpfen. Wenn Sie es jedoch in cmake verwenden möchten, versuchen Sie Folgendes:

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

Ich habe folgende Arbeiten überprüft (Quelle: dieser Link ):

        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" $*

Update : Ich habe später festgestellt, dass auch das nicht funktioniert. Seltsamerweise funktioniert es jedes zweite Mal (das andere Mal beschwert sich cmake).

amit
quelle
4

Lassen Sie mich einen wichtigen Punkt hinzufügen, der hier zuvor nicht erwähnt wurde.

Beim Bootstrapping eines minimalistischen Build-Systems vom Docker-Image ubunutu: 18.04 habe ich festgestellt, dass die Reihenfolge der Installation einen Unterschied macht.

In meinem Fall funktionierte ccache beim Aufrufen einwandfrei gcc, konnte jedoch Aufrufe desselben Compilers mit den anderen Namen nicht abfangen: ccund c++. Um Ccache vollständig zu installieren, müssen Sie sicherstellen, dass alle Compiler zuerst installiert sind, oder einen Aufruf für die Update-Ccache-Symlinks hinzufügen, um die Sicherheit zu gewährleisten.

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

... und dann (aufgrund aktualisierter Symlinks) werden auch Aufrufe von cc und c ++ abgefangen!

Jürgen Weigert
quelle
Danke, ich wusste nichts darüber update-ccache-symlinks, ich habe einen c++Link mit einem Skript für ein Projekt erstellt und es hat funktioniert, aber nicht für ein anderes Projekt (ich weiß immer noch nicht warum, der Link war in Ordnung), update-ccache-symlinksgelöst.
Alex