Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

I have a c++ project that I built with cmake. It compiles and links fine. The goal is to use Emscripten to generate code from it that will run in the browser.

From the docs on the Emscripten site here one finds:

enter image description here

After running the first two commands (emconfigure and emmake), seemingly successfully, I do not have any .bc file anywhere, although it actually does produce a .js and .wasm file. The docs imply there that the .js file would only result from executing the third command ./emcc.

A little further down on the same docs page you find:

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.

so it seems it should produce some bitcode. How to do this?

(I did use the VERBOSE command as those docs suggest and although I do not see emcc being used instead of the native compiler, em++ is being used, which seems to mostly the same as emcc.)

like image 822
Alyoshak Avatar asked Dec 05 '19 00:12

Alyoshak


2 Answers

When the Emscripten build system is used to build a project, it will always generate a bitcode file. This is regardless of the file extension of the default output file. It can't generate a different file, since that would confuse Make, with the file not being created that it was told would be. At the Emscripten website there is a note a short way down the page that says:

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.

Whatever files the build is supposed to create, even ones that are usually shared libraries, will always contain the bitcode, and can be linked directly with the rest of your project.

Edit:
I can only assume that the reason for the .js output file is because the CMake project is set up to produce an executable. It is possible that Emscripten is smart enough to create .js in that case, but I don't know for sure.

like image 53
Circuit Craft Avatar answered Sep 30 '22 19:09

Circuit Craft


From the manpage of 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)

I assume you can just then create a custom command where the output file has the extension .bc to produce bitcode. Seems like you could just skip the hassle potentially by going straight to producing .js from .c(pp).

Edit: Alternatively, if you just want it as a side-effect and not the actual product:

       --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).
like image 39
Braaedy Avatar answered Sep 30 '22 19:09

Braaedy