Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,13 @@
# them differing depending on the line-ending style of the host they
# were checked out on.
* text eol=lf

# All of the `expected/**/*.txt` files are auto-generated via the
# `update-symbols` target, so flag them as such.
expected linguist-generated

# Flag some wit-bindgen-generated files checked into the repo as generated
__generated_wasip2.h linguist-generated
__generated_wasip3.h linguist-generated
libc-bottom-half/sources/wasip2.c linguist-generated
libc-bottom-half/sources/wasip3.c linguist-generated
13 changes: 13 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,19 @@ jobs:
test: true
args: -DCMAKE_BUILD_TYPE=Debug -DTARGET_TRIPLE=wasm32-wasip1-threads

- name: Test wasm32-wasip3
os: ubuntu-24.04
clang_version: 19
test: true
upload: wasm32-wasip3
args: -DTARGET_TRIPLE=wasm32-wasip3

- name: Test wasm32-wasip3 (debug)
os: ubuntu-24.04
clang_version: 19
test: true
args: -DCMAKE_BUILD_TYPE=Debug -DTARGET_TRIPLE=wasm32-wasip3

- name: Test emmalloc
os: ubuntu-24.04
clang_version: 19
Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ elseif(TARGET_TRIPLE MATCHES "-wasip1$")
elseif(TARGET_TRIPLE MATCHES "-wasip2$")
set(WASI p2)
set(SHARED ON)
elseif(TARGET_TRIPLE MATCHES "-wasip3$")
set(WASI p3)
set(SHARED ON)
else()
message(FATAL_ERROR "Unknown WASI target triple: ${TARGET_TRIPLE}")
endif()
Expand Down Expand Up @@ -131,6 +134,8 @@ if(WASI STREQUAL "p1")
set(__wasip1__ ON)
elseif(WASI STREQUAL "p2")
set(__wasip2__ ON)
elseif(WASI STREQUAL "p3")
set(__wasip3__ ON)
else()
message(FATAL_ERROR "Unknown WASI version: ${WASI}")
endif()
Expand Down Expand Up @@ -317,6 +322,8 @@ endif()
# here since I can't figure out anything else that works for now.
if (WASI STREQUAL "p2")
set(libc_extra_objects libc-bottom-half/sources/wasip2_component_type.o)
elseif (WASI STREQUAL "p3")
set(libc_extra_objects libc-bottom-half/sources/wasip3_component_type.o)
endif()

