crossbind
GitHub
GUIDE · CONCEPTS · ASSETS AND DATA FILES

Assets and data files

Plenty of C++ libraries refuse to work without their data: PROJ wants its coordinate database, GDAL its format tables, OpenSSL a CA bundle. Declare those files once in targetSpecs and they are copied to the right place on every platform, with the environment variables wired to match.

The shape

Each entry in targetSpecs is a filter plus overrides. The filter fields - platform, arch, runtime, buildType, runtimeEnv - are all optional; an entry applies to every build target that matches the fields you did set. specs.data copies files, specs.env sets environment variables inside the running module.

cppjs.config.js
export default {
paths: { config: import.meta.url },
targetSpecs: [
{
platform: 'wasm',
runtimeEnv: 'browser',
specs: {
data: { 'share/proj': '/usr/share/proj' },
env: { PROJ_LIB: '/usr/share/proj' },
},
},
{
platform: 'wasm',
runtimeEnv: 'node',
specs: {
data: { 'share/proj': 'proj' },
env: { PROJ_LIB: '_CPPJS_DATA_PATH_/proj' },
},
},
{
platform: 'android',
specs: {
data: { 'share/proj': 'proj' },
env: { PROJ_LIB: '_CPPJS_DATA_PATH_/proj' },
},
},
{
platform: 'ios',
specs: {
data: { 'share/proj': 'proj' },
env: { PROJ_LIB: '_CPPJS_DATA_PATH_/proj' },
},
},
],
};

How data paths resolve

In data, the key is where the files are in the build (share/proj), and the value is where they land on the target platform.

  • A value starting with / is an absolute path inside the module's virtual filesystem - /usr/share/proj in the browser example.
  • A value without a leading slash is relative to the platform's data directory, the one _CPPJS_DATA_PATH_ expands to.

That is why the browser entry differs from the others: in the browser everything lives in the virtual filesystem, while Node and mobile have a real directory on disk that the runtime resolves at load time.

Environment variables

specs.env values are passed into the wasm (or native) process, and _CPPJS_DATA_PATH_ inside any value is replaced with the runtime data path. Values can also be functions of (state, target) when the path is only known at build time - they resolve lazily and produce a string.

Runtime env can also be set per call, which is handy for anything that is not a build-time constant:

src/main.js
const m = await initNative({
env: { TMPDIR: '_CPPJS_DATA_PATH_/scratch' },
});

Assets that come with a package

A prebuilt package carries its own data declarations, so installing @cpp.js/package-proj brings the coordinate database and its PROJ_LIB wiring along with it. You only write targetSpecs for data of your own - or to override where a dependency's data goes.

WASI is the same declaration, different mechanics
On platform: 'wasi' the data and env entries double as the runtime contract for the command: data directories become --dir preopens and env becomes the guest environment, with _CPPJS_DATA_PATH_ pointing at the mounted directory. See WASI commands.

What else targetSpecs carries

The same entries are where per-target build flags live, which keeps every platform-specific tweak in one list:

KeyEffect
cmakeextra -D flags for the cmake configure step
emccFlagsextra flags for the emscripten link (wasm only)
wasiFlagsextra flags for the wasi command link
envenvironment variables for the build and the running module
datadata files to ship, as described above
ignoreLibNamedrop a specific .a from the link line

The full list of configuration keys is in Configuration.

Type to search every guide page and section.
↑↓ navigate↵ openesc close