From 05eace275ff3ddf73062943dd23823f690f57f42 Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Tue, 14 May 2024 08:16:35 +0200 Subject: [PATCH 1/3] Document how to get GHC to work --- sql/files/defaultdata/hs/run | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/files/defaultdata/hs/run b/sql/files/defaultdata/hs/run index d48e2930eb..736de457a5 100755 --- a/sql/files/defaultdata/hs/run +++ b/sql/files/defaultdata/hs/run @@ -10,6 +10,9 @@ MAINSOURCE="$1" # Set non-existing HOME variable to make GHC program happy, see: # https://ghc.haskell.org/trac/ghc/ticket/11678 export HOME=/does/not/exist +# Allow temporary files during compilation, this directory is not +# available during the submission run. +export TMPDIR="$PWD" # Add -DONLINE_JUDGE or -DDOMJUDGE below if you want it make easier for teams # to do local debugging. From 1361ca739286740923e424664f847c26d0df68cf Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Fri, 10 May 2024 23:25:58 +0200 Subject: [PATCH 2/3] Add version commands and installation instructions for chroot in manual DOMjudge ships with default languages but no documentation on how to install those. This commit documents how to get a working setup in the chroot to get the example problems to run. In the past we had the idea to enable all languages in the integration test. If we would do that we could detect the required package changes also and keep this up to date. For the interpreted languages we use mostly use the same binary as runner & compiler. Some of the versions were already added before and are only documented on how to install those now. The migration is added for people to get the version commands to make it easier to use additional languages and still make it easy to publish the used versions, useful for online mirrors etc. The version for `dash`/`sh` is difficult as there is no simple `--version` and getting the value with `dpkg -s` does not work inside our chroot during runtime as not all locations are mounted. For more information see: https://stackoverflow.com/questions/36660724/how-to-tell-the-version-number-of-dash and https://unix.stackexchange.com/questions/416760/how-to-find-out-the-version-number-of-dash-without-resorting-to-package-manage. The other alternative would be `file` as that gives more information than `md5sum` but its also not available in the chroot. The installation for swift could be easier if we allow tarballs to be unpacked in the future. At the moment people would either need to change `dj_make_chroot` or do it afterwards with `dj_run_chroot`. Javascript is interpreted so we copy the behaviour of python. While testing I found that we can only have run-error but there is a `--check` which we could use to verify that there is a sort of compilation step. --- doc/manual/index.rst | 1 + doc/manual/install-language.rst | 97 +++++++++++++++++++ .../DefaultData/LanguageFixture.php | 28 +++--- 3 files changed, 112 insertions(+), 14 deletions(-) create mode 100644 doc/manual/install-language.rst diff --git a/doc/manual/index.rst b/doc/manual/index.rst index 2af6aeffa8..1ba568179c 100644 --- a/doc/manual/index.rst +++ b/doc/manual/index.rst @@ -26,3 +26,4 @@ Appendices problem-format shadow configuration-reference + install-language diff --git a/doc/manual/install-language.rst b/doc/manual/install-language.rst new file mode 100644 index 0000000000..61ec9b2557 --- /dev/null +++ b/doc/manual/install-language.rst @@ -0,0 +1,97 @@ +Appendix: Installing the example languages +========================================== + +DOMjudge ships with some default languages with a default configuration. +As you might set up contests with those languages we provide how those languages were +installed in the past as guideline. Use ``dj_run_chroot`` for most of those packages, and see +the section :ref:`make-chroot` for more information. + +Most of the languages can be installed from the table below as there is a package available +to install inside the judging chroot. Given that you can install your own chroot we only provide the +packages for Ubuntu as that is the most used at the moment of writing. + +.. list-table:: Packages for languages + :header-rows: 1 + + * - Language + - Ubuntu package + - Remarks + * - Ada + - `gnat` + - + * - AWK + - `mawk`/`gawk` + - `mawk` is default installed + * - Bash + - `bash` + - Default installed in the chroot + * - C + - `gcc` + - Default installed in the chroot + * - C++ + - `g++` + - Default installed in the chroot + * - C# + - `mono-mcs` + - + * - Fortran + - `gfortran` + - + * - Haskell + - `ghc` + - After installing you need to move these files + `/{usr->var}/lib/ghc/package.conf.d` as `/var` + is not mounted during compilation. + * - Java + - `default-jdk-headless` + - Default installed in the chroot + * - Javascript + - `nodejs` + - + * - Kotlin + - `kotlin` + - + * - Lua + - `lua5.4` + - Ubuntu does not ship a generic meta package (yet). + * - Pascal + - `fp-compiler` + - + * - Perl + - `perl-base` + - Default installed in the chroot + * - POSIX shell + - `dash` + - Default installed in the chroot + * - Prolog + - `swi-prolog-core-packages` + - + * - Python3 + - `pypy3`/`python3` + - Default installed in the chroot. + DOMjudge assumes `pypy3` as it runs faster in general. + Consider the `PyPy3 PPA`_ if you need the latest python3 features. PyPy3 does not have 100% + compatibility with all non-standard libraries. In case this is needed you should reconsider the default + CPython implementation. + * - OCaml + - `ocaml` + - + * - R + - `r-base-core` + - + * - Ruby + - `ruby` + - + * - Rust + - `rustc` + - + * - Scala + - `scala` + - + * - Swift + - + - See the `Swift instructions`_, unpack the directory in the chroot and install `libncurses6`. Depending + on where you install the directory you might need to extend the `PATH` in the `run` script. + +.. _PyPy3 PPA: https://launchpad.net/~pypy/+archive/ubuntu/ppa +.. _Swift instructions: https://www.swift.org/documentation/server/guides/deploying/ubuntu.html diff --git a/webapp/src/DataFixtures/DefaultData/LanguageFixture.php b/webapp/src/DataFixtures/DefaultData/LanguageFixture.php index a4e6007179..1ee4ce8be5 100644 --- a/webapp/src/DataFixtures/DefaultData/LanguageFixture.php +++ b/webapp/src/DataFixtures/DefaultData/LanguageFixture.php @@ -25,29 +25,29 @@ public function load(ObjectManager $manager): void $data = [ // ID external ID name extensions require entry point allow allow time compile compiler version runner version // entry point description submit judge factor script command command - ['adb', 'ada', 'Ada', ['adb', 'ads'], false, null, false, true, 1, 'adb', '', ''], - ['awk', 'awk', 'AWK', ['awk'], false, null, false, true, 1, 'awk', '', ''], - ['bash', 'bash', 'Bash shell', ['bash'], false, 'Main file', false, true, 1, 'bash', '', ''], + ['adb', 'ada', 'Ada', ['adb', 'ads'], false, null, false, true, 1, 'adb', 'gnatmake --version', ''], + ['awk', 'awk', 'AWK', ['awk'], false, null, false, true, 1, 'awk', 'awk --version', ''], + ['bash', 'bash', 'Bash shell', ['bash'], false, 'Main file', false, true, 1, 'bash', 'bash --version', ''], ['c', 'c', 'C', ['c'], false, null, true, true, 1, 'c', 'gcc --version', ''], ['cpp', 'cpp', 'C++', ['cpp', 'cc', 'cxx', 'c++'], false, null, true, true, 1, 'cpp', 'g++ --version', ''], ['csharp', 'csharp', 'C#', ['csharp', 'cs'], false, null, false, true, 1, 'csharp', 'mcs --version', 'mono --version'], - ['f95', 'f95', 'Fortran', ['f95', 'f90'], false, null, false, true, 1, 'f95', '', ''], - ['hs', 'haskell', 'Haskell', ['hs', 'lhs'], false, null, false, true, 1, 'hs', '', ''], + ['f95', 'f95', 'Fortran', ['f95', 'f90'], false, null, false, true, 1, 'f95', 'gfortran --version', ''], + ['hs', 'haskell', 'Haskell', ['hs', 'lhs'], false, null, false, true, 1, 'hs', 'ghc --version', ''], ['java', 'java', 'Java', ['java'], false, 'Main class', true, true, 1, 'java_javac_detect', 'javac -version', 'java -version'], - ['js', 'javascript', 'JavaScript', ['js'], false, 'Main file', false, true, 1, 'js', '', ''], - ['lua', 'lua', 'Lua', ['lua'], false, null, false, true, 1, 'lua', '', ''], + ['js', 'javascript', 'JavaScript', ['js'], false, 'Main file', false, true, 1, 'js', 'nodejs --version', 'nodejs --version'], + ['lua', 'lua', 'Lua', ['lua'], false, null, false, true, 1, 'lua', 'luac -v', ''], ['kt', 'kotlin', 'Kotlin', ['kt'], true, 'Main class', false, true, 1, 'kt', 'kotlinc -version', 'kotlin -version'], - ['pas', 'pascal', 'Pascal', ['pas', 'p'], false, 'Main file', false, true, 1, 'pas', '', ''], - ['pl', 'pl', 'Perl', ['pl'], false, 'Main file', false, true, 1, 'pl', '', ''], - ['plg', 'prolog', 'Prolog', ['plg'], false, 'Main file', false, true, 1, 'plg', '', ''], + ['pas', 'pascal', 'Pascal', ['pas', 'p'], false, 'Main file', false, true, 1, 'pas', 'fpc -iW', ''], + ['pl', 'pl', 'Perl', ['pl'], false, 'Main file', false, true, 1, 'pl', 'perl -v', 'perl -v'], + ['plg', 'prolog', 'Prolog', ['plg'], false, 'Main file', false, true, 1, 'plg', 'swipl --version', 'swipl --version'], ['py3', 'python3', 'Python 3', ['py'], false, 'Main file', true, true, 1, 'py3', 'pypy3 --version', 'pypy3 --version'], ['ocaml', 'ocaml', 'OCaml', ['ml'], false, null, false, true, 1, 'ocaml', 'ocamlopt --version', ''], - ['r', 'r', 'R', ['R'], false, 'Main file', false, true, 1, 'r', '', ''], - ['rb', 'ruby', 'Ruby', ['rb'], false, 'Main file', false, true, 1, 'rb', '', ''], + ['r', 'r', 'R', ['R'], false, 'Main file', false, true, 1, 'r', 'Rscript --version', 'Rscript --version'], + ['rb', 'ruby', 'Ruby', ['rb'], false, 'Main file', false, true, 1, 'rb', 'ruby --version', 'ruby --version'], ['rs', 'rust', 'Rust', ['rs'], false, null, false, true, 1, 'rs', 'rustc --version', ''], ['scala', 'scala', 'Scala', ['scala'], false, null, false, true, 1, 'scala', 'scalac -version', 'scala -version'], - ['sh', 'sh', 'POSIX shell', ['sh'], false, 'Main file', false, true, 1, 'sh', '', ''], - ['swift', 'swift', 'Swift', ['swift'], false, 'Main file', false, true, 1, 'swift', '', ''], + ['sh', 'sh', 'POSIX shell', ['sh'], false, 'Main file', false, true, 1, 'sh', 'md5sum /bin/sh', ''], + ['swift', 'swift', 'Swift', ['swift'], false, 'Main file', false, true, 1, 'swift', 'swiftc --version', ''], ]; foreach ($data as $item) { From d074fff070bb5641e0d0fdb7d8e35b44ccab28aa Mon Sep 17 00:00:00 2001 From: Michael Vasseur <14887731+vmcj@users.noreply.github.com> Date: Sat, 11 May 2024 13:41:34 +0200 Subject: [PATCH 3/3] Add migration to upgrade version commands when unset Contents based on the values in the DefaultData/LanguageFixture. --- webapp/migrations/Version20240511091916.php | 82 +++++++++++++++++++ .../DefaultData/LanguageFixture.php | 10 +-- 2 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 webapp/migrations/Version20240511091916.php diff --git a/webapp/migrations/Version20240511091916.php b/webapp/migrations/Version20240511091916.php new file mode 100644 index 0000000000..47fd04c297 --- /dev/null +++ b/webapp/migrations/Version20240511091916.php @@ -0,0 +1,82 @@ + 'gnatmake --version', + 'awk'=> 'awk --version', + 'bash'=> 'bash --version', + 'c' => 'gcc --version', + 'cpp' => 'g++ --version', + 'csharp' => 'mcs --version', + 'f95' => 'gfortran --version', + 'hs' => 'ghc --version', + 'java' => 'javac --version', + 'js' => 'nodejs --version', + 'kt' => 'kotlinc --version', + 'lua' => 'luac -v', + 'pas' => 'fpc -iW', + 'pl' => 'perl -v', + 'plg' => 'swipl --version', + 'py3' => 'pypy3 --version', + 'ocaml' => 'ocamlopt --version', + 'r' => 'Rscript --version', + 'rb' => 'ruby --version', + 'rs' => 'rustc --version', + 'scala' => 'scalac --version', + 'sh' => 'md5sum /bin/sh', + 'swift' => 'swiftc --version']; + + private const RUNNER_VERSION_COMMAND = ['awk'=> 'awk --version', + 'bash'=> 'bash --version', + 'csharp' => 'mono --version', + 'java' => 'java --version', + 'js' => 'nodejs --version', + 'kt' => 'kotlin --version', + 'lua' => 'lua -v', + 'pl' => 'perl -v', + 'py3' => 'pypy3 --version', + 'r' => 'Rscript --version', + 'rb' => 'ruby --version', + 'scala' => 'scala --version', + 'sh' => 'md5sum /bin/sh']; + + public function getDescription(): string + { + return 'Fill default version command for compiler/runner.'; + } + + public function up(Schema $schema): void + { + foreach (self::COMPILER_VERSION_COMMAND as $lang => $versionCommand) { + $this->addSql("UPDATE language SET compiler_version_command = '" . $versionCommand ."' WHERE langid='" . $lang . "' AND compiler_version_command IS NULL;"); + } + foreach (self::RUNNER_VERSION_COMMAND as $lang => $versionCommand) { + $this->addSql("UPDATE language SET runner_version_command = '" . $versionCommand ."' WHERE langid='" . $lang . "' AND runner_version_command IS NULL;"); + } + } + + public function down(Schema $schema): void + { + foreach (self::COMPILER_VERSION_COMMAND as $lang => $versionCommand) { + $this->addSql("UPDATE language SET compiler_version_command = NULL WHERE langid='" . $lang . "' AND compiler_version_command = '" . $versionCommand ."';"); + } + foreach (self::RUNNER_VERSION_COMMAND as $lang => $versionCommand) { + $this->addSql("UPDATE language SET runner_version_command = NULL WHERE langid='" . $lang . "' AND runner_version_command = '" . $versionCommand ."';"); + } + } + + public function isTransactional(): bool + { + return false; + } +} diff --git a/webapp/src/DataFixtures/DefaultData/LanguageFixture.php b/webapp/src/DataFixtures/DefaultData/LanguageFixture.php index 1ee4ce8be5..09c090ae0a 100644 --- a/webapp/src/DataFixtures/DefaultData/LanguageFixture.php +++ b/webapp/src/DataFixtures/DefaultData/LanguageFixture.php @@ -26,8 +26,8 @@ public function load(ObjectManager $manager): void // ID external ID name extensions require entry point allow allow time compile compiler version runner version // entry point description submit judge factor script command command ['adb', 'ada', 'Ada', ['adb', 'ads'], false, null, false, true, 1, 'adb', 'gnatmake --version', ''], - ['awk', 'awk', 'AWK', ['awk'], false, null, false, true, 1, 'awk', 'awk --version', ''], - ['bash', 'bash', 'Bash shell', ['bash'], false, 'Main file', false, true, 1, 'bash', 'bash --version', ''], + ['awk', 'awk', 'AWK', ['awk'], false, null, false, true, 1, 'awk', 'awk --version', 'awk --version'], + ['bash', 'bash', 'Bash shell', ['bash'], false, 'Main file', false, true, 1, 'bash', 'bash --version', 'bash --version'], ['c', 'c', 'C', ['c'], false, null, true, true, 1, 'c', 'gcc --version', ''], ['cpp', 'cpp', 'C++', ['cpp', 'cc', 'cxx', 'c++'], false, null, true, true, 1, 'cpp', 'g++ --version', ''], ['csharp', 'csharp', 'C#', ['csharp', 'cs'], false, null, false, true, 1, 'csharp', 'mcs --version', 'mono --version'], @@ -35,18 +35,18 @@ public function load(ObjectManager $manager): void ['hs', 'haskell', 'Haskell', ['hs', 'lhs'], false, null, false, true, 1, 'hs', 'ghc --version', ''], ['java', 'java', 'Java', ['java'], false, 'Main class', true, true, 1, 'java_javac_detect', 'javac -version', 'java -version'], ['js', 'javascript', 'JavaScript', ['js'], false, 'Main file', false, true, 1, 'js', 'nodejs --version', 'nodejs --version'], - ['lua', 'lua', 'Lua', ['lua'], false, null, false, true, 1, 'lua', 'luac -v', ''], + ['lua', 'lua', 'Lua', ['lua'], false, null, false, true, 1, 'lua', 'luac -v', 'lua -v'], ['kt', 'kotlin', 'Kotlin', ['kt'], true, 'Main class', false, true, 1, 'kt', 'kotlinc -version', 'kotlin -version'], ['pas', 'pascal', 'Pascal', ['pas', 'p'], false, 'Main file', false, true, 1, 'pas', 'fpc -iW', ''], ['pl', 'pl', 'Perl', ['pl'], false, 'Main file', false, true, 1, 'pl', 'perl -v', 'perl -v'], - ['plg', 'prolog', 'Prolog', ['plg'], false, 'Main file', false, true, 1, 'plg', 'swipl --version', 'swipl --version'], + ['plg', 'prolog', 'Prolog', ['plg'], false, 'Main file', false, true, 1, 'plg', 'swipl --version', ''], ['py3', 'python3', 'Python 3', ['py'], false, 'Main file', true, true, 1, 'py3', 'pypy3 --version', 'pypy3 --version'], ['ocaml', 'ocaml', 'OCaml', ['ml'], false, null, false, true, 1, 'ocaml', 'ocamlopt --version', ''], ['r', 'r', 'R', ['R'], false, 'Main file', false, true, 1, 'r', 'Rscript --version', 'Rscript --version'], ['rb', 'ruby', 'Ruby', ['rb'], false, 'Main file', false, true, 1, 'rb', 'ruby --version', 'ruby --version'], ['rs', 'rust', 'Rust', ['rs'], false, null, false, true, 1, 'rs', 'rustc --version', ''], ['scala', 'scala', 'Scala', ['scala'], false, null, false, true, 1, 'scala', 'scalac -version', 'scala -version'], - ['sh', 'sh', 'POSIX shell', ['sh'], false, 'Main file', false, true, 1, 'sh', 'md5sum /bin/sh', ''], + ['sh', 'sh', 'POSIX shell', ['sh'], false, 'Main file', false, true, 1, 'sh', 'md5sum /bin/sh', 'md5sum /bin/sh'], ['swift', 'swift', 'Swift', ['swift'], false, 'Main file', false, true, 1, 'swift', 'swiftc --version', ''], ];