SquirrelJME requires the following before it can be built:
- Java 8 JDK
- CMake
- C Compiler
- Clang
- GCC
- Microsoft Visual C
- XCode
Installing Build Dependencies
These are simplified baseline instructions for installing build dependencies, note that these may change over time and are only here as a basis. Do not assume that this will be accurate.
Installing a C Compiler
A C compiler is needed for the intermediary layer along with NanoCoat.
Linux Distributions
These are instructions for Linux:
- Debian, Ubuntu, and derivatives:
apt-get install build-essential
Alternatively, your system likely already has cc/gcc already installed,
you may not have to do anything.
macOS
You must install XCode, more information on XCode is at https://developer.apple.com/xcode/. Alternatively there is a command line tool to install the XCode command line utilities for example if you are using Brew:
xcode-select --install
Note that if you are using an older version of macOS you will need to find and download an archived version of XCode.
Windows
Windows has multiple choices available.
Cygwin
You download Cygwin at: https://www.cygwin.com/.
If you wish to target actual Windows and not the Cygwin environment, be sure
to install the mingw-w64 GCC compilers.
Microsoft Visual Studio
Microsoft's Visual Studio may be used by Gradle to compile the code, note that it only uses the compiler tool from the installation (no GUI is needed).
- Download from https://visualstudio.microsoft.com/downloads/.
- At the minimum, the following must be installed (pieces that are crossed
out may be different for future versions of Microsoft's Compiler):
- Windows Universal C Runtime
- C++ Build Tools core Features
- MSVC ~~v142~~ - VS ~~2019~~ C++ ~~x86/x64~~ build tools
- C++ Redistributable Update
- Windows 10 SDK
- Alternatively, you can run the Visual Studio installer and import the
components file, this file can be found in the root and is called
.vsconfig.
Mingw-w64
You can use Mingw-w64 as well, it is a freely available compiler.
- Main web site: https://mingw-w64.org.
- In the downloads section it is recommended to use MingW-W64-builds:
- For the configuration use:
- GCC Version: The latest (at time of writing it was 8.0.0).
- Threads: win32.
- Exception Handling: seh.
- Install both 32-bit and 64-bit.
- For the configuration use:
MSYS2
TODO
Installing CMake
CMake can be downloaded and installed from https://cmake.org.
Note that for SquirrelJME, version 3.31 is recommended:
Installing a Java Development Kit
SquirrelJME requires a Java 8 virtual machine in order to build itself. Gradle is used as well however it is available through Gradle Wrapper.
Specific JDKs
These are instructions for specific JDKs.
AdoptOpenJDK/Adoptium
AdoptOpenJDK is the recommended way to build and setup SquirrelJME as it has long-term support and is easy to set up. You will need at least a Java 8 variant of AdoptOpenJDK.
Please note that Java 11 may be used as well.
Oracle's JDK (Windows, Linux, and Mac OS X)
Oracle's JDK supports modern systems and can be downloaded from:
Ensure that you download and install the JDK.
If running on ReactOS/Windows/Wine, make sure that the PATH environment
variables refers to the JDK's binary directory:
C:\Program Files\Java\jdk1.8.0_131\bin\
Linux Distributions
If you use a common Linux distribution it likely has a JDK available.
- Arch
- Debian, Ubuntu, and derivatives
- See https://wiki.debian.org/Java
- One of the following depending on package availability
apt-get install openjdk-8-jdkapt-get install openjdk-9-jdkapt-get install openjdk-11-jdk
- Gentoo
Developing Via IDEs, Editors, and the Command Line
SquirrelJME may be developed and used from within IDEs and Editors, however it is entirely possible to do everything from the command line using the most basic tools.
IntelliJ IDEA is the recommended IDE and Editor.
As a note due to the very large size of SquirrelJME, if you are using any tools that have metered costs. It is recommended to disable and turn those off, unless you are willing to accept the monetary risks and costs associated with such tools.
Eclipse
Before running on Eclipse you must run the following Gradle command:
- Setup Eclipse Project
- Windows:
gradlew eclipse - Linux/MacOS:
./gradlew eclipse
- Windows:
Then following this you may Import Existing Gradle Project and you will have access to the project for building.
VSCode
VSCode is not supported. It only has very minimal Java support, of which does not support an advanced project such as SquirrelJME. You may attempt to use VSCode, however expect the editor to crash and functionality to be limited.
It is recommended to disable any advanced features and not attempt to load the project structure as this may break your installation.
IntelliJ IDEA
SquirrelJME is developed with IntelliJ Ultimate, however Community Edition may still be used. This makes development easier and more integrated along with whatever code you write or contribute will match the style that is set in SquirrelJME.
This is the recommended way to develop SquirrelJME.
Developer Commands and Invocations
There are three core ways to invoke developer commands in SquirrelJME:
- CMake at the project root, for the entire project level.
- Gradle at the project root, for the SquirrelJME Java Runtime and testing.
- CMake in
nanocoat/, for NanoCoat.
Project Root (CMake)
The root CMake project is a supporting project that can detect, invoke, and build the common setups described in this document for both the SquirrelJME Java Runtime and NanoCoat. This is primarily intended for CI/CD pipelines to build the project and its distributions, however it may also be used by anyone to also get the same or similar result as a CI/CD pipeline.
CMake configure would be:
mkdir buildcmake -S . -B build
At configure time, the root project will scan for and detect for C compilers, a Java environment, whether this is being run in Fossil or Git, along with other details. This is so that you get the full experience accordingly, or not if anything is missing. There will also be a basic summary of what the current environment is capable of, along with anything that is missing.
The following main targets exist:
flatpakBundle(Not Supported) -- Builds the Flatpak bundle.fossilUpload-- Uploads everything to the Fossil unversioned space.fossilUpload.install4j-- Only uploads Install4J installers.fossilUpload.onlyNatives-- Only uploads native binaries.fossilUpload.<target>-- If applicable, upload specifically the output of another target, such asfossilUpload.sourceZip.
icon-- Converts the XPM icons to PNG forinstall4j.install4j-- Builds the Install4J Installer Bundle.natives.<os>.<arch>-- Builds and/or obtains the natives for a specific system. The configure step will show what is available.rom-- Builds all NanoCoat ROMs.romDebug-- Builds the debug ROM, with no tests.romRelease-- Builds the optimized ROM, with no tests.romTestDebug-- Builds the debug ROM, with tests.romTestRelease-- Builds the optimized ROM, with tests.
sourceTgz-- Bundles.tar.gzsources.sourceZip-- Bundles.zipsources.standaloneJar-- Builds the final merged Standalone Jar.standaloneJarBase-- Builds the non-merged non-final Standalone Jar without any native support layer other than the default.
test-- Runs all tests.testHostedDebug-- Runs hosted VM environment tests.testSpringCoatDebug-- Runs SpringCoat debug ROM tests.testSpringCoatRelease-- Runs SpringCoat optimized ROM tests.
More targets may exist, however these are usually sub-targets and helper targets to assist in the build. The ones listed above are the most important.
SquirrelJME Java Runtime (Gradle)
The main interaction with the SquirrelJME build environment is with Gradle which manages anything related to building and testing. All builds are performed through Gradle Wrapper which is used as the following:
- Windows:
gradlew - Others:
./gradlew
Gradle uses tasks of which multiple may be specified accordingly, such as running the tests within the repository:
gradlew test
If using IntelliJ you may tap Ctrl twice (Ctrl+Ctrl) and type in the following to run Gradle commands, it should automatically use the wrapper:
gradle
Invoking Virtual Machines Via Gradle
For development purposes you may use the virtual machines provided by the SquirrelJME run-time. Modules within SquirrelJME have tasks which allow them to be ran accordingly.
- SpringCoat
:modules:<name>:runSpringCoatDebug(running):modules:<name>:runSpringCoatRelease(running):modules:<name>:testSpringCoat(testing)
- Native (runs on the host Java SE)
:modules:<name>:runHostedDebug(running):modules:<name>:testHostedDebug(testing)
Note that the test task is not supported and will throw an exception, it
is not able to reliably test within SquirrelJME.
The following System properties are available:
squirreljme.jdwp=[hostname]:port-- Enable JDWP.- Enables JDWP for the given virtual machine.
- If only
:portis specified it will listen for incoming connections from a debugger. - If both
hostname:portis specified it will connect to a remote debugger. - Note that if the hosted environment is debugged, launched sub-tasks will not be run under the debugger.
squirreljme.xjdwp=[hostname]:port-- Enable JDWP for Hosted environment.- Does the same as
squirreljme.jdwpbut takes priority if both are specified in the event that debugging should be done for the hosted process.
- Does the same as
squirreljme.midlet=value-- The MIDlet to run, in the following order:- If
valueis a number and is-1, then no MIDlet will be selected and theMain-Classattribute will be force selected. - If
valueis a number, then it will be treated as an index. If the index is in bounds it will run the given MIDlet by index. - If
valueis a string, then a search will be performed for a MIDlet with a matching case-insensitive title. - If
valueis a string and starts or ends with an asterisk (*) then it will find a midlet whose title contains the text with a case-insensitive search. - Otherwise if
valueis a string, it will construct a virtual MIDlet which executes the given value as the name of a class within the JAR.
- If
squirreljme.sysprop.<systemProperty>=value-- Add system property.- This allows any system properties that are prefixed with this to be added into the target virtual machine when running.
- As an example
squirreljme.sysprop.favorite.animal=squirrel:- Will define system property
favorite.animal=squirrelwithin the virtual machine.
- Will define system property
squirreljme.thread=value-- The threading model to use.singleorcoop-- Single Cooperatively Threaded.multiorsmt-- Simultaneous Multi-Threading.
test.single=classname-- Run only the given test:- Will be the test class to be run.
- Multi-parameter tests are in the form of
classname@parameter, if a parameter is specified then only that one will be matched. Otherwise this will include all tests of that given parameter.
Custom Jar Runners
There are tasks that start with runJar in the root project which can run
a Jar specified by a property or environment variable, this is to ease
debugging in running a specific target accordingly.
-Djar=(path)-- The path to the Jar to run.$SQUIRRELJME_JAR-- The path to the Jar to run.
As an example you can run the following:
./gradlew runJarHostedDebug1 -Djar="application.jar"
Building ROMs
Full ROMs can be built with the following tasks, note that test ROMs contain all the testing libraries and are generally used to ensure things are working:
romSpringCoatDebugromSpringCoatRelease
Full Suite Virtual Machines
There is a task which initializes a full suite of SquirrelJME, including every module. This can be used to run a specific program within SquirrelJME's environment through Gradle.
- Hosted Environment.
fullHostedDebug
- SpringCoat
fullSpringCoatReleasefullSpringCoatDebug
There are system properties that are available and can be used to modify the behavior:
full.libraries=path...-- Additional libraries to place onto the suite path.- Same format as the
-classpathargument. On Windows this will use;as separators, while other systems will use:.
- Same format as the
cc.squirreljme.vm.trace=option[,option[,...]]-- Trace optionsall-- Enable all.instructions-- Instructions being executed.methodEntry-- Entry of methods.methodExit-- Exit of methods.mleCall-- SquirrelJME MLE Native Calls.invokeStatic-- Static invocations.allocation-- Allocations such asnew.classInitialize-- Class is initialized.vmException-- Virtual machine exceptions.missingClass-- Class does not exist.monitorEnter-- Monitor is entered.monitorExit-- Exiting a monitor.monitorWait-- Monitor is waited on.monitorNotify-- Monitor is notified.threadNew-- New thread is created.
New Java Version Contingency
With regard to https://github.com/SquirrelJME/SquirrelJME/issues/6 if in
the event this occurs, building with Gradle will attempt to use the
Eclipse Java Compiler to compile the project. It may be forced by passing
to Gradle -Dforce.ecj=true.
Standalone Java Based Emulators
A standalone Java emulator Jar which contains all the available test virtual machine implementations is available when calling the task:
:emulators:standalone:shadowJar
NanoCoat (CMake)
TODO
Antiquated Builds
These are builds which are antiquated, these still exist however they are likely to be removed and/or migrated to the improved CMake system.
Flatpak
Flatpak is no longer supported, however instructions here still remain if you wish you experiment. These instructions are very likely out of date.
This has been replaced by flatpakBundle.
This is used with Flatpak. This requires some dependencies first:
- Install
flatpak-builder flatpak install flathub org.freedesktop.Platform//23.08flatpak install flathub org.freedesktop.Sdk//23.08flatpak install flathub org.freedesktop.Sdk.Extension.openjdk11
With the dependencies installed, it may be built with:
flatpak-builder build-dir cc.squirreljme.SquirrelJME.ymlflatpak-builder --user --install build-dircc.squirreljme.SquirrelJME.yml
To bundle into a single file, run the following:
flatpak build-bundle $HOME/.local/share/flatpak/repo squirreljme.flatpakcc.squirreljme.SquirrelJME
To run from the command line, you may want to add to your PATH:
$HOME/.local/share/flatpak/exports/bin/
Mac OS
This is used with Homebrew, with checked out source code the following can be run:
- brew install --HEAD Formula/squirreljme-standalone.rb`