cmake_minimum_required(VERSION 3.12) project(wasmtime C) set(WASMTIME_USER_CARGO_BUILD_OPTIONS "" CACHE STRING "Additional cargo flags (such as --features) to apply to the build command") option(BUILD_SHARED_LIBS "Build using shared libraries" OFF) option(WASMTIME_ALWAYS_BUILD "If cmake should always invoke cargo to build wasmtime" ON) option(WASMTIME_FASTEST_RUNTIME "Set flags designed to optimize runtime performance" OFF) set(WASMTIME_TARGET "" CACHE STRING "Rust target to build for") if(WASMTIME_TARGET STREQUAL "") execute_process(COMMAND rustc -vV OUTPUT_VARIABLE RUSTC_VERSION) string(REGEX MATCH "host: ([^ \n]*)" RUSTC_HOST ${RUSTC_VERSION}) string(STRIP ${CMAKE_MATCH_1} RUSTC_HOST_TARGET) set(WASMTIME_TARGET ${RUSTC_HOST_TARGET}) endif() include(cmake/features.cmake) if(WASMTIME_FASTEST_RUNTIME) set(WASMTIME_BUILD_TYPE_FLAG "--profile=fastest-runtime") set(WASMTIME_BUILD_TYPE "fastest-runtime") set(CARGO_PROFILE_PANIC CARGO_PROFILE_RELEASE_PANIC) else() if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(WASMTIME_BUILD_TYPE "debug") set(CARGO_PROFILE_PANIC CARGO_PROFILE_DEBUG_PANIC) else() set(WASMTIME_BUILD_TYPE_FLAG "--release") set(WASMTIME_BUILD_TYPE "release") set(CARGO_PROFILE_PANIC CARGO_PROFILE_RELEASE_PANIC) endif() endif() set(WASMTIME_TARGET_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../target/${WASMTIME_TARGET}/${WASMTIME_BUILD_TYPE}) if(WASMTIME_TARGET MATCHES "darwin") set(WASMTIME_SHARED_FILES libwasmtime.dylib) set(WASMTIME_STATIC_FILES libwasmtime.a) elseif(WASMTIME_TARGET MATCHES "windows-gnu") set(WASMTIME_SHARED_FILES libwasmtime.dll.a wasmtime.dll) set(WASMTIME_STATIC_FILES libwasmtime.a) elseif(WASMTIME_TARGET MATCHES "windows-msvc") set(WASMTIME_SHARED_FILES wasmtime.dll.lib wasmtime.dll) set(WASMTIME_STATIC_FILES wasmtime.lib) else() set(WASMTIME_SHARED_FILES libwasmtime.so) set(WASMTIME_STATIC_FILES libwasmtime.a) endif() list(TRANSFORM WASMTIME_SHARED_FILES PREPEND ${WASMTIME_TARGET_DIR}/) list(TRANSFORM WASMTIME_STATIC_FILES PREPEND ${WASMTIME_TARGET_DIR}/) include(ExternalProject) find_program(WASMTIME_CARGO_BINARY cargo) if(NOT WASMTIME_CARGO_BINARY) message(FATAL_ERROR [["cargo" was not found. Ensure "cargo" is in PATH. Aborting...]]) endif() ExternalProject_Add( wasmtime-crate DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" INSTALL_COMMAND "${WASMTIME_INSTALL_COMMAND}" BUILD_COMMAND ${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 # 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) add_dependencies(wasmtime wasmtime-crate) if(BUILD_SHARED_LIBS) if(NOT WASMTIME_TARGET MATCHES "windows") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath='$ORIGIN'") endif() list(GET WASMTIME_SHARED_FILES 0 WASMTIME_SHARED_LIB_TO_LINK) target_link_libraries(wasmtime INTERFACE ${WASMTIME_SHARED_LIB_TO_LINK}) else() if(WASMTIME_TARGET MATCHES "windows") target_compile_options(wasmtime INTERFACE -DWASM_API_EXTERN= -DWASI_API_EXTERN=) target_link_libraries(wasmtime INTERFACE ${WASMTIME_STATIC_FILES} ws2_32 advapi32 userenv ntdll shell32 ole32 bcrypt) elseif(WASMTIME_TARGET MATCHES "darwin") target_link_libraries(wasmtime INTERFACE ${WASMTIME_STATIC_FILES}) else() target_link_libraries(wasmtime INTERFACE ${WASMTIME_STATIC_FILES} pthread dl m) endif() endif() target_include_directories(wasmtime INTERFACE ${CMAKE_BINARY_DIR}/include) set(WASMTIME_HEADER_DST ${CMAKE_BINARY_DIR}/include) include(cmake/install-headers.cmake) include(GNUInstallDirs) install(SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/cmake/install-headers.cmake) install(FILES ${WASMTIME_SHARED_FILES} ${WASMTIME_STATIC_FILES} DESTINATION ${CMAKE_INSTALL_LIBDIR}) if(WASMTIME_TARGET MATCHES "darwin") # Postprocess the macOS dylib a bit to have a more reasonable `LC_ID_DYLIB` # directive than the default one that comes out of the linker when typically # doing `cargo build`. For more info see #984 set(INSTALLED_LIB ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libwasmtime.dylib) install(CODE "execute_process(COMMAND install_name_tool -id \"@rpath/libwasmtime.dylib\" ${INSTALLED_LIB})") endif() set(DOXYGEN_CONF_IN ${CMAKE_CURRENT_SOURCE_DIR}/doxygen.conf.in) set(DOXYGEN_CONF_OUT ${CMAKE_BINARY_DIR}/doxygen.conf) configure_file(${DOXYGEN_CONF_IN} ${DOXYGEN_CONF_OUT}) 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})