mlton for Debian
----------------

1. Repacking upstream tarballs
==============================

The upstream mlton source tarball contains non-DFSG-free files. It also
contains nested tarballs and patches for their extracted contents. We
repack the original tarball to remove the non-DFSG-free files and to
extract the nested tarballs. (Strictly speaking, we don't bother with
sources, but just use the upstream VCS tags.) Here are the instructions
for importing a new upstream release.

First, make sure that upstream MLton's git repository is known to your
local git clone of the Debian packaging:

    git remote add mlton https://github.com/MLton/mlton.git

Next, fetch any known tags:

    git fetch mlton

We now merge the desired tag into the upstream branch:

    export VERSION=202YMMDD
    git switch upstream
    git merge on-${VERSION}-release
    # Delete previously extracted tarballs to make sure that
    # files deleted upstream are deleted in the repacked tarball:
    rm -fr lib/mllpt-lib/ml-lpt
    rm -fr lib/mlrisc-lib/MLRISC
    rm -fr lib/smlnj-lib/smlnj-lib
    # Extract the nested tarballs and apply upstream's patches
    make -C lib/mllpt-lib ml-lpt/README
    make -C lib/mlrisc-lib MLRISC/README.mlton
    make -C lib/smlnj-lib smlnj-lib/README.mlton
    # You'll need to manually edit runtime/Makefile to extract
    # and patch runtime/gdtoa.tgz without also compiling a bunch
    # of stuff, but don't forget to revert your changes.
    # Delete the nested tarballs and patches
    rm lib/mllpt-lib/ml-lpt.tgz lib/mllpt-lib/ml-lpt.patch
    rm lib/mlrisc-lib/MLRISC.tgz lib/mlrisc-lib/MLRISC.patch
    rm lib/smlnj-lib/smlnj-lib.tgz lib/smlnj-lib/smlnj-lib.patch
    rm runtime/gdtoa.tgz runtime/gdtoa.*.patch
    # Delete non-DFSG-free files from unpacked tarballs
    rm -fr lib/smlnj-lib/smlnj-lib/HTML4/tests/
    # We need to pass -f to git add because upstream ignores
    # extracted contents via .gitignore
    git add -f lib runtime
    git commit -m "Repacked new upstream release ${VERSION}"
    git tag -s "upstream/${VERSION}+dfsg"

Now we can merge in back into the desired packaging branch, e.g.:

    git switch debian/unstable
    git merge upstream/${VERSION}+dfsg

2. Rebootstrapping
==================

MLton, as with most SML compilers, requires a SML compiler to compile
itself. If ever mlton becomes uninstallable, you will need to compile
it with the last installable version. Unfortunately,

    Building the runtime system requires compiling and executing
    programs that determine characteristics of the platform, which is
    why it isn’t currently feasible to build the runtime system on the
    host machine using a cross-compiler toolchain.

per doc/guide/src/CrossCompiling.adoc. This means that you cannot use
sbuild to locally cross-compile for a different architecture, and that
you will have to manually build the package on that architecture.
Assuming you have access to a porterbox of that architecture and that it
has sbuild, here are some instructions you can use:

1. Fetch last working version
-----------------------------

Use debsnap or some other mechanism to fetch the last installable
version of mlton (prune the list of packages down to those you need):

    mkdir mlton-bootstrap-debs
    for p in \
            mlton \
            mlton-basis \
            mlton-compiler \
            mlton-runtime-aarch64-linux-gnu \
            mlton-runtime-arm-linux-gnueabi \
            mlton-runtime-arm-linux-gnueabihf \
            mlton-runtime-hppa-linux-gnu \
            mlton-runtime-i486-kfreebsd-gnu \
            mlton-runtime-i486-linux-gnu \
            mlton-runtime-mips-linux-gnu \
            mlton-runtime-mips64el-linux-gnuabi64 \
            mlton-runtime-mipsel-linux-gnu \
            mlton-runtime-native \
            mlton-runtime-powerpc-linux-gnu \
            mlton-runtime-powerpc64le-linux-gnu \
            mlton-runtime-s390x-linux-gnu \
            mlton-runtime-x86-64-kfreebsd-gnu \
            mlton-runtime-x86-64-linux-gnu \
            mlton-tools; do \
        debsnap --force -d mlton-bootstrap-debs --binary $p VERSION; \
    done

2. Force schroot to use the downloaded binaries
-----------------------------------------------

We need to pin the old version so that apt in the build environment
doesn't complain about dependencies being uninstallable.

    schroot -c mychroot -u root --
    for p in \
            mlton \
            mlton-basis \
            mlton-compiler \
            mlton-runtime-aarch64-linux-gnu \
            mlton-runtime-arm-linux-gnueabi \
            mlton-runtime-arm-linux-gnueabihf \
            mlton-runtime-hppa-linux-gnu \
            mlton-runtime-i486-kfreebsd-gnu \
            mlton-runtime-i486-linux-gnu \
            mlton-runtime-mips-linux-gnu \
            mlton-runtime-mips64el-linux-gnuabi64 \
            mlton-runtime-mipsel-linux-gnu \
            mlton-runtime-native \
            mlton-runtime-powerpc-linux-gnu \
            mlton-runtime-powerpc64le-linux-gnu \
            mlton-runtime-s390x-linux-gnu \
            mlton-runtime-x86-64-kfreebsd-gnu \
            mlton-runtime-x86-64-linux-gnu \
            mlton-tools; do \
        cat <<EOF>>/etc/apt/preferences
Package: $p
Pin: version VERSION
Pin-Priority: 999

EOF
    done

3. Building the package
-----------------------

We can point sbuild to the binaries we downloaded in step 1. The
pinning in step 2 ensures that these are installed, instead of the
broken or missing binaries currently in the archives:

    export DEB_BUILD_OPTS=nocheck
    sbuild --no-clean-source --no-arch-all-d unstable \
           --extra-package=../mlton-bootstrap-bins/

 -- Ryan Kavanagh <rak@debian.org>  Sat, 31 Dec 2021 10:21:23 -0500