add_library(c SHARED EXCLUDE_FROM_ALL
Expand Down
139 changes: 100 additions & 39 deletions cmake/bindings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -31,63 +31,124 @@ if (NOT WIT_BINDGEN_EXECUTABLE)
ExternalProject_Get_Property(wit-bindgen SOURCE_DIR)
set(wit_bindgen "${SOURCE_DIR}/wit-bindgen")
else()
add_custom_target(wit-bindgen)
set(wit_bindgen ${WIT_BINDGEN_EXECUTABLE})
endif()

include(ExternalProject)
set(p2 0.2.0)
ExternalProject_Add(
wasi-wits
URL https://github.com/WebAssembly/wasi-cli/archive/refs/tags/v0.2.0.tar.gz
wasip2-wits
URL https://github.com/WebAssembly/wasi-cli/archive/refs/tags/v${p2}.tar.gz
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
EXCLUDE_FROM_ALL TRUE
)
ExternalProject_Get_Property(wasi-wits SOURCE_DIR)
set(wit_dir ${SOURCE_DIR}/wit)
ExternalProject_Get_Property(wasip2-wits SOURCE_DIR)
set(wasip2_wit_dir ${SOURCE_DIR}/wit)
set(bottom_half "${CMAKE_SOURCE_DIR}/libc-bottom-half")

add_custom_target(
bindings
bindings-p2
COMMAND
${wit_bindgen} c
--autodrop-borrows yes
--rename-world wasip2
--type-section-suffix __wasi_libc
--world wasi:cli/imports@0.2.0
--rename wasi:clocks/monotonic-clock@0.2.0=monotonic_clock
--rename wasi:clocks/wall-clock@0.2.0=wall_clock
--rename wasi:filesystem/preopens@0.2.0=filesystem_preopens
--rename wasi:filesystem/types@0.2.0=filesystem
--rename wasi:io/error@0.2.0=io_error
--rename wasi:io/poll@0.2.0=poll
--rename wasi:io/streams@0.2.0=streams
--rename wasi:random/insecure-seed@0.2.0=random_insecure_seed
--rename wasi:random/insecure@0.2.0=random_insecure
--rename wasi:random/random@0.2.0=random
--rename wasi:sockets/instance-network@0.2.0=instance_network
--rename wasi:sockets/ip-name-lookup@0.2.0=ip_name_lookup
--rename wasi:sockets/network@0.2.0=network
--rename wasi:sockets/tcp-create-socket@0.2.0=tcp_create_socket
--rename wasi:sockets/tcp@0.2.0=tcp
--rename wasi:sockets/udp-create-socket@0.2.0=udp_create_socket
--rename wasi:sockets/udp@0.2.0=udp
--rename wasi:cli/environment@0.2.0=environment
--rename wasi:cli/exit@0.2.0=exit
--rename wasi:cli/stdin@0.2.0=stdin
--rename wasi:cli/stdout@0.2.0=stdout
--rename wasi:cli/stderr@0.2.0=stderr
--rename wasi:cli/terminal-input@0.2.0=terminal_input
--rename wasi:cli/terminal-output@0.2.0=terminal_output
--rename wasi:cli/terminal-stdin@0.2.0=terminal_stdin
--rename wasi:cli/terminal-stdout@0.2.0=terminal_stdout
--rename wasi:cli/terminal-stderr@0.2.0=terminal_stderr
${wit_dir}
COMMAND cmake -E copy wasip2.h ${bottom_half}/headers/public/wasi/
--world wasi:cli/imports@${p2}
--rename wasi:clocks/monotonic-clock@${p2}=monotonic_clock
--rename wasi:clocks/wall-clock@${p2}=wall_clock
--rename wasi:filesystem/preopens@${p2}=filesystem_preopens
--rename wasi:filesystem/types@${p2}=filesystem
--rename wasi:io/error@${p2}=io_error
--rename wasi:io/poll@${p2}=poll
--rename wasi:io/streams@${p2}=streams
--rename wasi:random/insecure-seed@${p2}=random_insecure_seed
--rename wasi:random/insecure@${p2}=random_insecure
--rename wasi:random/random@${p2}=random
--rename wasi:sockets/instance-network@${p2}=instance_network
--rename wasi:sockets/ip-name-lookup@${p2}=ip_name_lookup
--rename wasi:sockets/network@${p2}=network
--rename wasi:sockets/tcp-create-socket@${p2}=tcp_create_socket
--rename wasi:sockets/tcp@${p2}=tcp
--rename wasi:sockets/udp-create-socket@${p2}=udp_create_socket
--rename wasi:sockets/udp@${p2}=udp
--rename wasi:cli/environment@${p2}=environment
--rename wasi:cli/exit@${p2}=exit
--rename wasi:cli/stdin@${p2}=stdin
--rename wasi:cli/stdout@${p2}=stdout
--rename wasi:cli/stderr@${p2}=stderr
--rename wasi:cli/terminal-input@${p2}=terminal_input
--rename wasi:cli/terminal-output@${p2}=terminal_output
--rename wasi:cli/terminal-stdin@${p2}=terminal_stdin
--rename wasi:cli/terminal-stdout@${p2}=terminal_stdout
--rename wasi:cli/terminal-stderr@${p2}=terminal_stderr
${wasip2_wit_dir}
COMMAND cmake -E copy wasip2.h ${bottom_half}/headers/public/wasi/__generated_wasip2.h
COMMAND cmake -E copy wasip2_component_type.o ${bottom_half}/sources
COMMAND cmake -E copy wasip2.c ${bottom_half}/sources
COMMAND sed -i "'s_#include .wasip2\.h._#include \"wasi/wasip2.h\"_'" ${bottom_half}/sources/wasip2.c
COMMAND sed -i "s/extern void exit_exit/_Noreturn extern void exit_exit/" ${bottom_half}/headers/public/wasi/wasip2.h
COMMAND sed -i "s/extern void __wasm_import_exit_exit/_Noreturn extern void __wasm_import_exit_exit/" ${bottom_half}/sources/wasip2.c
DEPENDS wit-bindgen wasi-wits
DEPENDS wit-bindgen wasip2-wits
)

set(p3 0.3.0-rc-2025-09-16)
ExternalProject_Add(
wasip3-wits
URL https://github.com/WebAssembly/wasi-cli/archive/refs/tags/v${p3}.tar.gz
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
EXCLUDE_FROM_ALL TRUE
)
ExternalProject_Get_Property(wasip3-wits SOURCE_DIR)
set(wasip3_wit_dir ${SOURCE_DIR}/wit-0.3.0-draft)

add_custom_target(
bindings-p3
COMMAND
${wit_bindgen} c
--autodrop-borrows yes
--rename-world wasip3
--type-section-suffix __wasi_libc
--world wasi:cli/imports@${p3}
--rename wasi:clocks/monotonic-clock@${p3}=monotonic_clock
--rename wasi:clocks/wall-clock@${p3}=wall_clock
--rename wasi:filesystem/preopens@${p3}=filesystem_preopens
--rename wasi:filesystem/types@${p3}=filesystem
--rename wasi:random/insecure-seed@${p3}=random_insecure_seed
--rename wasi:random/insecure@${p3}=random_insecure
--rename wasi:random/random@${p3}=random
--rename wasi:sockets/types@${p3}=sockets
--rename wasi:sockets/ip-name-lookup@${p3}=ip_name_lookup
--rename wasi:cli/environment@${p3}=environment
--rename wasi:cli/exit@${p3}=exit
--rename wasi:cli/stdin@${p3}=stdin
--rename wasi:cli/stdout@${p3}=stdout
--rename wasi:cli/stderr@${p3}=stderr
--rename wasi:cli/terminal-input@${p3}=terminal_input
--rename wasi:cli/terminal-output@${p3}=terminal_output
--rename wasi:cli/terminal-stdin@${p3}=terminal_stdin
--rename wasi:cli/terminal-stdout@${p3}=terminal_stdout
--rename wasi:cli/terminal-stderr@${p3}=terminal_stderr
${wasip3_wit_dir}
COMMAND cmake -E copy wasip3.h ${bottom_half}/headers/public/wasi/__generated_wasip3.h
COMMAND cmake -E copy wasip3_component_type.o ${bottom_half}/sources
COMMAND cmake -E copy wasip3.c ${bottom_half}/sources
DEPENDS wit-bindgen wasip3-wits
)

add_custom_target(bindings DEPENDS bindings-p2 bindings-p3)

function(wit_bindgen_edit p)
add_custom_target(
bindings-${p}-edit
COMMAND sed -i "" "'s_#include .wasi${p}\.h._#include \"wasi/wasi${p}.h\"_'" ${bottom_half}/sources/wasi${p}.c
COMMAND sed -i "" "s/extern void exit_exit/_Noreturn extern void exit_exit/" ${bottom_half}/headers/public/wasi/__generated_wasi${p}.h
COMMAND sed -i "" "s/extern void __wasm_import_exit_exit/_Noreturn extern void __wasm_import_exit_exit/" ${bottom_half}/sources/wasi${p}.c
DEPENDS bindings-${p}
)
add_dependencies(bindings bindings-${p}-edit)
endfunction()

wit_bindgen_edit(p2)
wit_bindgen_edit(p3)
2 changes: 2 additions & 0 deletions cmake/check-symbols.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ elseif(WASI STREQUAL "p1")
set(expected "${CMAKE_SOURCE_DIR}/expected/wasm32-wasip1")
elseif(WASI STREQUAL "p2")
set(expected "${CMAKE_SOURCE_DIR}/expected/wasm32-wasip2")
elseif(WASI STREQUAL "p3")
set(expected "${CMAKE_SOURCE_DIR}/expected/wasm32-wasip3")
else()
message(FATAL_ERROR "Unknown WASI version: ${WASI}")
endif()
Expand Down
3 changes: 2 additions & 1 deletion cmake/clang-format.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ add_custom_target(format-check)
set(formatted_sources)

function(clang_format_file file)
if (file MATCHES "wasip2\..$") # Skip auto-generated files
if (file MATCHES "__generated" OR
file MATCHES "wasip.\.c$") # Skip auto-generated files
return()
endif()
cmake_path(ABSOLUTE_PATH file BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} OUTPUT_VARIABLE src)
Expand Down
3 changes: 2 additions & 1 deletion cmake/wasm-component-ld.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ if (NOT WASM_COMPONENT_LD_EXECUTABLE)
)
ExternalProject_Get_Property(wasm-component-ld SOURCE_DIR)
set(WASM_COMPONENT_LD_EXECUTABLE "${SOURCE_DIR}/wasm-component-ld")
add_link_options(-fuse-ld=${WASM_COMPONENT_LD_EXECUTABLE})
add_dependencies(sysroot_inc wasm-component-ld)
endif()

