Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use cmake to build wasmtime-c-api #9031

Merged
merged 16 commits into from
Aug 9, 2024
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
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,9 @@ semver = { version = "1.0.17", default-features = false }
# in configuring binary size and or exploring the binary size implications of
# various features. Most features are enabled by default but most embeddings
# likely won't need all features.
#
# When adding or removing a feature, make sure to kepe the C API in sync by
Copy link

Choose a reason for hiding this comment

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

Suggested change
# When adding or removing a feature, make sure to kepe the C API in sync by
# When adding or removing a feature, make sure to keep the C API in sync by

# modifying locations marked WASMTIME_FEATURE_LIST
[features]
default = [
# All subcommands are included by default.
Expand Down
76 changes: 17 additions & 59 deletions crates/c-api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,52 +14,7 @@ if(WASMTIME_TARGET STREQUAL "")
set(WASMTIME_TARGET ${RUSTC_HOST_TARGET})
endif()

set(WASMTIME_FEATURES "--no-default-features")

option(WASMTIME_DISABLE_ALL_FEATURES
"disable all features by default instead of enabling them"
OFF)

macro(feature rust_name default)
string(TOUPPER "wasmtime_feature_${rust_name}" cmake_name)
string(REPLACE "-" "_" cmake_name ${cmake_name})
if(${default})
if(${WASMTIME_DISABLE_ALL_FEATURES})
set(feature_default OFF)
else()
set(feature_default ON)
endif()
else()
set(feature_default OFF)
endif()

option(${cmake_name} "enable the Cargo feature ${rust_name}" ${feature_default})

if(${cmake_name})
list(APPEND WASMTIME_FEATURES "--features=${rust_name}")
message(STATUS "Enabling feature ${rust_name}")
endif()
endmacro()

feature(profiling ON)
feature(wat ON)
feature(cache ON)
feature(parallel-compilation ON)
feature(wasi ON)
feature(logging ON)
feature(disable-logging OFF)
feature(coredump ON)
feature(addr2line ON)
feature(demangle ON)
feature(threads ON)
feature(gc ON)
feature(async ON)
feature(cranelift ON)
feature(winch ON)
# ... if you add a line above this be sure to also change:
#
# crates/c-api/include/wasmtime/conf.h.in
# crates/c-api/artifact/Cargo.toml
include(cmake/features.cmake)

if(WASMTIME_FASTEST_RUNTIME)
set(WASMTIME_BUILD_TYPE_FLAG "--profile=fastest-runtime")
Expand Down Expand Up @@ -109,11 +64,14 @@ ExternalProject_Add(
${CMAKE_COMMAND} -E env ${CARGO_PROFILE_PANIC}=abort
${WASMTIME_CARGO_BINARY} build
--target ${WASMTIME_TARGET}
--package wasmtime-c-api
${WASMTIME_BUILD_TYPE_FLAG}
${WASMTIME_FEATURES}
${WASMTIME_USER_CARGO_BUILD_OPTIONS}
USES_TERMINAL_BUILD TRUE
BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/artifact
# Note that this is used as the cwd for the cargo invocation itself, build
# byproducts go in the `target` directory at the top-level.
BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}
BUILD_ALWAYS ${WASMTIME_ALWAYS_BUILD}
BUILD_BYPRODUCTS ${WASMTIME_SHARED_FILES} ${WASMTIME_STATIC_FILES})
add_library(wasmtime INTERFACE)
Expand All @@ -138,21 +96,12 @@ else()
endif()
endif()

target_include_directories(wasmtime INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include)

set(WASMTIME_GENERATED_CONF_H ${CMAKE_BINARY_DIR}/include/wasmtime/conf.h)
target_include_directories(wasmtime INTERFACE ${CMAKE_BINARY_DIR}/include)

configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/include/wasmtime/conf.h.in
${WASMTIME_GENERATED_CONF_H})
set(WASMTIME_HEADER_DST ${CMAKE_BINARY_DIR}/include)
include(cmake/install-headers.cmake)

include(GNUInstallDirs)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING REGEX "\\.hh?$")
install(FILES ${WASMTIME_GENERATED_CONF_H}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/wasmtime)
install(SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/cmake/install-headers.cmake)
install(FILES ${WASMTIME_SHARED_FILES} ${WASMTIME_STATIC_FILES}
DESTINATION ${CMAKE_INSTALL_LIBDIR})

