diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9b67eac..a4a6482 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,11 +5,12 @@ "dockerfile": "../Dockerfile", "target": "developer", "args": { - "TARGET_ARCHITECTURE": "RTEMS-beatnik", - // "TARGET_ARCHITECTURE": "linux-x86_64", - "EPICS_HOST_ARCH": "linux-x86_64", - "BASE_IMAGE": "ghcr.io/epics-containers/rtems6-powerpc-linux-runtime:6.2rc1ec2b2" - // "BASE_IMAGE": "ubuntu:22.04" + // Native target development settings ============================== + "EPICS_TARGET_ARCH": "linux-x86_64", + "BASE_IMAGE": "ubuntu:22.04" + // Local cross compilation settings ================================ + // "EPICS_TARGET_ARCH": "RTEMS-beatnik", + // "BASE_IMAGE": "ghcr.io/epics-containers/rtems-beatnik-runtime" } }, "remoteEnv": { diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 15acdf6..204ffe2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,40 +14,36 @@ jobs: strategy: fail-fast: false matrix: - epics-target: [RTEMS-beatnik, linux-x86_64, linux-arm] - target: [developer, runtime] + epics-target: [RTEMS-beatnik, linux-x86_64, linux-aarch64] include: + - os: ubuntu-latest # everyone is on os-latest + + # native linux compile + - epics-target: linux-x86_64 + epics-host: linux-x86_64 + name: epics-base + base_image: ubuntu:22.04 + platform: linux/amd64 + + # cross compile for RTEMS to VME5500 (power pc beatnik) - epics-target: RTEMS-beatnik epics-host: linux-x86_64 - image_name: rtems-beatnik + name: epics-base-rtems-beatnik base_image: ghcr.io/epics-containers/rtems-beatnik-runtime:6.1rc2 - os: ubuntu-latest platform: linux/amd64 - - epics-target: linux-x86_64 + # cross compile to arm64 + - epics-target: linux-aarch64 epics-host: linux-x86_64 - image_name: linux + name: epics-base-aarch64 base_image: ubuntu:22.04 - os: ubuntu-latest platform: linux/amd64 - - epics-target: linux-arm - epics-host: linux-arm - image_name: linux - base_image: ubuntu:22.04 - os: ubuntu-latest - platform: linux/arm64 - runs-on: ${{ matrix.os }} env: - TAG: ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}-${{ matrix.image_name }}-${{ matrix.target }}:${{ github.ref_name }} - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: recursive - fetch-depth: 1 + TAG: ghcr.io/${{ github.repository_owner }}/${{ matrix.name }} + steps: - name: Log in to GitHub Docker Registry uses: docker/login-action@v3 with: @@ -55,37 +51,44 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build image uses: docker/build-push-action@v5 with: - context: . platforms: ${{ matrix.platform }} - target: ${{ matrix.target }} + target: runtime build-args: | - TARGET_ARCHITECTURE=${{ matrix.epics-target }} + EPICS_TARGET_ARCH=${{ matrix.epics-target }} EPICS_HOST_ARCH=${{ matrix.epics-host }} BASE_IMAGE=${{ matrix.base_image }} - tags: ${{ env.TAG }} cache-from: type=gha,scope=${{ matrix.epics-target }} cache-to: type=gha,mode=max,scope=${{ matrix.epics-target }} load: true - - name: Push image + - name: Push developer image + if: ${{ github.event_name == 'push' && github.ref_type == 'tag' }} + uses: docker/build-push-action@v5 + with: + platforms: ${{ matrix.platform }} + target: developer + build-args: | + EPICS_TARGET_ARCH=${{ matrix.epics-target }} + EPICS_HOST_ARCH=${{ matrix.epics-host }} + BASE_IMAGE=${{ matrix.base_image }} + tags: ${{ env.TAG }}-developer:${{ github.ref_name }} + push: true + + - name: Push runtime image if: ${{ github.event_name == 'push' && github.ref_type == 'tag' }} uses: docker/build-push-action@v5 with: - context: . platforms: ${{ matrix.platform }} - target: ${{ matrix.target }} + target: runtime build-args: | - TARGET_ARCHITECTURE=${{ matrix.epics-target }} + EPICS_TARGET_ARCH=${{ matrix.epics-target }} EPICS_HOST_ARCH=${{ matrix.epics-host }} BASE_IMAGE=${{ matrix.base_image }} - tags: ${{ env.TAG }} + tags: ${{ env.TAG }}-runtime:${{ github.ref_name }} push: true diff --git a/.gitignore b/.gitignore index 9644380..67a818e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ repos/ repos-build/ *.log *.out +*.code-workspace diff --git a/Dockerfile b/Dockerfile index 00597d8..8bf6213 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,35 +1,31 @@ # EPICS 7 Base Dockerfile # build args -# TARGET_ARCHITECTURE: the epics cross compile target platform +# EPICS_TARGET_ARCH: the epics cross compile target platform # note that linux-x86_64 is shortened to linux and is the default # EPICS_HOST_ARCH: the epics host architecture name # BASE_IMAGE: can be used to bring in cross compilation tools ARG BASE_IMAGE=ubuntu:22.04 +ARG RUNTIME_BASE=ubuntu:22.04 -##### shared environment stage ################################################# -FROM ${BASE_IMAGE} AS environment +##### developer stage ########################################################## +FROM ${BASE_IMAGE} AS developer -ARG TARGET_ARCHITECTURE=linux-x86_64 +ARG EPICS_TARGET_ARCH=linux-x86_64 ARG EPICS_HOST_ARCH=linux-x86_64 -ENV TARGET_ARCHITECTURE=${TARGET_ARCHITECTURE} +# environment variables - must be duplicated in the runtime stage +ENV EPICS_VERSION=R7.0.8 +ENV EPICS_TARGET_ARCH=${EPICS_TARGET_ARCH} ENV EPICS_HOST_ARCH=${EPICS_HOST_ARCH} ENV EPICS_ROOT=/epics ENV EPICS_BASE=${EPICS_ROOT}/epics-base ENV SUPPORT ${EPICS_ROOT}/support ENV IOC ${EPICS_ROOT}/ioc +ENV PATH=/venv/bin:${EPICS_BASE}/bin/${EPICS_HOST_ARCH}:${PATH} ENV LD_LIBRARY_PATH=${EPICS_BASE}/lib/${EPICS_HOST_ARCH} -ENV VIRTUALENV /venv -ENV PATH=${VIRTUALENV}/bin:${EPICS_BASE}/bin/${EPICS_HOST_ARCH}:${PATH} - -ENV EPICS_VERSION=R7.0.8 - -##### developer stage ########################################################## -FROM environment AS developer - # install build tools and utilities RUN apt-get update -y && apt-get upgrade -y && \ apt-get install -y --no-install-recommends \ @@ -38,6 +34,7 @@ RUN apt-get update -y && apt-get upgrade -y && \ build-essential \ busybox \ git \ + inotify-tools \ libreadline-dev \ python3-minimal \ python3-pip \ @@ -45,27 +42,44 @@ RUN apt-get update -y && apt-get upgrade -y && \ re2c \ rsync \ ssh-client \ + telnet \ vim \ - && rm -rf /var/lib/apt/lists/* \ - && busybox --install + && rm -rf /var/lib/apt/lists/* # get and build EPICS base -COPY epics /epics -RUN bash epics/scripts/get-base.sh && \ - bash /epics/scripts/patch-epics-base.sh +COPY epics ${EPICS_ROOT} +RUN bash ${EPICS_ROOT}/scripts/get-base.sh && \ + bash ${EPICS_ROOT}/scripts/patch-epics-base.sh RUN make -C ${EPICS_BASE} -j $(nproc); make -C ${EPICS_BASE} clean -COPY requirements.txt /requirements.txt -RUN python3 -m venv ${VIRTUALENV} && pip install -r /requirements.txt +# create a virtual environment to be used by IOCs to install ibek +RUN python3 -m venv /venv ##### runtime preparation stage ################################################ FROM developer AS runtime_prep # get the products from the build stage and reduce to runtime assets only -RUN ibek ioc extract-runtime-assets /assets --no-defaults /venv +RUN bash epics/scripts/move_runtime.sh /assets ##### runtime stage ############################################################ -FROM environment as runtime +FROM ${RUNTIME_BASE} as runtime + +ARG EPICS_TARGET_ARCH=linux-x86_64 +ARG EPICS_HOST_ARCH=linux-x86_64 + +# environment variables - must be duplicated in the developer stage +ENV EPICS_VERSION=R7.0.8 +ENV EPICS_TARGET_ARCH=${EPICS_TARGET_ARCH} +ENV EPICS_HOST_ARCH=${EPICS_HOST_ARCH} +ENV EPICS_ROOT=/epics +ENV EPICS_BASE=${EPICS_ROOT}/epics-base +ENV SUPPORT ${EPICS_ROOT}/support +ENV IOC ${EPICS_ROOT}/ioc +ENV PATH=/venv/bin:${EPICS_BASE}/bin/${EPICS_HOST_ARCH}:${PATH} +ENV LD_LIBRARY_PATH=${EPICS_BASE}/lib/${EPICS_HOST_ARCH}z + +# add products from build stage +COPY --from=runtime_prep /assets / # add runtime system dependencies RUN apt-get update -y && apt-get upgrade -y && \ @@ -73,6 +87,7 @@ RUN apt-get update -y && apt-get upgrade -y && \ libpython3-stdlib \ libreadline8 \ python3-minimal \ + telnet \ && rm -rf /var/lib/apt/lists/* # add products from build stage diff --git a/README.md b/README.md index 2bd8e3f..6737318 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,3 @@ # epics-base -An container image for EPICS base libraries and tools built for linux-x86_64 and RTEMS powerpc mvme5500. - -This repository supports - -- cross compilation to supported EPICS targets -- native compilation x86_64 -- native compilation using non x86 github runners or qemu - -At present only two target architecures are provided. Future expansion is available via the build matrix in build.yml. +An container image for EPICS base libraries and tools built for linux-x86_64 and RTEMS diff --git a/build b/build index 5e1da02..9cd8951 100755 --- a/build +++ b/build @@ -4,36 +4,34 @@ # generic local build script for epics-containers repositories # ################################################################################ -# set TARGET_ARCHITECTURE to rtems for RTEMS based targets -T_A=${TARGET_ARCHITECTURE:-linux_x86_64} +set -e + +# set EPICS_TARGET_ARCH to rtems for RTEMS based targets +T_A=${EPICS_TARGET_ARCH:-linux_x86_64} # set TARGET to runtime for runtime images TARGET=${TARGET:-developer} # set TAG to override the default tag TAG=${TAG:-ec_test} if [ "$T_A" = "RTEMS-beatnik" ]; then - base="ghcr.io/epics-containers/rtems6-powerpc-linux-runtime:6.2rc1ec2b2" + base="ghcr.io/epics-containers/rtems-beatnik-runtime" else base="ubuntu:22.04" fi -# log commands and stop on errors -set -xe - cd $(dirname ${0}) # use docker if available else use podman if ! docker version &>/dev/null; then docker=podman; else docker=docker; fi -if $docker buildx version &>/dev/null; then builx=buildx; load=--load; fi +if $docker buildx version &>/dev/null; then builx=buildx; load='--load --progress=plain'; fi # make sure new repos get their submodule ibek-support if [ ! -d ibek-support ] ; then git submodule update --init ; fi # build and developer images set -x -$docker build $buildx -t ${TAG} \ - --build-arg TARGET_ARCHITECTURE=$T_A \ +$docker build $buildx -t ${TAG} "${@}" $load \ + --build-arg EPICS_TARGET_ARCH=$T_A \ --build-arg BASE_IMAGE=$base \ - "${@}" \ - $load --target $TARGET . + --target $TARGET . diff --git a/epics/scripts/get-base.sh b/epics/scripts/get-base.sh index 74f92a3..146024d 100644 --- a/epics/scripts/get-base.sh +++ b/epics/scripts/get-base.sh @@ -3,7 +3,7 @@ # get the version of epics-base indicated by the environment unless we # are building for RTEMS6 which is temporarily in a forked version -if [[ ${TARGET_ARCHITECTURE} == "RTEMS-beatnik" ]] ; then +if [[ ${EPICS_TARGET_ARCH} == "RTEMS-beatnik" ]] ; then git clone https://github.com/kiwichris/epics-base.git \ --branch rtems-legacy-net-support -q \ --recursive ${EPICS_BASE} diff --git a/epics/scripts/move_runtime.sh b/epics/scripts/move_runtime.sh new file mode 100644 index 0000000..5890ab3 --- /dev/null +++ b/epics/scripts/move_runtime.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# A script to extract the runtime files from the developer stage for use in +# the runtime stage. + +# The first argument is the destination directory for the runtime files. +DEST=${1} + +cd / + +for i in epics/epics-base/bin epics/epics-base/lib venv epics/support; do + # strip any binaries + strip $(find ${i}) 2>/dev/null + + # make sure the path to the parent exists + if [ ! -d ${DEST}/$(dirname ${i}) ]; then + mkdir -p ${DEST}/$(dirname ${i}) + fi + + # move the directory to the new location + mv ${i} ${DEST}/${i} +done diff --git a/epics/scripts/patch-epics-base.sh b/epics/scripts/patch-epics-base.sh index 1f03d37..9ba3f4b 100755 --- a/epics/scripts/patch-epics-base.sh +++ b/epics/scripts/patch-epics-base.sh @@ -7,8 +7,14 @@ sed -i -E 's/(^[^#].*+= test.*$)/# \1/' \ /epics/epics-base/Makefile \ /epics/epics-base/modules/*/Makefile -if [[ $TARGET_ARCHITECTURE == "RTEMS-beatnik" ]]; then +if [[ ${EPICS_TARGET_ARCH} == "RTEMS-beatnik" ]]; then echo "Configuring epics-base to build RTEMS beatnik" cp ${THIS_DIR}/rtems/CONFIG_SITE.local ${EPICS_BASE}/configure/CONFIG_SITE.local -fi +elif [[ ${EPICS_TARGET_ARCH} != "linux-x86_64" ]]; then + echo "Configuring epics-base for target ${EPICS_TARGET_ARCH}" + + touch ${EPICS_BASE}/configure/CONFIG_SITE.local + echo CROSS_COMPILER_TARGET_ARCHS=${EPICS_TARGET_ARCH} >> \ + ${EPICS_BASE}/configure/CONFIG_SITE.local +fi \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 8cc9393..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -ibek==1.7.1