#!/bin/bash # "SoftPLC C++ Toolkit 5" startup script # ====================================== # This script starts a Docker container running the docker image # named: "softplc/toolkit". # This image is found at hub.docker.com and will be automatically downloaded # by a proper Docker installation as part of the first time of use. # # This script uses 2 directories: # BUILD_DIR and SOURCE_DIR # # It results in a Docker container which mounts those 2 host directories # into the container's /build and /source directories. The BUILD_DIR is provided # to this script by way of your CWD (current working directory) at the time # that you run the script. The SOURCE_DIR is provided on the command line when # you run this script. # # Each of the 2 fixed container directories can be mapped to any directory on # your host build system. While the container is running, it will have the # two mapped directories, and this is typically temporary and project or TLM specific. # You will be running only build tools (cmake and make) from a shell within the # container. For source code text editing, use your normal text editor, and do # it *outside* of the container as you normally do. # # The 2 host directories, BUILD_DIR and SOURCE_DIR will always be mapped into # the container at /build and /source respectively. These are bind mounts in # the Docker vernacular. # Think of those 2 bind mounts as two legs. That makes for a memory # aid for remembering the name of this script: standup-toolkit.sh. # # Example: # $ cd ~/tlms/mytlm # $ mkdir build-arm64 # $ cd build-arm64 # CWD provides BUILD_DIR # $ standup-toolkit.sh ~/tlms/mytlm # SOURCE_DIR on command line # # The above starts a container running softplc/toolkit and opens up a terminal # within it. The container is focused on its /build and /source directories, # which are identical to the host's ~/tlms/mytlm/build-arm64 and # ~/tlms/mytlm respectively. # # If you need more VOLUME_MOUNTS, you may modify this script in your own # copy. # # Using CMake and make are the same as prior SoftPLC Toolkits. From the # /build directory you run "makemake.sh". Then you run "make". # The only differences are that you do this from the container's bash terminal # and that the host's BUILD_DIR and SOURCE_DIR will be mapped into the # container's /build and /source. Below is an example that would be done # after the one time "standup-toolkit.sh". # # $ cd /build # tooltkit bash starts here any way. # now run makemake.sh found in this location: # $ /opt/softplc/c++-toolkit-5/bin/makemake.sh ARCH /source # always "/source" # $ make # # Terminate the container by running exit from its terminal; because bash is the # container's only job, the container stops and (with --rm) is removed: # $ exit # The container runs as YOUR host user id (see USER_RUN below), so files it # writes into BUILD_DIR are owned by you, not root. Running as your uid needs a # writable HOME inside the container: the host uid has no passwd entry there, so # HOME would otherwise default to "/" and any build step that touches $HOME fails # with a permission error. We set HOME=/tmp to solve that. If some build step # must write to a root-owned path inside the image, comment out USER_RUN to fall # back to running as root (outputs are then root-owned, but you can copy them out). # The version tag named "latest" is used by the toolkit maintainers to earmark # the most recently released image. You may want to pin DOCKER_IMAGE to a # known stable numeric version, like "softplc/toolkit:1.9" DOCKER_IMAGE="softplc/toolkit:trixie_latest" #DOCKER_IMAGE="softplc/toolkit:bullseye_latest" usage() { echo echo "Usage:" echo echo "$ cd BUILD_DIR" echo "$ $0 SOURCE_DIR" echo exit 1 } if ! command -v docker >/dev/null 2>&1; then echo "You must have a recent version of Docker installed" exit 2 fi # Portable daemon check: works on Linux, macOS/Windows Docker Desktop, and WSL. # ('systemctl is-active docker' is Linux-systemd-only and wrongly fails elsewhere.) if ! docker info >/dev/null 2>&1; then echo "Docker does not appear to be running; please start Docker and retry." exit 3 fi # The documented, reserved first argument is SOURCE_DIR. An undocumented second # argument "-v" enables the maintainer-only extra mounts (the FOR_DICK block # further down). Deliberately not shown in usage(). if [[ $# -lt 1 || $# -gt 2 ]]; then usage fi EXTRA_VOLUMES= if [[ $# -eq 2 ]]; then if [[ "$2" == "-v" ]]; then EXTRA_VOLUMES=1 else usage fi fi echo "using image \"$DOCKER_IMAGE\"" # Resolve SOURCE_DIR to an absolute path portably (no realpath dependency) and # validate that it exists. SOURCE_DIR="$(cd "$1" 2>/dev/null && pwd)" || { echo "SOURCE_DIR \"$1\" not found"; usage; } BUILD_DIR="$(pwd)" echo "SOURCE_DIR=\"$SOURCE_DIR\" BUILD_DIR=\"$BUILD_DIR\"" VOLUME_MOUNTS="$VOLUME_MOUNTS -v $SOURCE_DIR:/source" VOLUME_MOUNTS="$VOLUME_MOUNTS -v $BUILD_DIR:/build" # The image self-registers the running uid into /etc/passwd at startup (see its # entrypoint), so getpwuid() resolves for scp/ssh/sudo without mounting the host # /etc/passwd -- works on any OS. We pass HOST_USER so the registered account # (and your shell prompt) shows your real name instead of the generic "builder". USER_ENV="-e HOST_USER=$(id -un)" # --- Advanced / maintainer-only extra mounts -------------------------------- # The two mounts above are all a standard TLM build needs. Add project-specific # host directories below only if a particular TLM requires them, and keep them # commented for normal distribution. NOTE: Docker auto-creates a missing # bind-mount source as a root-owned empty dir, so a stray mount is NOT harmless. # # Example -- a client project that needs an extra cloned repo: # Enabled only by the undocumented "-v" second argument (see arg # parsing near the top). Extra volume mounts can be placed in here. if [[ -n "$EXTRA_VOLUMES" ]]; then VOLUME_MOUNTS="$VOLUME_MOUNTS -v /i/git-repos/CIPster:/CIPster" VOLUME_MOUNTS="$VOLUME_MOUNTS -v /svn/softplc/h:/opt/softplc/c++-toolkit-5/h" fi # Maintainer overrides -- live-mount toolkit sources over the image's copies: #VOLUME_MOUNTS="$VOLUME_MOUNTS -v /svn/softplc/h/tlm.h:/opt/softplc/c++-toolkit-5/h/tlm.h" #VOLUME_MOUNTS="$VOLUME_MOUNTS -v /opt/softplc/c++-toolkit-5/h/dt_objects.h:/opt/softplc/c++-toolkit-5/h/dt_objects.h" #VOLUME_MOUNTS="$VOLUME_MOUNTS -v /opt/softplc/c++-toolkit-5/cmake/tlm.cmake:/opt/softplc/c++-toolkit-5/cmake/tlm.cmake" # Run as your host user so build outputs in BUILD_DIR are owned by you, not root. # HOME=/tmp gives that uid a writable home inside the image (see the note near the # top). Comment this line out to run as root instead. USER_RUN="--user $(id -u):$(id -g) -e HOME=/tmp" #SET_CONTAINER_NAME="--name toolkit" # keep this line if you want the newest image on each run: docker pull $DOCKER_IMAGE cat <