<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:DengXian;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@DengXian";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-GB">
<div class="WordSection1">
<p class="MsoNormal">For review by anone.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Add Dockerfile to containerise mmc.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Docker is a popular way to achieve cross-platform containerisation of applications.</p>
<p class="MsoNormal">Due to the rather lengthy compile time of the Mercury compiler itself, a way to package the compiler and all of its</p>
<p class="MsoNormal">dependencies is a desirable goal.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">.dockerignore:</p>
<p class="MsoNormal">    Ignore README files, extras and everything from</p>
<p class="MsoNormal">    library/.gitignore and compiler/.gitignore, except for "configure".</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Dockerfile:</p>
<p class="MsoNormal">    Dockerfile to create a containerised mmc, using a build script</p>
<p class="MsoNormal">    similar to INSTALL.git.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">README.Docker:</p>
<p class="MsoNormal">    Readme on how to use Docker with Mercury.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">README.md:</p>
<p class="MsoNormal">    Add link to README.Docker.</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">---</p>
<p class="MsoNormal">diff --git a/.dockerignore b/.dockerignore</p>
<p class="MsoNormal">new file mode 100644</p>
<p class="MsoNormal">index 000000000..9f9294a95</p>
<p class="MsoNormal">--- /dev/null</p>
<p class="MsoNormal">+++ b/.dockerignore</p>
<p class="MsoNormal">@@ -0,0 +1,112 @@</p>
<p class="MsoNormal">+*.a</p>
<p class="MsoNormal">+aclocal.m4</p>
<p class="MsoNormal">+autom4te.cache</p>
<p class="MsoNormal">+/benchmarks/*</p>
<p class="MsoNormal">+/extras/*</p>
<p class="MsoNormal">+*.c</p>
<p class="MsoNormal">+*.check.mmacros</p>
<p class="MsoNormal">+*.class</p>
<p class="MsoNormal">+COMP_FLAGS</p>
<p class="MsoNormal">+.compiler_tags</p>
<p class="MsoNormal">+confdefs.h</p>
<p class="MsoNormal">+config.cache</p>
<p class="MsoNormal">+config.log</p>
<p class="MsoNormal">+config.status</p>
<p class="MsoNormal">+# configure is not ignored, s.th. tarballs are supported</p>
<p class="MsoNormal">+# configure</p>
<p class="MsoNormal">+/.configured_library_grades</p>
<p class="MsoNormal">+configure.help</p>
<p class="MsoNormal">+configure.log</p>
<p class="MsoNormal">+*__cpp_code.cpp</p>
<p class="MsoNormal">+*__csharp_code.cs</p>
<p class="MsoNormal">+*.d</p>
<p class="MsoNormal">+*.date</p>
<p class="MsoNormal">+*.*_date</p>
<p class="MsoNormal">+*.date0</p>
<p class="MsoNormal">+*.date3</p>
<p class="MsoNormal">+*.dll</p>
<p class="MsoNormal">+erlang_conf.hrl</p>
<p class="MsoNormal">+*.err</p>
<p class="MsoNormal">+*.exe</p>
<p class="MsoNormal">+/.git/*</p>
<p class="MsoNormal">+*.h</p>
<p class="MsoNormal">+*.il</p>
<p class="MsoNormal">+*.ilk</p>
<p class="MsoNormal">+/INSTALL</p>
<p class="MsoNormal">+/install_grade_dir.*</p>
<p class="MsoNormal">+*.int</p>
<p class="MsoNormal">+*.int0</p>
<p class="MsoNormal">+*.int2</p>
<p class="MsoNormal">+*.int3</p>
<p class="MsoNormal">+*.jar</p>
<p class="MsoNormal">+*.java</p>
<p class="MsoNormal">+jmercury</p>
<p class="MsoNormal">+LIB_FLAGS</p>
<p class="MsoNormal">+libmer_rt.a</p>
<p class="MsoNormal">+libmer_rt.dylib</p>
<p class="MsoNormal">+libmer_rt.lib</p>
<p class="MsoNormal">+libmer_rt.so</p>
<p class="MsoNormal">+libmer_std.dylib</p>
<p class="MsoNormal">+libmer_std.lib</p>
<p class="MsoNormal">+libmer_std.so</p>
<p class="MsoNormal">+library.dep</p>
<p class="MsoNormal">+library.dv</p>
<p class="MsoNormal">+/main.o</p>
<p class="MsoNormal">+Mercury</p>
<p class="MsoNormal">+mercury_compile</p>
<p class="MsoNormal">+mercury_compile.dep</p>
<p class="MsoNormal">+mercury_compile.dep_err</p>
<p class="MsoNormal">+mercury_compile.dv</p>
<p class="MsoNormal">+mercury_compile.exe</p>
<p class="MsoNormal">+mercury_compile.jar</p>
<p class="MsoNormal">+mercury_compile.stats</p>
<p class="MsoNormal">+mercury_conf.h</p>
<p class="MsoNormal">+mercury_conf.h.date</p>
<p class="MsoNormal">+mercury_dotnet.cs</p>
<p class="MsoNormal">+mercury.*.h</p>
<p class="MsoNormal">+mercury_ho_call_codes.i</p>
<p class="MsoNormal">+mercury_ho_call_declares.i</p>
<p class="MsoNormal">+mercury_ho_call_inits.i</p>
<p class="MsoNormal">+mercury_method_call_codes.i</p>
<p class="MsoNormal">+mercury_method_call_declares.i</p>
<p class="MsoNormal">+mercury_method_call_inits.i</p>
<p class="MsoNormal">+Mercury.modules</p>
<p class="MsoNormal">+/Mercury.options</p>
<p class="MsoNormal">+mercury_profiling_builtin.c</p>
<p class="MsoNormal">+mercury_profiling_builtin.h</p>
<p class="MsoNormal">+mer_rt.init</p>
<p class="MsoNormal">+mer_std</p>
<p class="MsoNormal">+mer_std.dep</p>
<p class="MsoNormal">+mer_std.dep_err</p>
<p class="MsoNormal">+mer_std.dv</p>
<p class="MsoNormal">+mer_std.init</p>
<p class="MsoNormal">+*.mh</p>
<p class="MsoNormal">+*.mih</p>
<p class="MsoNormal">+Mmake.common</p>
<p class="MsoNormal">+Mmake.params</p>
<p class="MsoNormal">+Mmake.stage.params</p>
<p class="MsoNormal">+*.module_dep</p>
<p class="MsoNormal">+*.o</p>
<p class="MsoNormal">+*.obj</p>
<p class="MsoNormal">+*.obj_check</p>
<p class="MsoNormal">+*.opt</p>
<p class="MsoNormal">+*.optdate</p>
<p class="MsoNormal">+*.pdb</p>
<p class="MsoNormal">+*.pic_o</p>
<p class="MsoNormal">+*.pl</p>
<p class="MsoNormal">+*.prof</p>
<p class="MsoNormal">+*.ql</p>
<p class="MsoNormal">+/README</p>
<p class="MsoNormal">+/README.*</p>
<p class="MsoNormal">+/samples/*</p>
<p class="MsoNormal">+sicstus_compile sicstus_saved_state</p>
<p class="MsoNormal">+so_locations</p>
<p class="MsoNormal">+/stage1</p>
<p class="MsoNormal">+/stage2</p>
<p class="MsoNormal">+/stage3</p>
<p class="MsoNormal">+tags</p>
<p class="MsoNormal">+/TODO</p>
<p class="MsoNormal">+*.trans_opt</p>
<p class="MsoNormal">+*.trans_opt_date</p>
<p class="MsoNormal">+*.used</p>
<p class="MsoNormal">+/WORK_IN_PROGRESS</p>
<p class="MsoNormal">diff --git a/Dockerfile b/Dockerfile</p>
<p class="MsoNormal">new file mode 100644</p>
<p class="MsoNormal">index 000000000..8082ca410</p>
<p class="MsoNormal">--- /dev/null</p>
<p class="MsoNormal">+++ b/Dockerfile</p>
<p class="MsoNormal">@@ -0,0 +1,84 @@</p>
<p class="MsoNormal">+# vim: ft=dockerfile tw=78 ts=4 sw=4 et</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+# Supported Debian base images</p>
<p class="MsoNormal">+#   - stretch</p>
<p class="MsoNormal">+#   - jessie</p>
<p class="MsoNormal">+ARG MERCURY_DEPEND_TAG=stretch</p>
<p class="MsoNormal">+ARG MERCURY_DEV_PREFIX=/usr/local/mercury</p>
<p class="MsoNormal">+ARG MERCURY_DEV_TARGET=/var/tmp/mercury</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+# first stage, base image</p>
<p class="MsoNormal">+FROM debian:${MERCURY_DEPEND_TAG} AS base</p>
<p class="MsoNormal">+RUN apt-get update && apt-get install -y \</p>
<p class="MsoNormal">+    apt-utils \</p>
<p class="MsoNormal">+    gcc \</p>
<p class="MsoNormal">+    libc-dev \</p>
<p class="MsoNormal">+    make \</p>
<p class="MsoNormal">+    pkg-config</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+FROM base AS bootstrap</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+ARG MERCURY_BOOTSTRAP=y</p>
<p class="MsoNormal">+ARG MERCURY_DL=http://dl.mercurylang.org/deb/</p>
<p class="MsoNormal">+ARG MERCURY_DEV_DEFAULT_GRADE=asm_fast.gc</p>
<p class="MsoNormal">+ARG MERCURY_DEV_LIBGRADES=${MERCURY_DEV_DEFAULT_GRADE}</p>
<p class="MsoNormal">+ARG MERCURY_DEV_PARALLEL=-j3</p>
<p class="MsoNormal">+# When using a source tarball, the source needs to be the top level directory,</p>
<p class="MsoNormal">+# e.g. `mercury-srcdist-rotd-2017-10-19'</p>
<p class="MsoNormal">+ARG MERCURY_DEV_SOURCE=.</p>
<p class="MsoNormal">+# inherited variables</p>
<p class="MsoNormal">+ARG MERCURY_DEV_PREFIX</p>
<p class="MsoNormal">+ARG MERCURY_DEV_TARGET</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+ENV APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE y</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+# install packaged compiler for bootstrapping</p>
<p class="MsoNormal">+# first install curl and lsb-realse so we can add the public key for downloading</p>
<p class="MsoNormal">+# Mercury packages.</p>
<p class="MsoNormal">+# Then add the remote repository and install all packages required for building</p>
<p class="MsoNormal">+# the Mercury compiler from source.</p>
<p class="MsoNormal">+RUN ( echo 'debconf debconf/frontend select Noninteractive' \</p>
<p class="MsoNormal">+        | debconf-set-selections ) && \</p>
<p class="MsoNormal">+    apt-get update && apt-get install -y \</p>
<p class="MsoNormal">+        bison \</p>
<p class="MsoNormal">+        flex \</p>
<p class="MsoNormal">+        $([ "$MERCURY_BOOTSTRAP" != "y" ] || \</p>
<p class="MsoNormal">+            echo autoconf automake curl gnupg2 lsb-release) && \</p>
<p class="MsoNormal">+    [ "${MERCURY_BOOTSTRAP}" != "y" ] || \</p>
<p class="MsoNormal">+        ( \</p>
<p class="MsoNormal">+            ( curl -fsSL https://paul.bone.id.au/paul.asc | apt-key add - ) && \</p>
<p class="MsoNormal">+            printf "%s $MERCURY_DL $(lsb_release -cs) main\n" "deb" "deb-src" \</p>
<p class="MsoNormal">+                > /etc/apt/sources.list.d/mercury.list && \</p>
<p class="MsoNormal">+            apt-get update && apt-get install -y \</p>
<p class="MsoNormal">+                mercury-rotd-recommended \</p>
<p class="MsoNormal">+        )</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+WORKDIR $MERCURY_DEV_TARGET</p>
<p class="MsoNormal">+COPY ${MERCURY_DEV_SOURCE} .</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+# Checking for configure enables using</p>
<p class="MsoNormal">+#   - `docker build http://uri.to.bootstrapped.tar.gz',</p>
<p class="MsoNormal">+#   - `docker build https://github.com/:user:/mercury.git'</p>
<p class="MsoNormal">+#   - `docker build .'</p>
<p class="MsoNormal">+#</p>
<p class="MsoNormal">+# Bootcheck fails currently: ( MAKE_DIR=`pwd`/scripts PATH=$PATH:`pwd`/scripts tools/bootcheck $MERCURY_DEV_PARALLEL ) \</p>
<p class="MsoNormal">+RUN ( \</p>
<p class="MsoNormal">+        ([ -f ./configure ] || ./prepare.sh) \</p>
<p class="MsoNormal">+        && ./configure \</p>
<p class="MsoNormal">+            --enable-libgrades=$MERCURY_DEV_LIBGRADES \</p>
<p class="MsoNormal">+            --with-default-grade=$MERCURY_DEFAULT_GRADE \</p>
<p class="MsoNormal">+            --prefix=$MERCURY_DEV_PREFIX \</p>
<p class="MsoNormal">+            --disable-symlinks \</p>
<p class="MsoNormal">+        && make PARALLEL=$MERCURY_DEV_PARALLEL install \</p>
<p class="MsoNormal">+        && rm -fR ${MERCURY_BOOTSTRAP_TARGET} \</p>
<p class="MsoNormal">+        && rm -fR $MERCURY_DEV_TARGET \</p>
<p class="MsoNormal">+    )</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+FROM base AS compiler</p>
<p class="MsoNormal">+ARG MERCURY_DEV_PREFIX</p>
<p class="MsoNormal">+ARG MERCURY_DEV_TARGET</p>
<p class="MsoNormal">+WORKDIR $MERCURY_DEV_TARGET</p>
<p class="MsoNormal">+COPY --from=bootstrap $MERCURY_DEV_PREFIX $MERCURY_DEV_PREFIX</p>
<p class="MsoNormal">+ENV PATH ${MERCURY_DEV_PREFIX}/bin:$PATH</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+ENTRYPOINT ["mmc"]</p>
<p class="MsoNormal">diff --git a/README.Docker b/README.Docker</p>
<p class="MsoNormal">new file mode 100644</p>
<p class="MsoNormal">index 000000000..0635c32f4</p>
<p class="MsoNormal">--- /dev/null</p>
<p class="MsoNormal">+++ b/README.Docker</p>
<p class="MsoNormal">@@ -0,0 +1,69 @@</p>
<p class="MsoNormal">+This file documents using Mercury within a Docker container.</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+Motivation</p>
<p class="MsoNormal">+==========</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+Docker is a popular way to achieve cross-platform containerisation of applications.</p>
<p class="MsoNormal">+Due to the rather lengthy compile time of the Mercury compiler itself, a way to package the compiler and all of its</p>
<p class="MsoNormal">+dependencies is a desirable goal.</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+Building Mercury</p>
<p class="MsoNormal">+================</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+The [Dockerfile](Dockerfile) is a [multi-staged](https://docs.docker.com/develop/develop-images/multistage-build/) Dockerfile.</p>
<p class="MsoNormal">+Currently there are three stages:</p>
<p class="MsoNormal">+  * base: Defines the basic image that all Mercury related containers should use.</p>
<p class="MsoNormal">+    Based on Debian (Apline Linux works as well but is not supported yet), it comes with gcc, make, pkg-config and libc headers.</p>
<p class="MsoNormal">+  * bootstrap: Installs the packaged ROTD compiler from the [download page](http://dl.mercurylang.org/deb/) and autotools.</p>
<p class="MsoNormal">+  * compiler: Uses the bootstrapped compiler to (auto-)configure Mercury and install it into a single-layered container.</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+Used variables and arguments (for all stages):</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+  - MERCURY_BOOTSTRAP: iff "y" then use a bootstrap mmc while building the compiler</p>
<p class="MsoNormal">+  - MERCURY_DEPEND_ARG: Currently defined as either jessie or stretch, to support building for different debian distributions.</p>
<p class="MsoNormal">+  - MERCURY_DL: Where to find the packaged ROTD compiler for Debian (see above).</p>
<p class="MsoNormal">+  - MERCURY_DEV_SOURCE: Source directory from where to obtain the compiler source code. Used to support building from tarballs (see below).</p>
<p class="MsoNormal">+  - MERCURY_DEV_TARGET: Temporary directory used as container working directory and for building the compiler.</p>
<p class="MsoNormal">+  - MERCURY_DEV_PREFIX: Default prefix to install Mercury to (```/usr/local/mercury```).</p>
<p class="MsoNormal">+  - MERUCRY_DEV_LIBGRADES and MERCURY_DEV_DEFAULT_GRADE: Grades to build, as defined by ```./configure --enable-libgrades```.</p>
<p class="MsoNormal">+    Default is asm_fast.gc.</p>
<p class="MsoNormal">+  - MERCURY_DEV_PARALLEL: Just as ```make PARALLEL=```, defaults to ```-j3```.</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+Additionally building the ROTD tarball is supported via:</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+```bash</p>
<p class="MsoNormal">+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</p>
<p class="MsoNormal">+```</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+Using containerised mmc on the host platform</p>
<p class="MsoNormal">+============================================</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+```bash</p>
<p class="MsoNormal">+docker run --rm --mount type=bind,src="$(pwd)",dst=/var/tmp/mercury mercury-dev --linkage static -m hello</p>
<p class="MsoNormal">+```</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+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.</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+Another use case is to build entire libraries, such as [mercury-json](https://github.com/juliensf/mercury-json.git).</p>
<p class="MsoNormal">+For this the entry point has to be changed in case a Makefile or similar is used:</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+```bash</p>
<p class="MsoNormal">+git clone https://github.com/juliensf/mercury-json.git</p>
<p class="MsoNormal">+docker run --rm --mount type=bind,src="$(pwd)/mercury-json",dst=/var/tmp/mercury --entrypoint make mercury-dev:multi runtests</p>
<p class="MsoNormal">+```</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+Limitations</p>
<p class="MsoNormal">+===========</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+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.</p>
<p class="MsoNormal">+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.</p>
<p class="MsoNormal">+Windows containers are not supported yet, but will be in the future. For this multi-arch files can be utilised.</p>
<p class="MsoNormal">+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.</p>
<p class="MsoNormal">+Please follow all the instructions including changing the mount points from ```/mnt/c``` to ```/c``` only.</p>
<p class="MsoNormal">+Additionally only mounting shared volumes work, such as from the local user profile directory.</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+As this is not yet established within the Mercury community, there are no best-pratices and conventions defined.</p>
<p class="MsoNormal">+It would be desirable to define a common location for installing libraries, a default set of grades available.</p>
<p class="MsoNormal">+Using Docker volumes to store both the runtime libraries and the extra/third party libraries would allow composition of complex build scripts.</p>
<p class="MsoNormal">+</p>
<p class="MsoNormal">+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).</p>
<p class="MsoNormal">diff --git a/README.md b/README.md</p>
<p class="MsoNormal">index 11465021e..0f7e17dc8 100644</p>
<p class="MsoNormal">--- a/README.md</p>
<p class="MsoNormal">+++ b/README.md</p>
<p class="MsoNormal">@@ -36,6 +36,7 @@ Specific information is contained in individual README files:</p>
<p class="MsoNormal"></p>
<p class="MsoNormal">   * Platforms</p>
<p class="MsoNormal"></p>
<p class="MsoNormal">+      * [Docker](README.Docker)</p>
<p class="MsoNormal">       * [Linux](README.Linux)</p>
<p class="MsoNormal">         ([Alpha](README.Linux-Alpha),</p>
<p class="MsoNormal">         [PPC](README.Linux-PPC),</p>
</div>
</body>
</html>