I want to compile complex C++ code by using “stdlib, stdio,cmath,vector”, but the LLVM/VLang could not compile such code.
The Emscripten(emcc) could compile C++ system libs, When should the Emscripten(emcc) could be used in DFinity?
If I use WASM compiled by Emscripten(emcc), the dfx install return errors, such as the following:
Installing code for canister dlopen, with canister_id rrkah-fqaaa-aaaaa-aaaaq-cai
The invocation to the wallet call forward method failed with the error: An error happene
d during the call: 5: Wasm module of canister rrkah-fqaaa-aaaaa-aaaaq-cai is not valid:
Wasm module has an invalid import section. Module imports function ‘iprintf’ from ‘env’
that is not exported by the runtime.
Emscripten heavily relies on the presence of JavaScript in the host system, I believe, and compilation generates a mixture of Wasm and JS glue & runtime code. That works for the Web and derivatives like Node.js, but is not usable for the IC or other pure Wasm environments.
There currently is no SDK for using C/C++ on the IC, so it would require some work to get LLVM to function, but it can be done. However, if the code to compile makes use of libraries like stdio, then you will be out of luck, because there is no I/O on the IC. You would need a proper emulation layer. Maybe WASI could help there, but I am not aware of anybody who has tried to get this to work.
You can use Clang to compile anything to wasm. Here is a build example using wasi IC_sqlite/build-all.sh at main · HassenSaidi/IC_sqlite · GitHub. But in fact, you don’t need to use wasi if you build your own libc/libc++. The problem is (as mentioned by @rossberg) that your code might need to call some functions not supported by the IC. If you are sure that those functions are never called, you can simply provide dummy definitions like I am doing here: IC_sqlite/utils.c at main · HassenSaidi/IC_sqlite · GitHub. You can see what errors the dfx install might throw at you by looking at which functions are imported in your wasm file. Wasi will not help you if your code makes use of I/O operations or anything not supported by the IC. But you will be able to build a canister and deploy it, and you can trap if you ever call such non-supported function. Determining whether your code may or may not call such functions is undecidable in theory, but practically possible in most cases.