Expand All @@ -171,3 +120,12 @@ add_custom_target(doc
COMMAND doxygen ${DOXYGEN_CONF_OUT}
DEPENDS ${WASMTIME_GENERATED_CONF_H} ${DOXYGEN_CONF_OUT}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
add_dependencies(doc headers-to-doc)

file(GLOB headers "include/*.h")
add_custom_target(headers-to-doc
COMMAND
${CMAKE_COMMAND}
-DWASMTIME_HEADER_DST=${CMAKE_BINARY_DIR}/include
-P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/install-headers.cmake
DEPENDS ${headers})
8 changes: 4 additions & 4 deletions crates/c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repository = "https://github.com/bytecodealliance/wasmtime"
readme = "README.md"
edition.workspace = true
links = "wasmtime-c-api"
include = ["include", "src", "build.rs"]
include = ["include", "src", "build.rs", "CMakeLists.txt", "cmake", "doxygen.conf.in"]

[lints]
workspace = true
Expand Down Expand Up @@ -39,6 +39,7 @@ wasmtime-wasi = { workspace = true, optional = true, features = ["preview1"] }
futures = { workspace = true, optional = true }

[features]
# WASMTIME_FEATURE_LIST
async = ['wasmtime/async', 'futures']
profiling = ["wasmtime/profiling"]
cache = ["wasmtime/cache"]
Expand All @@ -53,6 +54,5 @@ threads = ["wasmtime/threads"]
gc = ["wasmtime/gc"]
cranelift = ['wasmtime/cranelift']
winch = ['wasmtime/winch']
# ... if you add a line above this be sure to also change:
#
# crates/c-api/artifact/Cargo.toml
# ... if you add a line above this be sure to change the other locations
# marked WASMTIME_FEATURE_LIST
1 change: 0 additions & 1 deletion crates/c-api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ fn main() {
// Wasm C API headers.
cfg
.include(std::env::var("DEP_WASMTIME_C_API_INCLUDE").unwrap());
.include(std::env::var("DEP_WASMTIME_C_API_WASM_INCLUDE").unwrap());

// Compile your C code.
cfg
Expand Down
7 changes: 3 additions & 4 deletions crates/c-api/artifact/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ doctest = false
wasmtime-c-api = { path = '..', package = 'wasmtime-c-api-impl' }

[features]
# WASMTIME_FEATURE_LIST
default = [
'profiling',
'wat',
Expand All @@ -34,10 +35,8 @@ default = [
'gc',
'cranelift',
'winch',
# ... if you add a line above this be sure to also change:
#
# crates/c-api/CMakeLists.txt
# crates/c-api/Cargo.toml
# ... if you add a line above this be sure to change the other locations
# marked WASMTIME_FEATURE_LIST
]
async = ['wasmtime-c-api/async']
profiling = ["wasmtime-c-api/profiling"]
Expand Down
45 changes: 43 additions & 2 deletions crates/c-api/build.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,45 @@
use std::env;
use std::process::Command;

// WASMTIME_FEATURE_LIST
const FEATURES: &[&str] = &[
"ASYNC",
"PROFILING",
"CACHE",
"PARALLEL_COMPILATION",
"WASI",
"LOGGING",
"DISABLE_LOGGING",
"COREDUMP",
"ADDR2LINE",
"DEMANGLE",
"THREADS",
"GC",
"CRANELIFT",
"WINCH",
];
// ... if you add a line above this be sure to change the other locations
// marked WASMTIME_FEATURE_LIST

fn main() {
let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
println!("cargo:include={dir}/include");
println!("cargo:rerun-if-changed=cmake/features.cmake");
println!("cargo:rerun-if-changed=cmake/install-headers.cmake");
println!("cargo:rerun-if-changed=include");

let out_dir = std::env::var("OUT_DIR").unwrap();
let mut cmake = Command::new("cmake");
cmake.arg("-DWASMTIME_DISABLE_ALL_FEATURES=ON");
cmake.arg(format!("-DCMAKE_INSTALL_PREFIX={out_dir}"));
for f in FEATURES {
if env::var_os(format!("CARGO_FEATURE_{f}")).is_some() {
cmake.arg(format!("-DWASMTIME_FEATURE_{f}=ON"));
}
}

cmake.arg("-P").arg("cmake/install-headers.cmake");

let status = cmake.status().expect("failed to spawn `cmake`");
assert!(status.success());

println!("cargo:include={out_dir}/include");
}
45 changes: 45 additions & 0 deletions crates/c-api/cmake/features.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
set(WASMTIME_FEATURES "--no-default-features")

option(WASMTIME_DISABLE_ALL_FEATURES
"disable all features by default instead of enabling them"
OFF)

macro(feature rust_name default)
string(TOUPPER "wasmtime_feature_${rust_name}" cmake_name)
string(REPLACE "-" "_" cmake_name ${cmake_name})
if(${default})
if(${WASMTIME_DISABLE_ALL_FEATURES})
set(feature_default OFF)
else()
set(feature_default ON)
endif()
else()
set(feature_default OFF)
endif()

option(${cmake_name} "enable the Cargo feature ${rust_name}" ${feature_default})

if(${cmake_name})
list(APPEND WASMTIME_FEATURES "--features=${rust_name}")
message(STATUS "Enabling feature ${rust_name}")
endif()
endmacro()

# WASMTIME_FEATURE_LIST
feature(profiling ON)
feature(wat ON)
feature(cache ON)
feature(parallel-compilation ON)
feature(wasi ON)
feature(logging ON)
feature(disable-logging OFF)
feature(coredump ON)
feature(addr2line ON)
feature(demangle ON)
feature(threads ON)
feature(gc ON)
feature(async ON)
feature(cranelift ON)
feature(winch ON)
# ... if you add a line above this be sure to change the other locations
# marked WASMTIME_FEATURE_LIST
17 changes: 17 additions & 0 deletions crates/c-api/cmake/install-headers.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.12)

include(${CMAKE_CURRENT_LIST_DIR}/features.cmake)

if(WASMTIME_HEADER_DST)
set(dst "${WASMTIME_HEADER_DST}")
else()
set(dst "${CMAKE_INSTALL_PREFIX}/include")
endif()
set(include_src "${CMAKE_CURRENT_LIST_DIR}/../include")

message(STATUS "Installing: ${dst}/wasmtime/conf.h")
file(READ "${include_src}/wasmtime/conf.h.in" conf_h)
file(CONFIGURE OUTPUT "${dst}/wasmtime/conf.h" CONTENT "${conf_h}")
file(INSTALL "${include_src}/"
DESTINATION "${dst}"
FILES_MATCHING REGEX "\\.hh?$")
4 changes: 2 additions & 2 deletions crates/c-api/doxygen.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.

INPUT = include @CMAKE_BINARY_DIR@/include
INPUT = @CMAKE_BINARY_DIR@/include

# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
Expand Down Expand Up @@ -2162,7 +2162,7 @@ SEARCH_INCLUDES = YES
# preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.

INCLUDE_PATH = include @CMAKE_BINARY_DIR@/include
INCLUDE_PATH = @CMAKE_BINARY_DIR@/include

# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
Expand Down
10 changes: 5 additions & 5 deletions crates/c-api/include/wasmtime/async.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@
* are three mechanisms for yielding control from wasm to the caller: fuel,
* epochs, and async host functions.
*
* When WebAssembly is executed, a #wasmtime_call_future_t is returned. This
* When WebAssembly is executed, a `wasmtime_call_future_t` is returned. This
Copy link

Choose a reason for hiding this comment

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

unrelated changes?

Copy link
Member

Choose a reason for hiding this comment

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

I found this was necessary at one stage of testing to appease doxygen. That being said I barely understanding doxygen and we could very well be holding doxygen wrong where this should work when it doesn't.

* struct represents the state of the execution and each call to
* #wasmtime_call_future_poll will execute the WebAssembly code on a separate
* `wasmtime_call_future_poll` will execute the WebAssembly code on a separate
* stack until the function returns or yields control back to the caller.
*
* It's expected these futures are pulled in a loop until completed, at which
* point the future should be deleted. Functions that return a
* #wasmtime_call_future_t are special in that all parameters to that function
* `wasmtime_call_future_t` are special in that all parameters to that function
* should not be modified in any way and must be kept alive until the future is
* deleted. This includes concurrent calls for a single store - another function
* on a store should not be called while there is a #wasmtime_call_future_t
* on a store should not be called while there is a `wasmtime_call_future_t`
* alive.
*
* As for asynchronous host calls - the reverse contract is upheld. Wasmtime
* will keep all parameters to the function alive and unmodified until the
* #wasmtime_func_async_continuation_callback_t returns true.
* `wasmtime_func_async_continuation_callback_t` returns true.
*
*/

Expand Down
3 changes: 3 additions & 0 deletions crates/c-api/include/wasmtime/conf.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef WASMTIME_CONF_H
#define WASMTIME_CONF_H

// WASMTIME_FEATURE_LIST
#cmakedefine WASMTIME_FEATURE_PROFILING
#cmakedefine WASMTIME_FEATURE_WAT
#cmakedefine WASMTIME_FEATURE_CACHE
Expand All @@ -22,6 +23,8 @@
#cmakedefine WASMTIME_FEATURE_ASYNC
#cmakedefine WASMTIME_FEATURE_CRANELIFT
#cmakedefine WASMTIME_FEATURE_WINCH
// ... if you add a line above this be sure to change the other locations
// marked WASMTIME_FEATURE_LIST
Copy link

Choose a reason for hiding this comment

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

If you move this comment above the list (here and elsewhere), then you can avoid the duplicate nonce (less noise when grepping).

Copy link
Member

Choose a reason for hiding this comment

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

Personally I like having this at the end because features are often added at the end and a comment only at the top might get missed. The amount of duplication here though is unfortunate across the codebase but that would probably be best fixed with a "tidy" script or something like that rather than relying on us humans to handle everything.

Copy link

Choose a reason for hiding this comment

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

I just mean as a trivial way to halve the number of hits: no need to have the nonce both before and after the list; once is enough (no matter where).


#if defined(WASMTIME_FEATURE_CRANELIFT) || defined(WASMTIME_FEATURE_WINCH)
#define WASMTIME_FEATURE_COMPILER
Expand Down
Loading