Skip to content
Closed
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
16 changes: 16 additions & 0 deletions .github/actions/wasi/base/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: "Ubuntu base dependencies"

runs:
using: "composite"
steps:
- name: Install system dependencies
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y ninja-build wget
- name: Install CMake
shell: bash
run: |
wget -nv -O ./cmake_install.sh https://github.com/Kitware/CMake/releases/download/v3.28.0-rc5/cmake-3.28.0-rc5-linux-x86_64.sh
sudo bash ./cmake_install.sh --skip-license --prefix=/usr --exclude-subdir
rm -f ./cmake_install.sh
17 changes: 17 additions & 0 deletions .github/actions/wasi/clang/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: "Ubuntu latest clang"

runs:
using: "composite"
steps:
- name: Install clang/llvm 17
shell: bash
run: |
sudo apt-add-repository 'deb https://apt.llvm.org/jammy llvm-toolchain-jammy-17 main'
sudo wget -qO /etc/apt/trusted.gpg.d/llvm.asc https://apt.llvm.org/llvm-snapshot.gpg.key
sudo apt-get update
sudo apt-get install -y -t llvm-toolchain-jammy-17 \
clang-17 llvm-17 lld-17 lldb-17 libc++-17-dev \
Copy link
Owner

Choose a reason for hiding this comment

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

Is it clang-17 minimum supported version?

libc++abi-17-dev libclang-rt-17-dev
for f in /usr/lib/llvm-*/bin/*; do sudo ln -sf "$f" /usr/bin; done
sudo mkdir -p /usr/lib/llvm-17/lib/clang/17/lib/wasi
sudo chmod 0777 /usr/lib/llvm-17/lib/clang/17/lib/wasi
1 change: 1 addition & 0 deletions .github/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ jobs:
fail-fast: false
matrix:
target: [
{ os: ubuntu-22.04, preset: wasm32-wasi-clang-static },
{ os: ubuntu-latest, preset: x64-linux-gcc-dynamic },
{ os: ubuntu-latest, preset: x86-linux-gcc-dynamic },
{ os: ubuntu-latest, preset: x64-linux-clang-dynamic },
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ jobs:
fail-fast: false
matrix:
target: [
{ os: ubuntu-22.04, preset: wasm32-wasi-clang-static },
{ os: ubuntu-latest, preset: x64-linux-gcc-dynamic },
{ os: ubuntu-latest, preset: x86-linux-gcc-dynamic },
{ os: ubuntu-latest, preset: x64-linux-clang-dynamic },
Expand All @@ -34,6 +35,15 @@ jobs:
- uses: ./.github/actions/vcpkg-cache

- name: CMake workflow
id: cmake-workflow
shell: bash
run: |
cmake --workflow --preset ${{matrix.target.preset}}

- name: Upload vcpkg error logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: logs-${{matrix.target.preset}}
path: |
/usr/local/share/vcpkg/**/*.log
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")

add_subdirectory(src)

enable_testing()
add_subdirectory(tests)
if (NOT WASI)
enable_testing()
add_subdirectory(tests)
Copy link
Owner

Choose a reason for hiding this comment

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

What is the issue with tests?

endif()
4 changes: 3 additions & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
"include": [
"cmake/presets/arm64-darwin-gcc.json",
"cmake/presets/arm64-darwin-clang.json",
"cmake/presets/wasm32-wasi-clang.json",
"cmake/presets/x64-darwin-gcc.json",
"cmake/presets/x64-darwin-clang.json",
"cmake/presets/x64-linux-gcc.json",
"cmake/presets/x64-windows-clang.json",
"cmake/presets/x64-windows-msvc.json",
"cmake/presets/x86-linux-gcc.json",
"cmake/presets/x86-linux-clang.json",
"cmake/presets/x64-linux-gcc.json",
"cmake/presets/x64-linux-clang.json"
]
}
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,17 @@ find_package(<PROJECT_NAME> CONFIG REQUIRED)
target_link_libraries(<TARGET> PUBLIC <PROJECT_NAME>::<MODULE_NAME>)
```

This will require that your library is published and installed via vcpkg or found locally by setting the `CMAKE_PREFIX_PATH` environment variable in your other project during configure.
This will require that your library is published and installed via vcpkg or found locally by setting the `CMAKE_PREFIX_PATH` environment variable in your other project during configure.

If you wish to expose parts of your library as a WebAssembly module, you can add the `WASM_EXPORT("<export_name>")` macro to any function you wish to expose in `src/wasm/interface.cpp`, and compile using the `wasm32-wasi-clang` preset. This will generate a minimal WebAssembly binary exposing your exported functions at `build/<PRESET>/src/wasm/<Debug|Release|RelWithDebInfo>/lib<PROJECT_NAME>.wasm`. This binary conforms to the [WASI WebAssembly standard](https://wasi.dev/), so it can be utilized in any WASI-supporting runtime like [`wasmer.io`](https://wasmer.io/)

```sh
wasmer run build/<PRESET>/src/cli/<Debug|Release|RelWithDebInfo>/<PROJECT_NAME>_cli

