Most likely when building, be it container images or standalone binaries, you don't want a separate set of scripts or Makefiles or Dockerfiles, or whatever you're using, for each architecture you want to target (e.g. amd64 or ppc64le). I was asked by some new team-members to provide examples of ways to get the architecture of the system on your scripts are running. It was a short little list of things I've used and seen over the years, so I thought it might be nice to share publicly.
-------------------------
The first example is using shell and uname in a Makefile. Under the lint target, you can see that linting is only done for amd64.
| @git diff-tree --check $(shell git hash-object -t tree /dev/null) HEAD $(shell ls -d * | grep -v cfc-files) |
| @docker run --rm -v $(shell pwd):/data -w /data $(ANSIBLE_IMAGE) ansible-playbook -e cluster/config.yaml playbook/install.yaml --syntax-check |
endif
But where did `ARCH` come from? In this use-case, which I've lifted from an internal project, there's an included file called Configfile that gets the arch using `uname`. You could just as easily put that into the top of your Makefile.
ARCH ?= $(shell uname -m | sed 's/x86_64/amd64/g')
ifeq ($(ARCH), amd64) |
| DOCKER_FLAG ?= Dockerfile |
DOCKER_FLAG ?= Dockerfile.$(ARCH)
You can see in this example that this project *does* have a separate Dockerfile for each target arch, which is fine. (However, you can just maintain one if you use multi-arch images, and/or build-args).
You can also see that there's a substitution done for x86_64. Most of the time using those interchangably is fine. There are most likely similar cases for ARM variants, so this is a good thing to keep in mind and keep your case statements cleaner later on.
---------------------------
My next example is a trick I stole from the nvidia-docker maintainers that lets you get an if-statement into a Dockerfile. Docker intentionally excludes conditional logic in Dockerfiles so that your images are the same from build to build. So use this example with great caution, and keep your images consistent.
| x86_64 | amd64) ARCH='amd64' ;; \ |
| ppc64el | ppc64le) ARCH='ppc64le' ;; \ |
| *) echo "unsupported architecture"; exit 1 ;; \ |
| wget -nv -O - https://storage.googleapis.com/golang/go${GO_VERSION}.linux-${ARCH}.tar.gz \ |
| tar -C /usr/local -xz
I have this in a Dockerfile of my own that I use it to set up a build environment. As you can see, it's a way to use a URL that has a hard-coded architecure.
-----------------------------
So that's it! If you have any of your own fun tricks for your projects, please share them!