¿Cómo utilizar CCache con CMake?

90

Me gustaría hacer lo siguiente: Si CCache está presente en PATH, use "ccache g ++" para la compilación, de lo contrario use g ++. Intenté escribir un pequeño script my-cmake que contenía

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

pero no parece funcionar (ejecutar make todavía no usa ccache; verifiqué esto usando CMAKE_VERBOSE_MAKEFILE encendido).

Actualizar:

Según este enlace , intenté cambiar mi script a

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

pero cmake se rescata quejándose de que una prueba falló al usar el compilador ccache (lo que se puede esperar).

amit
fuente
4
¿Por qué no simplemente enlazas simbólicamente gcc a ccache? Y si usted está distribuyendo esto, yo creo que el propio usuario hubiese hecho el enlace simbólico si se hubiera instalado ccache y quería que sea utilizado ..
int3
1
@ int3 Sí, probablemente eso funcionaría (no sabía que ccache tiene el compilador como argumento opcional). Sin embargo, sería más limpio ser más explícito.
amit

Respuestas:

67

Yo personalmente tengo /usr/lib/ccacheen mi$PATH . Este directorio contiene un montón de enlaces simbólicos para cada nombre posible desde el que se podría llamar al compilador (como gccy gcc-4.3), todos apuntando a ccache.

Y ni siquiera creé los enlaces simbólicos. Ese directorio viene precargado cuando instalo ccache en Debian.

Nicolás
fuente
11
Tenga en cuenta que esta ruta ccache debe colocarse antes de la ruta en la que se encuentra su compilador real $PATHpara que funcione. Algo comoexport PATH = /usr/lib/ccache:$PATH
Gui13
6
@ Gui13: Mejor que actualizar la RUTA sería decirle a cmake explícitamente dónde está el gcc que debe usar, por ejemplo, cmake -DCMAKE_CXX_COMPILER = / usr / lib / ccache / bin / g ++
cib
3
Después brew install ccache, tengo /usr/local/Cellar/ccache/3.2.1/libexec/.
cdunn2001
96

Ahora es posible especificar ccache como un lanzador para compilar comandos y enlaces de comandos (desde cmake 2.8.0). Eso funciona para Makefile y generador Ninja. Para hacer esto, simplemente configure las siguientes propiedades:

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)

También es posible establecer estas propiedades solo para directorios o destinos específicos.

Para Ninja, esto es posible desde la versión 3.4. Para XCode, Craig Scott ofrece una solución alternativa en su respuesta.

Editar: Gracias a uprego y al comentario de Lekensteyn, edité la respuesta para verificar si ccache está disponible antes de usarlo como lanzador y para qué generadores es posible usar un lanzador de compilación.

Edit2: @Emilio Cobos recomendó evitar hacer eso para la parte de enlace ya que ccache no mejora la velocidad de enlace y puede interferir con otros tipos de caché como sccache

Babcool
fuente
Muchos sitios aconsejan implícitamente el uso de comillas dobles como en find_program(CCACHE_FOUND "ccache"), no sé cuál es más portátil, mi kilometraje funcionó perfectamente sin la necesidad de las comillas dobles.
1737973
5
Vale la pena señalar que esto actualmente solo funciona para generadores Makefile (a partir de cmake 3.3.2). Consulte la página del manual de cmake-properties.
Lekensteyn
1
Vale la pena señalar que esto entra en conflicto con la configuración de CTEST_USE_LAUNCHERS. Esas propiedades también se establecen aquí: github.com/Kitware/CMake/blob/master/Modules/…
purpleKarrot
Creo que es posible que desee cambiar el código a este (excepto, eliminar el texto del interiorendif() ) . Las mejoras son: 1. Hay una opción de configuración para deshabilitarlo, y 2. Resulta que los colores desaparecen de GCC / Clang en Make backend cuando se usan de esta manera. El ninjabackend funciona a su alrededor agregando una -fdiagnostics-coloropción, por lo que es recomendable hacerlo también para el makebackend.
Hi-Angel
94

A partir de CMAKE 3.4 puede hacer:

-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
Jacob
fuente
1
Y -DCMAKE_CXX_COMPILER_LAUNCHER=ccache. ¡Funcionan maravillosamente! No sé por qué cmake insiste en buscar clangdesde /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc(por lo que el truco del enlace simbólico no funciona), en lugar de desde $PATH, pero su respuesta funciona de todos modos.
cdunn2001
2
Esta debería ser la mejor respuesta. ¡No más problemas con la variable de ruta y los enlaces simbólicos del compilador!
ilya b.
1
Intenté esto, pero solo me da el error "ccache: error: invocación recursiva (el nombre del binario ccache debe ser" ccache ")". Mirando el rastreo detallado, está intentando ejecutar "/ usr / local / bin / ccache ccache / usr / bin / c ++" ...
Chris Dodd
3
¿Cómo interactúa con RULE_LAUNCH_COMPILE?
Trass3r
10

