Cross-Kompilieren von Scala in einem Gradle-Projekt

In Scala-Projekten werden hĂ€ufig binĂ€re Artefakte bereitgestellt, die fĂŒr mehrere Versionen des Scala-Compilers kompiliert wurden. In der Regel ist es zum Erstellen mehrerer Versionen eines Artefakts in einer Community ĂŒblich, SBT zu verwenden, wobei diese Funktion sofort einsatzbereit ist und in mehreren Zeilen konfiguriert wird. Aber was ist, wenn wir verwirrt werden und einen Build fĂŒr die Cross-Kompilierung erstellen möchten, ohne SBT zu verwenden?


FĂŒr eines meiner Java-Projekte habe ich beschlossen, eine Scala-Fassade zu erstellen. In der Vergangenheit wurde das gesamte Projekt mit Gradle zusammengesetzt, und es wurde beschlossen, die Fassade demselben Projekt als Submodul hinzuzufĂŒgen. Gradle als Ganzes kann Scala-Module mit der EinschrĂ€nkung kompilieren, dass keine Cross-Compiling-UnterstĂŒtzung deklariert wurde. Es gibt ein offenes Ticket fĂŒr 2017 und einige Plugins ( 1 , 2 ), die versprechen, diese Funktion zu Ihrem Projekt hinzuzufĂŒgen, aber es gibt Probleme mit ihnen, die normalerweise mit der Veröffentlichung von Artefakten verbunden sind. Und allgemein gibt es nichts mehr. Ich habe mich entschlossen zu prĂŒfen, wie schwierig es ist, den Build fĂŒr die Cross-Kompilierung ohne spezielle Plugins und SMS zu konfigurieren.


ZunĂ€chst beschreiben wir das gewĂŒnschte Ergebnis. Ich möchte, dass derselbe Satz von Quellen von drei Versionen des Scala-Compilers kompiliert wird: 2.11, 2.12 und 2.13 (zu diesem Zeitpunkt der aktuellste 2.13.0-RC2). Und da Scala 2.13 eine Reihe von rĂŒckwĂ€rts inkompatiblen Änderungen in Sammlungen aufweist, möchte ich zusĂ€tzliche QuellensĂ€tze fĂŒr Code hinzufĂŒgen können, der fĂŒr jeden der Compiler spezifisch ist. Auch in SBT wird dies alles zu einigen Konfigurationszeilen hinzugefĂŒgt. Mal sehen, was in Gradle gemacht werden kann.


Projektstruktur


Die erste Schwierigkeit, der Sie sich stellen mĂŒssen, besteht darin, dass die Compilerversion aus der Version der deklarierten AbhĂ€ngigkeit von der Scala-Bibliothek berechnet wird. Außerdem mĂŒssen alle AbhĂ€ngigkeiten geĂ€ndert werden, die ein PrĂ€fix fĂŒr die Scala-Version des Compilers haben. Das heißt, FĂŒr jede Version des Compilers sollte die AbhĂ€ngigkeitsliste unterschiedlich sein. DarĂŒber hinaus ist der Satz von Flags fĂŒr verschiedene Versionen des Compilers tatsĂ€chlich unterschiedlich. Einige Flags wurden zwischen den Versionen umbenannt, wĂ€hrend andere einfach als veraltet markiert oder ganz entfernt wurden. Ich entschied, dass der Versuch, alle Nuancen verschiedener Compiler in einer Build-Datei zu erfassen, eine zu schwierige Aufgabe zu sein scheint und ihre weitere UnterstĂŒtzung noch schwieriger ist. Aus diesem Grund habe ich mich entschlossen, nach anderen Möglichkeiten zu suchen, um dieses Problem zu lösen. Was aber, wenn wir mehrere Build-Builds fĂŒr dieselbe Projektverzeichnisstruktur erstellen?


In der Deklaration fĂŒr die Aufnahme von Submodulen in das Gradle-Projekt können Sie das Verzeichnis angeben, in dem sich das Stammverzeichnis des Submoduls und der Name der fĂŒr seine Konfiguration verantwortlichen Datei befinden. Geben Sie dasselbe Verzeichnis fĂŒr mehrere Importe an und erstellen Sie fĂŒr jede Version des Compilers mehrere Kopien des Build-Skripts.


settings.gradle
rootProject.name = 'test' include 'java-library' include 'scala-facade_2.11' project(':scala-facade_2.11').with { projectDir = file('scala-facade') buildFileName = 'build-2.11.gradle' } include 'scala-facade_2.12' project(':scala-facade_2.12').with { projectDir = file('scala-facade') buildFileName = 'build-2.12.gradle' } include 'scala-facade_2.13' project(':scala-facade_2.13').with { projectDir = file('scala-facade') buildFileName = 'build-2.13.gradle' } 

Nicht schlecht, aber von Zeit zu Zeit können seltsame Kompilierungsfehler auftreten, die darauf zurĂŒckzufĂŒhren sind, dass alle drei Build-Skripte dasselbe Build-Verzeichnis verwenden. Wir können dies beheben, indem wir sie fĂŒr jeden Build festlegen:


build-2.12.gradle
 plugins { id 'scala' } buildDir = 'build-2.12' clean { delete 'build-2.12' } // ... 

Jetzt ist es sehr schön. Mit nur einem Problem wird ein solcher Build Ihre Lieblings-IDE verrĂŒckt machen, und höchstwahrscheinlich muss die weitere Bearbeitung Ihres Projekts mithilfe von Instrumenten erfolgen. Ich dachte, dass dies kein großes Problem ist, weil Sie können die ĂŒberschĂŒssigen Importe von Submodulen jederzeit einfach auskommentieren und den Cross-Build in einen regulĂ€ren Build verwandeln, mit dem Ihre IDE höchstwahrscheinlich arbeiten kann.


Was ist mit zusÀtzlichen QuellensÀtzen? Auch bei separaten Dateien stellte sich heraus, dass dies recht einfach ist. Erstellen Sie ein neues Verzeichnis und konfigurieren Sie es als Quellensatz.


build-2.12.gradle
 // ... sourceSets { compat { scala { srcDir 'src/main/scala-2.12-' } } main { scala { compileClasspath += compat.output } } test { scala { compileClasspath += compat.output runtimeClasspath += compat.output } } } // ... 

build-2.13.gradle
 // ... sourceSets { compat { scala { srcDir 'src/main/scala-2.13+' } } main { scala { compileClasspath += compat.output } } test { scala { compileClasspath += compat.output runtimeClasspath += compat.output } } } // ... 

Die endgĂŒltige Struktur des Projekts sieht folgendermaßen aus:


Abschlussprojekt


Hier können Sie auch einzelne gemeinsame Teile in externe Konfigurationsdateien trennen und in den Build importieren, um die Anzahl der Wiederholungen zu verringern. Aber fĂŒr mich hat es sich als ziemlich gut herausgestellt, deklarativ, isoliert und kompatibel mit allen möglichen Gradle-Plugins.


Insgesamt wurde das Problem gelöst, Gradles FlexibilitĂ€t reichte aus, um ein nicht triviales Setup recht elegant auszudrĂŒcken, und Scala-Crossbuild ist nicht nur mit SBT möglich. Wenn Sie aus dem einen oder anderen Grund Gradle zum Erstellen eines Scala-Projekts verwenden, ist Cross-Compilation eine Gelegenheit fĂŒr Sie auch erhĂ€ltlich. Ich hoffe jemand dieser Beitrag wird nĂŒtzlich sein. Vielen Dank fĂŒr Ihre Aufmerksamkeit.

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


All Articles