SGDK on Fedora
After a fairly long hiatus from making my own programming projects due to Real Life, I’ve decided to try to make time for fun things. I hope to get back to dilettante-ing retro game development on a regular basis in 2025. For now, I’m switching from Ubuntu to Fedora as my development environment for SGDK.
Setting up SGDK with Docker
One of the nice thing about SGDK is it has a Docker container. This makes developing Sega Genesis games on Linux easy to do. You just need to setup docker, pull the SGDK image, and compile with docker run
.
- Install docker on Fedora 41.
I followed the steps I found here. NOTE I’m only listing the steps for Fedora 41 here.
sudo dnf install dnf-plugins-core
sudo dnf config-manager addrepo --from-repofile="https://download.docker.com/linux/fedora/docker-ce.repo"
sudo dnf install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
As usual, if you want to enable it at startup use
sudo systemctl enable docker
- Allow Standard Users to run Docker.
I don’t particularly like using root
or sudo
every time I use docker, so I went with the group option.
sudo groupadd docker && sudo gpasswd -a ${USER} docker && sudo systemctl restart docker
newgrp docker
Log out and log back in to make this work.
- Download SGDK’s pre-built docker image.
docker pull ghcr.io/stephane-d/sgdk
docker tag ghcr.io/stephane-d/sgdk sgdk
- Grab an SGDK project and built it with docker.
I used my example repository (SGDKRocks)
git clone https://github.com/radioation/SGDKRocks.git
cd SGDKRocks/01_basic_sprite
And built using my id and group with docker run
docker run --user $(id -u):$(id -g) --rm -v "$PWD":/src sgdk $
If all goes well you should see a rom file
docker run --user $(id -u):$(id -g) --rm -v "$PWD":/src sgdk
$ mkdir -p out/
echo "out/res/resources.o out/src/main.o" > out/cmd_
mkdir -p out/
m68k-elf-gcc -m68000 -B/sgdk/bin -n -T /sgdk/md.ld -nostdlib out/sega.o @out/cmd_ /sgdk/lib/libmd.a -lgcc -o out/rom.out -Wl,--gc-sections -flto -flto=auto -ffat-lto-objects
rm out/cmd_
m68k-elf-objcopy -O binary out/rom.out out/rom.bin
java -jar /sgdk/bin/sizebnd.jar out/rom.bin -sizealign 131072 -checksum
m68k-elf-nm -n out/rom.out > out/symbol.txt
And test it out. I use blastem
NOTE I added the --user
option to the docker run
command because the process fails due to permssions without it.
docker run --rm -v "$PWD":/src sgdk
$ mkdir -p out/
echo "out/res/resources.o out/src/main.o" > out/cmd_
sh: can't create out/cmd_: Permission denied
make: *** [/sgdk/makefile.gen:176: out/cmd_] Error 1
ggallard@ractor:~/dev/SGDKRocks/01_basic_sprite$
Build Specific SGDK Release
One thing I noticed while building some of my example code is the latest
docker image has some breaking changes to the API.
src/main.c: In function 'main':
src/main.c:405:5: error: too few arguments to function 'VDP_showFPS'
405 | VDP_showFPS(TRUE);
| ^~~~~~~~~~~
In file included from /sgdk/inc/bmp.h:23,
from /sgdk/inc/tools.h:13,
from /sgdk/inc/genesis.h:17,
from src/main.c:1:
/sgdk/inc/vdp.h:1115:6: note: declared here
1115 | void VDP_showFPS(u16 asFloat, u16 x, u16 y);
| ^~~~~~~~~~~
make: *** [/sgdk/makefile.gen:206: out/src/main.o] Error 1
rm res/resources.rs
As Issue #356 points out:
The :latest Docker tag is the only Docker tag in the repo. Having the only tag always point to the latest commit has occasionally introduced some instability for me in dependent projects
Luckily you can build an image on your own. I haven’t tried 2.0 with my git repositories yet, so I’ll try it out.
- Get the Relase Source Code All of SGDK’s release are listed on github In my case I wanted to use version 2.0, so I pulled it with
wget
wget https://github.com/Stephane-D/SGDK/archive/refs/tags/v2.00.tar.gz
- Build from Source. Building a new SGDK image is easy, just unpack the tarball and build it from the source directory.
tar -xvf v2.0.0.tar.tz
cd SGDK-2.00/
sudo docker build -t sgdk_v2.0 .
If everything went well it will look something like this:
+] Building 91.3s (12/12) FINISHED docker:default
[> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 887B 0.0s
=> [internal] load metadata for docker.io/amd64/ubuntu:20.04 1.4s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 331B 0.0s
=> [1/7] FROM docker.io/amd64/ubuntu:20.04@sha256:10ce2724e9d27deaba0e1a8a6061e77955ca638 2.1s
=> => resolve docker.io/amd64/ubuntu:20.04@sha256:10ce2724e9d27deaba0e1a8a6061e77955ca638 0.0s
=> => sha256:10ce2724e9d27deaba0e1a8a6061e77955ca6385d6abb9fdec90d6094844 1.45kB / 1.45kB 0.0s
=> => sha256:e5a6aeef391a8a9bdaee3de6b28f393837c479d8217324a2340b64e45a81e0ef 424B / 424B 0.0s
=> => sha256:6013ae1a63c2ee58a8949f03c6366a3ef6a2f386a7db27d86de2de965e9f 2.30kB / 2.30kB 0.0s
=> => sha256:d9802f032d6798e2086607424bfe88cb8ec1d6f116e11cd99592dcaf26 27.51MB / 27.51MB 1.3s
=> => extracting sha256:d9802f032d6798e2086607424bfe88cb8ec1d6f116e11cd99592dcaf261e9cd2 0.6s
=> [internal] load build context 0.4s
=> => transferring context: 55.53MB 0.3s
=> [2/7] RUN dpkg --add-architecture i386 && apt-get update && DEBIAN_FRONTEND=noni 81.4s
=> [3/7] RUN useradd -ms /bin/sh -d /sgdk sgdk 0.3s
=> [4/7] COPY . /sgdk 0.4s
=> [5/7] RUN sed -i 's/\r$//' sgdk/bin/create-bin-wrappers.sh && chmod +x sgdk/bi 0.2s
=> [6/7] RUN sgdk/bin/create-bin-wrappers.sh 0.3s
=> [7/7] WORKDIR /src 0.1s
=> exporting to image 4.9s
=> => exporting layers 4.9s
=> => writing image sha256:0200b4a30d7c2a8d4e8219f33b5f60ca1937c89c53966706a839c693e4ac5b 0.0s
=> => naming to docker.io/library/sgdk_v2.0 0.0s =
- Build with Your New Docker Image. I can now build with version 2.0 by specifying the image I just built.
docker run --user $(id -u):$(id -g) --rm -v "$PWD":/src sgdk_v2.0
This time the compiler error goes away and the build completes:
cd SGDKRocks/01_simple_collision
$ docker run --user $(id -u):$(id -g) --rm -v "$PWD":/src sgdk_v2.0
$ mkdir -p src/boot
mkdir -p out
mkdir -p out/src/
/sgdk/bin/gcc -DSGDK_GCC -m68000 -Wall -Wextra -Wno-shift-negative-value -Wno-main -Wno-unused-parameter -fno-builtin -fms-extensions -Iinc -Isrc -Ires -I/sgdk/inc -I/sgdk/res -B/sgdk/bin -O3 -fuse-linker-plugin -fno-web -fno-gcse -fno-unit-at-a-time -fomit-frame-pointer -flto -MMD -c src/main.c -o out/src/main.o
wine: created the configuration directory '/tmp/wine/.wineconf'
Could not find Wine Gecko. HTML rendering will be disabled.
wine: configuration in L"/tmp/wine/.wineconf" has been updated.
echo "out/res/resources.o out/src/main.o" > out/cmd_
/sgdk/bin/gcc -m68000 -B/sgdk/bin -n -T /sgdk/md.ld -nostdlib out/sega.o @out/cmd_ /sgdk/lib/libmd.a /sgdk/lib/libgcc.a -o out/rom.out -Wl,--gc-sections -flto
rm out/cmd_
/sgdk/bin/objcopy -O binary out/rom.out out/rom.bin
java -jar /sgdk/bin/sizebnd.jar out/rom.bin -sizealign 131072 -checksum
/sgdk/bin/nm --plugin=liblto_plugin-0.dll -n out/rom.out > out/symbol.txt
And it runs! .