Manualinux
http://www.nvu.com http://www.gimp.org InicioPresentaciónActualizacionesManualesDescargasNoticiasAgradecimientoEnlaces

Entornos GráficosAplicaciones

DesarrolloEmuladoresInternetJuegosMultimediaSistema

Compiladores Caché - Ccache

Compiladores Caché - BuildCache




Compiladores Caché - BuildCache




Copyright

Copyright © José Luis Lara Carrascal  2023-2024   http://manualinux.es



Sumario

Introducción
Instalación
Configuración
Enlaces



 
Introducción

BuildCache es un compilador caché que puede llegar a acelerar hasta 10 veces la recompilación (esto implica también una instalación de versiones futuras del programa cacheado, pero con un mayor tiempo de compilación) de cualquier programa cuyo código fuente esté escrito en C, C++ y Rust (desde la versión 0.29.0). Su desarrollo está inspirado en Ccache, el otro compilador caché tratado en esta web, y también en sscache y clcache. Menos completo que Ccache, permite la creación de scripts personalizados escritos en Lua, como interfaces de los compiladores. Soporta compresión (LZ4 y ZSTD) con nivel de compresión configurable, un segundo directorio remoto de caché, estadísticas, limpieza de caché, etc.

Entendamos el uso de este programa, como un complemento de Ccache, nunca como una sustitución total del mismo, dado sus carencias evidentes, como la falta de soporte de los lenguajes de programación, Objetive-C y Objetive-C++ que, por ejemplo, nos impide utilizarlo en la compilación de un programa como FileZilla, y otros errores que se puedan producir en otros paquetes. Aún así, el programa merece una oportunidad y un hueco en esta web, y siempre es bueno, poder elegir o combinar el uso de este tipo de programas. 



Instalación

Dependencias

Herramientas de Compilación


Entre paréntesis la versión con la que se ha compilado BuildCache para la elaboración de este documento.

* GCC - (14.2.0) o Clang - (18.1.8)
* CMake - (3.30.3)
* Ninja - (1.12.1)

Librerías de Desarrollo

* OpenSSL - (3.3.1)



Descarga

buildcache-v0.31.0.tar.bz2

Optimizaciones

$ export {C,CXX}FLAGS='-O3 -march=znver3 -mtune=znver3'

Donde pone znver3 se indica el procesador respectivo de cada sistema seleccionándolo de la siguiente tabla:
Nota informativa sobre las optimizaciones para GCC
* La opción '-march=' establece el procesador mínimo con el que funcionará el programa compilado, la opción '-mtune=' el procesador específico para el que será optimizado. 

* Los valores separados por comas, son equivalentes, es decir, que lo mismo da poner '-march=k8' que '-march=athlon64'.

* En versiones de GCC 3.2 e inferiores se utiliza la opción '-mcpu=' en lugar de '-mtune='.
Nota informativa sobre las optimizaciones para Clang
* La opción '-mtune=' está soportada a partir de la versión 3.4 de Clang.

* Los valores de color azul no son compatibles con Clang.

* Las filas con el fondo de color amarillo son valores exclusivos de Clang y, por lo tanto, no son aplicables con GCC.
Valores CPU
Genéricos
Intel
AMD

Optimizaciones adicionales

Optimizaciones adicionales
GCC
Graphite
$ export {C,CXX}FLAGS+=' -ftree-loop-linear -floop-strip-mine -floop-block'
IPA
$ export {C,CXX}FLAGS+=' -fipa-pta'
LTO
$ export {C,CXX}FLAGS+=' -fuse-linker-plugin -flto=auto'
En versiones inferiores a GCC 10, sustituir auto por el número de núcleos que tenga nuestro procesador. Si sólo tiene uno, utilizar el parámetro -flto
PGO
1) Fase inicial de compilación e instalación del paquete.
$ export {C,CXX}FLAGS+=' -O2 -fprofile-generate=/var/pgo/buildcache'
Configurar el paquete con la opción -DCMAKE_BUILD_TYPE=Debug
2) Ejecutar 'ninja -C build test -j$(nproc)' en el directorio raíz del paquete.
3) Fase final de compilación e instalación del paquete.
$ export {C,CXX}FLAGS+=' -fprofile-use=/var/pgo/buildcache'
Clang
Polly
$ export {C,CXX}FLAGS+=' -O3 -mllvm -polly -mllvm -polly-vectorizer=stripmine'
LTO
$ export {C,CXX,LD}FLAGS+=' -flto'
ThinLTO
$ export {C,CXX,LD}FLAGS+=' -flto=thin'
La aplicación de esta optimización es alternativa a la tradicional LTO, a partir de Clang 3.9 y, por lo tanto, no es combinable con la misma.
Unified LTO
LTO >> ThinLTO
$ export {C,CXX}FLAGS+=' -flto -funified-lto'
$ export LDFLAGS+=' -Wl,--lto=thin'
ThinLTO >> LTO
$ export {C,CXX}FLAGS+=' -flto=thin -funified-lto'
$ export LDFLAGS+=' -Wl,--lto=full'
La aplicación de esta optimización es aplicable, a partir de Clang 17, y sólo es combinable con LLD.
PGO
1) Fase inicial de compilación e instalación del paquete.
$ export {C,CXX}FLAGS+=' -O2 -fprofile-generate=/var/pgo/buildcache'
Configurar el paquete con la opción -DCMAKE_BUILD_TYPE=Debug
2) Ejecutar 'ninja -C build test -j$(nproc)' en el directorio raíz del paquete.
3) Conversión del perfil de optimización a un formato legible por Clang.
$ PGODIR=/var/pgo/buildcache; llvm-profdata merge $PGODIR/default_*.profraw --output=$PGODIR/default.profdata
4) Fase final de compilación e instalación del paquete.
$ export {C,CXX}FLAGS+=' -fprofile-use=/var/pgo/buildcache'

Parámetros adicionales

Parámetros adicionales de eliminación de avisos en el proceso de compilación
$ export {C,CXX}FLAGS+=' -w'

Establecer la ruta de búsqueda de directorios de librerías en sistemas de 64 bits multiarquitectura
$ export LDFLAGS+=" -L/usr/lib64 -L/usr/local/lib64 -L/opt/gcc14/lib64"
Cada usuario tendrá que establecer la ruta de búsqueda de directorios, en función de la distribución que utilice.

Establecer el uso de librería estándar de C++ para Libc++
Clang
$ export CXXFLAGS+=' -stdlib=libc++'

Establecer el uso de enlazador dinámico para Mold
$ export LDFLAGS+=' -fuse-ld=mold'

Establecer el uso de enlazador dinámico para LLD
Clang
$ export LDFLAGS+=' -fuse-ld=lld'
Optimizaciones complementarias LTO/ThinLTO/PGO de LLD
$ export LDFLAGS+=' -Wl,--lto-aa-pipeline=globals-aa -Wl,--lto-newpm-passes=pgo-memop-opt'
Optimizaciones complementarias LTO de LLD
$ export LDFLAGS+=" -Wl,--lto-partitions=$(expr $(nproc) / 2)"
Optimizaciones complementarias ThinLTO de LLD
$ export LDFLAGS+=" -Wl,--thinlto-jobs=$(expr $(nproc) / 2)"

Establecer la variable de entorno de uso de compilador para Clang
$ export CC=clang CXX=clang++

Extracción y Configuración  Bloc de Notas Información general sobre el uso de los comandos

$ tar jxvf buildcache-0.31.0.tar.bz2
$ cd buildcache-0.31.0
$ cmake -S src -B build -DCMAKE_INSTALL_PREFIX=/usr -G Ninja

Explicación de los comandos

