CMake for Embedded
CMake's defaults encode one assumption so deeply that it is easy to miss: the machine running the build can also run what the build produces. That is what lets CMake test a compiler by compiling and linking a tiny program, what lets findpackage look in /usr/lib, and what lets checkcsourceruns exist at all. Every one of those assumptions is false for a Cortex-M4 with 128 KB of RAM and no operating system.
Cross-Compilation
The compiler on your laptop is not a general-purpose translator that happens to be pointed at x86. It is a program that was built to emit x86-64 instructions, linked against a C library that was built assuming a Linux kernel is underneath it, and wired to a startup object that assumes something already created a process, set up a stack, and handed it argc and argv. Every one of those assumptions is false on a microcontroller. That is the whole reason a separate toolchain exists — not because the MCU is "different hardware", but because three independent layers of the build all encode a machine and an environment, and all three have to change together.
Cross-Compilation
Cross-compilation builds executables for a different platform (target) than the one running the compiler (host). Essential for embedded systems, mobile development, and deploying to different architectures.