Use zig cc to cross-compile a CMake project
Imagine this: You're on a new M1 MacBook1. You need to compile a CMake project to run on your friend's Windows x86-64 PC. How do you do that? Use zig cc and friends! π
Here's an example project that only works on Windows:
main.c#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow)
{
return MessageBox(NULL, "hello, world", "caption", 0);
}
CMakeLists.txtcmake_minimum_required(VERSION 3.29)
project(hello-world LANGUAGES C)
add_executable(hello-world WIN32 main.c)
So how can we compile it for Windows x86-64 from our M1 MacBook1? We need to add some supporting infrastructure first. CMAKE_AR="zig;ar" and CMAKE_RANLIB="zig;ranlib" don't work. CMAKE_AR and CMAKE_RANLIB don't support commands with arguments so we need to use a wrapper ./zig-ar script instead. π€·ββοΈ
zig-ar (chmod +x)exec zig ar "$@"
zig-ar.cmd@zig ar %*
zig-ranlib (chmod +x)exec zig ranlib "$@"
zig-ranlib.cmd@zig ranlib %*
You now have everything ready to run the CMake configure & build steps! π Don't forget to pass all the appropriate flags to compile for Windows x86-64 using the Zig toolchain! π
|
|
π‘ You can change the CMAKE_C_COMPILER_TARGET and friends to any supported Zig target. Use zig targets to see them all.
Do I have to specify the CMAKE_SYSTEM_NAME and CMAKE_SYSTEM_PROCESSOR? Yeah. It triggers a cascade of configuration that sets the .exe output suffix, sets WIN32=1, uses .lib and .dll library suffixes, and a lot more.
What about platform-specific file extensions for ./zig-ar? Windows will helpfully scan all extensions from %PATHEXT% (.COM;.EXE;.BAT;.CMD;...) for you. That's why you can run zig in your PowerShell/CMD prompt when the actual file is called zig.exe.
How does CMAKE_C_COMPILER_TARGET make its way into zig cc --target? zig cc is detected as Clang which is known by CMake to support a --target option.
βΉ CMAKE_AR does not search $PATH. CMAKE_AR="zig-ar" is resolved as $PWD/zig-ar. π€·ββοΈ gitlab.kitware.com/cmake/cmake#18087
Why can't we do AR="./zig-ar" like CC and CXX? Unfixed issue. gitlab.kitware.com/cmake/cmake#18712
Now that the project is configured with all the compiler settings and other magic⨠we can run the build step:
|
|
Tada! π₯³ You have now built a Windows x86-64 .exe file from your M1 MacBook1!
|
|
|
You can use this on any ASM/C/C++ CMake project! π Cross-compiling has never been easier than with zig cc and friends. Use it in your CI pipeline to build binaries for more than just The Big 5 (Windows x86-64, macOS x86-64 & ARM64, Linux x86-64 & ARM64). You can see a bunch of Zig targets via zig targets.
-
It doesn't have to be an M1 MacBook. The point is to emphasize that a cross-compiler is required. β©
