Gradle + LLVM

Esta publicação curta pode ser útil para aqueles que gostariam de começar a trabalhar rapidamente com o LLVM , sem se preocupar em baixar o código-fonte e criar a estrutura. Quem não gostaria de bisbilhotar scripts obscuros do CMake para alcançar o resultado esperado e, finalmente, apenas para os preguiçosos :)

Vou lhe dizer como fazer isso normalmente, apenas algumas linhas no script de criação do Gradle.

Diante da necessidade de escrever código no LLVM, percebi que "atingi". :) "Hit" já está no estágio de configuração da compilação para o projeto. Eu precisava que o projeto fosse construído de maneira uniforme no Linux e no Windows. Escusado será dizer que toda vez que juntamente com o projeto eu não queria construir o LLVM inteiro. E, a princípio, contei com versões pré-criadas da biblioteca a partir do site oficial, mas, na verdade, existem apenas binários Linux construídos sem RTTI e exceções. No Windows, existe um instalador, mas, apesar de ser chamado LLVM-xxx-win64.exe, apenas dentro do clang.

Bem, no apêndice da compilação, existe um sistema CMake no qual, para compilar na versão de lançamento do Linux, você precisa definir no estágio de configuração:

cmake -DCMAKE_BUILD_TYPE=Release 

E no Windows, isso, por algum motivo, não é suficiente e você ainda precisa alterar adicionalmente a configuração no próprio comando build:

 cmake --build . --config Release 

Em geral, decidi voltar os olhos para Gradle e escrever um bom plug-in que teria o problema de configurar uma compilação para mim e me salvaria de uma rotina desnecessária, deixando apenas as coisas mais necessárias e de alto nível à vista.

Na verdade, a discussão abaixo será exclusivamente sobre ele: cpp-llvm .
Aqui está a configuração mínima necessária para integrar com o LLVM:

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

Requisitos para o trabalho:

  • Java instalado (8 e superior).
  • Gradle instalado (usei a versão mais recente 5.6.2 no momento da redação do artigo e não testei o plug-in em versões anteriores)
  • Gcc / CLang (versões que suportam pelo menos C ++ 11) no Linux.
  • MSVC 2019 (por exemplo, Community Edition) no Windows.
  • O plugin deve ser usado em conjunto com 'cpp-application' ou 'cpp-library'.
  • Acesso à rede no momento da primeira construção para baixar arquivos binários LLVM (ou modo offline, veja abaixo).

Versões suportadas do LLVM:

  • 9.0.0
  • 8.0.0

Compilações não oficiais para x86_64 no Windows (msvc 2019) e Linux (Debian 10.0 + CLang 10.0). Construído com RTTI ativado e exceções em duas versões, Release and 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

Compilações oficiais a partir de servidores LLVM, apenas x86_64 no Linux com RTTI desativado e exceções.

Para ver a lista de versões suportadas da plataforma atual, você pode usar o seguinte comando:

 gradle llvmVersions 

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

Todos os binários LLVM necessários para a construção são carregados no cache local (na pasta gradle no diretório do usuário) e reutilizados para outras construções.

No primeiro começo, a preparação para a construção pode levar um tempo considerável, porque cerca de 300 MB para a versão de depuração ou 30 MB para a versão de lançamento serão baixados da rede (as versões oficiais também pesam cerca de 300 MB).

Somente vinculação estática é usada. por algum motivo desconhecido, a ligação de compilação LLVM não pode criar bibliotecas dinâmicas no MSVC.

Outra configuração de plug-in


Você pode especificar um endereço específico para baixar o arquivo morto com binários (.tar.xz ou .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' } 

O principal é que a versão especificada (version = xxx) coincide com a versão real no arquivo morto selecionado para download, caso contrário, a configuração da compilação pode estar incorreta.

Você pode trabalhar com binários LLVM prontos (baixados ou criados por você) de forma autônoma


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

localPath deve apontar para uma pasta existente no sistema de arquivos local dentro da qual o plug-in espera ver os subdiretórios 'include' e 'lib', ou seja, estrutura de diretórios usada em compilações oficiais. Se após o autoajuste você tiver uma estrutura de pastas diferente, será necessário “pentear”. :)

As versões também devem corresponder, como já observado, no parágrafo anterior.
Nesse caso, nada relacionado ao LLVM será carregado da rede.

Trabalhe com componentes individuais:


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

Se você trabalha apenas com uma parte específica do LLVM, certamente precisa prestar atenção a esse parâmetro. Se, por exemplo, você só precisa do OrcJIT, por que vincular todas as cento e quarenta e cinco bibliotecas estáticas? A escolha de componentes específicos facilitará muito a vida do vinculador, e você economizará tempo.

Uma lista de todos os componentes disponíveis pode ser encontrada assim:

 gradle llvmComponents 

No Linux, você pode reduzir significativamente o tempo do link na versão de depuração, se você usar esta opção


 llvm { version = '9.0.0' forceReleaseLinux = true } 

Nesse caso, a versão forçada do LLVM é usada para a versão de depuração do seu build. Na maioria dos casos, eu recomendaria usá-lo, a menos que você precise depurar o próprio LLVM. Este parâmetro não afeta o assembly no Windows, porque, infelizmente, o MSVC 2019 não permite misturar bibliotecas de liberação e lançamento em uma compilação.

Bem, para concluir, é claro, eu recomendaria o uso deste plugin em conjunto com meus outros plugins :), que podem ser lidos neste artigo .

O cpp-build-tuner ajudará a otimizar o tempo de compilação e o tamanho do binário resultante.

O cpp-ide-generator oferecerá fácil integração com vários IDEs, na configuração dos quais já haverá caminhos para os cabeçalhos LLVM e o IDE poderá indexá-los corretamente.



Possível problema ao usar o 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. 

Se você viu isso, significa apenas que o cpp-ide-generator deve ser adicionado após o cpp-llvm, assim:

 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' } 

Um exemplo completo de uso do plugin pode ser encontrado aqui .

UPD:
Nova versão do plugin cpp-llvm v0.3 lançada :

  1. A tarefa llvmCleanCache foi llvmCleanCache para limpar todos os downloads do LLVM no cache local do usuário.
  2. Adicionado suporte para vinculação dinâmica. Somente a versão 9.0.0 do Windows / Linux, GCC / MinGW-W64 / CLang e MSVC é atualmente suportada.

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


UPD

Em conexão com a mudança de plugins de hospedagem, o grupo foi alterado:
 plugins { id 'loggersoft.cpp-llvm' version '0.5' } 

Novo endereço do projeto: gradle-cpp.sourceforge.io
Documentação: sourceforge.net/p/gradle-cpp/wiki/cpp-llvm

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


All Articles