Scala-Projekte mit Eclipse PDE Build bauen
PDE Build ist das Standard-Build-System von Eclipse. Es wird verwendet, um OSGi Bundles, Plugins, Features oder Produkte zu exportieren. Im so genannten Headless Mode kann man es einsetzen, um automatisierte Builds ohne Eclipse UI durchzuführen. Die Scala IDE unterstützt PDE Build bisher noch nicht. Um Scala-Projekte zu kompilieren, muss man selbst etwas Hand anlegen.
Dieser Artikel bezieht sich auf eine ältere Version der Scala IDE for Eclipse. Informationen über die aktuelle Version findet man in einem neueren Beitrag!
Zunächst benötigt man ein Ant-Skript, das man in den Build-Prozess
einhängen kann. Das Skript sollte den Namen customBuildCallbacks.xml
haben und im Wurzel-Verzeichnis des Bundles liegen, das den zu
kompilierenden Scala-Quellcode enthält:
de.michel-kraemer.myplugin/
|- bin
|- META-INF
|- src
|- build.properties
|- customBuildCallbacks.xml
Im gleichen Verzeichnis liegt die Datei build.properties des Plugins.
(Nicht zu verwechseln mit der build.properties-Datei, die man für den
Headless Build benötigt!) Damit das neue Ant-Skript während des PDE
Builds auch ausgeführt wird, muss man dieser Datei folgendes hinzufügen:
customBuildCallbacks=customBuildCallbacks.xml
customBuildCallbacks.inheritall=true
Die zweite Zeile ermöglicht den Zugriff auf globale Properties wie zum
Beispiel ${build.result.folder}.
Im Ant-Skript kann man spezielle Targets definieren, die zu bestimmten
Zeitpunkten im Build-Prozess aufgerufen werden. Am besten kopiert man
dazu die Vorlage aus dem Verzeichnis
${eclipse.home}/plugins/org.eclipse.pde.build_*/templates/plugins/.
Das Target post.compile.@dot eignet sich hervorragend, um den
Scala-Compiler manuell aufzurufen. Dazu muss man zunächst die
Ant-Tasks definieren, die bereits mit der Scala Library ausgeliefert
werden. Eine automatische Suche nach der Scala Library, die durch die
Scala IDE installiert wird, und den dazugehörigen Tools kann man in Ant
zum Beispiel folgendermaßen realisieren:
<!-- find eclipse.home -->
<pathconvert property="eclipse.home">
<path location="${eclipse.launcher}" />
<mapper>
<!-- map "${eclipse.home}/eclipse.exe" to "${eclipse.home}" -->
<globmapper from="*/eclipse.exe" to="*" handledirsep="true" />
</mapper>
</pathconvert>
<!-- find scala bundle -->
<pathconvert property="scala_bundle">
<path>
<fileset dir="${eclipse.home}/plugins">
<include name="scala.library_*" />
</fileset>
</path>
</pathconvert>
<!-- find scala tools -->
<pathconvert property="scala_tools_jar">
<path>
<fileset dir="${eclipse.home}/plugins">
<include name="scala.tools.nsc_*" />
</fileset>
</path>
</pathconvert>
Danach steht der Pfad zum Scala-OSGi-Bundle in der Variablen ${scala_bundle}
zur Verfügung. Die Variable ${scala_tools_jar} zeigt außerdem auf die
Jar-Datei, die die Scala-Tools und damit auch die Ant-Tasks enthält.
Das Library-Bundle muss als nächstes entpackt werden, damit die
eigentliche Scala-Library scala-library.jar bei der Task-Definition
und beim Kompilieren im Classpath verwendet werden kann. Dazu nutzt man
am besten das temporäre Build-Verzeichnis, das in der Variablen
${build.result.folder} zu finden ist:
<unjar dest="${build.result.folder}/scala-library" src="${scala_bundle}" />
<property name="scala_library_jar"
location="${build.result.folder}/scala-library/lib/scala-library.jar" />
Danach können die Scala-Ant-Tasks definiert werden:
<!-- define scalac task -->
<taskdef resource="scala/tools/ant/antlib.xml">
<classpath>
<pathelement location="${scala_tools_jar}" />
<pathelement location="${scala_library_jar}" />
</classpath>
</taskdef>
Vor dem Kompilieren der Klassen, muss zunächst noch der korrekte
Classpath definiert werden. Dieser setzt sich aus den vom PDE Build
vorgegebenen Classpath @dot.classpath und der Scala-Library zusammen:
<pathconvert property="my.classpath">
<restrict>
<path>
<path refid="@dot.classpath" />
<pathelement location="${scala_library_jar}" />
</path>
<!-- remove libraries from classpath that don't exist (optional) -->
<rsel:exists />
</restrict>
</pathconvert>
Das Filtern von nicht vorhandenen Bibliotheken aus dem Classpath über
<rsel:exists /> ist hierbei optional. Damit dies funktioniert, muss
man im Root-Knoten der XML-Datei den entsprechenden Namespace definieren:
<project name="Build specific targets and properties"
xmlns:rsel="antlib:org.apache.tools.ant.types.resources.selectors">
...
Schließlich wird der Quellcode kompiliert:
<!-- compile scala source files -->
<mkdir dir="${target.folder}" />
<scalac srcdir="${source.folder1}"
destdir="${target.folder}"
classpath="${my.classpath}">
<include name="**/*.scala" />
</scalac>
Als letztes kann man noch die Scala-Quelldateien aus dem Zielordner entfernen, damit diese nicht mit dem Plugin ausgeliefert werden:
<!-- delete scala source files in output folder -->
<delete>
<fileset dir="${target.folder}" includes="**/*.scala" />
</delete>
Zusammenfassung
Die hier vorgestellte Methode verwendet die Möglichkeit, eigene
Ant-Kommandos in den PDE-Build-Prozess aufzunehmen. Dabei wird versucht,
die Scala-Bibliothek und die -Tools zu verwenden, die zusammen mit der
IDE ausgeliefert werden. Falls man dies nicht möchte, kann man auch die
Dateien scala-library.jar sowie scala-compiler.jar (enthält den
Ant-Task) aus der Standard-Scala-Distribution kopieren und diese
stattdessen in den Classpath einbinden.
Den vollständigen Quellcode der generischen Datei customBuildCallbacks.xml
kann man hier herunterladen:
customBuildCallbacks-old.xml (3.8 KiB)
Dieser Artikel bezieht sich auf eine ältere Version der Scala IDE for Eclipse. Ein aktualisiertes Ant-Skript findet man in einem neueren Beitrag!
Die Datei kann ohne Änderungen in jedes OSGi-Bundle kopiert werden, das
mit PDE Build gebaut werden soll und Scala-Code enthält. Lediglich die
Datei build.properties muss noch wie oben beschrieben angepasst werden.
Add to: