A colleague recently asked me whether or not I would recommend using CMake for a project that needed to target multiple architectures. While I appreciate that his instinct was not to reach for Autotools, I think CMake falls firmly in the same category as Autotools (though, to be fair, you're only introducing one new problem rather than four).
As an example, I present a complete Makefile to build cat on every platform for which Debian packages a GCC cross compiler. I know, cat is not a particularly interesting program, but the focus is on the Makefile.
.POSIX: ARCHES= \ aarch64-linux-gnu \ arm-linux-gnueabi \ arm-linux-gnueabihf \ i686-linux-gnu \ mips-linux-gnu \ mips64el-linux-gnuabi64 \ mipsel-linux-gnu \ powerpc-linux-gnu \ powerpc64le-linux-gnu \ s390x-linux-gnu \ x86_64-linux-gnu CC=$(ARCH)-gcc all: for i in $(ARCHES); do make ARCH=$$i $$i; done $(ARCH): $(ARCH)/cat $(ARCH)/cat: $(ARCH)/cat.o $(CC) $(LDFLAGS) -s -o $@ $(ARCH)/cat.o $(ARCH)/cat.o: cat.c mkdir -p $(ARCH) $(CC) $(CFLAGS) -c cat.c -o $@
This will cause
make to loop through all the available architectures, outputting object files and linked binaries into a directory named for the target.
There's really no magic involved, though I understand that specifying a target that includes a macro name might seem so. Basically, the default target (
all) executes a loop through the list of targets in
ARCH to that target and building that same target (e.g.
make ARCH=aarch64-linux-gnu aarch64-linux-gnu). This causes the
$(ARCH) macro in each of the other targets to be replaced (in this case with
aarch64-linux-gnu). The substitution also happens in the prerequisites and rules. So, on the first iteration, the child
make process seems something more like (unchanged portions omitted for clarity):
.POSIX: CC=aarch64-linux-gnu-gcc aarch64-linux-gnu: aarch64-linux-gnu/cat aarch64-linux-gnu/cat: aarch64-linux-gnu/cat.o $(CC) $(LDFLAGS) -s -o $@ aarch64-linux-gnu/cat.o aarch64-linux-gnu/cat.o: cat.c mkdir -p aarch64-linux-gnu $(CC) $(CFLAGS) -c cat.c -o $@
This continues for each of the other architectures listed under
If you prefer to use Clang to GCC (and I won't blame you if you do), just change the
Copyright © 2019 Jakob Kaivo <firstname.lastname@example.org>
CC=clang -triple $(ARCH)