# syntax=docker/dockerfile:1.7

FROM ghcr.io/astral-sh/uv:0.11.2@sha256:c4f5de312ee66d46810635ffc5df34a1973ba753e7241ce3a08ef979ddd7bea5 AS uv
FROM ubuntu:24.04@sha256:534baea6a22c03a63003dbc8dbe78fe34bc0d7e595d9a9dc9834884ff530eb55 AS common

ENV DEBIAN_FRONTEND=noninteractive \
    UV_PROJECT_ENVIRONMENT=/opt/iclayout-bench-tools \
    UV_PYTHON_DOWNLOADS=never \
    UV_LINK_MODE=copy \
    PATH=/opt/iclayout-bench-tools/bin:${PATH} \
    QT_QPA_PLATFORM=offscreen

RUN test "$(dpkg --print-architecture)" = amd64 \
    && apt-get update \
    && apt-get install -y --no-install-recommends ca-certificates curl python3 python3-venv python3-tk \
    && rm -rf /var/lib/apt/lists/*

RUN curl --fail --show-error --silent --location --retry 3 --retry-all-errors --connect-timeout 20 \
        https://www.klayout.org/downloads/Ubuntu-24/klayout_0.30.11-1_amd64.deb \
        --output /tmp/klayout.deb \
    && echo '772eb2c597dc8ec054800841246fcbf6f3440581caee53663dc93afd135027b3  /tmp/klayout.deb' | sha256sum --check \
    && apt-get update \
    && apt-get install -y --no-install-recommends /tmp/klayout.deb \
    && rm /tmp/klayout.deb \
    && rm -rf /var/lib/apt/lists/*

RUN install -d -o ubuntu -g ubuntu /workspace

WORKDIR /workspace
CMD ["bash"]

FROM common AS ngspice-build
ARG NGSPICE_COMMIT=86c78150b77ceea8488707565b3be2d2f4e7fbb9
ARG NGSPICE_SHA256=dcc8f263bae8f3eb0717f36a6bf3b424f0531a33b9e51ce88aec0437694f0ad9
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        build-essential autoconf automake libtool bison flex libreadline-dev libsuitesparse-dev \
    && curl --fail --show-error --silent --location --retry 3 \
        "https://codeload.github.com/imr/ngspice/tar.gz/$NGSPICE_COMMIT" \
        --output /tmp/ngspice.tar.gz \
    && echo "$NGSPICE_SHA256  /tmp/ngspice.tar.gz" | sha256sum --check \
    && tar -xzf /tmp/ngspice.tar.gz -C /tmp \
    && cd "/tmp/ngspice-$NGSPICE_COMMIT" \
    && ./autogen.sh \
    && ./configure --prefix=/opt/ngspice --with-x=no --enable-xspice --enable-osdi \
        --enable-klu --with-readline=yes \
    && make -j4 \
    && make install \
    && install -D COPYING /opt/ngspice/share/doc/COPYING

FROM common AS qucsator-build
ARG QUCSATOR_COMMIT=e995f9acc71a8c7319286944e4a1692318b9dd80
ARG QUCSATOR_SHA256=ee77425b6714b14ee8ac2ba5c33709c00802fd3cdc1f6519cf5d7df033644964
RUN apt-get update \
    && apt-get install -y --no-install-recommends build-essential cmake flex bison gperf adms \
    && rm -rf /var/lib/apt/lists/*
RUN curl --fail --show-error --silent --location --retry 3 --retry-all-errors --connect-timeout 20 \
        "https://codeload.github.com/Qucs/qucsator/tar.gz/${QUCSATOR_COMMIT}" \
        --output /tmp/qucsator.tar.gz \
    && echo "${QUCSATOR_SHA256}  /tmp/qucsator.tar.gz" | sha256sum --check \
    && tar -xzf /tmp/qucsator.tar.gz -C /tmp \
    && cmake -S "/tmp/qucsator-${QUCSATOR_COMMIT}" -B /tmp/qucsator-build \
        -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/qucsator \
    && cmake --build /tmp/qucsator-build --parallel 4 \
    && cmake --install /tmp/qucsator-build \
    && rm -rf /tmp/qucsator.tar.gz "/tmp/qucsator-${QUCSATOR_COMMIT}" /tmp/qucsator-build

FROM common AS model-compiler
RUN apt-get update \
    && apt-get install -y --no-install-recommends binutils \
    && rm -rf /var/lib/apt/lists/*
RUN curl --fail --show-error --silent --location --retry 3 --retry-all-errors --connect-timeout 20 \
        https://fides.fe.uni-lj.si/openvaf/download/openvaf-reloaded-osdi_0.3-31-gf47d557-linux_x64.tar.gz \
        --output /tmp/openvaf.tar.gz \
    && echo '9bc343d52e00529ddba452b90358cdd14da14ec7437d75dec2dbd621eda54bc8  /tmp/openvaf.tar.gz' | sha256sum --check \
    && tar -xzf /tmp/openvaf.tar.gz -C /usr/local/bin openvaf \
    && rm /tmp/openvaf.tar.gz \
    && install -D /usr/share/common-licenses/GPL-3 /usr/local/share/doc/openvaf/COPYING
USER ubuntu

FROM common AS magic-build
# MAGIC_VERSION is an upstream make variable containing only major.minor.
ARG MAGIC_RELEASE=8.3.678
ARG MAGIC_SHA256=3f47b68d3ca2c0ef1cdf18916581a5ac3a529ecc83c6ad0d7cd8e1800d2c3614
COPY scripts/patches/magic-stable-device-order.patch /tmp/magic-stable-device-order.patch
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
        build-essential tcl-dev tk-dev libx11-dev zlib1g-dev libreadline-dev patch \
    && curl --fail --show-error --silent --location --retry 3 \
        --retry-all-errors --connect-timeout 20 \
        "https://codeload.github.com/RTimothyEdwards/magic/tar.gz/refs/tags/$MAGIC_RELEASE" \
        --output /tmp/magic.tar.gz \
    && echo "$MAGIC_SHA256  /tmp/magic.tar.gz" | sha256sum --check \
    && tar -xzf /tmp/magic.tar.gz -C /tmp \
    && cd "/tmp/magic-$MAGIC_RELEASE" \
    && python3 -c 'from pathlib import Path; p=Path("resis/ResRex.c"); s=p.read_text(); old="int\t\ttotWL, maxWL = 0;"; assert s.count(old)==1; p.write_text(s.replace(old,"float totWL, maxWL = 0.0;"))' \
    && patch -p1 < /tmp/magic-stable-device-order.patch \
    && ./configure --prefix=/opt/magic --without-opengl --without-cairo --disable-magic-builddate \
    && make -j4 \
    && make install \
    && test "$(/opt/magic/bin/magic --version)" = "$MAGIC_RELEASE" \
    && install -D LICENSE /opt/magic/share/doc/LICENSE \
    && install -D /tmp/magic-stable-device-order.patch \
        /opt/magic/share/doc/magic-stable-device-order.patch

FROM common AS xschem-build
# Release 3.4.7 supplies ev7, required by the pinned SG13G2 tap symbols.
ARG XSCHEM_COMMIT=92dd8fe5f4d5c1057489710d8a22f18fdc9d7ed0
ARG XSCHEM_SHA256=db5250690bc193bb2874e7a3b43d7bfc3499c882feb7fa885080434cc9a81c7c
RUN apt-get update \
    && apt-get install -y --no-install-recommends build-essential flex bison \
        tcl-dev tk-dev libx11-dev libxpm-dev libcairo2-dev libjpeg-dev \
    && rm -rf /var/lib/apt/lists/*
RUN curl --fail --show-error --silent --location --retry 3 --retry-all-errors --connect-timeout 20 \
        "https://codeload.github.com/StefanSchippers/xschem/tar.gz/${XSCHEM_COMMIT}" \
        --output /tmp/xschem.tar.gz \
    && echo "${XSCHEM_SHA256}  /tmp/xschem.tar.gz" | sha256sum --check \
    && tar -xzf /tmp/xschem.tar.gz -C /tmp \
    && cd "/tmp/xschem-${XSCHEM_COMMIT}" \
    && ./configure --prefix=/opt/xschem \
    && make -j4 \
    && make install \
    && install -D LICENSE /opt/xschem/share/doc/LICENSE

FROM common AS netgen-build
ARG NETGEN_COMMIT=e1528a797cdb155d6ebf8d91c5a55ed7d1713156
ARG NETGEN_SHA256=5d9de873dc354a0882fc9f67dbe0f80b65524330fbb34a08c232c75a38a27d67
RUN apt-get update \
    && apt-get install -y --no-install-recommends build-essential tcl-dev tk-dev libx11-dev \
    && curl --fail --show-error --silent --location --retry 3 \
        --retry-all-errors --connect-timeout 20 \
        "https://codeload.github.com/RTimothyEdwards/netgen/tar.gz/$NETGEN_COMMIT" \
        --output /tmp/netgen.tar.gz \
    && echo "$NETGEN_SHA256  /tmp/netgen.tar.gz" | sha256sum --check \
    && tar -xzf /tmp/netgen.tar.gz -C /tmp \
    && cd "/tmp/netgen-$NETGEN_COMMIT" \
    && ./configure --prefix=/opt/netgen \
    && make -j4 \
    && make install \
    && install -D Copying /opt/netgen/share/doc/Copying

# The public development environment is one image. Every preparation, solver,
# and judge container is an isolated invocation of this same EDA toolchain.
# Harness runtimes are supplied by the harness (or its selected image); the
# benchmark image does not install or privilege a particular Agent framework.
FROM common AS tools
LABEL org.opencontainers.image.title="ICLayout open EDA" \
      org.iclayout.eda="open"
USER root
RUN apt-get update \
    && apt-get install -y --no-install-recommends git jq make ripgrep \
        ngspice=42+ds-3build1 libklu2 libreadline8t64 binutils tk libxpm4 libcairo2 libjpeg-turbo8 \
    && rm -rf /var/lib/apt/lists/*
ARG QUCS_S_VERSION=26.1.1-1
ARG QUCS_S_SHA256=580c3cf5aa7f99bf76ee49822317633c46649aebec2f64f83fb52a2db8b45fab
RUN curl --fail --show-error --silent --location --retry 3 --retry-all-errors --connect-timeout 20 \
        "https://download.opensuse.org/repositories/home:/ra3xdh/xUbuntu_24.04/amd64/qucs-s_${QUCS_S_VERSION}_amd64.deb" \
        --output /tmp/qucs-s.deb \
    && echo "${QUCS_S_SHA256}  /tmp/qucs-s.deb" | sha256sum --check \
    && apt-get update \
    && apt-get install -y --no-install-recommends /tmp/qucs-s.deb \
    && rm /tmp/qucs-s.deb \
    && rm -rf /var/lib/apt/lists/*
COPY --from=ngspice-build /opt/ngspice /opt/ngspice
ENV PATH=/opt/ngspice/bin:${PATH}
COPY --from=qucsator-build /opt/qucsator /opt/qucsator
ENV PATH=/opt/qucsator/bin:${PATH}
RUN test -x /usr/bin/qucs-s \
    && test -x /opt/qucsator/bin/qucsator \
    && test -x /usr/bin/qucsator_rf \
    && test -x /opt/qucsator/bin/qucsconv
COPY --from=model-compiler /usr/local/bin/openvaf /usr/local/bin/openvaf
COPY --from=model-compiler /usr/local/share/doc/openvaf /usr/local/share/doc/openvaf
COPY --from=magic-build /opt/magic /opt/magic
ENV PATH=/opt/magic/bin:${PATH}
COPY --from=xschem-build /opt/xschem /opt/xschem
ENV PATH=/opt/xschem/bin:${PATH}
COPY --from=netgen-build /opt/netgen /opt/netgen
ENV PATH=/opt/netgen/bin:${PATH}
# Keep frequently changed Python dependencies after native EDA build stages.
# Lockfile changes must not invalidate tool downloads and compilation.
COPY --from=uv /uv /usr/local/bin/uv
COPY pyproject.toml uv.lock /opt/iclayout-bench-build/
RUN --mount=type=cache,target=/root/.cache/uv \
    cd /opt/iclayout-bench-build \
    && uv sync --locked --only-group eda --no-install-project --python /usr/bin/python3
USER ubuntu
