[m-rev.] for review: Add Dockerfile to containerise mmc.

Sebastian Godelet sebastian.godelet at outlook.com
Fri Dec 28 03:26:26 AEDT 2018


For review by anone.

Add Dockerfile to containerise mmc.

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.

.dockerignore:
    Ignore README files, extras and everything from
    library/.gitignore and compiler/.gitignore, except for "configure".

Dockerfile:
    Dockerfile to create a containerised mmc, using a build script
    similar to INSTALL.git.

README.Docker:
    Readme on how to use Docker with Mercury.

README.md:
    Add link to README.Docker.

---
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 000000000..9f9294a95
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,112 @@
+*.a
+aclocal.m4
+autom4te.cache
+/benchmarks/*
+/extras/*
+*.c
+*.check.mmacros
+*.class
+COMP_FLAGS
+.compiler_tags
+confdefs.h
+config.cache
+config.log
+config.status
+# configure is not ignored, s.th. tarballs are supported
+# configure
+/.configured_library_grades
+configure.help
+configure.log
+*__cpp_code.cpp
+*__csharp_code.cs
+*.d
+*.date
+*.*_date
+*.date0
+*.date3
+*.dll
+erlang_conf.hrl
+*.err
+*.exe
+/.git/*
+*.h
+*.il
+*.ilk
+/INSTALL
+/install_grade_dir.*
+*.int
+*.int0
+*.int2
+*.int3
+*.jar
+*.java
+jmercury
+LIB_FLAGS
+libmer_rt.a
+libmer_rt.dylib
+libmer_rt.lib
+libmer_rt.so
+libmer_std.dylib
+libmer_std.lib
+libmer_std.so
+library.dep
+library.dv
+/main.o
+Mercury
+mercury_compile
+mercury_compile.dep
+mercury_compile.dep_err
+mercury_compile.dv
+mercury_compile.exe
+mercury_compile.jar
+mercury_compile.stats
+mercury_conf.h
+mercury_conf.h.date
+mercury_dotnet.cs
+mercury.*.h
+mercury_ho_call_codes.i
+mercury_ho_call_declares.i
+mercury_ho_call_inits.i
+mercury_method_call_codes.i
+mercury_method_call_declares.i
+mercury_method_call_inits.i
+Mercury.modules
+/Mercury.options
+mercury_profiling_builtin.c
+mercury_profiling_builtin.h
+mer_rt.init
+mer_std
+mer_std.dep
+mer_std.dep_err
+mer_std.dv
+mer_std.init
+*.mh
+*.mih
+Mmake.common
+Mmake.params
+Mmake.stage.params
+*.module_dep
+*.o
+*.obj
+*.obj_check
+*.opt
+*.optdate
+*.pdb
+*.pic_o
+*.pl
+*.prof
+*.ql
+/README
+/README.*
+/samples/*
+sicstus_compile sicstus_saved_state
+so_locations
+/stage1
+/stage2
+/stage3
+tags
+/TODO
+*.trans_opt
+*.trans_opt_date
+*.used
+/WORK_IN_PROGRESS
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 000000000..8082ca410
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,84 @@
+# vim: ft=dockerfile tw=78 ts=4 sw=4 et
+
+# Supported Debian base images
+#   - stretch
+#   - jessie
+ARG MERCURY_DEPEND_TAG=stretch
+ARG MERCURY_DEV_PREFIX=/usr/local/mercury
+ARG MERCURY_DEV_TARGET=/var/tmp/mercury
+
+# first stage, base image
+FROM debian:${MERCURY_DEPEND_TAG} AS base
+RUN apt-get update && apt-get install -y \
+    apt-utils \
+    gcc \
+    libc-dev \
+    make \
+    pkg-config
+
+FROM base AS bootstrap
+
+ARG MERCURY_BOOTSTRAP=y
+ARG MERCURY_DL=http://dl.mercurylang.org/deb/
+ARG MERCURY_DEV_DEFAULT_GRADE=asm_fast.gc
+ARG MERCURY_DEV_LIBGRADES=${MERCURY_DEV_DEFAULT_GRADE}
+ARG MERCURY_DEV_PARALLEL=-j3
+# When using a source tarball, the source needs to be the top level directory,
+# e.g. `mercury-srcdist-rotd-2017-10-19'
+ARG MERCURY_DEV_SOURCE=.
+# inherited variables
+ARG MERCURY_DEV_PREFIX
+ARG MERCURY_DEV_TARGET
+
+ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE y
+
+# install packaged compiler for bootstrapping
+# first install curl and lsb-realse so we can add the public key for downloading
+# Mercury packages.
+# Then add the remote repository and install all packages required for building
+# the Mercury compiler from source.
+RUN ( echo 'debconf debconf/frontend select Noninteractive' \
+        | debconf-set-selections ) && \
+    apt-get update && apt-get install -y \
+        bison \
+        flex \
+        $([ "$MERCURY_BOOTSTRAP" != "y" ] || \
+            echo autoconf automake curl gnupg2 lsb-release) && \
+    [ "${MERCURY_BOOTSTRAP}" != "y" ] || \
+        ( \
+            ( curl -fsSL https://paul.bone.id.au/paul.asc | apt-key add - ) && \
+            printf "%s $MERCURY_DL $(lsb_release -cs) main\n" "deb" "deb-src" \
+                > /etc/apt/sources.list.d/mercury.list && \
+            apt-get update && apt-get install -y \
+                mercury-rotd-recommended \
+        )
+
+WORKDIR $MERCURY_DEV_TARGET
+COPY ${MERCURY_DEV_SOURCE} .
+
+# Checking for configure enables using
+#   - `docker build http://uri.to.bootstrapped.tar.gz',
+#   - `docker build https://github.com/:user:/mercury.git'
+#   - `docker build .'
+#
+# Bootcheck fails currently: ( MAKE_DIR=`pwd`/scripts PATH=$PATH:`pwd`/scripts tools/bootcheck $MERCURY_DEV_PARALLEL ) \
+RUN ( \
+        ([ -f ./configure ] || ./prepare.sh) \
+        && ./configure \
+            --enable-libgrades=$MERCURY_DEV_LIBGRADES \
+            --with-default-grade=$MERCURY_DEFAULT_GRADE \
+            --prefix=$MERCURY_DEV_PREFIX \
+            --disable-symlinks \
+        && make PARALLEL=$MERCURY_DEV_PARALLEL install \
+        && rm -fR ${MERCURY_BOOTSTRAP_TARGET} \
+        && rm -fR $MERCURY_DEV_TARGET \
+    )
+
+FROM base AS compiler
+ARG MERCURY_DEV_PREFIX
+ARG MERCURY_DEV_TARGET
+WORKDIR $MERCURY_DEV_TARGET
+COPY --from=bootstrap $MERCURY_DEV_PREFIX $MERCURY_DEV_PREFIX
+ENV PATH ${MERCURY_DEV_PREFIX}/bin:$PATH
+
+ENTRYPOINT ["mmc"]
diff --git a/README.Docker b/README.Docker
new file mode 100644
index 000000000..0635c32f4
--- /dev/null
+++ b/README.Docker
@@ -0,0 +1,69 @@
+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](Dockerfile) is a [multi-staged](https://docs.docker.com/develop/develop-images/multistage-build/) Dockerfile.
+Currently there are three stages:
+  * base: Defines the basic image that all Mercury related containers should use.
+    Based on Debian (Apline 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](http://dl.mercurylang.org/deb/) 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: iff "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```).
+  - MERUCRY_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:
+
+```bash
+docker build --build-arg MERCURY_BOOTSTRAP=n --build-arg MERCURY_DEV_SOURCE=mercury-srcdist-rotd-2018-12-24 http://dl.mercurylang.org/rotd/mercury-srcdist-rotd-2018-12-24.tar.gz
+```
+
+Using containerised mmc on the host platform
+============================================
+
+```bash
+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](https://github.com/juliensf/mercury-json.git).
+For this the entry point has to be changed in case a Makefile or similar is used:
+
+```bash
+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.
+Similary, ```--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 comination with WSL](https://nickjanetakis.com/blog/setting-up-docker-for-windows-and-wsl-to-work-flawlessly) 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-pratices 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 executables. This is already something [.NET Core](https://github.com/dotnet/core) supports via the [.NET Core CLI](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore21).
diff --git a/README.md b/README.md
index 11465021e..0f7e17dc8 100644
--- a/README.md
+++ b/README.md
@@ -36,6 +36,7 @@ Specific information is contained in individual README files:
   * Platforms
+      * [Docker](README.Docker)
       * [Linux](README.Linux)
         ([Alpha](README.Linux-Alpha),
         [PPC](README.Linux-PPC),
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20181227/da3b4996/attachment-0001.html>


More information about the reviews mailing list