WASI — это системный интерфейс, предназначенный для создания программных модулей .wasm не только для Node.js и веб-браузеров, но и для любой совместимой с WASI среды выполнения. Хотя WASI ещё находится на стадии разработки и не отличается стабильностью, его вполне можно применять для некоторых экспериментальных проектов.
Нас интересуют две WASI-совместимые среды выполнения: Wasmer и Wasmtime.
Wasmer
Набираем в терминале:
https://get.wasmer.io -sSfL | sh
Wasmtime
Получаем исходный код и собираем wasmtime с помощью компилятора Rust.
Настройка среды сборки WASI
Начнём с wasi-libc. Для компиляции нам понадобится clang 8 или более поздняя версия. Если у вас ещё не установлен clang, не спешите бежать в репозитории: последней версии вы там не найдёте.
Мы пойдём другим путём: добавляем deb http://deb.debian.org/debian/ testing main
к /etc/apt/sources.list
и обновляем источники:
sudo apt update
И вот перед нами последняя версия — clang 9:
Устанавливаем её и создаём соответствующие символьные ссылки:
sudo apt install clang-9
sudo ln -s /usr/bin/clang-9 /usr/bin/clang
sudo ln -s /usr/bin/clang++-9 /usr/bin/clang++
Теперь можно скомпилировать WASI Libs из исходного кода. Если вам нужны только инструменты, лучше установить wasi-sdk:
sudo dpkg -i wasi-sdk_7.0_amd64.deb
export PATH=/opt/wasi-sdk/bin:$PATH
export CC=/opt/wasi-sdk/bin/clang
export CXX=/opt/wasi-sdk/bin/clang++
#include <stdio.h>
int main()
{
printf("hello wasi libc\n");
return 0;
}
Теперь проверяем простенькой программой:
Компилируем код:
$ clang — target=wasm32-wasi — sysroot=/opt/wasi-sdk/share/wasi-sysroot/ test.c -o test.wasm
И запускаем приложение:
wasmer run test.wasm
wasmtime test.wasm
Портирование ZXing C++ для WASI Libc
Возьмём исходный код zxing-cpp. На данный момент WASI libc ещё не поддерживает исключения C++, поэтому надо добавить -fno-exceptions к CMakeLists.txt:
set (CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} — target=wasm32-wasi -Wall -Wextra -fno-exceptions”)
Далее устанавливаем sysroot:
set (CMAKE_SYSROOT /opt/wasi-sdk/share/wasi-sysroot)
Для успешной сборки я отключил в коде всё, что имеет отношение к исключениям C++, и подкорректировал структуру проекта. Выполняем сборку проекта в wasm-файл:
mkdir build
cd build
cmake ..
cmake --build .
Запускаем приложение в папке сборки:
$ wasmer run zxing_barcode_reader.wasm — dir=$(pwd)/../ $(pwd)/../test.png
Text: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
Format: QR_CODE
Position: 190x367 205x162 422x165 405x342
EC Level: M
$ wasmtime zxing_barcode_reader.wasm — dir=$(pwd)/../ $(pwd)/../test.png
Text: MEBKM:URL:http\://en.wikipedia.org/wiki/Main_Page;;
Format: QR_CODE
Position: 190x367 205x162 422x165 405x342
EC Level: M
Использование Wapm для передачи и выполнения Wasm-файла
Генерируем файл wapm.toml командой init:
$ wapm init zxing_barcode_reader
Редактируем этот wapm.toml:
[package]
name = "yushulx/zxing_barcode_reader"
version = "0.1.4"
description = "A barcode reader app built with ZXing C/C++ and wasi-sdk"
readme = "README.md"
repository = "https://github.com/yushulx/wasi-zxing-wasm"
[[module]]
name = "zxing_barcode_reader"
source = "dist/zxing_barcode_reader.wasm"
abi = "wasi"
[[command]]
name = "zxing_barcode_reader"
module = "zxing_barcode_reader"
Передаём пакет на wapm.io:
wapm login
wapm publish
Устанавливаем пакет через wapm и считываем штрих-код в PNG:
wapm install yushulx/zxing_barcode_reader
wapm run zxing_barcode_reader — dir=. test.png
Читайте также:
- 10 правил программирования NASA
- Как не лажать с JavaScript. Часть 1
- Повесть об однонаправленном потоке данных в Angular
Перевод статьи Xiao Ling: How to Build ZXing C++ to Wasm using WASI SDK in Linux