add_link_options(-fuse-ld=${WASM_COMPONENT_LD_EXECUTABLE})
2 changes: 2 additions & 0 deletions expected/wasm32-wasip1-threads/include-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,7 @@
#include <wasi/libc.h>
#include <wasi/version.h>
#include <wasi/wasip1.h>
#include <wasi/wasip2.h>
#include <wasi/wasip3.h>
#include <wchar.h>
#include <wctype.h>
2 changes: 2 additions & 0 deletions expected/wasm32-wasip1-threads/predefined-macros.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3093,6 +3093,8 @@
#define __WASI_SDFLAGS_WR ((__wasi_sdflags_t)(1 << 1))
#define __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME ((__wasi_subclockflags_t)(1 << 0))
#define __WASI_VERSION_H
#define __WASI_WASIP2_H
#define __WASI_WASIP3_H
#define __WASI_WHENCE_CUR (UINT8_C(1))
#define __WASI_WHENCE_END (UINT8_C(2))
#define __WASI_WHENCE_SET (UINT8_C(0))
Expand Down
2 changes: 2 additions & 0 deletions expected/wasm32-wasip1/include-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,5 +173,7 @@
#include <wasi/libc.h>
#include <wasi/version.h>
#include <wasi/wasip1.h>
#include <wasi/wasip2.h>
#include <wasi/wasip3.h>
#include <wchar.h>
#include <wctype.h>
2 changes: 2 additions & 0 deletions expected/wasm32-wasip1/predefined-macros.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3090,6 +3090,8 @@
#define __WASI_SDFLAGS_WR ((__wasi_sdflags_t)(1 << 1))
#define __WASI_SUBCLOCKFLAGS_SUBSCRIPTION_CLOCK_ABSTIME ((__wasi_subclockflags_t)(1 << 0))
#define __WASI_VERSION_H
#define __WASI_WASIP2_H
#define __WASI_WASIP3_H
#define __WASI_WHENCE_CUR (UINT8_C(1))
#define __WASI_WHENCE_END (UINT8_C(2))
#define __WASI_WHENCE_SET (UINT8_C(0))
Expand Down
2 changes: 2 additions & 0 deletions expected/wasm32-wasip2/include-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@
#include <unistd.h>
#include <utime.h>
#include <values.h>
#include <wasi/__generated_wasip2.h>
Copy link
Contributor

