Skip to content

Conversation

@loganek
Copy link
Contributor

@loganek loganek commented Sep 30, 2022

This is a work-in-progress PR and still require a few actions. I open the PR to get early feedback. Some of the changes are clone from the other attempt of migrating this repository to CMake build system: #154. One major difference between this change and the previous one is that I'm using install target to create sysroot; I find this to be a bit more natural than specifying destination for every target.

I tested the changes by diff-ing generated install directory with the sysroot generated by Makefile. I also compiled and ran a few apps on WAMR runtime.

  • remove Makefile
  • update CI files
  • update README file

Resolves #322

@sbc100
Copy link
Member

sbc100 commented Sep 30, 2022

I know you mention some rational in #322, but I'm curious what you personal primary motivation is for wanting to make this change? I guess better native windows support is the big one? Without needing to setup something like mingw?

I personally find cmake syntax and semantics pretty confusing (more so than the relative simplicity of a Makefile), but I get that its personal preference.

This does seem to make some things more complex. For example, it looks like it takes roughly twice as many lines of code to implement. We would also be adding a python dependency. I'm generally a fan of python over shell scripts for this kind of thing but others might feel differently.

Copy link
Member

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add some instructions (maybe as a mod to the README) so I can try it out? I've love to give it go. Does this setup support out-of-tree building?

list(REMOVE_ITEM LIBC_BOTTOM_HALF_ALL_SOURCES ${CHDIR_SRC})
list(APPEND LIBC_BOTTOM_HALF_ALL_SOURCES ${CHDIR_SRC})

add_library(libc-bottom-half OBJECT
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is some kind of "library" that getting somehow inlined into the main libc? More like a list of object files that a library per-say?

I assume all the object files that make up libc-bottom-half will still show up as individual object files within libc.a?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they're just object files.

@abrown
Copy link
Collaborator

abrown commented Sep 30, 2022

I personally find cmake syntax and semantics pretty confusing

I'm also not sold on replacing make with cmake. make is available on Windows in various ways: WSL, MinGW, and Visual Studio. I'm not opposed to replacing it, but I feel cmake would have to offer something better than what currently exists. Also, I'm a bit concerned that people working on the project may be familiar with a Makefile but would be slower to hack on a CMakeLists.txt (as @sunfishcode mentions in #322). Just some thoughts...

@penzn
Copy link
Collaborator

penzn commented Sep 30, 2022

In my opinion, it provides more watertight ways to ensure you have the pieces you need, also it has "first class types" for sub-targets like libraries, including dependence detection, this reduces risk of mistyping or having parts of the build go out of sync. It isn't a silver bullet, though.

@loganek
Copy link
Contributor Author

loganek commented Oct 3, 2022

I know you mention some rational in #322, but I'm curious what you personal primary motivation is for wanting to make this change?

Pretty much what @penzn already mentioned but also having experience with both Makefile and CMake, I find both learning CMake and maintaining CMake project easier. I also think Makefile has a steeper learning curve than CMake but that may be because I learned used Makefile first.

This does seem to make some things more complex. For example, it looks like it takes roughly twice as many lines of code to implement.

I wouldn't use number of lines as a metric for complexity. If needed, I could probably optimize (most likely at a cost of readability, although I didn't look into it).

We would also be adding a python dependency. I'm generally a fan of python over shell scripts for this kind of thing but others might feel differently.

I don't think this is relevant to Makefile vs CMake discussion. They both can run shell and python scripts; I copied it (and slightly modified) from previous PR because I found it more readable.

Also, I'm a bit concerned that people working on the project may be familiar with a Makefile but would be slower to hack on a CMakeLists.txt (as @sunfishcode mentions in #322). Just some thoughts...

What I found is that creating a CMake project from scratch requires some knowledge, but most of the modifications don't often require looking into documentation, as you can do most of what you need based on already written code (I guess just like Makefile)

@loganek
Copy link
Contributor Author

loganek commented Oct 3, 2022

Could you add some instructions (maybe as a mod to the README) so I can try it out? I've love to give it go. Does this setup support out-of-tree building?

I can definitely update the README file; meanwhile, here's a command you can use:

# assume you're in wasi-libc
cd .. # go up; we'll do out-of-tree build
mkdir wasi-libc-build && cd wasi-libc-build
# configure the project
cmake \
  -DCMAKE_C_COMPILER=/usr/bin/clang-15 \ # optional, cmake will try to find a default one
 -DCMAKE_BUILD_TYPE=Release \ # optimized build; other options: Debug, RelWithDebInfo
 -DTHREAD_MODEL=posix \ # thread model: single
 -DCMAKE_INSTALL_PREFIX=../cmake-install \ # where to install the sysroot
 -G Ninja \ # generator, default on Linux is most likely Unix Makefiles
 ../wasi-libc # path to source directory
ninja install # build and install

@sunfishcode
Copy link
Member

One concrete advantage of moving to CMake is that the current wasi-libc Makefile doesn't do dependency management correctly, so we effectively don't have incremental builds right now.

@loganek
Copy link
Contributor Author

loganek commented Oct 10, 2022

Yes, incremental build is a huge benefit, but I never listed it as a benefit because I'm not sure how hard is it to implement it for the existing Makefile.

@loganek loganek force-pushed the loganek/cmake branch 5 times, most recently from d9c4692 to b984e91 Compare October 11, 2022 06:37
Copy link

@compnerd compnerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of why I had lost interest was the difficulty to get the proper support for CMake added due to upstream resistance.

enable_testing()

if("${CMAKE_C_COMPILER}" MATCHES "(.*)clang(-[0-9]+)?$")
set(CMAKE_NM "${CMAKE_MATCH_1}llvm-nm${CMAKE_MATCH_2}")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend against this. This prevents the user from specifying the name tool to use.


add_library(c)

set (LIBC_LINK_LIBRARIES

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an anti-pattern. Prefer to directly use the targets with target_link_libraries

libc-bottom-half
)

if(${BUILD_LIBC_TOP_HALF} STREQUAL "ON")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to prefer the more concise spelling:

Suggested change
if(${BUILD_LIBC_TOP_HALF} STREQUAL "ON")
if(BUILD_LIBC_TOP_HALF)

This has the benefit of allowing the user to specify the value with a truthy value that CMake permits (ON, YES, 1).

if(${BUILD_LIBC_TOP_HALF} STREQUAL "ON")
list(APPEND LIBC_LINK_LIBRARIES
libc-top-half
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, an anti-pattern. Prefer to use a generator expression with target_link_libraries.


if(${MALLOC_IMPL} STREQUAL "dlmalloc")
list(APPEND LIBC_LINK_LIBRARIES
dlmalloc)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar


add_test(NAME check-headers
COMMAND ${CMAKE_C_COMPILER}
-target ${CMAKE_C_COMPILER_TARGET}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prevents the use of any compiler other than clang.

@@ -0,0 +1,10 @@
set(DLMALLOC_DIR ${PROJECT_SOURCE_DIR}/dlmalloc)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the variable for a single use?

@@ -0,0 +1,39 @@
# WebAssembly floating-point match doesn't trap.
# TODO: Add -fno-signaling-nans when the compiler supports it.
add_compile_options(-fno-trapping-math)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should validate that the compiler supports the option.

-Wno-ignored-pragmas
-Wno-unused-but-set-variable
-Wno-unknown-warning-option
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar

LIBC_BOTTOM_HALF_ALL_SOURCES
CONFIGURE_DEPENDS
${LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_DIR}/*.c
${LIBC_BOTTOM_HALF_SRC_DIR}/*.c)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a highly dubious. This will lose the ability to alter the sources. The glob is applied once at configure time and never again. You should explicitly list the sources. Similar throughout.

alexcrichton added a commit to alexcrichton/wasi-libc that referenced this pull request 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 WebAssembly#46
Closes WebAssembly#156
Closes WebAssembly#295
Closes WebAssembly#322
Closes WebAssembly#330
Closes WebAssembly#514
Closes WebAssembly#605
@alexcrichton
Copy link
Collaborator

A few years later, but if folks are interested I have an updated version of this at #685

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate build system to CMake

7 participants