-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Filesystem Guide
Emscripten allows you to set up a virtual filesystem that points to preloaded data, as well as virtual devices that can read and write data.
There are two basic ways to use the filesystem:
- Package some files with your build. You can just tell emcc to package a directory or a set of files, and those files will be accessible from the compiled code normally, using
fopen
etc. - Manually use the FS API from JavaScript. This lets you create, modify etc. files in a more manual manner.
For concrete examples of using the filesystem API, see the automatic tests in tests/runner.py
. Search for FS.
for find relevant tests, for example test_files. For specific examples of how to embed files that can be read from compiled C/C++, see for example the OpenJPEG test.
The simplest thing to do is just tell emcc to package files for you,
emcc file.cpp -o file.html --preload-file asset_dir
That command will generate file.html, and alongside it file.data which will contain all the files in asset_dir/
. You can then distribute your application with just those two files.
Assets can also be embedded directly into the html file:
emcc file.cpp -o file.html --embed-file asset_dir
When this is done with a relative path, the prefixes will remain the same in the file system. For example:
emcc file.cpp -o file.html --embed-file ../../asset_dir
Files will all be prefixed with ../../asset_dir/. To change this behavior, call emcc as follows:
emcc file.cpp -o file.html --embed-file ../../assets@/
This will package the files at the root of the file system.
You can also run the file packager manually, tools/file_packager.py
. See docs in that file. It generates a .data
file and .js
file, which contains the manual commands to utilize the data file (emcc --preload
just bundles that code in your normal generated output). You can then load that JavaScript before loading your main compiled code.
- Note that this lets you do the file packaging without running emcc to compile your code, the two processes are separated this way.
- Note also that you can load multiple datafiles. Just run the file packager on each and load the
.js
outputs. See BananaBread for an example of this (cube2/js/game-setup.js
).
It is important to only preload the files your app actually needs, to reduce download size and improve startup speed. There is an option to log all the actually used files during runtime, which you can use to figure out which files your app actually needs. To use it, define logReadFiles
on the Module object. Module.printErr
will then be called on each file that is read from, so you can define that function to log to a convenient place.
You can also look at FS.readFiles
, which will be an object whose keys are all the files that were read from. This might be easier to use than logging. Note that you can also modify the object, even remove it entirely. This can be useful in order to see which files are read between two points in time in your app, for example.
Checkout out the Filesystem API docs.
README.md ``