-S src -B build : Establece el directorio del código fuente y crea de forma automática el directorio de compilación.

-DCMAKE_INSTALL_PREFIX=/usr : Instala el programa en el directorio principal, /usr.

-G Ninja : Utiliza Ninja en lugar de GNU Make para compilar el paquete (opcional).

Compilación

$ ninja -C build

Parámetros de compilación opcionales

-v : Muestra más información en el proceso de compilación.

-j$(nproc) : Establece el número de procesos de compilación en paralelo, en función del número de núcleos e hilos que tenga nuestro procesador, tomando como referencia la información mostrada por el sistema con el comando correspondiente. Si nuestro procesador es mononúcleo de un solo hilo, no añadir esta opción.

Instalación como root

$ su
# ninja -C build install/strip
# install -dm755 /usr/libexec/buildcache
# for i in gcc g++ cc c++ clang clang++; do \
ln -s /usr/bin/buildcache /usr/libexec/buildcache/$i ; \
done

Explicación de los comandos

install -dm755 /usr/libexec/buildcache : Crea el directorio de ubicación de los enlaces simbólicos, cuya ubicación activaremos con el correspondiente alias global de bash, para evitar problemas, si tenemos instalado también Ccache.

for i in gcc g++ cc c++ clang clang++; do \
ln -s /usr/bin/buildcache /usr/libexec/buildcache/$i ; \
done : Crea los enlaces simbólicos correspondientes relativos a GCC y Clang, apuntando al binario ejecutable buildcache.

Creación de un alias global de Bash

Para activar BuildCache, cuando lo creamos conveniente, creamos el alias global de Bash correspondiente, que instalaremos en /etc/profile.d.

# cat > buildcache.sh << "EOF"
#!/bin/sh

alias buildc="export PATH=/usr/libexec/buildcache:$PATH"
EOF
# install -m755 buildcache.sh /etc/profile.d

Ahora basta ejecutar buildc, para activar el uso de BuildCache:

$ buildc

Para comprobar que estamos utilizando estos enlaces simbólicos, nada mejor que utilizar el programa which, que se encarga de buscar el binario que le indiquemos previamente.

[jose@localhost ~]$ which gcc
/usr/libexec/buildcache/gcc

O, utilizar directamente BuildCache en modo DEBUG.

[jose@localhost ~]$ BUILDCACHE_DEBUG=1 gcc
BuildCache[8546] (DEBUG) Invoked as symlink: gcc
BuildCache[8546] (DEBUG) Found exe: /opt/gcc13/bin/gcc (gcc, /usr/bin/gcc)

En el caso de uso de Clang, basta establecer la correspondiente variable de entorno, al igual que hicieramos si no tuvieramos instalado BuildCache.

$ export CC=clang CXX=clang++

Otra solución es utilizar directamente BuildCache sin enlaces simbólicos alguno, estableciendo las correspondientes variables de entorno de uso de compilador, antes de configurar un determinado paquete.

GCC
$ export CC="buildcache gcc" CXX="buildcache g++"

Clang
$ export CC="buildcache clang" CXX="buildcache clang++"

Estadísticas de Compilación e Instalación de BuildCache

Estadísticas de Compilación e Instalación de BuildCache
CPU AMD Ryzen 5 5500
MHz 3600 (BoostMax=4457)
RAM 32 GB
Sistema de archivos XFS
Versión del Kernel 6.10.7-ml SMP PREEMPT_DYNAMIC x86_64
Modo de frecuencia de la CPU powersave (balance performance)
Planificador de CPU BMQ
Versión de Glibc 2.40
Librería estándar de C++ Libc++ 18.1.8
Enlazador dinámico LLD 18.1.8
Compilador Clang 18.1.8
Parámetros de optimización -03 -march=znver3 -mtune=znver3 -mllvm -polly -mllvm -polly-vectorizer=stripmine -flto -funified-lto -fprofile-use=/var/pgo/buildcache -Wl,--lto=thin -Wl,--thinlto-jobs=6 -Wl,--lto-aa-pipeline=globals-aa -Wl,--lto-newpm-passes=pgo-memop-opt
Parámetros de compilación -v -j12
Tiempo de compilación 12"
Archivos instalados 5
Mostrar/Ocultar la lista de archivos instalados
Enlaces simbólicos creados 6
Mostrar/Ocultar la lista de enlaces simbólicos creados
Ocupación de espacio en disco 1,3 MB

