I am working on a Webgl plugin and want to add a library(.lib/ dll/ framework/ bundle) inside it.
You cannot run code compiled for other platforms (as the lib/ dll/ framework/ bundle would suggest) to webgl. What are you trying to achieve?
Thanks for your reply. I have c++ code of it but number of files is huge. For all other platforms I have created respected libraries but want to know how to create a lib for webgl and use it.
You can use the emscripten compiler toolchain to compile your files into a single .bc (llvm bitcode) file. The bc file can be included in unity as a plugin, similar to lib/dll/framework/bundle files on other platforms.
Thank you for showing the way. I will be trying it.
I"m not sure if this blog post will be helpful here, because it doesnāt seem to cover that particular use-case:
https://blogs.unity3d.com/2017/01/19/low-level-plugins-in-unity-webgl/
So here is a question, if I compile a C/C++ library to llvm bitcode, I still have to write the same p/invoke C# code to interface to it, correct? Is the only difference from using a native .dll/.so is that I would just reference .bc file?
Yes, if you compile C/C++ code to llvm bitcode, you still need to write the C# bindings for it like you normally would for other plugins.
What does the optimizer do in the case of AOT compiling? Do the C# bindings have any performance impact due to p/invoke or do they get optimized away?
Iāve built a simple static lib from very simple .c source file into a .bc file but I canāt never call the function from c#.
My .c file is:
#include <stdio.h>
int AddNumbers (int x, int y)
{
return x + y;
}
and then on c#
[DllImport("__Internal")]
private static extern int AddNumbers(int x, int y);
To compile the .c file Iāve created a MakeFile using CMake and compiled it with Emscripten
./emmake make
It generates a .a lib file that Iāve renamed to .bc and moved into Unity Assets and market as a WebGL plugin.
When i call the AddNumber method I always get this error:
An error occurred running the Unity content on this page. See your browser's JavaScript console for more info. The error was:
abort(-1) at jsStackTrace (WebGLPlugin.js:1:19708)
stackTrace (WebGLPlugin.js:1:19882)
abort (WebGLPlugin.js:3:32695)
_AddNumbers (WebGLPlugin.js:1:186759)
Pwo (WebGLPlugin.asm.js:10:844115)
N_l (WebGLPlugin.asm.js:4:87306)
If I just drop the .c file inside Unity Assets it runs without a problem.
The reason I want to create the .bc file is because I want to compile a much larger code base.
Thanks
I donāt think you do it that way. The .lib file is not the right bitcode format.
Try building the .c file with emscripten with the -emit-llvm flag set to generate the IL code.
I found an article on stack overflow that might be useful: How do I generate LLVM bitcode for use by emscripten? - Stack Overflow
Thanks for the guidance.
Iāve added ā-emit-llvmā to CFLAGS and i still canāt get it to work. I must be missing something obvious here.
Did you try using the toolchain that is supplied by Unity? Also, apparently not all llvm bitcode is equal in the emscripten world. Iām still doing some research, so hopefully Iāll find something useful.
I could compile it now using clang directly.
clang -emit-llvm -o MyPlugin.bc -c MyPlugin.c
Then I just need to drop the MyPlugin.bc inside Unity and it will work.
I was always under the impression I would need to compile it using emscripten.
Thanks for the help ![]()
You would still need to write a C# wrapper, and I believe you have to use the usual [DllImport(ā¦)] stuff. Iām not sure if you would be able to get away with DllImport(ā__Internalā) or not, youāll have to check the Unity docs.
Yes I still need the c# wrapper just with [DllImport(ā__Internalā)].
Although I can compile it using clang directly Iām having a hard time making that possible with CMAKE.
Added set (CMAKE_C_FLAGS ā-emit-llvm -cā) to CMakeLists.txt but the resulting lib doesnāt work.
Ok, so to make it work with CMake I had to set the compiler and linker executables to use the ones from Emscripten.
I now can run that simple .c code.
I can also compile my c/c++ codebase into a llvm bitcode file (.bc) but when I build it with Unity WebGL I get an error upon running.
abort(-1) at jsStackTrace (WebGLPlugin.js:1:19708)
stackTrace (WebGLPlugin.js:1:19882)
abort (WebGLPlugin.js:3:32695)
_llvm_objectsize_i64_p0i8 (WebGLPlugin.js:1:299381)
t3e (WebGLPlugin.asm.js:11:461661)
a4e (WebGLPlugin.asm.js:11:498065)
...
Is your C++ codebase large? Have you tried just a simple C++ module like hello world?
Iāve tried with simple files and it works fine. My codebase is a bit large ![]()
In my last attempt to compile a C/C++ library to a bitcode (.bc) static library I got an error that this is no longer supported on Emscripten upstream. I switched back to Emscripten fastcomp for now, but this is not recommended anymore:
emcc: warning: the fastcomp compiler is deprecated. Please switch to the upstream llvm backend as soon as possible and open issues if you have trouble doing so [-Wfastcomp]
The newer Emscripten (upstream/llvm) creates ā.aā library files. Can those be used as well and with which versions of Unity?
Is there a table showing which Unity version uses what exact Emscripten version, so we can match them?
Thanks!
P.S.: sorry for digging out this old post, but itās the top search result.
Weāve only started looking at this again recently. Itās now 2022, so if we discover anything Iāll post about it here.