File System Emulation
I'm trying to get a file system emulation POC going. https://docs.leaningtech.com/cheerp/Filesystem-emulation
The core of my new code for this is as simple as that doc page:
I get this in the browser js console:
I'm not sure exactly which version of cheerp I have. It's a windows installer support gave me that includes file system emulation.
The `tstcweb.scr' is a plain text file I have at the root of my cheerp project, though I also tried putting it in an assets subfolder. Note that the open() call is commented out -- it's not making it that far. Is there something that needs to be done to include such files in the package given to the browser?
docs.leaningtech.com
Filesystem emulation
Cheerp is the enterprise-grade C/C++ compiler for the Web and can compile C/C++ into WebAssembly and JavaScript.
18 Replies
The
__dummy
function is being called, which is a placeholder for some symbol that is not linked. What is the command you are using to build the file?
You should also consider using the -cheerp-strict-linking=error
or -cheerp-strict-linking=warning
to get more verbose information about missing symbols at buildtime.I had commented out the
-cheerp-strict-linking=warning
that I had there before. Restoring that gives me
c:\cheerp\bin\clang++ -target cheerp-wasm obj/arg.bc ...<several more files> ... obj/xlink_cheerp_cpp.bc -o xlink_cheerp_wasm.js -cheerp-linear-heap-size=128 -cheerp-pretty-code -cheerp-strict-linking=warning
That gives me warning: symbol not defined _ZN6cheerp13FilePreloader8downloadEv
Commenting out the code from my first post (void preloadCallback()... files(preloadCallback,...
) results in a successful compile/runWell, the issue seems quite clear
You need to link the
libposixcompat
library
just add -lposixcompat
to the command lineOk, added
-lposixcompat
to the command line, now I get this:
Uncaught Error: Cheerp: Signal raised
__ZN12_GLOBAL__N_111raiseSignalEv http://localhost:8000/xlink_cheerp_wasm.js:159
__ZN6cheerp13FilePreloader14finishDownloadEii ...wasm.js:339
__ZN6cheerp12InvokeHelperIvE6invokeINS_13FilePreloader16DownloadCallbackEJEEEvPT_DpT0_ ...wasm.js:287
cheerpCreateClosure ...wasm.js:352
__ZN6cheerp13FilePreloader8downloadEv ...wasm.js:277
__start ...wasm.js:342
promise ...wasm.js:437
promise callback* ...wasm.js:402
xlink_cheerp_wasm.js:159:8
__ZN12_GLOBAL__N_111raiseSignalEv ...wasm.js:159
abort ...wasm.js line 393 > WebAssembly.instantiate:14566
_ZSt25__throw_bad_function_callB7v160000v_icf ...wasm.js line 393 > WebAssembly.instantiate:10582
_ZN6cheerp13FilePreloader10commitFileERNS0_11PendingFileE ...wasm.js line 393 > WebAssembly.instantiate:22329
__ZN6cheerp13FilePreloader14finishDownloadEii ...wasm.js:339
_ZN6cheerp13FilePreloader16DownloadCallbackclEv ...wasm.js line 393 > WebAssembly.instantiate:23438
__ZN6cheerp12InvokeHelperIvE6invokeINS_13FilePreloader16DownloadCallbackEJEEEvPT_DpT0_ ...wasm.js:287
cheerpCreateClosure ...wasm.js:352
(Async: EventHandlerNonNull) __ZN6cheerp13FilePreloader8downloadEv ...wasm.js:277
_ZN6cheerp13FilePreloaderC2IJPKcEEEOKSt8functionIFvvEEDpT_ ...wasm.js line 393 > WebAssembly.instantiate:34018
__cxx_global_var_init ...wasm.js line 393 > WebAssembly.instantiate:34086
__start ...wasm.js:342
promise ...wasm.js:437
(Async: promise callback) <anonymous> ...wasm.js:402
That looks like an assertion, is there any error message in the console? Please also check the network tab for failures
no error message in the console. no failures in the network tab -- it found my
tstcweb.scr
file ok.Please deploy this compiled example somewhere, if possible directly on a web server so that I can quickly investigate it
Please see your DMs for the compiled code.
@.letminnow Please try again using a
[[cheerp::wasm]]
tagged callback, if needed you can call a [[cheerp::genericjs]]
function later.
I currently believe the compiler is mistakenly letting you use a genericjs function as a callback from wasm context, that is not supportedI threw that
genericjs
in trying to get compile error to resolve. Using wasm
gives me the below errors (which seems to be the default because I get the same errors without any attribute at all).
The example on the page has int fd = open()
but then it complains it's not Window *
. Then using Window *
gives me:
xlink_cheerp_cpp.cpp:38:13: error: Cheerp: Type 'Window *' of local variable 'fd' is incompatible with attribute 'wasm' of function 'preloadCallback'
Window *fd = open("tstcweb.scr");
^
xlink_cheerp_cpp.cpp:38:23: error: Cheerp: Attribute 'genericjs' of constructor 'String' is incompatible with attribute 'wasm' of caller function 'preloadCallback'
Window *fd = open("tstcweb.scr");
^
xlink_cheerp_cpp.cpp:38:36: error: Cheerp: Attribute 'genericjs' of function parameter 'url' is incompatible with attribute 'wasm' of caller 'preloadCallback'
Window *fd = open("tstcweb.scr");
^
xlink_cheerp_cpp.cpp:38:36: error: Cheerp: Attribute 'genericjs' of function return 'open' is incompatible with attribute 'wasm' of caller 'preloadCallback'
The errors are expected. The callback itself must be wasm, then you can make another genericjs function to interact with Web APIs
Wasm code can call
genericjs
code, it's just using that as a callback (i.e. an indirect call) that is problematicOk, I made the wasm function into a wrapper that calls a genericjs function and that worked. The open() function results in the file getting downloaded into the browser's downloads folder, which is not what I expected. Where do I find more documentation about the open/read/close? Ultimately, I just need to read the contents of the file for the rest of the code to use. I tried looking for the mentioned
libposixcompat
library or documentation on it, but I can't find anything.The open() function results in the file getting downloaded into the browser's downloadsThis is not supposed to happen, and it is also extremely unclear to me how that could ever happen. Please send me another build.
open/read/closeThey are posix APIs, nothing fancy Also in this case the error is pretty obvious The code is not calling the POSIX open method, which has signature
int open(const char *pathname, int flags)
It's calling the Web API client::open(const String&)
that opens a new browser tab
Please note that if you are not comfortable with using POSIX APIs you can use higher level constructs to access the files
For example fopen
, these all boils down to the same POSIX APIs that the library provides
using namespace client;
is not necessarily a great solution, since it does import in the global scope a very large number of APIs. Ultimately the using
statement is the main reason for this error to happen.Is there an include or namespace needed to help the compiler find the posix open()?
No, POSIX APIs are designed for C and hence are in the global namespace. Namespaces did not exists when they were designed.
You might try to use the
::open
syntax to clarify to the compiler that you are referring to the global namespace.First off, a big thank you for all your help in getting this going for me. (Just a quick note for posterity: file reading has to use 'readv()', not 'read()').
Next item: we have extensive debug/trace capability which I have currently adapted to send its output to the js console with 'printf()'. Normally, it just goes to a file descriptor. From the js console we can save to a file if needed -- and doing so will be needed so we can share the sometimes very large output with other and more easily search it, etc. Is there any way cheerp can facilitate saving this output more directly to a file? I understand browsers not allowing write access in general, but they do allow one to download a file to the downloads folder (or elsewhere). If we could get a file descriptor for that, or have a char buffer, or...?
No, there is no support for writing files of any sort in the current implementation we provide
It could be implemented, but it would require an ad-hoc project.
We have long term plans of significantly upgrade how much normal "syscalls" are supported out-of-the-box, but that will require some time.
Even if there is no builtin support at the library level, it does not mean that you could not build a solution at the application level. For example using the standard C library
fmemopen
or open_memstream
+ fprintf
which should all be supported