Choose a reason for hiding this comment

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

Why __generated_wasip2.h but not __generate_wasip3.h?

Copy link
Contributor

Choose a reason for hiding this comment

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

because there is a wasm32-wasip3/include-all.c which contains __generate_wasip3.h, I guess.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh this is due to how include-all.c works. The file is generated here during the check-symbols step and is a #include of all headers located in the sysroot. The sysroot differs from wasip2 to wasip3 due to this cmake logic

The general idea was that I didn't want to tamper with the auto-generated output of wit-bindgen too too much (doing the seds below is already cumbersome enough). I also didn't want header files to be available in a wasip2 sysroot, for example to give access to wasip3 APIs. For example #include <wasi/wasip3.h> expands to nothing on wasm32-wasip2, intentionally so.

#include <wasi/api.h>
#include <wasi/libc-busywait.h>
#include <wasi/libc-environ.h>
Expand All @@ -175,5 +176,6 @@
#include <wasi/version.h>
#include <wasi/wasip1.h>
#include <wasi/wasip2.h>
#include <wasi/wasip3.h>
Copy link
Contributor

Choose a reason for hiding this comment

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

My question would be more: Why include wasip1.h and wasip3.h in wasm32-wasip2/include-all.c?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good point! I sort of arbitrarily decided that I ideally want header files to be present on all targets, but the contents will differ per-target. I don't have the strongest of reasons for doing so, but this means that all these headers are present on all targets, but #ifdef and such means that on any one target only one of these headers actually expands to anything.

#include <wchar.h>
#include <wctype.h>
2 changes: 2 additions & 0 deletions expected/wasm32-wasip2/predefined-macros.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3091,6 +3091,8 @@
#define __USER_LABEL_PREFIX__
#define __USE_TIME_BITS64 1
#define __WASI_VERSION_H
#define __WASI_WASIP2_H
#define __WASI_WASIP3_H
#define __WCHAR_MAX__ 2147483647
#define __WCHAR_TYPE__ int
#define __WCHAR_WIDTH__ 32
Expand Down
Loading