Desinstalación como root

1) MODO TRADICIONAL

Este programa no tiene soporte para desinstalación con el comando 'ninja uninstall'

2) MODO MANUALINUX

El principal inconveniente del comando anterior es que tenemos que tener el directorio de compilación en nuestro sistema para poder desinstalar el programa. En algunos casos esto supone muchos megas de espacio en disco. Con el paquete de scripts que pongo a continuación logramos evitar el único inconveniente que tiene la compilación de programas, y es el tema de la desinstalación de los mismos sin la necesidad de tener obligatoriamente una copia de las fuentes compiladas.

buildcache-0.31.0-scripts.tar.gz

$ su
# tar zxvf buildcache-0.31.0-scripts.tar.gz
# cd buildcache-0.31.0-scripts
# ./Desinstalar_buildcache-0.31.0

Copia de Seguridad como root

Con este otro script creamos una copia de seguridad de los binarios compilados, recreando la estructura de directorios de los mismos en un directorio de copias de seguridad (copibin) que se crea en el directorio /var. Cuando se haya creado el paquete comprimido de los binarios podemos copiarlo como usuario a nuestro home y borrar el que ha creado el script de respaldo, teniendo en cuenta que si queremos volver a restaurar la copia, tendremos que volver a copiarlo al lugar donde se ha creado.

$ su
# tar zxvf buildcache-0.31.0-scripts.tar.gz
# cd buildcache-0.31.0-scripts
# ./Respaldar_buildcache-0.31.0

Restaurar la Copia de Seguridad como root

Y con este otro script (que se copia de forma automática cuando creamos la copia de respaldo del programa) restauramos la copia de seguridad como root cuando resulte necesario.

$ su
# cd /var/copibin/restaurar_copias
# ./Restaurar_buildcache-0.31.0



Configuración de BuildCache  

1) El directorio por defecto de ubicación de la caché
2) Establecer un directorio único de caché para todos los usuarios
3) Limpiar la caché
4) Establecer el tamaño máximo de la caché
5) Estadísticas de uso
6) Desactivar el uso de BuildCache
7) Utilizar ZSTD en lugar de LZ4 para la compresión de la caché
8) Desactivar la compresión de la caché de BuildCache
9) Mostrar las opciones en curso de BuildCache
10) Utilizar BuildCcache con Rust



1) El directorio por defecto de ubicación de la caché  

El directorio predefinido de ubicación de la caché de BuildCache es el siguiente:

~/.buildcache

Y la ubicación del archivo de configuración es la siguiente:

~/.buildcache/config.json

Tanto en nuestro directorio personal, como en el directorio del root, el tamaño máximo definido por defecto de la caché es de 5 GB, establecidos en bytes. A diferencia de Ccache, BuildCache no permite modificar las opciones de configuración desde línea de comandos y, por lo tanto, no crea en ningún momento el archivo de configuración del mismo, hay que crearlo a mano en formato JSON, con lo que, en este manual recurriremos a las variables de entorno para modificar las opciones del programa.

2) Establecer un directorio único de caché para todos los usuarios  

La única condición que debe de tener este directorio es que sea accesible para lectura y escritura por todos los usuarios. La ventaja mayor es que nos ahorramos una duplicación de directorios, el del root y el nuestro propio. Lo primero que debemos de hacer es crear el directorio con los permisos correspondiente de acceso y escritura.

$ su -c "install -dm777 /.buildcache"

