diff --git a/build.gradle b/build.gradle
index 03170b2193172398fcaf465fdf0d94037ae28a1d..dfbb25f81aef9514984d28d26e6f46a3929eff24 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,6 @@
 plugins {
     id 'java-library'
+    id 'application'
     id 'org.jastadd'
     id 'java'
     id 'idea'
@@ -7,11 +8,18 @@ plugins {
     id 'com.github.ben-manes.versions' version '0.34.0'
 }
 
+ext {
+    mainClassName = 'org.jastadd.relast.compiler.RelastSourceToSourceCompiler'
+}
+
+// set the main class name for `gradle run`
+application.mainClassName = "${mainClassName}"
+
 sourceCompatibility = 1.8
 targetCompatibility = 1.8
 
 repositories {
-    jcenter()
+    mavenCentral()
 }
 
 sourceSets {
@@ -25,6 +33,7 @@ sourceSets {
 task modelJar(type: Jar) {
     group = "build"
     archiveBaseName = 'model'
+    archiveVersion = ''
     from sourceSets.model.output
 }
 
@@ -37,7 +46,7 @@ dependencies {
     modelImplementation group: 'org.jastadd', name: 'jastadd', version: '2.3.4'
     modelImplementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
 
-    compileOnly files(modelJar.archiveFile.get())
+    implementation files(modelJar.archiveFile.get())
     api group: 'org.jastadd', name: 'jastadd', version: '2.3.4'
     api group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
     implementation group: 'com.github.jknack', name: 'handlebars', version: '4.2.0'
@@ -56,6 +65,27 @@ dependencies {
     testFixturesApi group: 'commons-io', name: 'commons-io', version: '2.8.0'
 }
 
+def versionFile = 'src/main/resources/preprocessor.properties'
+def versionProps = new Properties()
+
+try {
+    file(versionFile).withInputStream { stream -> versionProps.load(stream) }
+    version = versionProps['version']
+} catch (e) {
+    // this happens, if either the properties file is not present, or cannot be read from
+    throw new GradleException("File ${versionFile} not found or unreadable. Aborting.", e)
+}
+
+jar {
+    manifest {
+        attributes "Main-Class": "${mainClassName}"
+    }
+
+    from {
+        configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
+    }
+}
+
 test {
     useJUnitPlatform()
 
diff --git a/src/main/java/org/jastadd/PreprocessorConfiguration.java b/src/main/java/org/jastadd/PreprocessorConfiguration.java
index 726aba32937e914fd6d10e0af8f20d8372c35acd..39fd43963ecdc1cece0649cf3e1123ed228e4505 100644
--- a/src/main/java/org/jastadd/PreprocessorConfiguration.java
+++ b/src/main/java/org/jastadd/PreprocessorConfiguration.java
@@ -28,6 +28,7 @@
 package org.jastadd;
 
 import org.jastadd.option.ArgumentParser;
+import org.jastadd.option.FlagOption;
 import org.jastadd.option.Option;
 
 import java.io.PrintStream;
@@ -70,6 +71,11 @@ public class PreprocessorConfiguration extends org.jastadd.Configuration {
       if (options.containsKey(option.name())) {
         System.err.println("Unable to add option '" + option.name() + "', because there is a JastAdd option with the same name.");
       } else {
+        if (option.name().equals("help") && option instanceof FlagOption) {
+          this.helpOption = (FlagOption) option;
+        } else if (option.name().equals("version") && option instanceof FlagOption) {
+          this.versionOption = (FlagOption) option;
+        }
         argParser.addOption(option);
         options.put(option.name(), option);
       }
diff --git a/src/main/java/org/jastadd/relast/compiler/AbstractCompiler.java b/src/main/java/org/jastadd/relast/compiler/AbstractCompiler.java
index 7c136853f1dd1b7f33c134ac2425e320b1ff685c..e9d55b5665735b74f05abe433c3bf1edc980ab57 100644
--- a/src/main/java/org/jastadd/relast/compiler/AbstractCompiler.java
+++ b/src/main/java/org/jastadd/relast/compiler/AbstractCompiler.java
@@ -5,6 +5,8 @@ import org.jastadd.option.FlagOption;
 import org.jastadd.option.Option;
 
 import java.util.ArrayList;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
 
 public abstract class AbstractCompiler {
 
@@ -13,7 +15,7 @@ public abstract class AbstractCompiler {
   protected ArrayList<Option<?>> options;
   private PreprocessorConfiguration configuration;
 
-  public AbstractCompiler(String name, boolean jastaddCompliant) {
+  protected AbstractCompiler(String name, boolean jastaddCompliant) {
     this.name = name;
     this.jastAddCompliant = jastaddCompliant;
   }
@@ -33,6 +35,16 @@ public abstract class AbstractCompiler {
       return 0;
     }
 
+    if (configuration.shouldPrintVersion()) {
+      try {
+        ResourceBundle resources = ResourceBundle.getBundle("preprocessor");
+        System.out.println(getName() + ", version " + resources.getString("version"));
+      } catch (MissingResourceException e) {
+        System.out.println(getName() + ", unknown version");
+      }
+      return 0;
+    }
+
     return compile();
   }
 
diff --git a/src/main/java/org/jastadd/relast/compiler/RelastSourceToSourceCompiler.java b/src/main/java/org/jastadd/relast/compiler/RelastSourceToSourceCompiler.java
index 7c394837fec649d30464cf882bc9578f205494a6..696c3c17ef59872ffaf174d4b8e4b4b7e8e9bdd1 100644
--- a/src/main/java/org/jastadd/relast/compiler/RelastSourceToSourceCompiler.java
+++ b/src/main/java/org/jastadd/relast/compiler/RelastSourceToSourceCompiler.java
@@ -15,7 +15,7 @@ public class RelastSourceToSourceCompiler extends RelAstProcessor {
 
   public static void main(String[] args) {
     try {
-      new RelastSourceToSourceCompiler("relast-preprocessor", true).run(args);
+      new RelastSourceToSourceCompiler("Relational RAGs Source-To-Source Compiler", false).run(args);
     } catch (CompilerException e) {
       System.err.println(e.getMessage());
       System.exit(-1);
diff --git a/src/main/resources/preprocessor.properties b/src/main/resources/preprocessor.properties
new file mode 100644
index 0000000000000000000000000000000000000000..aef125e08364f1a7ea3c0b1efce5449891cd4ea9
--- /dev/null
+++ b/src/main/resources/preprocessor.properties
@@ -0,0 +1 @@
+version=1.0.0