Come utilizzare CCache con CMake?


92

Vorrei fare quanto segue: Se CCache è presente in PATH, usa "ccache g ++" per la compilazione, altrimenti usa g ++. Ho provato a scrivere un piccolo script my-cmake contenente

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

ma non sembra funzionare (l'esecuzione di make continua a non utilizzare ccache; l'ho verificato utilizzando CMAKE_VERBOSE_MAKEFILE su).

Aggiornare:

Come da questo collegamento ho provato a cambiare il mio script in

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

ma cmake salta lamentandosi che un test non è riuscito utilizzando il compilatore ccache (cosa che ci si può aspettare).


4
Perché non colleghi semplicemente gcc a ccache? E se lo stai distribuendo, penso che l'utente stesso avrebbe fatto il collegamento simbolico se avesse installato ccache e volesse che fosse usato ..
int3

1
@ int3 Sì, probabilmente avrebbe funzionato (non sapevo che ccache ha il compilatore come argomento opzionale). Tuttavia sarebbe più pulito essere più esplicito.
amit

Risposte:


68

Personalmente ho /usr/lib/ccachenel mio file $PATH. Questa directory contiene un sacco di collegamenti simbolici per ogni possibile nome da cui il compilatore può essere chiamato (come gccegcc-4.3 ), tutti che puntano a ccache.

E non ho nemmeno creato i collegamenti simbolici. Quella directory viene precompilata quando installo ccache su Debian.


11
Nota che questo percorso ccache deve essere posizionato prima del percorso in cui si trova il tuo vero compilatore $PATHaffinché funzioni. Qualcosa comeexport PATH = /usr/lib/ccache:$PATH
Gui13

6
@ Gui13: Meglio che aggiornare il PATH sarebbe dire a cmake esplicitamente dove si trova il gcc che dovrebbe usare, ad esempio cmake -DCMAKE_CXX_COMPILER = / usr / lib / ccache / bin / g ++
cib

3
Dopo brew install ccache, l'ho fatto /usr/local/Cellar/ccache/3.2.1/libexec/.
cdunn2001

98

A partire da CMAKE 3.4 puoi fare:

-DCMAKE_CXX_COMPILER_LAUNCHER=ccache

1
E -DCMAKE_CXX_COMPILER_LAUNCHER=ccache. Questi funzionano magnificamente! Non so perché cmake insiste nel cercare clangda /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc(quindi il trucco del collegamento simbolico non funziona), piuttosto che da $PATH, ma la tua risposta funziona comunque.
cdunn2001

3
Questa dovrebbe essere la risposta migliore. Niente più problemi con la variabile di percorso e i collegamenti simbolici del compilatore!
ilya b.

1
Ho provato questo, ma mi dà solo l'errore "ccache: errore: invocazione ricorsiva (il nome del binario ccache deve essere" ccache ")". Guardando la traccia dettagliata, sta tentando di eseguire "/ usr / local / bin / ccache ccache / usr / bin / c ++" ...
Chris Dodd

3
Come interagisce con RULE_LAUNCH_COMPILE?
Trass3r

98

È ora possibile specificare ccache come lanciatore per i comandi di compilazione e di collegamento (a partire da cmake 2.8.0). Funziona per Makefile e Ninja generator. Per fare ciò, basta impostare le seguenti proprietà:

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)

È anche possibile impostare queste proprietà solo per directory o destinazioni specifiche.

Per Ninja, questo è possibile dalla versione 3.4. Per XCode, Craig Scott fornisce una soluzione nella sua risposta.

Modifica: Grazie a uprego e al commento di Lekensteyn, ho modificato la risposta per verificare se ccache è disponibile prima di utilizzarlo come lanciatore e per quali generatori è possibile utilizzare un lanciatore di compilazione.

Edit2: @Emilio Cobos consiglia di evitare di farlo per la parte di collegamento poiché ccache non migliora la velocità di collegamento e può fare confusione con altri tipi di cache come sccache


Molti siti consigliano implicitamente l'uso di virgolette doppie come in find_program(CCACHE_FOUND "ccache"), non so quale sia più portabile, il mio chilometraggio è andato benissimo senza bisogno delle doppie virgolette.
1737973

5
Vale la pena notare che questo attualmente funziona solo per i generatori di Makefile (a partire da cmake 3.3.2). Vedere la pagina di manuale di cmake-properties.
Lekensteyn

1
Vale la pena notare che questo è in conflitto con l'impostazione CTEST_USE_LAUNCHERS. Queste proprietà sono impostate anche qui: github.com/Kitware/CMake/blob/master/Modules/…
purpleKarrot

Penso che potresti voler cambiare il codice in questo (tranne, rimuovere il testo dall'interno diendif() ) . I miglioramenti sono: 1. C'è un'opzione di configurazione per disabilitarlo, e 2. Risulta che i colori scompaiono da GCC / Clang in Make backend se usati in questo modo. Il ninjabackend funziona aggiungendo -fdiagnostics-colorun'opzione, quindi è consigliabile farlo anche per il makebackend.
Hi-Angel

9

Da CMake 3.1, è possibile utilizzare ccache con il generatore di Xcode e Ninja è supportato da CMake 3.4 in poi. Ninja onorerà RULE_LAUNCH_COMPILEproprio come il generatore di Makefiles Unix (quindi la risposta di @ Babcool ti porta lì anche per Ninja), ma far funzionare ccache per il generatore di Xcode richiede un po 'più di lavoro. Il seguente articolo spiega il metodo in dettaglio, concentrandosi su un'implementazione generale che funziona per tutti e tre i generatori CMake e non facendo ipotesi sulla configurazione di collegamenti simbolici ccache o sul compilatore sottostante utilizzato (consente comunque a CMake di decidere il compilatore):

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

L'essenza generale dell'articolo è la seguente. L'inizio del tuo CMakeLists.txtfile dovrebbe essere impostato in questo modo:

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

I due file modello di script launch-c.ine hanno questo launch-cxx.inaspetto (dovrebbero trovarsi nella stessa directory del CMakeLists.txtfile):

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

Quanto sopra viene utilizzato RULE_LAUNCH_COMPILEda solo per Unix Makefiles e Ninja, ma per il generatore Xcode si basa sull'aiuto del CMAKE_XCODE_ATTRIBUTE_...supporto delle variabili di CMake . L'impostazione della CCe CXXdefinito dall'utente Xcode attributi per controllare il comando del compilatore e LDe LDPLUSPLUSper il comando del linker non è, per quanto ne so, una caratteristica documentata di progetti Xcode, ma non sembra funzionare. Se qualcuno può confermare che è ufficialmente supportato da Apple, aggiornerò l'articolo collegato e questa risposta di conseguenza.


Avevo anche bisogno del contenuto set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}")dell'articolo citato.
Jörn Reimerdes

Grazie per il promemoria, ho aggiornato la risposta per includere l'impostazione di LD e LDPLUSPLUS.
Craig Scott

ccache non supporta i compilatori VS, quindi non puoi usarlo per questo. C'è un progetto chiamato clcache che mira a fornire la stessa funzionalità per VS, ma non posso commentare come funziona bene.
Craig Scott

8

Non mi piaceva impostare un collegamento simbolico da g++a ccache. ECXX="ccache g++" non ha funzionato per me perché alcuni casi di test di cmake volevano avere solo il programma del compilatore senza attributi.

Quindi ho usato un piccolo script bash invece:

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

e salvato come eseguibile in /usr/bin/ccache-g++.

Quindi C ha configurato cmake per essere utilizzato /usr/bin/ccache-g++come compilatore C ++. In questo modo supera i casi di test cmake e mi sento più a mio agio di avere collegamenti simbolici che potrei dimenticare in 2 o 3 settimane e poi forse mi chiedo se qualcosa non funziona ...


6

Ho verificato i seguenti lavori (fonte: questo 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" $*

Aggiornamento : ho poi capito che anche questo non funziona. Stranamente funziona ogni volta alterne (le altre volte si lamenta cmake).


5

Secondo me il modo migliore è collegare simbolicamente gcc, g ++ a ccache, ma se vuoi usarlo all'interno di cmake, prova questo:

export CC="ccache gcc" CXX="ccache g++" cmake ...

4

Vorrei aggiungere un elemento importante che non è stato menzionato qui prima.

Durante l'avvio di un sistema di compilazione minimalista dall'immagine docker ubunutu: 18.04, ho scoperto che l'ordine di installazione fa la differenza.

Nel mio caso ccache ha funzionato bene durante la chiamata gcc, ma non è riuscito a catturare le chiamate dello stesso compilatore con gli altri nomi: cce c++. Per installare completamente ccache, è necessario assicurarsi che tutti i compilatori siano installati prima o aggiungere una chiamata ai collegamenti simbolici update-ccache per sicurezza.

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

... e poi (a causa dei collegamenti simbolici aggiornati) anche le chiamate a cc e c ++ vengono catturate!


Grazie non sapevo update-ccache-symlinks, stavo creando un c++collegamento con uno script per un progetto e funzionava ma non per un altro progetto (ancora non so perché, il collegamento andava bene),update-ccache-symlinks risolto.
Alex
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.