5

I am investigating emscripten for a personal project, and I would like to use a language other than C or C++ to do so.

However, while I am investigating emscripten, I figured I should use a trivial 'hello world' example written in C.

I know that I should compile this using emcc:

$ python `which emcc` tmp.c

And this will generate a working a.out.js file for me. So far it's good.

However, I want to use a different language, which means I can't use emcc or emcc++, so I want to generate the llvm bitcode directly.

I have tried using clang 3.3, which is the current version on my mac os x 10.9.2 system, however the following does not work:

$ clang -S -emit-llvm tmp.c -o tmp.ll
$ python `which emcc` tmp.ll      
warning: incorrect target triple 'x86_64-apple-macosx10.9.0' (did you use emcc/em++ on all source files and not clang directly?)

The warning is correct; I am indeed using clang directly, how do I do so regardless, so that I can then attempt to do the same thing in another language that also uses llvm?

Arafangion
  • 11,517
  • 1
  • 40
  • 72
  • So, I'm not entirely sure, but I think if you targeted i386 with Clang, it might work: https://github.com/kripken/emscripten/blob/0fdd070030c66338490a031327afe0c5f990fdd8/tools/shared.py#L676 Just a gut feeling though - I haven't tried it yet. – user May 09 '14 at 06:55
  • It has been about 2 years since this question so I was wondering if you had found a solution as I will be looking into the same use case. The Emscripten website seems to suggest that ANY language that compiles to LLVM IR would work. As the other answer and comments suggest I know this is probably not 100% true. – Matthew Sanders Jun 23 '16 at 15:01
  • @MatthewSanders: I ended up giving up, as it turns out to be a difficult problem. Basically emscripten has a very specific idea as to what sort of llvm you want, and I ultimately hoped to get haskell's llvm output to work with emscripten's llvm input. As it stands, however, today, ghcjs (and purescript) are far better for my purposes. – Arafangion Jul 19 '16 at 07:39
  • Thanks for the follow up. Ya... The big problem with emscripten is that it diverged from llvm at one point making it more difficult to keep up with upstream changes. It sounds like LLVM upstream is starting to get support for webassembly which would be better in the long run anyway IMHO. – Matthew Sanders Jul 19 '16 at 20:37

2 Answers2

4

According to this issue, Emscripten supports the wasm32-unknown-unknown-elf target, common for both CLang & Emscripten.

So, for compiling code in your language to Emscripten-compatible LLVM-bitcode via plain Clang you can use:

clang -emit-llvm --target=wasm32-unknown-unknown-elf -S test.c

And for compiling resulting bitcode to WASM:

emcc -s WASM=1 test.ll

Tested this approach on Emscripten's test file linpack.c - 1157 lines of code, works as expected.

getupandgo
  • 105
  • 1
  • 12
0

You need to use emscripten's LLVM and clang (as it is not upstream yet), so that you can emit code using the emscripten-asmjs target.

If you have another language using llvm, and you can use a build of that llvm with it, then it should work. You just need to tell that language to emit LLVM IR targeting the emscripten-asmjs target.

Alon Zakai
  • 1,038
  • 5
  • 4
  • 1
    Isn't clang, with the -emit-llvm option, doing this? – Arafangion May 09 '14 at 03:55
  • I don't know this for a fact, but I feel that the answer is 'no'. The LLVM bitcode has a 'target triple', which doesn't make sense for a fully device agnostic IR... so I imagine LLVM bitcode is not 100% device agnostic... and this just raises more questions than answers. >_ – user May 09 '14 at 06:45