Documentation/README.Docker:
Rename -> README.Docker.md. This file was already in Markdown
format.
Adjust heading levels.
Fix a broken link.
README.md:
Conform to the above change.
4.5 KiB
Mercury in Docker
This file documents using Mercury within a Docker container.
Motivation
Docker is a popular way to achieve cross-platform containerisation of applications. Due to the rather lengthy compile time of the Mercury compiler itself, a way to package the compiler and all of its dependencies is a desirable goal.
Building Mercury
The Dockerfile is a multi-staged Dockerfile.
Currently there are three stages:
-
base: Defines the basic image that all Mercury related containers should use. Based on Debian (Alpine Linux works as well but is not supported yet), it comes with gcc, make, pkg-config and libc headers.
-
bootstrap: Installs the packaged ROTD compiler from the download page and autotools.
-
compiler: Uses the bootstrapped compiler to (auto-)configure Mercury and install it into a single-layered container.
Used variables and arguments (for all stages):
-
MERCURY_BOOTSTRAP: if set to "y" then use a bootstrap mmc while building the compiler.
-
MERCURY_DEPEND_ARG: Currently defined as either jessie or stretch, to support building for different Debian distributions.
-
MERCURY_DL: Where to find the packaged ROTD compiler for Debian (see above).
-
MERCURY_DEV_SOURCE: Source directory from where to obtain the compiler source code. Used to support building from tarballs (see below).
-
MERCURY_DEV_TARGET: Temporary directory used as container working directory and for building the compiler.
-
MERCURY_DEV_PREFIX: Default prefix to install Mercury to (
/usr/local/mercury). -
MERCURY_DEV_LIBGRADES and MERCURY_DEV_DEFAULT_GRADE: Grades to build, as defined by
./configure --enable-libgrades. Default is asm_fast.gc. -
MERCURY_DEV_PARALLEL: Just as
make PARALLEL=, defaults to-j3.
Additionally building the ROTD tarball is supported via:
docker build --build-arg MERCURY_BOOTSTRAP=n \
--build-arg MERCURY_DEV_SOURCE=mercury-srcdist-rotd-2018-12-24 \
https://dl.mercurylang.org/rotd/mercury-srcdist-rotd-2018-12-24.tar.gz
Using containerised mmc on the host platform
docker run --rm \
--mount type=bind,src="$(pwd)",dst=/var/tmp/mercury \
mercury-dev --linkage static -m hello
The mount directive mounts the current working directory as a directory
inside the container, where the containers default working directory is
/var/tmp/mercury (see MERCURY_DEV_TARGET).
Another use case is to build entire libraries, such as mercury-json. For this the entry point has to be changed in case a Makefile or similar is used:
git clone https://github.com/juliensf/mercury-json.git
docker run --rm \
--mount type=bind,src="$(pwd)/mercury-json",dst=/var/tmp/mercury \
--entrypoint make \
mercury-dev:multi runtests
Limitations
Currently only static linkage is supported, as dynamic linkage searches the
host for the Mercury runtime library, which might not be installed or not
binary compatible. Similarly, --use-grade-subdirs is not supported as it
uses symbolic links that do not work properly on all platforms, but might work
in a Linux only environment. Windows containers are not supported yet, but
will be in the future. For this multi-arch files can be utilised.
Note that using
Docker in combination with WSL
is tested and supported. Please follow all the instructions including changing
the mount points from /mnt/c to /c only. Additionally only mounting shared
volumes work, such as from the local user profile directory.
As this is not yet established within the Mercury community, there are no best-practices and conventions defined. It would be desirable to define a common location for installing libraries, a default set of grades available. Using Docker volumes to store both the runtime libraries and the extra/third party libraries would allow composition of complex build scripts.
As an enhancement to the Mercury compiler special publish and pack targets could be designed that would allow isolated deployment and packaging of Mercury libraries and executable. This is already something .NET Core supports via the .NET Core CLI.