# Prints:
# <PROJECT_NAME> version: 0.0.1
```

> [!NOTE]
> Exposed functions with `WASM_EXPORT` currently only accept parameters and return values of numerical type. This is because the proposal for WebAssembly Interface Types has not yet been standardized, and until then, complex data-types cannot be sent over the runtime's ABI boundary. Complex data must be transferred via pointer into exported/shared memory.

1 change: 1 addition & 0 deletions cmake/Platform/WASI.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
set(WASI 1)
13 changes: 13 additions & 0 deletions cmake/presets/toolchains/wasi-sdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": 6,
"configurePresets": [
{
"name": "wasi-sdk",
"hidden": true,
"cacheVariables": {
"VCPKG_CHAINLOAD_TOOLCHAIN_FILE": "${sourceDir}/cmake/wasi-sdk/wasi-sdk.toolchain.cmake",
"VCPKG_OVERLAY_PORTS": "${sourceDir}/cmake/vcpkg/ports/wasm32-wasi"
}
}
]
}
41 changes: 41 additions & 0 deletions cmake/presets/wasm32-wasi-clang.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"version": 6,
"include": [
"base.json",
"compilers/clang.json",
"toolchains/wasi-sdk.json"
],
"configurePresets": [
{
"name": "wasm32-wasi-clang-static",
"inherits": [
"base",
"wasi-sdk",
"clang"
],
"displayName": "WASM32 WASI clang static libs"
}
],
"buildPresets": [
{
"name": "wasm32-wasi-clang-static",
"inherits": "base",
"configurePreset": "wasm32-wasi-clang-static"
}
],
"workflowPresets": [
{
"name": "wasm32-wasi-clang-static",
"steps": [
{
"type": "configure",
"name": "wasm32-wasi-clang-static"
},
{
"type": "build",
"name": "wasm32-wasi-clang-static"
}
]
}
]
}
13 changes: 13 additions & 0 deletions cmake/vcpkg/ports/wasm32-wasi/fmt/001-fix-write-batch.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f21cf45..691a632 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -157,7 +157,7 @@ if (MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio")
join(netfxpath
"C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\"
".NETFramework\\v4.0")
- file(WRITE run-msbuild.bat "
+ file(WRITE ${CMAKE_BINARY_DIR}/run-msbuild.bat "
${MSBUILD_SETUP}
${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\"${netfxpath}\" %*")
endif ()
47 changes: 47 additions & 0 deletions cmake/vcpkg/ports/wasm32-wasi/fmt/002-disable-posix-fd.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
diff --git a/src/os.cc b/src/os.cc
index 7813c433..b472f0a6 100644
--- a/src/os.cc
+++ b/src/os.cc
@@ -279,7 +279,7 @@ std::size_t file::write(const void* buffer, std::size_t count) {
file file::dup(int fd) {
// Don't retry as dup doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html
- int new_fd = FMT_POSIX_CALL(dup(fd));
+ int new_fd = -1;
if (new_fd == -1)
FMT_THROW(system_error(
errno, FMT_STRING("cannot duplicate file descriptor {}"), fd));
@@ -287,8 +287,7 @@ file file::dup(int fd) {
}

void file::dup2(int fd) {
- int result = 0;
- FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
+ int result = -1;
if (result == -1) {
FMT_THROW(system_error(
errno, FMT_STRING("cannot duplicate file descriptor {} to {}"), fd_,
@@ -297,8 +296,7 @@ void file::dup2(int fd) {
}

void file::dup2(int fd, std::error_code& ec) noexcept {
- int result = 0;
- FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd)));
+ int result = -1;
if (result == -1) ec = std::error_code(errno, std::generic_category());
}

@@ -335,11 +333,11 @@ pipe::pipe() {
# ifdef _WIN32
// Make the default pipe capacity same as on Linux 2.6.11+.
enum { DEFAULT_CAPACITY = 65536 };
- int result = FMT_POSIX_CALL(pipe(fds, DEFAULT_CAPACITY, _O_BINARY));
+ int result = -1;
# else
// Don't retry as the pipe function doesn't return EINTR.
// http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html
- int result = FMT_POSIX_CALL(pipe(fds));
+ int result = -1;
# endif
if (result != 0)
FMT_THROW(system_error(errno, FMT_STRING("cannot create pipe")));
1 change: 1 addition & 0 deletions cmake/vcpkg/ports/wasm32-wasi/fmt/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This overlay port is a direct copy from https://github.com/microsoft/vcpkg/tree/master/ports/fmt with modifications to allow compilation on wasm32-wasi as a target by removing POSIX filesystem calls.
38 changes: 38 additions & 0 deletions cmake/vcpkg/ports/wasm32-wasi/fmt/portfile.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
vcpkg_from_github(
OUT_SOURCE_PATH SOURCE_PATH
REPO fmtlib/fmt
REF "${VERSION}"
SHA512 27df90c681ec37e55625062a79e3b83589b6d7e94eff37a3b412bb8c1473f757a8adb727603acc9185c3490628269216843b7d7bd5a3cb37f0029da5d1495ffa
HEAD_REF master
PATCHES
001-fix-write-batch.patch
002-disable-posix-fd.patch
)

vcpkg_cmake_configure(
SOURCE_PATH "${SOURCE_PATH}"
OPTIONS
-DFMT_CMAKE_DIR=share/fmt
-DFMT_TEST=OFF
-DFMT_DOC=OFF
)

vcpkg_cmake_install()
vcpkg_cmake_config_fixup()
vcpkg_fixup_pkgconfig()
vcpkg_copy_pdbs()

if(VCPKG_LIBRARY_LINKAGE STREQUAL dynamic)
vcpkg_replace_string(${CURRENT_PACKAGES_DIR}/include/fmt/core.h
"defined(FMT_SHARED)"
"1"
)
endif()

file(REMOVE_RECURSE
"${CURRENT_PACKAGES_DIR}/debug/include"
"${CURRENT_PACKAGES_DIR}/debug/share"
)

file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")
8 changes: 8 additions & 0 deletions cmake/vcpkg/ports/wasm32-wasi/fmt/usage
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
The package fmt provides CMake targets:

find_package(fmt CONFIG REQUIRED)
target_link_libraries(main PRIVATE fmt::fmt)

# Or use the header-only version
find_package(fmt CONFIG REQUIRED)
target_link_libraries(main PRIVATE fmt::fmt-header-only)
17 changes: 17 additions & 0 deletions cmake/vcpkg/ports/wasm32-wasi/fmt/vcpkg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "fmt",
"version": "10.2.1",
"description": "Formatting library for C++. It can be used as a safe alternative to printf or as a fast alternative to IOStreams.",
"homepage": "https://github.com/fmtlib/fmt",
"license": "MIT",
"dependencies": [
{
"name": "vcpkg-cmake",
"host": true
},
{
"name": "vcpkg-cmake-config",
"host": true
}
]
}
9 changes: 9 additions & 0 deletions cmake/vcpkg/triplets/wasm32-wasi.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
set(VCPKG_TARGET_ARCHITECTURE wasm32)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CRT_LINKAGE static)

set(VCPKG_CMAKE_SYSTEM_NAME WASI)
set(VCPKG_CMAKE_SYSTEM_VERSION 1)
set(VCPKG_CMAKE_SYSTEM_PROCESSOR wasm32)

set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/../../wasi-sdk/wasi-sdk.toolchain.cmake")
4 changes: 0 additions & 4 deletions cmake/vcpkg/triplets/x86-linux-clang-dynamic.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,3 @@ set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE dynamic)

set(VCPKG_CMAKE_SYSTEM_NAME Linux)

set(VCPKG_CXX_FLAGS -stdlib=libc++)
set(VCPKG_C_FLAGS -stdlib=libc++)
set(VCPKG_LINKER_FLAGS "-stdlib=libc++ -lc++abi")
52 changes: 52 additions & 0 deletions cmake/wasi-sdk/wasi-sdk.toolchain.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
include_guard(GLOBAL)

cmake_minimum_required(VERSION 3.25)

get_property(IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE)

if (IN_TRY_COMPILE)
return()
endif()

unset(IN_TRY_COMPILE)

# Until Platform/WASI.cmake is upstream we need to inject the path to it
# into CMAKE_MODULE_PATH.
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/..")

include(${CMAKE_CURRENT_LIST_DIR}/wasi-sdk_bootstrap.cmake)
wasi_sdk_bootstrap(
TAG wasi-sdk-21
WASI_SYSROOT_OUTPUT CMAKE_SYSROOT
)

set(CMAKE_SYSTEM_NAME WASI)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR wasm32)
set(triple wasm32-wasi)

set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_ASM_COMPILER clang)
set(CMAKE_AR llvm-ar)
set(CMAKE_RANLIB llvm-ranlib)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER_TARGET ${triple})
set(CMAKE_ASM_COMPILER_TARGET ${triple})

# Don't look in the sysroot for executables to run during the build
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Only look in the sysroot (not in the host paths) for the rest
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

set(CLANG_DEFAULT_RTLIB "compiler-rt")
set(LIBCXX_USE_COMPILER_RT "YES")
set(LIBCXXABI_USE_COMPILER_RT "YES")

add_compile_options(
"-stdlib=libc++"
"-fno-exceptions"
"-D_WASI_EMULATED_SIGNAL"
)
Loading