If you're looking to get some work done with gcc or clang but you're on Windows, fear not - there's a way to do it without regrets.
I played around with GCC and clang for my exception handling post. Typically I work on a Windows machine, and prior experience has taught me that getting GCC and Clang working just right can be a bit of a mess.
So, I installed the trusty Docker for Windows and got going. If you, like me, need a refresher every time you're about to do something interesting, follow along!
Instructions on how to install Docker are available here. I often reach out for Chocolatey, where you can get set up with a simple choco install docker-desktop
.
If you've just installed docker or if you haven't used it in a while, you may want to make sure you're properly set up.
docker --version
to check your version.docker run hello-world
to make sure it works.docker run --interactive --tty ubuntu bash
to get an interactive Ubuntu container. Run hostname
or whatever, then exit
So far, so good. If you didn't get this far, you'll need to get this sorted out before you can continue.
Now let's actually build something.
Open up notepad and paste the program you want to build, for example as ex.cpp. You can seve it to %TEMP% if you want.
#include <stdio.h>
void main() {
std::string message("hello, world!");
printf("%s", message.c_str());
}
Docker containers aren't great at user interface, so you'll want to edit the files from something richer. Even notepad looks good when all you have is a CLI.
docker run --rm -v %CD%:/usr/src/myapp --interactive --tty gcc bash
, and run the following.cd /usr/src/myapp
g++ -o ex ex.cpp
./ex
The switches, explained:
--rm
: automatically remove the container when it exits--interactive
: keep STDIN open even if not attached --tty
: Allocate a pseudo-TTYgcc
: this is the image name to runbash
: this is the program to runTo avoid the cd
, you can also specifify the working directory in the docker run command with -w /usr/src/myapp
.
The gcc
image comes from here. You can look at the various tags to get specific versions, and you can look at the linked Dockerfile for any one to see how this works. The scripts are not trivial, but they're not too hard to follow along either and show the details of how things are set up.
Clang doesn't have a ready-made image in docker, but we can simply spin up an Ubuntu image and install it.
docker run --rm -v %CD%:/usr/src/myapp --interactive --tty ubuntu bash
apt-get update
apt-get install clang
cd /usr/src/myapp
clang++ -o ex ex.cpp
./ex
Now, re-installing Clang every time is a bit of a pain. Instead, we can create an image to our liking, and then start from there.
Create the following plain text Dockerfile in an empty directory:
FROM ubuntu as BASE
RUN set -ex; \
apt-get update; \
apt-get install -y clang;
Now run the following in that directory from a command prompt: docker build -t myclang:v1 .
(note the trailing period).
Go back to your temporary directory, and build with this:
docker run --rm -v %CD%:/usr/src/myapp -i -w /usr/src/myapp --tty myclang:v1 bash
You can verify you have things set up properly with clang --version
.
This RUN command is there to make it easy to add other things to your images; best practices for simple apt-get and a few other RUN commands is available here.
Happy compiling!