Gradle + LLVM

Esta breve publicación puede ser útil para aquellos que desean comenzar a trabajar rápidamente con LLVM , sin molestarse en descargar el código fuente y construir el marco. ¿Quién no querría hurgar en oscuros scripts de CMake para lograr el resultado esperado, y finalmente, solo para los perezosos :)

Te diré cómo hacerlo con gracia, solo un par de líneas en el script de compilación de Gradle.

Ante la necesidad de escribir código bajo LLVM, me di cuenta de que "golpeó". :) "Hit" ya se encuentra en la etapa de configuración de la compilación del proyecto. Necesitaba que el proyecto se construyera uniformemente tanto en Linux como en Windows. No hace falta decir que, cada vez que estuve junto con el proyecto, no quería construir el LLVM completo. Y, al principio, confié en versiones precompiladas de la biblioteca desde su sitio oficial, pero resultó que, de hecho, solo hay binarios de Linux construidos sin RTTI y excepciones. En Windows hay un instalador, pero a pesar del hecho de que se llama LLVM-xxx-win64.exe dentro de solo clang.

Bueno, en el apéndice de la compilación, hay un sistema CMake en el que para compilar en la versión de lanzamiento de Linux debe establecer en la etapa de configuración:

cmake -DCMAKE_BUILD_TYPE=Release 

Y en Windows esto, por alguna razón, no es suficiente y aún tiene que cambiar adicionalmente la configuración en el comando de compilación en sí:

 cmake --build . --config Release 

En general, decidí dirigir mis ojos a Gradle y escribir un buen complemento que me tomaría la molestia de configurar una compilación para mí y salvarme de una rutina innecesaria, dejando a la vista solo las cosas más necesarias y de alto nivel.

En realidad, la discusión a continuación será exclusivamente sobre él: cpp-llvm .
Aquí está la configuración mínima requerida para integrarse con LLVM:

 plugins { id 'org.bitbucket.akornilov.cpp-llvm' version '0.1' } llvm { version = '9.0.0' // Required version. } 

Requisitos para el trabajo:

  • Java instalado (8 y superior).
  • Gradle instalado (utilicé la última versión 5.6.2 al momento de escribir el artículo y no probé el complemento en versiones anteriores)
  • Gcc / CLang (versiones que admiten al menos C ++ 11) en Linux.
  • MSVC 2019 (por ejemplo, Community Edition) en Windows.
  • El complemento debe usarse junto con 'cpp-application' o 'cpp-library'.
  • Acceso a la red en el momento de la primera construcción para descargar archivos binarios LLVM (o modo fuera de línea, ver más abajo).

Versiones compatibles de LLVM:

  • 9.0.0
  • 8.0.0

Compilaciones no oficiales para x86_64 en Windows (msvc 2019) y Linux (Debian 10.0 + CLang 10.0). Construido con RTTI habilitado y excepciones en dos versiones Release y Debug.

  • 7.1.0
  • 7.0.1
  • 7.0.0
  • 6.0.1
  • 6.0.0
  • 5.0.2
  • 5.0.1
  • 5.0.0
  • 4.0.1
  • 4.0.0
  • 3.9.1
  • 3.9.0
  • 3.8.1
  • 3.8.0
  • 3.7.1
  • 3.7.0
  • 3.6.2
  • 3.6.1
  • 3.6.0
  • 3.5.2
  • 3.5.1
  • 3.5.0
  • 3.4.2
  • 3.4.1
  • 3.4
  • 3,3
  • 3.2
  • 3.1
  • 3.0

Compilaciones oficiales de servidores LLVM, solo x86_64 en Linux con RTTI desactivado y excepciones.

Para ver la lista de versiones compatibles para la plataforma actual, puede usar el siguiente comando:

 gradle llvmVersions 

 > Task :llvm-app:llvmVersions 9.0.0 8.0.0 BUILD SUCCESSFUL in 2s 1 actionable task: 1 executed 

Todos los archivos binarios de LLVM necesarios para la compilación se cargan en la memoria caché local (en la carpeta gradle en el directorio del usuario) y se reutilizan para otras compilaciones.

Al principio, la preparación para la construcción puede llevar un tiempo considerable, porque se descargarán de la red aproximadamente 300 MB para la versión de depuración o 30 MB para la versión de lanzamiento (las versiones oficiales también pesan aproximadamente 300 MB).

Solo se usa el enlace estático. por alguna razón desconocida, el enlace LLVM de compilación no puede crear bibliotecas dinámicas en MSVC.

Otra configuración de complemento


Puede especificar una dirección específica para descargar el archivo con binarios (.tar.xz o .tar.gz).


 llvm { version = '7.0.1' serverUrl = 'http://releases.llvm.org/7.0.1/clang%2bllvm-7.0.1-x86_64-linux-gnu-ubuntu-18.04.tar.xz' } 

Lo principal es que la versión especificada (versión = xxx) coincide con la que es real en el archivo seleccionado para descargar, de lo contrario, la configuración de compilación puede ser incorrecta.

Puede trabajar con binarios LLVM listos para usar (descargados o creados usted mismo) de forma autónoma


 llvm { version = '7.0.1' localPath = '<path to unpacked LLVM build>' } 

localPath debería apuntar a una carpeta existente en el sistema de archivos local dentro del cual el complemento espera ver los subdirectorios 'incluir' y 'lib', es decir estructura de directorios utilizada en compilaciones oficiales. Si después del autoajuste tiene una estructura de carpetas diferente, deberá "peinarla". :)

