cmake_minimum_required(VERSION 3.18) project(wasmi C) set(WASMI_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(WASMI_ALWAYS_BUILD "If cmake should always invoke cargo to build Wasmi" ON) set(WASMI_TARGET "" CACHE STRING "Rust target to build for") if(NOT WASMI_TARGET) execute_process( COMMAND rustc -vV OUTPUT_VARIABLE RUSTC_VERSION ) string(REGEX MATCH "host: ([^ \n]+)" RUSTC_VERSION_MATCH "${RUSTC_VERSION}") string(STRIP "${CMAKE_MATCH_1}" WASMI_TARGET) endif() # If the Wasmi Rust crate shall be built using debug or release settings. if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(WASMI_BUILD_TYPE "debug") set(CARGO_PROFILE_PANIC CARGO_PROFILE_DEBUG_PANIC) else() set(WASMI_BUILD_TYPE_FLAG "--profile" "bench") set(WASMI_BUILD_TYPE "release") set(CARGO_PROFILE_PANIC CARGO_PROFILE_RELEASE_PANIC) endif() # Sets the Wasmi target directory. set(WASMI_TARGET_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../target/${WASMI_TARGET}/${WASMI_BUILD_TYPE}) if(WASMI_TARGET MATCHES "darwin") set(WASMI_SHARED_FILES libwasmi.dylib) set(WASMI_STATIC_FILES libwasmi.a) elseif(WASMI_TARGET MATCHES "windows-gnu") set(WASMI_SHARED_FILES libwasmi.dll.a wasmi.dll) set(WASMI_STATIC_FILES libwasmi.a) elseif(WASMI_TARGET MATCHES "windows-msvc") set(WASMI_SHARED_FILES wasmi.dll.lib wasmi.dll) set(WASMI_STATIC_FILES wasmi.lib) else() set(WASMI_SHARED_FILES libwasmi.so) set(WASMI_STATIC_FILES libwasmi.a) endif() list(TRANSFORM WASMI_SHARED_FILES PREPEND ${WASMI_TARGET_DIR}/) list(TRANSFORM WASMI_STATIC_FILES PREPEND ${WASMI_TARGET_DIR}/) # Instructions on how to build and install the Wasmi Rust crate. find_program(WASMI_CARGO_BINARY cargo REQUIRED) include(ExternalProject) ExternalProject_Add( wasmi-crate DOWNLOAD_COMMAND "" CONFIGURE_COMMAND "" INSTALL_COMMAND "${WASMI_INSTALL_COMMAND}" BUILD_COMMAND ${CMAKE_COMMAND} -E env ${CARGO_PROFILE_PANIC}=abort ${WASMI_CARGO_BINARY} build --package wasmi_c_api --target ${WASMI_TARGET} --no-default-features ${WASMI_BUILD_TYPE_FLAG} ${WASMI_FEATURES} ${WASMI_USER_CARGO_BUILD_OPTIONS} USES_TERMINAL_BUILD TRUE BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR}/artifact BUILD_ALWAYS ${WASMI_ALWAYS_BUILD} BUILD_BYPRODUCTS ${WASMI_SHARED_FILES} ${WASMI_STATIC_FILES} ) add_library(wasmi INTERFACE) add_dependencies(wasmi wasmi-crate) # Handle platform-specific settings for linking if(BUILD_SHARED_LIBS) if(NOT WASMI_TARGET MATCHES "windows") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath='$ORIGIN'") endif() list(GET WASMI_SHARED_FILES 0 WASMI_SHARED_LIB_TO_LINK) target_link_libraries(wasmi INTERFACE ${WASMI_SHARED_LIB_TO_LINK}) else() target_link_libraries(wasmi INTERFACE ${WASMI_STATIC_FILES}) if(WASMI_TARGET MATCHES "windows") target_compile_options(wasmi INTERFACE -DWASM_API_EXTERN= -DWASI_API_EXTERN=) target_link_libraries(wasmi INTERFACE ws2_32 advapi32 userenv ntdll shell32 ole32 bcrypt) elseif(NOT WASMI_TARGET MATCHES "darwin") target_link_libraries(wasmi INTERFACE pthread dl m) endif() endif() target_include_directories(wasmi INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/include ) set(WASMI_GENERATED_CONF_H ${CMAKE_BINARY_DIR}/include/wasmi/conf.h) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/include/wasmi/conf.h.in ${WASMI_GENERATED_CONF_H} ) include(GNUInstallDirs) install( DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h" PATTERN "*.hh" ) install( FILES ${WASMI_GENERATED_CONF_H} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/wasmi ) install( FILES ${WASMI_SHARED_FILES} ${WASMI_STATIC_FILES} DESTINATION ${CMAKE_INSTALL_LIBDIR} ) if(WASMI_TARGET MATCHES "darwin") set(INSTALLED_LIB "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/libwasmi.dylib") install( FILES "${INSTALLED_LIB}" DESTINATION "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" COMPONENT Runtime ) if(NOT CMAKE_INSTALL_NAME_TOOL) message(WARNING "CMAKE_INSTALL_NAME_TOOL is not set. LC_ID_DYLIB for libwasmi.dylib will not be set.") else() set(install_name_tool_cmd "${CMAKE_INSTALL_NAME_TOOL}" "-id" "@rpath/libwasmi.dylib" "${INSTALLED_LIB}" ) install(CODE "execute_process(COMMAND ${install_name_tool_cmd})") endif() endif() # Documentation Generation via Doxygen: 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 ${WASMI_GENERATED_CONF_H} ${DOXYGEN_CONF_OUT} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) # C-Header Formatting via clang-format: find_program(CLANG_FORMAT clang-format REQUIRED) file(GLOB_RECURSE HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/wasmi.h ${CMAKE_CURRENT_SOURCE_DIR}/include/wasmi/*.h ${CMAKE_CURRENT_SOURCE_DIR}/include/wasmi/*.hh ) add_custom_target(check-format COMMAND ${CLANG_FORMAT} -style=llvm -Werror --dry-run ${HEADER_FILES} COMMENT "clang-format: Check formatting for Wasmi C-API header files" ) add_custom_target(format COMMAND ${CLANG_FORMAT} -style=llvm -i ${HEADER_FILES} COMMENT "clang-format: Apply formatting rules for Wasmi C-API header files" )