This is a guide for developers to follow for various parts of the repository. This is mostly intended for maintainers of SquirrelJME.
Accepting Changes
TO BE WRITTEN
Applying Patches
TO BE WRITTEN
Merging Branches
To merge a branch locally, do the following:
- Update to the branch that will get submissions merged into:
fossil update trunk
- Merge the other branch into your current
trunk:fossil merge other-branch
- Commit the changes:
fossil commit
- Synchronize the repositories:
fossil sync -u
Releasing
When a release is to be made, it is performed in another branch and becomes
separate from trunk. This means that trunk is always in a state of
perpetual development. Within these branches, there are bug fixes and
releases. When a commit is ready for a release then it should just be tagged
and built accordingly. It is best to avoid having releases and such in the
trunk branch because it will complicate bug fixes and other things. So
when a release is to be made:
- Update the changelog with the planned release date if it is known at the time, otherwise it is not known.
- Fork the branch and make a new branch from
trunkfor the release to be done, an example would berelease-0.2.x. - In the new
release-0.2.xbranch, update the version numbers in the appropriate places so things are updated. - Tag the commit as
0.2.0or an increasing release version (example:0.2.1) for each increasing release. - Do all the common release stuff, noted in a future section.
- While in
trunk, do the following:- The development version can be bumped in which case the version will be incremented by two and will be odd (3, 5, 7, etc.).
- Add the next version to the changelog, so that it may be updated when there is a new major change.
RetroArch
For RetroArch, the SquirrelJME recipes should be updated to reflect the release tag.
Bug-fix and Otherwise Releases
If a bug-fix or otherwise has to be done on a release version, since the
release is in its own branch, the work can be done in that branch. Any fixes
should have already been made in trunk if applicable, then it can be
cherry-picked into the release branch. Then once the fixes have been made and
a new version is released the release version should be incremented (that is
0.2.0 to 0.2.1 to 0.2.2). Then any of the release related stuff should
be done.
Common Release Stuff
With the new pipeline build using CMake scripts, checkout the tag for the SquirrelJME release and run the following commands:
mkdir release- This can be done on any operating system.
cmake -B release -S squirreljme- This will configure the build.
- WARNING: The build will alert you if there are any release targets missing! There must never be an incomplete release!
cmake --build release --target fossilUpload- This will perform the build and upload all results to Fossil locally.
Fossil
- This is done automatically via
fossilUpload. - Download and test all the generated binaries to make sure they at least function.
- You will need to edit the download page to add the new version, this
will be done with
fossil unversion edit download.mkd. - Synchronize the repository with the unversioned space.
- This is done automatically via
GitHub
- Go to releases.
- Draft a new release.
- Choose the release tag you just made. Note that there might be a delay before GitHub is updated, so be patient or force it to update manually.
- Title the release.
SourceForge
- Create a new directory for the release number.
- Upload all the files into that directory.
- Appropriately set the operating systems for the binaries.
Importing SquirrelJME Into Another Project
Any one of SquirrelJME's modules can be used as a dependency for a project.
Note that the versions that are used depend on if a release is being used or
not, which is in the format of M.m.r for releases and M.m.r-SNAPSHOT for
development versions. Note that even minor versions are releases (ex: 0.4.0),
and odd minor versions are development versions (ex: 0.3.0-SNAPSHOT).
Snapshot Repository
<!-- Maven -->
<project>
<repositories>
<repository>
<id>oss.sonatype.org-snapshot</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
// Gradle
repositories {
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
}
}
Debugging
SquirrelJME's VMs may be debugged by having it connect to a debugger or waiting for a debug connection. Debugging happens purely over TCP/IP. It is not possible to use existing debuggers to debug SquirrelJME virtual machines there are debug interfaces available through standardized JDWP. Note that it is not recommended for the debugger port to be open to the internet as it will allow the remote debugger to have access to all the virtual machine internals.
Arguments to the virtual machines for SpringCoat, SummerCoat, etc.:
- Connect to remote debugger
-Dsquirreljme.jdwp=localhost:5005
- Listen for a remote connection
-Dsquirreljme.jdwp=:5005
Instructions for specific debuggers:
- jdb
- Connect:
jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=5005
- Listen:
jdb -connect com.sun.jdi.SocketListen:port=5005
- Connect:
- IntelliJ
- Eclipse
IntelliJ
SquirrelJME uses IntelliJ IDEA Ultimate which is highly recommended for development.
Recommended Plugins
The following plugins are recommended:
- EmbeddedProjectJdk -- Allows for custom defined JDKs, which SquirrelJME is its own JDK.
Build Issues
Cleaning your entire tree
Your entire source tree along with everything can be wiped cleaned with the following commands, NOTE THAT THIS WILL DELETE EVERYTHING:
- Fossil:
fossil clean -x -v - Git:
git clean -x -f -d
Environment Options
To account for potential future situations and pitfalls with different systems and environments, to account for potential situations may exist yet which have not been tested at all:
These options are available for CMake:
SJME_CONFIG_EO_LIBWINE_NATIVE_THREADS-- Use native threads instead of libwine's implementation of threads.
Foreign ScritchUI Libraries
It may be useful to use an alternative or additional implementation of ScritchUI.
When running SquirrelJME, set the following environment variables:
SQUIRRELJME_LIB_JVM=/path/to/nativesSQUIRRELJME_SCRITCHUI_INTERFACE=whattotest
libwine in-place of Win32
Quoted from the Wine mailing list, this is not possible to do natively
with Wine using dlopen and equivalent:
You need to compile and link your entire application with winegcc (or wineg++) and run it through Wine. winegcc will give you a file app.exe.so, which you can run with "wine app.exe.so". It'll also create an app.exe shell script that invokes Wine for you.
The reason why you cannot simply dlopen a Wine DLL and call code from it is that Wine's DLLs depend on having a running wineserver instance to take care of Windows kernel tasks that do not exist on the Linux side, e.g. the registry. Furthermore dependencies between Wine DLLs are resolved via PE exports / imports, so when you dlopen crypt32.dll the required user32.dll, advapi32.dll and bcrypt.dll libs won't be loaded and linked.
A winelib-linked program can call link to and call any Linux shared library. If the Wine-dependent functionality is relatively small and you do not with to have all of Wine loaded whenever your program is running, you could consider making the Wine-dependent bits run in an external process and communicate via pipes, sockets or shared memory with your main program.
TODO: ScritchUI proxy server?
GNUStep in-place of Cocoa
TODO: To be written, preferably in the wip-cocoa branch.
Custom File Type for Jasmin
IntelliJ supports custom file type definitions, the following is for Jasmin so that it has much better syntax highlighting.
Use the following setting:
- Name:
.j - Description:
Jasmin Instructions - Line comment:
; - Line comment only at line start:
Checked - Hex Prefix:
0x - Support String Escapes:
Checked
Then associated with:
*.j
Keywords
The following goes into the keyword fields.
1
abstract
final
native
private
protected
public
static
synchronized
transient
volatile
2
default
boolean
byte
short
char
int
long
float
double
3
.catch
.class
.end
.end field
.end method
.field
.implements
.interface
.limit
.limit locals
.limit stack
.line
.method
.source
.super
.throws
.var
4
aaload
aastore
aconst_null
aload
aload_0
aload_1
aload_2
aload_3
anewarray
areturn
arraylength
astore
astore_0
astore_1
astore_2
astore_3
athrow
baload
bastore
bipush
breakpoint
caload
castore
checkcast
d2f
d2i
d2l
dadd
daload
dastore
dcmpg
dcmpl
dconst_0
dconst_1
ddiv
dload
dload_0
dload_1
dload_2
dload_3
dmul
dneg
drem
dreturn
dstore
dstore_0
dstore_1
dstore_2
dstore_3
dsub
dup
dup2
dup2_x1
dup2_x2
dup_x1
dup_x2
f2d
f2i
f2l
fadd
faload
fastore
fcmpg
fcmpl
fconst_0
fconst_1
fconst_2
fdiv
fload
fload_0
fload_1
fload_2
fload_3
fmul
fneg
frem
freturn
fstore
fstore_0
fstore_1
fstore_2
fstore_3
fsub
getfield
getstatic
goto
goto_w
i2d
i2f
i2l
iadd
iaload
iand
iastore
iconst_0
iconst_1
iconst_2
iconst_3
iconst_4
iconst_5
iconst_m1
idiv
if_acmpeq
if_acmpne
if_icmpeq
if_icmpge
if_icmpgt
if_icmple
if_icmplt
if_icmpne
ifeq
ifge
ifgt
ifle
iflt
ifne
ifnonnull
ifnull
iinc
iload
iload_0
iload_1
iload_2
iload_3
imul
ineg
instanceof
int2byte
int2char
int2short
invokenonvirtual
invokestatic
invokevirtual
ior
irem
ireturn
ishl
ishr
istore
istore_0
istore_1
istore_2
istore_3
isub
iushr
ixor
jsr
jsr_w
l2d
l2f
l2i
ladd
laload
land
lastore
lcmp
lconst_0
lconst_1
ldc
ldc_w
ldiv
lload
lload_0
lload_1
lload_2
lload_3
lmul
lneg
lookupswitch
lor
lrem
lreturn
lshl
lshr
lstore
lstore_0
lstore_1
lstore_2
lstore_3
lsub
lushr
lxor
monitorenter
monitorexit
multianewarray
new
newarray
nop
pop
pop2
putfield
putstatic
ret
return
saload
sastore
sipush
swap
tableswitch
Build Job Scripts
The CI/CD scripts invoke the main primary build system that is in the root of the project via CMake. As such, much of the heavy lifting is not needed to be specifically handled. These scripts are POSIX compliant and do not require Bash, only a POSIX compliant shell. This means that BusyBox, Ash, and Dash should be able to execute these scripts without issues.
build-all.sh- This is the main build script which performs the build.
build-config.sh- Additional configure script run in the current shell context, so ensure that the current environment is properly setup and shared.
build-sync.sh- This is the synchronization script which uploads and downloads the repository and handles all changes.
build-vacuum.sh- This rebuilds and vacuums the Fossil database to reduce disk space and perform general optimizations.
Build Job Scheduling
Various systems have different scheduling systems available for running
jobs at specific times. This is generally for systems where cron is not
available or where there are different systems in place for builds. This is
generally just a reference for future usage.
It is recommended for sync to occur before all. Builds done with all may
be run as frequent as you are comfortable, officially this is done every
six hours. Otherwise, vacuum is a minor task used to save on disk space and
as such at a maximum only needs to be run weekly, however due to how long it
can take it can be run monthly. You should run all and vacuum to gauge
how often and the times you should schedule them.
cron
TODO
Haiku
TODO
macOS launchd Jobs
These .plist files are generally placed in /Library/LaunchDaemons/.
Jobs on macOS will not run unless the system is unlocked and decrypted, whether that is done through login or if FileVault is disabled. If a personal system is being used for building, it is not recommended to disable FileVault. You will have to log in as any user to unlock the system. Otherwise, it is suggested to keep the system in a secure and monitored location where it is tethered to a sturdy support if you are considering disabling FileVault.
Configuring the Time
The <key>StartCalendarInterval</key> value may contain multiple values within
the <array>, such as:
<array>
<dict>
<key>Hour</key>
<integer>3</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
<dict>
<key>Hour</key>
<integer>7</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
<dict>
<key>Hour</key>
<integer>13</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
<dict>
<key>Hour</key>
<integer>17</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
<dict>
<key>Hour</key>
<integer>22</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
</array>
cc.squirreljme.build.WHAT.plist:
Replace WHAT with script names accordingly, along with time adjustments.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>cc.squirreljme.build.WHAT</string>
<key>UserName</key>
<string>squirreljme</string>
<key>Program</key>
<string>/Users/squirreljme/build-WHAT.sh</string>
<key>WorkingDirectory</key>
<string>/Users/squirreljme/</string>
<key>RunAtLoad</key>
<true/>
<!-- Do not consume all system resources. -->
<key>Nice</key>
<integer>19</integer>
<key>ProcessType</key>
<string>Background</string>
<key>LowPriorityIO</key>
<true/>
<key>LowPriorityBackgroundIO</key>
<true/>
<!-- Adjust the time accordingly. -->
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Hour</key>
<integer>12</integer>
<key>Minute</key>
<integer>00</integer>
</dict>
</array>
</dict>
</plist>
systemd Jobs
Timer Units
TODO
Installation
TODO
Windows Task Scheduler
TODO