Skip to content

Conversation

@alexcrichton
Copy link
Collaborator

@alexcrichton alexcrichton commented Nov 21, 2025

This commit migrates wasi-libc's build system from a make-based system to CMake. This is a complete rewrite of the build system which culminates in the deletion of the current Makefile and a few supporting scripts and files.

The rationale/reasons for this are similar to WebAssembly/wasi-sdk#429, namely:

  • Building a correct and robust build system in make is not easy. There are many times I've found myself in a situation where I need to blow away the entire build directory between builds. Much of the this this bottoms out in subtle behavior like "this file was renamed, but didn't get deleted in the archive" or subtle things like that. CMake is responsible for handling these by default and, in general, is probably going to be more correct than what we write.

  • Out-of-tree builds are now supported.

  • Customizing CFLAGS is now supported via standard mechanisms. Previously EXTRA_CFLAGS was required since using CFLAGS could break the build.

  • It's easier to move more logic into CMake, such as downloading compiler-rt, than it is to codify it all in makefiles.

  • Platform portability is generally easier in CMake than make. Building on Windows shouldn't require a full GNU-like environment, for example.

  • Tests now properly rebuild themselves when wasi-libc changes.

  • It's easier to customize high-level options, like "enable SIMD", in CMake than it is in Makefiles. This can be documented as a single option to pass where that option affects the build, flags, etc.

Personally I'm not a fan of CMake, but I'm more of a fan of it than Makefiles, hence my desire to switch. I want to make this repository easier to build, configure, and change over time. This will also make it easier to integrate this all into wasi-sdk where everything is CMake-based over there as well.

I am not a CMake expert, nor am I necessarily an expert in the previous Makefiles. I've done my best here, but I'm happy to change things if someone who knows more about CMake than I (which is a lot of folks) recommends doing so. I'm also happy to adjust the libc build as desired too.

Closes #46
Closes #156
Closes #259
Closes #322
Closes #330
Closes #514
Closes #551
Closes #605

This commit migrates wasi-libc's build system from a `make`-based system
to CMake. This is a complete rewrite of the build system which
culminates in the deletion of the current `Makefile` and a few
supporting scripts and files.

The rationale/reasons for this are similar to WebAssembly/wasi-sdk#429,
namely:

* Building a correct and robust build system in `make` is not easy.
  There are many times I've found myself in a situation where I need to
  blow away the entire build directory between builds. Much of the
  this this bottoms out in subtle behavior like "this file was renamed,
  but didn't get deleted in the archive" or subtle things like that.
  CMake is responsible for handling these by default and, in general, is
  probably going to be more correct than what we write.

* Out-of-tree builds are now supported.

* Customizing CFLAGS is now supported via standard mechanisms.
  Previously `EXTRA_CFLAGS` was required since using `CFLAGS` could
  break the build.

* It's easier to move more logic into CMake, such as downloading
  compiler-rt, than it is to codify it all in makefiles.

* Platform portability is generally easier in CMake than make. Building
  on Windows shouldn't require a full GNU-like environment, for example.

* Tests now properly rebuild themselves when wasi-libc changes.

* It's easier to customize high-level options, like "enable SIMD", in
  CMake than it is in Makefiles. This can be documented as a single
  option to pass where that option affects the build, flags, etc.

Personally I'm not a fan of CMake, but I'm more of a fan of it than
Makefiles, hence my desire to switch. I want to make this repository
easier to build, configure, and change over time. This will also make it
easier to integrate this all into wasi-sdk where everything is
CMake-based over there as well.

I am not a CMake expert, nor am I necessarily an expert in the previous
Makefiles. I've done my best here, but I'm happy to change things if
someone who knows more about CMake than I (which is a lot of folks)
recommends doing so. I'm also happy to adjust the libc build as desired
too.

Closes WebAssembly#46
Closes WebAssembly#156
Closes WebAssembly#295
Closes WebAssembly#322
Closes WebAssembly#330
Closes WebAssembly#514
Closes WebAssembly#605
@alexcrichton alexcrichton mentioned this pull request Nov 21, 2025
3 tasks
@alexcrichton
Copy link
Collaborator Author

To verify this change I've built the sysroot with the old makefile and this PR. The order of files in libc.a, and thus linked into libc.so, is different meaning that libc.so is not byte-equivalent. What I did do, however, was unpack libc.a in both sysroots and ensure that each individual file is the same. The resulting diff (for wasm32-wasip1) is:

Only in make: "/home/alex/code/libc-diff/../wasi-libc/sysroot/include/wasm32-wasip1/wasi/wasip2.h"
Only in make archive "lib/wasm32-wasip1/libc.a": "wasip2_stdio"
Only in make archive "lib/wasm32-wasip1/libc.a": "wasip2_tcp"
Only in make archive "lib/wasm32-wasip1/libc.a": "wasip2_udp"
Only in make archive "lib/wasm32-wasip1/libc.a": "wasip2_file_utils"
Only in make archive "lib/wasm32-wasip1/libc.a": "wasip2_file"
Different: "include/wasm32-wasip1/__wasi_snapshot.h"

This is expected in that I removed some wasip2 bits from the wasip1 archives/sysroot (e.g. the header and wasip2-only objects). The __wasi_snapshot.h is then an intentional change in this PR (a file generated by CMake as opposed to handwritten via shell).

Basically I've double-checked that, with the right compile flags, the set of objects produced is the same and they all have the exact same contents as well. Artifacts will differ slightly as items are reordered, however.

I'll also note that CMake's release build uses -O3 by default, which is different from the previous makefile's -O2-by-default. I didn't see a reason to change this, but this means that the default release builds have differences caused by this, so the diff I did above was done by explicitly specifying CMake's flags to use -O2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant