Skip to content

Building from Source

Complete guide to building the Onion compiler from source.

Prerequisites

Required Software

  1. Java Development Kit (JDK) 17 or later

Check version:

java -version
javac -version

Install: - macOS: brew install openjdk@17 - Ubuntu/Debian: sudo apt install openjdk-17-jdk - Windows: Download from Adoptium

  1. SBT (Scala Build Tool)

Check version:

sbt version

Install: - macOS: brew install sbt - Ubuntu/Debian: Follow official guide - Windows: Download MSI installer

  1. Git
git --version

Cloning the Repository

git clone https://github.com/onion-lang/onion.git
cd onion

Building

Basic Compilation

Compile the entire project:

sbt compile

This will: 1. Download dependencies (first time only) 2. Generate parser from JavaCC grammar 3. Compile Scala and Java source files

Expected output:

[info] compiling ... Scala sources and ... Java sources to target/scala-3.3.7/classes ...
[success] Total time: 45 s

Clean Build

Remove all generated files and rebuild:

sbt clean compile

Incremental Compilation

SBT automatically performs incremental compilation. Only changed files are recompiled:

# Edit a file
vim src/main/scala/onion/compiler/Typing.scala

# Fast recompilation
sbt compile

Testing

Run All Tests

sbt test

Run Specific Test Suite

sbt 'testOnly *HelloWorldSpec'
sbt 'testOnly *FactorialSpec'

Run Tests Matching Pattern

sbt 'testOnly *String*'

Creating Distributions

Standalone JAR

Create a fat JAR with all dependencies:

sbt assembly

Output: target/scala-3.3.7/onion.jar

The JAR's default main class is the compiler (onionc), so java -jar compiles a source file to .class files:

java -jar target/scala-3.3.7/onion.jar Hello.on   # compiles Hello.on

To run a script instead, invoke the ScriptRunner main class (this is what the onion launcher does):

java -cp target/scala-3.3.7/onion.jar onion.tools.ScriptRunner Hello.on

Distribution Package

Create a complete distribution ZIP:

sbt dist

Output: target/onion-dist.zip

Contents:

onion-dist/
├── onion.jar          # Main compiler JAR
├── lib/               # Dependencies
│   ├── asm-9.8.jar
│   ├── scala-library-3.3.7.jar
│   └── ...
├── bin/               # Executables
│   ├── onionc
│   ├── onion
│   └── onion-repl
├── run/               # Example programs
│   ├── Hello.on
│   ├── Array.on
│   └── ...
└── README.md

Extract and use:

unzip target/onion-dist.zip
cd onion-dist
export PATH=$PATH:$PWD/bin
onionc run/Hello.on

Development Build

Continuous Compilation

Watch for changes and recompile automatically:

sbt ~compile

Run from SBT

Execute without creating a JAR:

sbt 'run Hello.on'

Run script runner:

sbt 'runScript run/Hello.on'

Run the promoted REPL:

sbt repl

Run the benchmark suite:

sbt bench

Emit compile profiles:

sbt 'runMain onion.tools.CompilerFrontend --profile-compile run/Hello.on'

Interactive SBT

Start SBT shell:

sbt

Then run commands:

> compile
> test
> run Hello.on
> ~compile  # Continuous compilation
> exit

Parser Development

Modifying the Grammar

  1. Edit the JavaCC grammar:

    vim grammar/JJOnionParser.jj
    

  2. Regenerate parser:

    sbt clean compile
    

The parser is automatically regenerated when: - Grammar file is newer than generated parser - Running sbt clean

Parser Location

Generated parser:

target/scala-3.3.7/src_managed/main/java/onion/compiler/parser/
├── JJOnionParser.java
├── Token.java
├── TokenManager.java
└── ...

IDE Setup

IntelliJ IDEA

  1. Install Scala plugin
  2. Open project: File > Open > select build.sbt
  3. Wait for indexing to complete
  4. Build: Build > Build Project

Run configuration: - Main class: onion.tools.CompilerFrontend - Program arguments: path/to/source.on - Working directory: $PROJECT_DIR$

Visual Studio Code

  1. Install Metals extension
  2. Open project folder
  3. Wait for import to complete
  4. Build via command palette: Metals: Compile workspace

Troubleshooting

Parser Generation Fails

# Clean and rebuild
sbt clean
rm -rf target
sbt compile

Out of Memory

Increase SBT memory:

export SBT_OPTS="-Xmx2G"
sbt compile

Or edit .sbtopts:

-Xmx2G
-Xss2M

Dependency Issues

Clear Ivy cache:

rm -rf ~/.ivy2/cache
sbt update
sbt compile

Compilation Errors

Check Scala and Java versions:

sbt scalaVersion
java -version

Ensure they match requirements: - Scala 3.3.7 - Java 17+

Build Configuration

build.sbt

Key settings:

// Version is derived from git tags via sbt-dynver
scalaVersion := "3.3.7"
name := "onion"
organization := "org.onion_lang"

// Dependencies
libraryDependencies ++= Seq(
  "org.ow2.asm" % "asm" % "9.8",
  "net.java.dev.javacc" % "javacc" % "5.0",
  "org.scalatest" %% "scalatest" % "3.2.19" % "test"
)

// Main class
mainClass := Some("onion.tools.CompilerFrontend")

Compiler Options

Scala compiler options:

scalacOptions ++= Seq(
  "-encoding", "utf8",
  "-unchecked",
  "-deprecation",
  "-feature"
)

Java compiler options:

javacOptions ++= Seq(
  "-source", "17",
  "-Xlint:unchecked"
)

Performance Tips

Faster Builds

  1. Use incremental compilation (default)
  2. Don't clean unless necessary
  3. Increase JVM memory
  4. Use SBT shell for multiple commands

Parallel Compilation

SBT compiles in parallel by default. Adjust thread count:

Global / concurrentRestrictions := Seq(
  Tags.limitAll(4)
)

Platform-Specific Notes

macOS

May need to set JAVA_HOME:

export JAVA_HOME=$(/usr/libexec/java_home -v 17)

Linux

Ensure sufficient memory:

free -h
# Increase swap if needed

Windows

Use PowerShell or Git Bash. Paths use backslashes:

sbt assembly
# compile a source file:
java -jar target\scala-3.3.7\onion.jar Hello.on
# or run a script:
java -cp target\scala-3.3.7\onion.jar onion.tools.ScriptRunner Hello.on

Next Steps