mirror of
https://github.com/autc04/Retro68.git
synced 2025-08-15 16:27:55 +00:00
Merge pull request #216 from mcayland/feature/docker-build-universal
Retro68: improve Docker support to enable builds with Universal interfaces
This commit is contained in:
16
Dockerfile
16
Dockerfile
@@ -7,7 +7,7 @@ RUN apt-get update && \
|
|||||||
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
DEBIAN_FRONTEND=noninteractive apt-get install -y \
|
||||||
cmake libgmp-dev libmpfr-dev libmpc-dev \
|
cmake libgmp-dev libmpfr-dev libmpc-dev \
|
||||||
libboost-all-dev bison texinfo \
|
libboost-all-dev bison texinfo \
|
||||||
ruby flex curl g++ git
|
ruby flex curl g++ git macutils
|
||||||
|
|
||||||
# Add toolchain to default PATH
|
# Add toolchain to default PATH
|
||||||
ENV PATH=/Retro68-build/toolchain/bin:$PATH
|
ENV PATH=/Retro68-build/toolchain/bin:$PATH
|
||||||
@@ -19,11 +19,25 @@ FROM base AS build
|
|||||||
ADD . /Retro68
|
ADD . /Retro68
|
||||||
|
|
||||||
RUN mkdir /Retro68-build && \
|
RUN mkdir /Retro68-build && \
|
||||||
|
mkdir /Retro68-build/bin && \
|
||||||
bash -c "cd /Retro68-build && bash /Retro68/build-toolchain.bash"
|
bash -c "cd /Retro68-build && bash /Retro68/build-toolchain.bash"
|
||||||
|
|
||||||
# Release image
|
# Release image
|
||||||
FROM base AS release
|
FROM base AS release
|
||||||
|
|
||||||
|
ENV INTERFACES=multiversal
|
||||||
|
|
||||||
|
COPY --from=build \
|
||||||
|
/Retro68/interfaces-and-libraries.sh \
|
||||||
|
/Retro68/prepare-headers.sh \
|
||||||
|
/Retro68/prepare-rincludes.sh \
|
||||||
|
/Retro68/install-universal-interfaces.sh \
|
||||||
|
/Retro68/docker-entrypoint.sh \
|
||||||
|
/Retro68-build/bin/
|
||||||
|
|
||||||
COPY --from=build /Retro68-build/toolchain /Retro68-build/toolchain
|
COPY --from=build /Retro68-build/toolchain /Retro68-build/toolchain
|
||||||
|
|
||||||
LABEL org.opencontainers.image.source https://github.com/autc04/Retro68
|
LABEL org.opencontainers.image.source https://github.com/autc04/Retro68
|
||||||
|
|
||||||
|
CMD [ "/bin/bash" ]
|
||||||
|
ENTRYPOINT [ "/Retro68-build/bin/docker-entrypoint.sh" ]
|
||||||
|
83
README.md
83
README.md
@@ -192,6 +192,89 @@ package contains a very portable library, the command will of course fail. Pleas
|
|||||||
report bugs, please report successes instead!
|
report bugs, please report successes instead!
|
||||||
|
|
||||||
|
|
||||||
|
Using Retro68 with Docker
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Whenever commits are merged into the Retro68 git repository, a build pipeline is triggered to
|
||||||
|
create a container image which is then pushed to the Retro68 package repository as
|
||||||
|
`ghcr.io/autc04/retro68`. This image contains the complete 68K and PPC toolchains ready for
|
||||||
|
use for either local development or as part of CI pipeline. The command line below shows an
|
||||||
|
example invocation of Retro68 to build the `Samples/Raytracer` app:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git clone --depth 1 https://github.com/autc04/Retro68.git
|
||||||
|
$ cd Retro68
|
||||||
|
$ docker run --rm -v $(pwd):/root -i ghcr.io/autc04/retro68 /bin/bash <<"EOF"
|
||||||
|
cd Samples/Raytracer
|
||||||
|
rm -rf build && mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_TOOLCHAIN_FILE=/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake
|
||||||
|
make
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
The container image is configured by default to use the multiversal interfaces, but it is
|
||||||
|
possible to use the universal interfaces by passing a path to either a local file or a URL
|
||||||
|
that points to a Macbinary DiskCopy image containing the "Interfaces&Libraries" directory
|
||||||
|
from MPW.
|
||||||
|
|
||||||
|
Using the universal interfaces from a local file:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker run --rm -v $(pwd):/root -v $(pwd)/MPW-GM.img.bin:/tmp/MPW-GM.img.bin \
|
||||||
|
-e INTERFACES=universal -e INTERFACESFILE=/tmp/MPW-GM.img.bin \
|
||||||
|
-i ghcr.io/autc04/retro68 /bin/bash <<"EOF"
|
||||||
|
cd Samples/Raytracer
|
||||||
|
rm -rf build && mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_TOOLCHAIN_FILE=/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake
|
||||||
|
make
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Using the universal interfaces from a URL:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker run --rm -v $(pwd):/root \
|
||||||
|
-e INTERFACES=universal -e INTERFACESFILE=https://mysite.com/MPW-GM.img.bin \
|
||||||
|
-i ghcr.io/autc04/retro68 /bin/bash <<"EOF"
|
||||||
|
cd Samples/Raytracer
|
||||||
|
rm -rf build && mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_TOOLCHAIN_FILE=/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake
|
||||||
|
make
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that `entrypoint.sh` checks to see if the universal interfaces are installed into
|
||||||
|
`/Retro68/toolchain/universal` first before attempting to access the file or URL specified
|
||||||
|
by INTERFACESFILE. This means that it is possible to use caching or another volume so that
|
||||||
|
the universal interfaces are only processed once to speed up builds e.g.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker run --rm -v $(pwd):/root \
|
||||||
|
-v $(pwd)/universal:/Retro68-build/toolchain/universal \
|
||||||
|
-e INTERFACES=universal -e INTERFACESFILE=https://mysite.com/MPW-GM.img.bin \
|
||||||
|
-i ghcr.io/autc04/retro68 /bin/bash <<"EOF"
|
||||||
|
cd Samples/Raytracer
|
||||||
|
rm -rf build && mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_TOOLCHAIN_FILE=/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake
|
||||||
|
make
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
and then on subsequent runs:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ docker run --rm -v $(pwd):/root \
|
||||||
|
-v $(pwd)/universal:/Retro68-build/toolchain/universal \
|
||||||
|
-e INTERFACES=universal \
|
||||||
|
-i ghcr.io/autc04/retro68 /bin/bash <<"EOF"
|
||||||
|
cd Samples/Raytracer
|
||||||
|
rm -rf build && mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_TOOLCHAIN_FILE=/Retro68-build/toolchain/m68k-apple-macos/cmake/retro68.toolchain.cmake
|
||||||
|
make
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
Sample programs
|
Sample programs
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
65
docker-entrypoint.sh
Executable file
65
docker-entrypoint.sh
Executable file
@@ -0,0 +1,65 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TMPDIR=/tmp
|
||||||
|
BUILDDIR=/Retro68-build
|
||||||
|
|
||||||
|
if [[ $INTERFACES == "universal" ]];
|
||||||
|
then
|
||||||
|
# If the universal RIncludes directory is empty, download and install the universal headers
|
||||||
|
if [ ! "$(ls -A $BUILDDIR/toolchain/universal/RIncludes 2> /dev/null)" ]; then
|
||||||
|
# If INTERFACESFILE is empty, exit
|
||||||
|
if [[ -z $INTERFACESFILE ]];
|
||||||
|
then
|
||||||
|
echo -n "Universal interfaces not present, please specify the location of a suitable "
|
||||||
|
echo "MacBinary DiskCopy image using the INTERFACESFILE environment variable."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
BASEINTERFACESFILE=`basename $INTERFACESFILE`
|
||||||
|
|
||||||
|
# If INTERFACESFILE is a URL, download it first to TMPDIR. Otherwise assume the file is
|
||||||
|
# already present and copy it to TMPDIR for installation
|
||||||
|
if [[ $INTERFACESFILE == http* ]];
|
||||||
|
then
|
||||||
|
echo "Downloading Universal interfaces from MacBinary DiskCopy image $BASEINTERFACESFILE..."
|
||||||
|
curl -s $INTERFACESFILE -o $TMPDIR/$BASEINTERFACESFILE
|
||||||
|
echo "done"
|
||||||
|
else
|
||||||
|
if [[ -z $INTERFACESFILE ]];
|
||||||
|
then
|
||||||
|
echo "Unable to locate universal interfaces file $INTERFACESFILE"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Using Universal intefaces from MacBinary Diskcopy image $BASEINTERFACESFILE"
|
||||||
|
cp $INTERFACESFILE $TMPDIR/$BASEINTERFACESFILE
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract the file
|
||||||
|
$BUILDDIR/bin/install-universal-interfaces.sh $TMPDIR $BASEINTERFACESFILE
|
||||||
|
|
||||||
|
# Switch to universal
|
||||||
|
echo "Linking Universal interfaces..."
|
||||||
|
$BUILDDIR/bin/interfaces-and-libraries.sh $BUILDDIR/toolchain $TMPDIR/InterfacesAndLibraries
|
||||||
|
echo "done"
|
||||||
|
else
|
||||||
|
echo "Linking Universal interfaces..."
|
||||||
|
|
||||||
|
# Link to existing universal interfaces
|
||||||
|
PREFIX=$BUILDDIR/toolchain
|
||||||
|
. "$BUILDDIR/bin/interfaces-and-libraries.sh"
|
||||||
|
BUILD_68K=true
|
||||||
|
BUILD_PPC=true
|
||||||
|
|
||||||
|
unlinkInterfacesAndLibraries
|
||||||
|
linkInterfacesAndLibraries "universal"
|
||||||
|
echo "done"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "Using multiversal interfaces"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Execute command
|
||||||
|
exec "$@"
|
101
install-universal-interfaces.sh
Executable file
101
install-universal-interfaces.sh
Executable file
@@ -0,0 +1,101 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
#
|
||||||
|
# install-universal-interfaces.sh
|
||||||
|
#
|
||||||
|
# Optionally download and attempt to install the universal interfaces from
|
||||||
|
# a Macbinary disk image containing the Interfaces&Libraries directory
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# install-universal-interfaces.sh <tempdir> <filename>
|
||||||
|
#
|
||||||
|
# Decompress the Macbinary image at <tempdir>/<filename> into
|
||||||
|
# <tempdir>/InterfacesAndLibraries in the correct format for
|
||||||
|
# interfaces-and-libraries.sh.
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
TMPDIR=$1
|
||||||
|
FILENAME=$2
|
||||||
|
|
||||||
|
if [[ ! -f $TMPDIR/$FILENAME ]];
|
||||||
|
then
|
||||||
|
echo "$TMPDIR/$FILENAME not found"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Decompressing $FILENAME..."
|
||||||
|
ConvertDiskImage $TMPDIR/$FILENAME $TMPDIR/$FILENAME.img
|
||||||
|
echo "Decompression complete"
|
||||||
|
|
||||||
|
# Copy over Interfaces&Libraries files
|
||||||
|
echo "Copying Interfaces&Libraries files..."
|
||||||
|
hmount $TMPDIR/$FILENAME.img
|
||||||
|
|
||||||
|
# Find Interfaces&Libraries directory, get recursive directory listing
|
||||||
|
HFSINTERFACESANDLIBSDIR=`hls -R | grep 'Interfaces&Libraries:$'`
|
||||||
|
IFS="$(printf '\n')"
|
||||||
|
echo "Found Interfaces&Libraries at $HFSINTERFACESANDLIBSDIR"
|
||||||
|
FILES=`hls -FR1 $HFSINTERFACESANDLIBSDIR`
|
||||||
|
|
||||||
|
UNIXINTERFACESANDLIBSDIR=$TMPDIR/InterfacesAndLibraries
|
||||||
|
mkdir -p $UNIXINTERFACESANDLIBSDIR
|
||||||
|
|
||||||
|
# Parse results: first line is the HFS path, following lines contain one file
|
||||||
|
# per line terminated by an empty line
|
||||||
|
while IFS= read -r LINE; do
|
||||||
|
if [[ $LINE == :* ]];
|
||||||
|
then
|
||||||
|
# If it starts with : then it is a HFS path
|
||||||
|
HFSPATH=$LINE
|
||||||
|
UNIXRELPATH=$(echo "$HFSPATH" | sed "s#$HFSINTERFACESANDLIBSDIR##g" | sed "s#:#/"#g)
|
||||||
|
UNIXPATH="$UNIXINTERFACESANDLIBSDIR/$UNIXRELPATH"
|
||||||
|
|
||||||
|
# Make UNIX directory
|
||||||
|
mkdir -p $UNIXPATH
|
||||||
|
else
|
||||||
|
# If it ends with : it is a directory so ignore (we will find it during the descent)
|
||||||
|
if [[ ! $LINE == *: ]];
|
||||||
|
then
|
||||||
|
# If it isn't empty, it must be a filename
|
||||||
|
if [[ ! -z $LINE ]];
|
||||||
|
then
|
||||||
|
HFSFULLPATH="$HFSPATH$LINE"
|
||||||
|
UNIXFULLPATH="$UNIXPATH$LINE"
|
||||||
|
|
||||||
|
echo "Copying $HFSFULLPATH to $UNIXFULLPATH"
|
||||||
|
|
||||||
|
# PPC libraries need a resource fork, but the code in
|
||||||
|
# interfaces-and-libraries.sh doesn't correctly detect InterfaceLib in
|
||||||
|
# Macbinary format. Work around this for now by using Basilisk II format
|
||||||
|
# which can be parsed by ResourceFile and still allows the filename
|
||||||
|
# detection logic to work.
|
||||||
|
if [[ $HFSPATH == *SharedLibraries: ]];
|
||||||
|
then
|
||||||
|
if [[ ! -d $UNIXPATH.rsrc ]];
|
||||||
|
then
|
||||||
|
mkdir $UNIXPATH.rsrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
# First copy as Macbinary
|
||||||
|
hcopy -m $HFSFULLPATH $UNIXFULLPATH.bin
|
||||||
|
|
||||||
|
# Extract data fork using normal name
|
||||||
|
bash -c "cd $UNIXPATH && macunpack -d $UNIXFULLPATH.bin && mv $UNIXFULLPATH.data $UNIXFULLPATH"
|
||||||
|
|
||||||
|
# Extract resource fork into .rsrc directory
|
||||||
|
bash -c "cd $UNIXPATH && macunpack -r $UNIXFULLPATH.bin && mv $UNIXFULLPATH.rsrc $UNIXPATH.rsrc/$LINE"
|
||||||
|
|
||||||
|
# Delete original Macbinary
|
||||||
|
rm -rf $UNIXFULLPATH.bin
|
||||||
|
else
|
||||||
|
hcopy -r $HFSFULLPATH $UNIXFULLPATH
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done <<< "$FILES"
|
||||||
|
|
||||||
|
# Unmount image
|
||||||
|
humount
|
Reference in New Issue
Block a user