While Objective-Smalltalk’s’s architecture seems perfect for cloud environments, this has remained mostly theoretical. Historically, Objective-Smalltalk only functioned on macOS and iOS.
My previous experience porting projects like MusselWind to Linux using GNUstep and Cocotron showed me this wasn’t impossible. But, configuring VMs and operating systems for compilation was a headache, and rarely reproducible.
Enter Docker for Mac. I’d heard a lot about Docker, but never had the chance to properly use it. Well, maybe not “use” – Docker isn’t designed to run Linux binaries on Macs. Surprisingly, it excels at this. Instead of struggling with VMs, guest OS tools, and display issues, you get a seamless Linux shell within your Terminal. Mounting Mac directories is also simple. Very nice.
The real game-changer is the reproducibility offered by Dockerfiles. Containers are temporary; your knowledge isn’t tied to a VM’s state. Instead, it’s captured within the Dockerfile used to create your image.
The Dockerfile for building a GNUstep image capable of compiling and running Objective-Smalltalk is here:
https://github.com/mpw/MPWFoundation/tree/master/GNUstep/gnustep-combined
This Dockerfile begins by installing several packages with apt-get:
` ``` FROM ubuntu
ENV LC_ALL en_US.UTF-8 ENV LANG en_US.UTF-8 ENV TZ ‘Europe/Berlin’ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN apt-get update && apt-get install -y
git
make
ssh
sudo
curl
inetutils-ping
vim build-essential
clang llvm libblocksruntime-dev libkqueue-dev libpthread-workqueue-dev libxml2-dev cmake
libffi-dev
libreadline6-dev
libedit-dev
libmicrohttpd-dev
gnutls-dev
RUN useradd -ms /bin/bash gnustep
COPY install-gnustep-clang /home/gnustep/ RUN chmod u+x /home/gnustep/install-gnustep-clang RUN /home/gnustep/install-gnustep-clang
COPY bashrc /home/gnustep/.bashrc COPY profile /home/gnustep/.profile COPY bashrc /root/.bashrc COPY profile /root/.profile COPY bashrc /.bashrc COPY profile /.profile
COPY build-gnustep-clang /home/gnustep/build-gnustep-clang RUN mkdir -p /home/gnustep/patches/libobjc2-1.8.1/ COPY patches/libobjc2-1.8.1/objcxx_eh.cc /home/gnustep/patches/libobjc2-1.8.1/objcxx_eh.cc
RUN chmod u+x /home/gnustep/build-gnustep-clang RUN /home/gnustep/build-gnustep-clang
COPY build-gnustep-clang /home/gnustep/build-gnustep-clang RUN mkdir -p /home/gnustep/patches/libobjc2-1.8.1/ COPY patches/libobjc2-1.8.1/objcxx_eh.cc /home/gnustep/patches/libobjc2-1.8.1/objcxx_eh.cc
RUN chmod u+x /home/gnustep/build-gnustep-clang RUN /home/gnustep/build-gnustep-clang
CMD [“bash”]
``` `
A “gnustep” user is added, then a script downloads specific gnustep and libobjc2 source versions, patches one that wouldn’t compile, and builds/installs everything. These scripts are adapted from Tobias Lensing’s work at post.
` ``` #!/bin/bash
cd /home/gnustep/
echo Installing gnustep-make export CC=clang echo compiler is $CC
tar zxf gnustep-make-2.7.0.tar.gz cd gnustep-make-2.7.0 ./configure make install cd ..
echo echo echo ====================== echo Installing libobjc2
tar zxf libobjc2-1.8.1.tar.gz cp patches/libobjc2-1.8.1/* libobjc2-1.8.1/ cd libobjc2-1.8.1 mkdir Build cd Build
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang -DTESTS=OFF -DLLVM_OPTS=OFF ..
cmake -DTESTS=OFF .. make install cd ../..
cd gnustep-make-2.7.0 make clean ./configure –with-library-combo=ng-gnu-gnu make install cd ..
source /usr/local/share/GNUstep/Makefiles/GNUstep.sh tar zxf gnustep-base-1.25.1.tar.gz cd gnustep-base-1.25.1 ./configure make installn cd ..
echo Installation script finished successfully
``` `
One tricky part is installing gnustep-make twice. The first time enables libobjc2 installation, and the second, with libobjc2 present, ensures other packages find the correct runtime. The apt-get packages didn’t work for me because I required newer compiler/runtime features.
Once the image is ready, you can start it and log in. I then use su -l to access the “gnustep” account, working with MPWFoundation, ObjectiveSmalltalk, and ObjectiveHTTPD mounted from my local filesystem instead of separate copies within the container.
While not everything is ported yet, fundamental expressions, communication between Objective-Smalltalk and Objective-C, Higher Order Messaging, and more, are functional. Given the runtime complexity, I was impressed by how easy this was.
I plan to build a runtime image with pre-built libraries and executables in the future.