Building from Source¶
Complete guide to building the Onion compiler from source.
Prerequisites¶
Required Software¶
- Java Development Kit (JDK) 17 or later
Check version:
Install:
- macOS: brew install openjdk@17
- Ubuntu/Debian: sudo apt install openjdk-17-jdk
- Windows: Download from Adoptium
- SBT (Scala Build Tool)
Check version:
Install:
- macOS: brew install sbt
- Ubuntu/Debian: Follow official guide
- Windows: Download MSI installer
- Git
Cloning the Repository¶
Building¶
Basic Compilation¶
Compile the entire project:
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:
Incremental Compilation¶
SBT automatically performs incremental compilation. Only changed files are recompiled:
Testing¶
Run All Tests¶
Run Specific Test Suite¶
Run Tests Matching Pattern¶
Creating Distributions¶
Standalone JAR¶
Create a fat JAR with all dependencies:
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:
To run a script instead, invoke the ScriptRunner main class (this is what the
onion launcher does):
Distribution Package¶
Create a complete distribution ZIP:
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:
Development Build¶
Continuous Compilation¶
Watch for changes and recompile automatically:
Run from SBT¶
Execute without creating a JAR:
Run script runner:
Run the promoted REPL:
Run the readiness benchmark suite:
The default suite reports six explicit protocols:
- steady-state fresh compiler measurements for
run/Hello.on,run/TodoManager.on, andrun/StatsApp.on; - a process-cold
onion run/Hello.onmeasurement that includes child-JVM startup and shutdown; - submissions to one persistent, growing Onion REPL session; and
- one compilation of the deterministic 20-file automation fixture under
benchmarks/fixtures/automation-project/.
Process-cold uses 3 warmups by default; the other protocols use 8. Every
protocol uses 25 measured iterations and a 30-second iteration timeout.
--warmups N overrides the scenario defaults. The schema-v3 JSON report stores
the effective configuration beside every scenario so unlike lifecycles are
never presented as identical measurements. It also retains raw nanosecond
observations, median and p95 latency, phase timings where available, source
metrics, JVM/OS metadata, assigned memory, and typed absolute-policy checks.
The first practical milestone uses these inclusive latency ceilings:
| Protocol | Median | p95 |
|---|---|---|
Fresh onion Hello.on process |
1.5 s | 2.5 s |
Steady-state compile of Hello.on |
150 ms | 300 ms |
Steady-state compile of StatsApp.on |
750 ms | 1.2 s |
| Subsequent REPL snippet | 100 ms | 250 ms |
| 20-file/~2,000-line project | 2.0 s | 3.0 s |
The absolute policy is enforced only when the captured environment exactly
matches the reference lane: Ubuntu 24.04 x86-64, Eclipse Adoptium Temurin
JDK 21, two assigned processors, 4 GiB assigned memory, a 2 GiB maximum heap,
and G1. A breach on that lane fails the benchmark task. On every other
machine, the checks are not-applicable and the overall policy status is
informational; those measurements are useful for profiling but do not count
as release evidence.
The machine-readable report is written to
target/readiness/benchmark-v3.json. For a quick protocol smoke test:
sbt bench remains a compatibility alias and accepts the same options.
Emit compile profiles:
Interactive SBT¶
Start SBT shell:
Then run commands:
Parser Development¶
Modifying the Grammar¶
-
Edit the JavaCC grammar:
-
Regenerate parser:
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¶
- Install Scala plugin
- Open project:
File > Open > select build.sbt - Wait for indexing to complete
- Build:
Build > Build Project
Run configuration:
- Main class: onion.tools.CompilerFrontend
- Program arguments: path/to/source.on
- Working directory: $PROJECT_DIR$
Visual Studio Code¶
- Install Metals extension
- Open project folder
- Wait for import to complete
- Build via command palette:
Metals: Compile workspace
Troubleshooting¶
Parser Generation Fails¶
Out of Memory¶
.jvmopts already sets the project default to -Xmx10g. If you still hit an
OutOfMemoryError (most likely running the full test suite, not compile),
raise it further — do not set SBT_OPTS to something below 10g, since that
overrides .jvmopts and makes things worse, not better:
Dependency Issues¶
Clear Ivy cache:
Compilation Errors¶
Check Scala and Java versions:
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:
Java compiler options:
Performance Tips¶
Faster Builds¶
- Use incremental compilation (default)
- Don't clean unless necessary
- Increase JVM memory
- Use SBT shell for multiple commands
Parallel Compilation¶
SBT compiles in parallel by default. Adjust thread count:
Platform-Specific Notes¶
macOS¶
May need to set JAVA_HOME:
Linux¶
Ensure sufficient memory:
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¶
- Development Guide - Contributing to Onion
- Compiler Architecture - Internals
- Running Tests - Testing guide