Las versiones también deben coincidir, como ya se señaló, en el párrafo anterior.
En este caso, nada relacionado con LLVM se cargará desde la red.

Trabajar con componentes individuales:


 llvm { version = '9.0.0' components = ['Engine', 'OrcJIT'] } 

Si trabaja solo con una parte específica de LLVM, entonces ciertamente debe prestar atención a este parámetro. Si, por ejemplo, solo necesita OrcJIT, ¿por qué vincular las ciento cuarenta y cinco bibliotecas estáticas? La elección de componentes específicos facilitará en gran medida la vida útil del enlazador y ahorrará tiempo.

Una lista de todos los componentes disponibles se puede encontrar así:

 gradle llvmComponents 

En Linux, puede reducir significativamente el tiempo de enlace en la versión de depuración, si usa esta opción


 llvm { version = '9.0.0' forceReleaseLinux = true } 

En este caso, la versión forzada de LLVM se usa para la versión de depuración de su compilación. En la mayoría de los casos, recomendaría usarlo a menos que necesite depurar LLVM. Este parámetro no afecta el ensamblado en Windows, porque, desafortunadamente, MSVC 2019 no permite mezclar versiones y bibliotecas de versiones en una compilación.

Bueno, en conclusión, por supuesto, recomendaría usar este complemento junto con mis otros complementos :), que se pueden leer en este artículo .

cpp-build-tuner ayudará a optimizar el tiempo de compilación y el tamaño del binario resultante.

cpp-ide-generator le proporcionará una fácil integración con varios IDE, en cuya configuración ya habrá rutas a los encabezados de LLVM y el IDE podrá indexarlos correctamente.



Posible problema al usar cpp-ide-generator:

 FAILURE: Build failed with an exception. * What went wrong: A problem occurred configuring project ':llvm-app'. > Cannot change dependencies of configuration ':llvm-app:cppCompileDebug' after it has been resolved. 

Si vio esto, solo significa que cpp-ide-generator debe agregarse después de cpp-llvm, como aquí:

 plugins { id 'cpp-application' id 'org.bitbucket.akornilov.cpp-build-tuner' version '0.7' id 'org.bitbucket.akornilov.cpp-llvm' version '0.1' id 'org.bitbucket.akornilov.cpp-ide-generator' version '0.5' } 

Puede encontrar un ejemplo completo del uso del complemento aquí .

UPD:
Nueva versión del complemento cpp-llvm v0.3 lanzado :

  1. La tarea llvmCleanCache se ha llvmCleanCache para borrar todas las descargas de LLVM en la memoria caché local del usuario.
  2. Soporte agregado para enlaces dinámicos. Actualmente solo se admite la versión 9.0.0 de Windows / Linux, GCC / MinGW-W64 / CLang y MSVC.

 llvm { version = '9.0.0' linkage = Linkage.SHARED } 


UPD

En relación con el cambio de complementos de alojamiento, el grupo cambió:
 plugins { id 'loggersoft.cpp-llvm' version '0.5' } 

Nueva dirección del proyecto: gradle-cpp.sourceforge.io
Documentación: sourceforge.net/p/gradle-cpp/wiki/cpp-llvm

Source: https://habr.com/ru/post/469855/


All Articles