没有脚本,如何将C ++编译为WebAssembly

问题描述 投票:2回答:1

我在构建独立的Web程序集时遇到麻烦,我需要完全控制内存和布局。我不想使用emscripten,因为,正如下面的帖子所述,它不能满足我所需的所有编译时选项(例如,堆栈大小控制,能够选择以独立模式导入内存等)。 )我一直关注以下页面:How to generate standalone webassembly with emscripten而且,emscripten太过分了。

到目前为止,我已经做了:我有一个通过自制软件下载的完全正常工作的llvm 9工具链(我在macOS 10.14上)。我正在混用https://aransentin.github.io/cwasm/https://depth-first.com/articles/2019/10/16/compiling-c-to-webassembly-and-running-it-without-emscripten/我使用wasi来获取C标准库。使用-Wl,-z,stack-size=$[1024 * 1024]这样的链接器标记,我可以控制堆栈的大小。编译成功。太好了!

但是,我需要使用C ++标准库来支持我自己的库和其他第三方库。据我所知,似乎没有任何简单的方法来获取libc ++和libc ++ abi。

我尝试了“ hack”,在其中下载了Emscripten,并让它构建了自己的libc ++和libc ++ abi文件。然后,我尝试将那些文件和标头复制到正确的位置。然后我收到了有关缺少线程API的错误消息,这显然是由于未使用EMSCRIPTEN进行编译引起的。因此,我定义了EMSCRIPTEN宏并进行了这种工作。然后我以为也许可以删除wasi依赖项,并使用emscripten的libc版本保持一致,但是随后也有冲突/缺少标头。

简而言之,我认为我已经接近需要的位置,但是事情变得非常混乱。我怀疑我采用了最简单的非脚本化方法。

有人成功为独立的Web程序集创建了一个构建系统,可让您使用c和c ++标准库吗?

编辑:

这是我现在拥有的超级hacky构建脚本(它是我在网上找到的东西的重大修改版本:]

DEPS = 
OBJ = library.o
STDLIBC_OBJ = $(patsubst %.cpp,%.o,$(wildcard stdlibc/*.cpp))
OUTPUT = library.wasm

DIR := ${CURDIR}

COMPILE_FLAGS = -Wall \
        --target=wasm32-unknown-wasi \
        -Os \
        -D __EMSCRIPTEN__ \
        -D _LIBCPP_HAS_NO_THREADS \
        -flto \
        --sysroot ./ \
        -std=c++17 \
        -ffunction-sections \
        -fdata-sections \
        -I./libcxx/ \
        -I./libcxx/support/xlocale \
        -I./libc/include \
        -DPRINTF_DISABLE_SUPPORT_FLOAT=1 \
        -DPRINTF_DISABLE_SUPPORT_LONG_LONG=1 \
        -DPRINTF_DISABLE_SUPPORT_PTRDIFF_T=1

$(OUTPUT): $(OBJ) $(NANOLIBC_OBJ) Makefile
    wasm-ld \
        -o $(OUTPUT) \
        --no-entry \
        --export-all \
        --initial-memory=131072 \
        --stack-size=$[1024 * 1024] \
        -error-limit=0 \
        --lto-O3 \
        -O3 \
        -lc -lc++ -lc++abi \
        --gc-sections \
        -allow-undefined-file ./stdlibc/wasm.syms \
        $(OBJ) \
        $(LIBCXX_OBJ) \
        $(STDLIBC_OBJ)


%.o: %.cpp $(DEPS) Makefile
    clang++ \
        -c \
        $(COMPILE_FLAGS) \
        -fno-exceptions \
        -o $@ \
        $<

library.wat: $(OUTPUT) Makefile
    ~/build/wabt/wasm2wat -o library.wat $(OUTPUT)

wat: library.wat

clean:
    rm -f $(OBJ) $(STDLIBC_OBJ) $(OUTPUT) library.wat

我从emscripten中放入了libc,libc ++和libc ++ abi(但老实说,这是一个糟糕的安装过程。)

我一直在逐步尝试填补我猜emscripten通常会做的空白,但现在我再次陷入困境:

./libcxx/type_traits:4837:57: error: use of undeclared identifier 'byte'
  constexpr typename enable_if<is_integral_v<_Integer>, byte>::type &
                                                        ^
./libcxx/type_traits:4837:64: error: definition or redeclaration of 'type'
      cannot name the global scope
  constexpr typename enable_if<is_integral_v<_Integer>, byte>::type &

由于系统可能会意外地编译特定于平台的内容,因此我不再确定这是否还会起作用。我真正想要的是一个垫片,该垫片将只允许我主要使用标准容器。这已经变得难以管理。接下来我该怎么办?

编辑2:是的,因此缺少C ++ 17类型特征内容,当我使用C ++ 14(我仍然想要C ++ 17)时,我最终会遇到更多丢失的东西。绝对卡住了。

c++ compilation llvm-clang webassembly
1个回答
0
投票

如果有帮助,Surma就如何做到这一点写了一篇很棒的文章:

https://dassur.ma/things/c-to-webassembly/

© www.soinside.com 2019 - 2024. All rights reserved.