Luego, movemos como usuario, el contenido de la caché ubicada en nuestro directorio personal, al nuevo directorio.

$ mv ~/.buildcache/* /.buildcache

La que tengamos en el directorio del root, que siempre será de menor tamaño, simplemente la borramos.

$ su -c "buildcache -C"

Editamos con cat el archivo que hemos creado antes e instalado en /etc/profile.d, buildcache.sh y añadimos lo siguiente:

$ su
# cat >> /etc/profile.d/buildcache.sh << "EOF"
export BUILDCACHE_DIR=/.buildcache
EOF

Ejecutamos el archivo y comprobamos que la variable de entorno está en uso, con el comando que muestra la configuración del programa, acortando las opciones con grep.

[jose@localhost ~]$ buildcache -c | grep BUILDCACHE_DIR:
  BUILDCACHE_DIR:                    /.buildcache


3) Limpiar la caché  

Para ajustar el tamaño de la caché al máximo establecido en su configuración, ejecutamos el siguiente comando.

$ buildcache -H

Para borrarla por completo, el siguiente:

$ buildcache -C

4) Establecer el tamaño máximo de la caché  

Con la variable de entorno BUILDCACHE_MAX_CACHE_SIZE, estableceremos el tamaño máximo de la caché en bytes. Nos vamos a este enlace, metemos por ejemplo, 30, en la casilla gigabyte (GB), hacemos clic en calcular, y tomamos el resultado de la casilla byte (B), que añadiremos al archivo que hemos creado antes.

$ su
# cat >> /etc/profile.d/buildcache.sh << "EOF"
export BUILDCACHE_MAX_CACHE_SIZE=32212254720
EOF

Ejecutamos el archivo y comprobamos que la variable de entorno está en uso, con el comando que muestra la configuración del programa, acortando las opciones con grep.

[jose@localhost ~]$ buildcache -c | grep BUILDCACHE_MAX_CACHE
  BUILDCACHE_MAX_CACHE_SIZE:         32212254720 (30.0 GiB)

5) Estadísticas de uso

Como cualquier aplicación caché que se precie, BuildCache también nos muestra estadísticas de uso, con el siguiente comando:

[jose@localhost ~]$ buildcache -s
Cache status:
  Entries in cache:  118054
  Cache size:        2.7 GiB (9.0%)
  Direct hits:       1156
  Direct misses:     62139
  Local hits:        6282
  Local misses:      50876
  Remote hits:       0
  Remote misses:     0
  Misses:            50876
  Direct hit ratio:  1.8%
  Local hit ratio:   11.0%
  Remote hit ratio:  0.0%
  Hit ratio:         11.0%


Para poner a cero las estadísticas, ejecutamos el siguiente comando:

$ buildcache -z

6) Desactivar el uso de BuildCache

Esto es útil si, por ejemplo, queremos saber el tiempo real de compilación de un paquete determinado. Con la siguiente variable de entorno, BuildCache actuará como un simple intermediario sin almacenar dato alguno del proceso de compilación en curso. Eso sí, este modo es ligeramente más lento que utilizar el compilador de forma directa.

$ export BUILDCACHE_DISABLE=true

7) Utilizar ZSTD en lugar LZ4 para la compresión de la caché

BuildCache soporta dos formatos de compresión de la caché, LZ4 (el predefinido) y ZSTD. Si tenemos un procesador moderno, es recomendable utilizar ZSTD que ahorra más espacio en disco que LZ4. Con la variable de entorno BUILDCACHE_COMPRESS_FORMAT, estableceremos el formato de compresión ZSTD, que añadiremos al archivo que hemos creado antes.

$ su
# cat >> /etc/profile.d/buildcache.sh << "EOF"
export BUILDCACHE_COMPRESS_FORMAT=ZSTD
EOF

Ejecutamos el archivo y comprobamos que la variable de entorno está en uso, con el comando que muestra la configuración del programa, acortando las opciones con grep.

[jose@localhost ~]$ buildcache -c | grep BUILDCACHE_COMPRESS_FORMAT
  BUILDCACHE_COMPRESS_FORMAT:        ZSTD

8) Desactivar la compresión de la caché de BuildCache

Si nuestro procesador no es muy potente, lo más recomendable es desactivar la compresión, aunque para procesadores relativamente antiguos, LZ4 no es muy exigente que digamos. También hay que desactivarla si utilizamos sistemas de archivos como BTRFS o ZFS que ya tienen este soporte de forma nativa. Con la variable de entorno BUILDCACHE_COMPRESS, desactivamos la compresión de la caché

$ su
# cat >> /etc/profile.d/buildcache.sh << "EOF"
export BUILDCACHE_COMPRESS=false
EOF

Ejecutamos el archivo y comprobamos que la variable de entorno está en uso, con el comando que muestra la configuración del programa, acortando las opciones con grep.

[jose@localhost ~]$ buildcache -c | grep BUILDCACHE_COMPRESS:
  BUILDCACHE_COMPRESS:        false

9) Mostrar las opciones en curso de BuildCache


En cualquier momento, ejecutando el siguiente comando, podemos saber las opciones de BuildCache que se están utilizando. 

[jose@localhost ~]$ buildcache -c
Configuration file: /mnt/cache2/.buildcache/config.json

  BUILDCACHE_ACCURACY:               DEFAULT
  BUILDCACHE_CACHE_LINK_COMMANDS:    false
  BUILDCACHE_COMPRESS:               true
  BUILDCACHE_COMPRESS_FORMAT:        ZSTD
  BUILDCACHE_COMPRESS_LEVEL:         -1
  BUILDCACHE_DEBUG:                  -1
  BUILDCACHE_DIR:                    /mnt/cache2/.buildcache
  BUILDCACHE_DIRECT_MODE:            true
  BUILDCACHE_DISABLE:                false
  BUILDCACHE_HARD_LINKS:             false
  BUILDCACHE_HASH_EXTRA_FILES:      
  BUILDCACHE_IMPERSONATE:           
  BUILDCACHE_LOG_FILE:              
  BUILDCACHE_LUA_PATH:               /mnt/cache2/.buildcache/lua
  BUILDCACHE_MAX_CACHE_SIZE:         32212254720 (30.0 GiB)
  BUILDCACHE_MAX_LOCAL_ENTRY_SIZE:   134217728 (128.0 MiB)
  BUILDCACHE_MAX_REMOTE_ENTRY_SIZE:  134217728 (128.0 MiB)
  BUILDCACHE_PERF:                   false
  BUILDCACHE_PREFIX:                
  BUILDCACHE_READ_ONLY:              false
  BUILDCACHE_READ_ONLY_REMOTE:       false
  BUILDCACHE_REDIS_USERNAME:        
  BUILDCACHE_REDIS_PASSWORD:        
  BUILDCACHE_REMOTE:                
  BUILDCACHE_REMOTE_LOCKS:           false
  BUILDCACHE_S3_ACCESS:             
  BUILDCACHE_S3_SECRET:             
  BUILDCACHE_TERMINATE_ON_MISS:      false

10) Utilizar BuildCache con Rust

Para que BuildCache, almacene las compilaciones de Rust (soportadas de la versión 0.31.0), añadimos lo siguiente al archivo, buildcache.sh:

$ su
# cat >> /etc/profile.d/buildcache.sh << "EOF"
export RUSTC_WRAPPER=/usr/bin/buildcache
export CARGO_INCREMENTAL=0
EOF



Enlaces


https://gitlab.com/bits-n-bites/buildcache >> Enlace al proyecto del programa en GitLab.


Foro Galería Blog


Actualizado el 02-09-2024

Compiladores Caché - BuildCache

Compiladores Caché - Ccache