# Dockerfile
# Pierre-André Noël, May 12th 2020
# Copyright © Element AI Inc. All rights reserved.
# Apache License, Version 2.0
#
# This builds `manylinux_2_28_x86_64` Python wheels for `pynini`, wrapping
# all its dependencies.
#
# This Dockerfile uses multi-stage builds; for more information, see:
# https://docs.docker.com/develop/develop-images/multistage-build/
# 
# The recommended installation method for Pynini is through Conda-Forge. This gives Linux
# x86-64 users another option: installing a precompiled module from PyPI.
# 
# 
# To build wheels and run Pynini's tests, run:
# 
#     docker build --target=run-tests -t build-pynini-wheels .
# 
# To extract the resulting wheels from the Docker image, run:
#
#     docker run --rm -v `pwd`:/io build-pynini-wheels cp -r /wheelhouse /io
#
# Notice that this also generates Cython wheels.
# 
# Then, `twine` (https://twine.readthedocs.io/en/latest/) can be used to
# publish the resulting Pynini wheels.

# ******************************************************
# *** All the following images are based on this one ***
# ******************************************************
#from quay.io/pypa/manylinux_2_28_x86_64 AS common

# ***********************************************************************
# *** Image providing all the requirements for building Pynini wheels ***
# ***********************************************************************
FROM harbor.4pd.io/inf/base-python3.8-ubuntu:1.1.0

# The versions we want in the wheels.
ENV FST_VERSION "1.8.3"
ENV PYNINI_VERSION "2.1.6"

# Location of OpenFst and Pynini.
ENV FST_DOWNLOAD_PREFIX "https://www.openfst.org/twiki/pub/FST/FstDownload"
ENV PYNINI_DOWNLOAD_PREFIX "https://www.opengrm.org/twiki/pub/GRM/PyniniDownload"

# Note that our certificates are not known to the version of wget available in this image.

# Gets and unpack OpenFst source.
RUN apt update && apt-get install -y wget gcc-9 g++-9 make && ln -s $(which gcc-9) /usr/bin/gcc && ln -s $(which g++-9) /usr/bin/g++
RUN cd /tmp \
    && wget -q --no-check-certificate "${FST_DOWNLOAD_PREFIX}/openfst-${FST_VERSION}.tar.gz" \
    && tar -xzf "openfst-${FST_VERSION}.tar.gz" \
    && rm "openfst-${FST_VERSION}.tar.gz"

# Compiles OpenFst.
RUN cd "/tmp/openfst-${FST_VERSION}" \
    && ./configure --enable-grm \
    && make --jobs 4 install \
    && rm -rd "/tmp/openfst-${FST_VERSION}"

# Gets and unpacks Pynini source.
RUN mkdir -p /src && cd /src \
    && wget -q --no-check-certificate "${PYNINI_DOWNLOAD_PREFIX}/pynini-${PYNINI_VERSION}.tar.gz" \
    && tar -xzf "pynini-${PYNINI_VERSION}.tar.gz" \
    && rm "pynini-${PYNINI_VERSION}.tar.gz"

# Installs requirements in all our Pythons.
RUN pip install -i https://nexus.4pd.io/repository/pypi-all/simple -r "/src/pynini-${PYNINI_VERSION}/requirements.txt" || exit; 


# **********************************************************
# *** Image making pynini wheels (placed in /wheelhouse) ***
# **********************************************************
#FROM wheel-building-env AS build-wheels

# Compiles the wheels to a temporary directory.
RUN pip wheel -i https://nexus.4pd.io/repository/pypi-all/simple -v "/src/pynini-${PYNINI_VERSION}" -w /tmp/wheelhouse/ || exit; 

RUN wget ftp://ftp.4pd.io/pub/pico/temp/patchelf-0.18.0-x86_64.tar.gz && tar xzf patchelf-0.18.0-x86_64.tar.gz && rm -f patchelf-0.18.0-x86_64.tar.gz
RUN pip install -i https://nexus.4pd.io/repository/pypi-all/simple auditwheel
# Bundles external shared libraries into the wheels.
# See https://github.com/pypa/manylinux/tree/manylinux2014
RUN for WHL in /tmp/wheelhouse/pynini*.whl; do \
    PATH=$(pwd)/bin:$PATH auditwheel repair --plat manylinux_2_31_x86_64 "${WHL}" -w /wheelhouse/ || exit; \
done
#RUN mkdir -p /wheelhouse && for WHL in /tmp/wheelhouse/pynini*.whl; do \
#    cp "${WHL}" /wheelhouse/; \
#done

# Removes the non-repaired wheels.
RUN rm -rd /tmp/wheelhouse

