如何使用带有 cmake 项目的 emscripten 生成位码(.bc 文件)?

How to generate bitcode (.bc file) using emscripten with a cmake project?

我有一个用 cmake 构建的 c++ 项目。它可以很好地编译和链接。目标是使用 Emscripten 从中生成代码,这些代码将 运行 在浏览器中。

从 Emscripten 站点上的文档 here 可以发现:

运行前两个命令(emconfigure 和 emmake)似乎成功后,我在任何地方都没有任何 .bc 文件,尽管它实际上确实生成了 .js 和 .wasm 文件。文档在那里暗示 .js 文件只会由执行第三个命令 ./emcc.

产生

在同一文档页面的更下方,您会发现:

Make generates linked LLVM bitcode. It does not automatically generate JavaScript during linking because all the files must be compiled using the same optimizations and compiler options — and it makes sense to do this in the final conversion from bitcode to JavaScript.

所以它似乎应该产生一些位码。如何做到这一点?

(我确实按照那些文档的建议使用了 VERBOSE 命令,虽然我没有看到使用 emcc 而不是本机编译器,但使用了 em++,这似乎与 emcc 基本相同。)

来自 emscripten 的联机帮助页:

The target file, if specified (-o <target>), defines what will be generated:

       <name>.js
              JavaScript

       <name>.html
              HTML with embedded JavaScript

       <name>.bc
              LLVM bitcode (default)

       <name>.o
              LLVM bitcode (same as .bc)

我假设您可以创建一个自定义命令,其中输出文件的扩展名为 .bc 以生成位码。似乎您可以通过直接从 .c(pp) 生成 .js 来跳过麻烦。

编辑: 或者,如果您只想将其作为副作用而不是实际产品:

       --save-bc PATH
              When  compiling  to  JavaScript or HTML, this option will save a copy of the bitcode to the specified
              path. The bitcode will include all files being linked, including standard libraries,  and  after  any
              link-time optimizations (if any).

当使用Emscripten构建系统构建项目时,它会总是生成一个bitcode文件。这与默认输出文件的文件扩展名无关。它不能生成不同的文件,因为这会使 Make 混淆,因为文件没有被创建,就像它被告知的那样。 At the Emscripten website 页面下方有一条注释,上面写着:

The file output from make might have a different suffix: .a for a static library archive, .so for a shared library, .o or .bc for object files (these file extensions are the same as gcc would use for the different types). Irrespective of the file extension, these files contain linked LLVM bitcode that emcc can compile into JavaScript in the final step. If the suffix is something else - like no suffix at all, or something like .so.1 - then you may need to rename the file before sending it to emcc.

构建应该创建的任何文件,即使是通常是共享库的文件,也将始终包含位码,并且可以直接与项目的其余部分链接。

编辑:
我只能假设 .js 输出文件的原因是因为 CMake 项目设置为生成可执行文件。 Emscripten 可能足够聪明,可以在这种情况下创建 .js,但我不确定。

根据项目的不同,您可以完全跳过 configure。过去,我指定了 C 函数来导出我的 Wasm 实现,然后用于快速构建。一些 C 库要求 autogen 至少为 运行,但我已经绕过 configure 用于多依赖 C 项目。

# create bitcode library for WebAssembly module
$ emcc \
  -o wasmlib.bc \
  -s EXPORTED_FUNCTIONS="[ \
     '_needed_c_function1' \
     '_needed_c_function2', \
  ]" \
  -I "c_lib_src/include" \
  c_lib_src/*.c

# Quickly build using the bitcode we just created
$ emcc \
  -o my_wasm_module.js \
  -I "c_lib_src/include" \
  wasmlib.bc \
  my_wasm_impl.c

在 Emscripten 1.38.x fastcomp 之前,您可以使用 CMake 选项 EMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES 设置为 ON,静态库最终将成为 .bc 文件:

cmake -Bbuild -DEMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES=ON

要检查,在 hex-editor 中检查那些以 BC.

开头的 .bc 文件

该选项在最近的上游 Emscripten 版本(如 2.0.x)中被删除(并引发错误)。我还得弄清楚,那里是怎么做到的。