diff --git a/Cargo.toml b/Cargo.toml index d9059edc2736..a804dc431c26 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 +# modifying locations marked WASMTIME_FEATURE_LIST [features] default = [ # All subcommands are included by default. diff --git a/crates/c-api/CMakeLists.txt b/crates/c-api/CMakeLists.txt index 1235c61a0f00..09e8104a2710 100644 --- a/crates/c-api/CMakeLists.txt +++ b/crates/c-api/CMakeLists.txt @@ -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") @@ -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) @@ -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}) @@ -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}) diff --git a/crates/c-api/Cargo.toml b/crates/c-api/Cargo.toml index 5b8a964f25ec..ccf78db10b8a 100644 --- a/crates/c-api/Cargo.toml +++ b/crates/c-api/Cargo.toml @@ -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 @@ -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"] @@ -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 diff --git a/crates/c-api/README.md b/crates/c-api/README.md index 8f093855a091..7a858cab86e2 100644 --- a/crates/c-api/README.md +++ b/crates/c-api/README.md @@ -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 diff --git a/crates/c-api/artifact/Cargo.toml b/crates/c-api/artifact/Cargo.toml index a64007cc225e..789789b43eb1 100644 --- a/crates/c-api/artifact/Cargo.toml +++ b/crates/c-api/artifact/Cargo.toml @@ -20,6 +20,7 @@ doctest = false wasmtime-c-api = { path = '..', package = 'wasmtime-c-api-impl' } [features] +# WASMTIME_FEATURE_LIST default = [ 'profiling', 'wat', @@ -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"] diff --git a/crates/c-api/build.rs b/crates/c-api/build.rs index 7c9151fbe7ab..6db41dec75cc 100644 --- a/crates/c-api/build.rs +++ b/crates/c-api/build.rs @@ -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"); } diff --git a/crates/c-api/cmake/features.cmake b/crates/c-api/cmake/features.cmake new file mode 100644 index 000000000000..44ae4b9b5ec3 --- /dev/null +++ b/crates/c-api/cmake/features.cmake @@ -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 diff --git a/crates/c-api/cmake/install-headers.cmake b/crates/c-api/cmake/install-headers.cmake new file mode 100644 index 000000000000..2468cfa77768 --- /dev/null +++ b/crates/c-api/cmake/install-headers.cmake @@ -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?$") diff --git a/crates/c-api/doxygen.conf.in b/crates/c-api/doxygen.conf.in index 1f6645dfda93..6ba0b993b710 100644 --- a/crates/c-api/doxygen.conf.in +++ b/crates/c-api/doxygen.conf.in @@ -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 @@ -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 diff --git a/crates/c-api/include/wasmtime/async.h b/crates/c-api/include/wasmtime/async.h index d2a8d125d56c..c0f6a14b4fd6 100644 --- a/crates/c-api/include/wasmtime/async.h +++ b/crates/c-api/include/wasmtime/async.h @@ -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 * 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. * */ diff --git a/crates/c-api/include/wasmtime/conf.h.in b/crates/c-api/include/wasmtime/conf.h.in index 009c00b9d289..c04cfca886ad 100644 --- a/crates/c-api/include/wasmtime/conf.h.in +++ b/crates/c-api/include/wasmtime/conf.h.in @@ -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 @@ -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 #if defined(WASMTIME_FEATURE_CRANELIFT) || defined(WASMTIME_FEATURE_WINCH) #define WASMTIME_FEATURE_COMPILER