Desde CMake 3.1, es posible usar ccache con el generador Xcode y Ninja es compatible desde CMake 3.4 en adelante. Ninja honrará RULE_LAUNCH_COMPILEal igual que el generador de Makefiles de Unix (por lo que la respuesta de @ Babcool lo lleva allí para Ninja también), pero hacer que ccache funcione para el generador de Xcode requiere un poco más de trabajo. El siguiente artículo explica el método en detalle, centrándose en una implementación general que funciona para los tres generadores de CMake y sin hacer suposiciones sobre la configuración de los enlaces simbólicos de ccache o el compilador subyacente utilizado (aún permite que CMake decida el compilador):

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

La esencia general del artículo es la siguiente. El inicio de su CMakeLists.txtarchivo debe configurarse de esta manera:

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

Los dos archivos de plantilla de secuencia de comandos launch-c.iny se launch-cxx.inven así (deben estar en el mismo directorio que el CMakeLists.txtarchivo):

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

Lo anterior se usa RULE_LAUNCH_COMPILEsolo para Unix Makefiles y Ninja, pero para el generador Xcode se basa en la ayuda del CMAKE_XCODE_ATTRIBUTE_...soporte de variables de CMake . El ajuste de la CCy CXXdefinida por el usuario Xcode atributos para controlar el comando compilador y LDy LDPLUSPLUSde comando de enlace no es, por lo que yo puedo decir, una característica documentada de proyectos de Xcode, pero parece que no funciona. Si alguien puede confirmar que Apple lo admite oficialmente, actualizaré el artículo vinculado y esta respuesta en consecuencia.

Craig Scott
fuente
También necesitaba el set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_C_COMPILER}") set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_CXX_COMPILER}")del artículo mencionado.
Jörn Reimerdes
Gracias por el recordatorio, he actualizado la respuesta para incluir la configuración de LD y LDPLUSPLUS.
Craig Scott
ccache no admite compiladores VS, por lo que no puede usarlo para eso. Hay un proyecto llamado clcache que tiene como objetivo proporcionar la misma funcionalidad para VS, pero no puedo comentar qué tan bien funciona.
Craig Scott
9

No me gustó establecer un enlace simbólico de g++a ccache. Y CXX="ccache g++"no funcionó para mí, ya que algunos casos de prueba de cmake querían tener solo el programa compilador sin atributos.

Entonces usé un pequeño script bash en su lugar:

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

y lo guardó como ejecutable en /usr/bin/ccache-g++.

Luego, C configuró cmake para usarlo /usr/bin/ccache-g++como compilador de C ++. De esta manera pasa los casos de prueba de cmake y me siento más cómodo que tener enlaces simbólicos que podría olvidar en 2 o 3 semanas y luego quizás me pregunte si algo no funciona ...

Jonás
fuente
5

En mi opinión, la mejor manera es enlazar simbólicamente gcc, g ++ a ccache, pero si desea usar dentro de cmake, intente esto:

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

Verifiqué los siguientes trabajos (fuente: este enlace ):

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

Actualización : más tarde me di cuenta de que incluso esto no funciona. Curiosamente, funciona cada vez que se alternan (las otras veces cmake se queja).

amit
fuente
4

Permítanme agregar un elemento importante que no se mencionó aquí antes.

Mientras arrancaba un sistema de compilación minimalista de la imagen de la ventana acoplable ubunutu: 18.04, descubrí que el orden de instalación marca la diferencia.

En mi caso, ccache funcionó bien al llamar gcc, pero no pudo detectar las invocaciones del mismo compilador por los otros nombres: ccy c++. Para instalar ccache por completo, primero debe asegurarse de que todos los compiladores estén instalados o agregar una llamada a los enlaces simbólicos update-ccache para estar seguro.

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

... y luego (debido a los enlaces simbólicos actualizados) ¡también se detectan las llamadas a cc y c ++!

Jürgen Weigert
fuente
Gracias que no conocía update-ccache-symlinks, estaba creando un c++enlace con un script para un proyecto y estaba funcionando pero no para otro proyecto (todavía no sé por qué, el enlace estaba bien), update-ccache-symlinksresuelto.
Alex