Skip to content

Adding a new language

MCJ Vasseur edited this page Jun 4, 2024 · 6 revisions

Adding a new language

DOMjudge has a default set of languages but it is possible to add your own.

Every submission is ran in an isolated container so the best way to test a new language is to first get the new language installed in the container via the options of dj_make_chroot; start this container with dj_run_chroot and test if you can compile and run some default programs to verify that everything can work; when this works, start to build the run/build scripts by looking at similar languages which already exist in DOMjudge and create the language with you own build/run scripts.

Default DOMjudge will mount only a limited set of directories and those does not include the /tmp/ directory which is used by R for example; therefore, in case of such failures, check if the tmp directory can be set with an environment variable, or extend the chroot-startstop.sh, or look into CREATE_WRITABLE_TEMP_DIR defined here. Be aware that providing writable directories opens up a security hole where the submission may write data into and pass information from one test-case-run to the next.

Kotlin

Kotlin is an officially supported programming language in the programming environment of the ICPC world finals.

To add the Kotlin programming language to a DOMjudge installation, first, the Kotlin command-line compiler should be installed in the chroot environment of the judgehosts (see Installation of the judgehosts - creating a chroot environment | DOMjudge documentation).

Installing Kotlin on existing judgehost

If there is an already running instance of judgehost, access its terminal and unzip the Kotlin compiler in its chroot environment directory (usually /chroot/domjudge/); optionally, for automatic Kotlin compiler discovery in the Kotlin run script, include the extracted bin/kotlinc in the PATH variable of the chroot environment (can be done by creating a symbolic link to the extracted bin/kotlinc inside a directory already included in the PATH); for example:

# A judgehost terminal

CHROOTDIR="/chroot/domjudge"
KOTLIN_VERSION="1.7.21"

# Download the Kotlin compiler zip.
wget -q "https://github.com/JetBrains/kotlin/releases/download/v$KOTLIN_VERSION/kotlin-compiler-$KOTLIN_VERSION.zip"

# Unzip the Kotlin compiler inside the chroot environment.
unzip -qq -d "$CHROOTDIR/usr/local/lib/" "./kotlin-compiler-$KOTLIN_VERSION.zip"

# Include bin/kotlinc in the PATH variable of the chroot environment by creating a symbolic link.
chroot "$CHROOTDIR/" ln -s "/usr/local/lib/kotlinc/bin/kotlinc" "/usr/local/bin/kotlinc"

# Optionally as a cleanup step, remove the downloaded zip file.
rm "./kotlin-compiler-$KOTLIN_VERSION.zip"

Installing Kotlin by editing judgehost install scripts

You can also modify the judgehost install scripts to add Kotlin; simply edit the misc_tools/dj_make_chroot.in script (this raw script can be found a release tarball or git sources) and add something like the above in an appropriate place; for example, after installing debs (this line), add:

...

# Install Kotlin
KOTLIN_VERSION="1.7.21"
wget -q "https://github.com/JetBrains/kotlin/releases/download/v$KOTLIN_VERSION/kotlin-compiler-$KOTLIN_VERSION.zip"
unzip -qq -d "$CHROOTDIR/usr/local/lib/" "./kotlin-compiler-$KOTLIN_VERSION.zip"
in_chroot "ln -s \"/usr/local/lib/kotlinc/bin/kotlinc\" \"/usr/local/bin/kotlinc\""
rm "./kotlin-compiler-$KOTLIN_VERSION.zip"

...

Judgehost Docker image with Kotlin

If you want a judgehost Docker image with Kotlin, modify the docker/judgehost/chroot-and-tar.sh script in the DOMjudge packaging repository, such as:

#!/bin/bash

# Usage: https://github.com/DOMjudge/domjudge/blob/main/misc-tools/dj_make_chroot.in#L58-L87
/opt/domjudge/judgehost/bin/dj_make_chroot

CHROOTDIR="/chroot/domjudge"
KOTLIN_VERSION="1.7.21"

echo "Downloading Kotlin compiler"
wget -q "https://github.com/JetBrains/kotlin/releases/download/v$KOTLIN_VERSION/kotlin-compiler-$KOTLIN_VERSION.zip" -P /
echo "Extracting Kotlin compiler"
unzip -qq -d "/chroot/domjudge/usr/local/lib/" "/kotlin-compiler-$KOTLIN_VERSION.zip"
chroot "$CHROOTDIR" ln -s "/usr/local/lib/kotlinc/bin/kotlinc" "/usr/local/bin/kotlinc"
rm "/kotlin-compiler-$KOTLIN_VERSION.zip"
echo "Done setting up Kotlin"

cd /
echo "[..] Compressing chroot"
tar -czpf /chroot.tar.gz --exclude=/chroot/tmp --exclude=/chroot/proc --exclude=/chroot/sys --exclude=/chroot/mnt --exclude=/chroot/media --exclude=/chroot/dev --one-file-system /chroot
echo "[..] Compressing judge"
tar -czpf /judgehost.tar.gz /opt/domjudge/judgehost

Then run docker/build.sh to build judgehost and domserver images, or docker/build-judgehost.sh after manually downloading the DOMjudge source (first steps of the docker/build.sh), to build only the judgehost image:

# In the DOMjudge packaging repository root.

cd docker/
DOMJUDGE_VERSION="8.2.2"
wget --quiet "https://www.domjudge.org/releases/domjudge-${DOMJUDGE_VERSION}.tar.gz" -O "./domjudge.tar.gz"
./build-judgehost.sh "localhost/domjudge/judgehost:${DOMJUDGE_VERSION}-kotlin"

Enabling Kotlin in the admin dashboard

After successfully installing the Kotlin command-line compiler on judgehosts, Kotlin language should be enabled in the DOMjudge Jury interface for submissions:

  • Navigate to the DOMjudge website.
  • Login as admin.
  • Go to "Languages" settings.
  • Select kt from "Disabled languages"; if it is already in "Enabled languages", then you are done.
  • Turn the "Allow submit" to "Yes".

A heads-up about the default kt run script: if the DOMjudge version is in range 8.2.0 to 8.2.2 (both inclusive), the automatic Kotlin compiler directory discovery might fail if kotlinc is a symbolic link; one solution is to manually fill-in the KOTLIN_DIR variable in the run script; another solution is to update the run script to its latest commit.

The run script can be edited in the DOMjudge Jury interface: "Languages" - kt - "Compile script / kt" - Content / run.