jvm/doc/howto/howto.tex
2025-01-14 22:10:46 -06:00

207 lines
6.0 KiB
TeX

\documentclass[20pt]{article}
\usepackage{hyperref}
\hypersetup{
colorlinks=true,
linkcolor=blue,
filecolor=magenta,
urlcolor=cyan,
pdftitle={Dreamcast},
pdfpagemode=FullScreen,
}
\usepackage{graphicx}
\graphicspath{ {./images/} }
\title{Building and running the Dreamcast JVM}
\date{}
\setcounter{secnumdepth}{0}
\begin{document}
\maketitle
\tableofcontents
\section{Introduction}
The \texttt{jvm} project's Dreamcast build system depends on the
\texttt{dreamcast} project. This dependency is limited mostly to sharing Make
rules. Clone both of these as siblings of the same parent directory, as in:
\begin{verbatim}
git clone https://github.com/buhman/dreamcast
git clone https://github.com/buhman/jvm
\end{verbatim}
If you would like to use a \texttt{.cdi} image, the build process also depends
on \texttt{cdi4dc}. It is assumed that this tool exists in the same directory
that contains the \texttt{dreamcast} and \texttt{jvm} directories. On Linux, do:
\begin{verbatim}
curl -LO https://files.dcemulation.org/software/pctools/cdi4dc/cdi4dc_02b_linux.zip
unzip cdi4dc_02b_linux.zip
chmod +x cdi4dc
\end{verbatim}
To build everything, do the following:
\begin{verbatim}
cd jvm
sh generate_classpath.sh
rm -f main.bin main.elf jvm.iso
make -f Makefile.dreamcast.mk TARGET=sh-elf- jvm.iso
../cdi4dc jvm.iso jvm.cdi
\end{verbatim}
You should change the value of \texttt{TARGET=sh-elf-} to whatever matches your
GCC SH installation. If for example your GCC is named \texttt{sh4-none-elf-gcc}
then the correct \texttt{TARGET} value would be \texttt{TARGET=sh4-none-elf-}
(including the trailing hyphen).
You can then run the generated \texttt{jvm.cdi} on Dreamcast hardware or
emulators.
\section{Additional notes}
\subsection{Generate classpath}
The \texttt{generate\_classpath.sh} script is terrible. It is a ``quick hack''
to work around \hyperref[sec:unsolved]{multiple unsolved problems}.
If you wish to modify the build process to include newly-written classes, you
should append them to the \texttt{application\_classes} array in
\texttt{generate\_classpath.sh}.
\subsection{Flycast settings}
I recommend the following Flycast settings:
\begin{itemize}
\item Video → Transparent Sorting → Per Pixel (selected)
\item Video → Rendering Options → Full Framebuffer Emulation (checked)
\item Video → Advanced → Copy Rendered Textures to VRAM (checked)
\item Advanced → Other → Serial Console (checked)
\end{itemize}
\subsection{Run the Dreamcast JVM on Linux/Windows/macOS}
The Dreamcast JVM can also run as a application on a PC operating system. This
can be useful for testing general Java features independently of running on a
Dreamcast.
\begin{verbatim}
make clean
make main
\end{verbatim}
You should run \texttt{make clean} any time you wish to swap between the PC and
Dreamcast versions of the JVM.
Compile one of the tests as an example:
\begin{verbatim}
make classes/test/TestIntegerBitCount.class
\end{verbatim}
Run the Dreamcast JVM like this:
\begin{verbatim}
cd classes
# ../main [entry_class_name] [class_file...]
../main test/TestIntegerBitCount test/*.class java/lang/*.class java/io/*.class
\end{verbatim}
Note that for no specific reason, the Dreamcast JVM main method declaration is
\begin{verbatim}
public static void main()
\end{verbatim}
rather than the standard
\begin{verbatim}
public static void main(String[] args)
\end{verbatim}
I may change this in the future (it is not hard to support either, or even
both).
\subsection{JVM debug print}
\texttt{DEBUG\_PRINT} is \textbf{very slow} and unintelligibly verbose for
non-trivial programs. It is mostly useful for doing low-level debugging of the
JVM itself for very simple programs.
This can be disabled/enabled in either \texttt{Makefile} or
\texttt{Makefile.dreamcast.mk} by commenting/uncommenting the line
\begin{verbatim}
CFLAGS += -DDEBUG_PRINT
\end{verbatim}
When changing \texttt{CFLAGS}, remove all previously-built object files with the
command:
\begin{verbatim}
make clean
\end{verbatim}
\section{Unsolved problems}
\label{sec:unsolved}
There are a few issues that currently cause the build process to be uglier than
I'd like it to be. I welcome any suggestions regarding any of these topics:
\subsection{Boot class path}
The Dreamcast JVM includes its own versions the classes from
\texttt{java.lang}. The OpenJDK \texttt{javac}, however, will attempt to link
against OpenJDK's own version of \texttt{java.lang}.
In many cases, this will coincidentally not cause issues. However, it is better
to explicitly reference the Dreamcast JVM's version of \texttt{java.lang} to be
able to catch any linking errors as early as possible (\texttt{javac}'s error
messages are also much better than those you'd get from \texttt{jvm.bin}).
However, \texttt{javac} doesn't appear to support this in a convenient way. The
best invocation I've found so far is:
\begin{verbatim}
cd jvm/classes
javac -Xlint:-options --source 8 --target 8 --boot-class-path . path/to/YourClass.java
\end{verbatim}
This does limit you to Java 8 language features, but this appears to be the only
way to enable the \texttt{--boot-class-path} option, for which there is no clear
replacement in newer versions.
\subsection{Nested class filenames contain the dollar-sign character}
I have not managed to make my Make rules tolerant of \texttt{\$} characters in
filenames. This is the main reason why \texttt{generate\_classpath.sh} exists,
and it's also the reason why it's terrible.
\subsection{Unused class/method removal}
It would be nice to have a build process/tool that works like this:
\begin{itemize}
\item give the name of the ``main''/entrypoint class as a command-line argument
\item automatically/recursively calculate the minimum set of
classes/methods/fields that ``main'' depends on
\item from the full library of available classes, emit a reduced/minimal set of
(compiled) class files that only contain the methods and fields that are
reachable via ``main''.
\end{itemize}
I will create this tool at some point.
\end{document}