Skip to content

Latest commit

 

History

History
240 lines (201 loc) · 10.9 KB

File metadata and controls

240 lines (201 loc) · 10.9 KB

cppjs.config.js — Build-time Configuration

Build-time only. Read once by the cppjs build CLI. NOT consumed at runtime. Runtime configuration lives in init.md.

Every consumer (app or library) writes a cppjs.config.js at the project root. It declares dependencies, source paths, build target, and export shape — everything the CLI needs to compile and package your C++.

Shape

export default {
  // ─────────────────────────────────────────────────────────────
  // General identity
  // ─────────────────────────────────────────────────────────────
  general: {
    name: 'myapp',
      // Logical app/lib name. Used for:
      //   - Output binary names (lib<name>.a, <name>.xcframework)
      //   - Browser fs namespace: /opfs/<name>/, /memfs/<name>/
      // Defaults to fixPackageName(package.json.name) or 'cppjssample'.
  },

  // ─────────────────────────────────────────────────────────────
  // Other cpp.js packages this project depends on
  // ─────────────────────────────────────────────────────────────
  dependencies: [],
    // Array of cppjs.config.js values, imported from @cpp.js/package-*.
    // Example:
    //   import gdal from '@cpp.js/package-gdal/cppjs.config.js'
    //   dependencies: [gdal]
    //
    // Transitive deps are automatically flattened into config.allDependencies.
    // If ANY dep declares target.runtime === 'mt', this project auto-promotes
    // to 'mt' too.

  // ─────────────────────────────────────────────────────────────
  // Paths (all relative to paths.project; see resolution rules below)
  // ─────────────────────────────────────────────────────────────
  paths: {
    config: import.meta.url,
      // ALWAYS SET THIS. Anchors all relative paths to this file's location.

    project: undefined,
      // Project root. Defaults to the dir of paths.config (or cwd if neither set).

    base: undefined,
      // Alternative project root override. Used by samples to point above
      // the workspace boundary in the monorepo.

    cache:  '.cppjs',                 // build cache root
    build:  '.cppjs/build',           // staging dir
    output: '.cppjs/build',           // dist artifacts (defaults to build)

    native: ['src/native'],
      // ARRAY. C++ source roots. Order matters for include precedence.

    module: undefined,                // SWIG .i interfaces; defaults to native
    header: undefined,                // headers; defaults to native
    bridge: undefined,                // bridge code; defaults to [...native, build]
    cmake:  undefined,                // override CMakeLists.txt path
  },

  // ─────────────────────────────────────────────────────────────
  // File extension filters
  // ─────────────────────────────────────────────────────────────
  ext: {
    header: ['h', 'hpp', 'hxx', 'hh'],
    source: ['c', 'cpp', 'cxx', 'cc'],
    module: ['i'],   // SWIG interfaces
  },

  // ─────────────────────────────────────────────────────────────
  // Export (output) settings
  // ─────────────────────────────────────────────────────────────
  export: {
    type: 'cmake',
      // Currently 'cmake' is the only fully-supported value.

    header:  'include',          // include dir name in dist
    libPath: 'lib',              // .a output dir
    libName: ['<general.name>'], // .a basenames; one per item
    binHeaders: [],              // headers to ship as raw binary blobs
  },

  // ─────────────────────────────────────────────────────────────
  // Build target / runtime
  // ─────────────────────────────────────────────────────────────
  target: {
    runtime: 'st',
      // 'st' (single-threaded) | 'mt' (multi-threaded WASM)
      // 'mt' requires SharedArrayBuffer + COOP/COEP in browser production.
      // See threading.md for the full requirements.
      //
      // Auto-promotes to 'mt' if any item in `dependencies` is 'mt'.
  },

  targetSpecs: [
    {
      // Filter (any combination — entry matches if all set fields match)
      platform:   'wasm' | 'android' | 'ios',     // optional
      arch:       'wasm32' | 'wasm64' | 'arm64-v8a' | 'x86_64' | 'iphoneos' | 'iphonesimulator',
      runtime:    'st' | 'mt',
      buildType:  'release' | 'debug',
      runtimeEnv: 'browser' | 'node' | 'edge',

      // Overrides (apply when filter matches)
      specs: {
        cmake:         ['-DSOMETHING=ON'],         // -D flags appended to cmake configure
        emccFlags:     ['-sINITIAL_MEMORY=64MB'],  // -s/-O flags appended to emcc (wasm only)
        env:           { GDAL_NUM_THREADS: '0' },  // env vars passed to running Wasm + build env
        data:          { 'share/myapp': 'myapp/data' },  // bundle data files into .data preload
        ignoreLibName: ['libtiff_legacy'],         // suppress these .a names from link line
      },
    },
  ],
    // See `overrides.md` for the catalog of override mechanisms and when
    // to reach for `targetSpecs` vs `cppjs.build.js` hooks vs `extensions`.

  // ─────────────────────────────────────────────────────────────
  // Build hooks (merged from cppjs.build.js if present)
  // ─────────────────────────────────────────────────────────────
  build: {},
    // Don't write this here directly. Put hooks in cppjs.build.js — the
    // CLI auto-merges. See cppjs-build.md.

  // ─────────────────────────────────────────────────────────────
  // Plugin / extension system
  // ─────────────────────────────────────────────────────────────
  extensions: [
    {
      loadConfig: {
        after: (config) => { /* mutate resolved config after load */ },
      },
      buildWasm: {
        beforeBuild:        (emccFlags) => {},   // all wasm targets — mutate emccFlags array
        beforeBuildBrowser: (emccFlags) => {},   // browser runtimeEnv only
        beforeBuildEdge:    (emccFlags) => {},   // edge runtimeEnv only
        beforeBuildNodeJS:  (emccFlags) => {},   // node runtimeEnv only
      },
      createLib: {
        setFlagWithBuildConfig:    (buildEnv, cFlags, ldFlags) => {},  // tweak CFLAGS/LDFLAGS
        setFlagWithoutBuildConfig: (buildEnv) => {},                   // env-level override
      },
    },
  ],
    // Plugin objects with hooks at config-load and build-step boundaries.
    // Use only when sharing an override across multiple cpp.js packages —
    // for single-package needs, prefer `targetSpecs` or `cppjs.build.js`.
    // Real example: OpenSSL Android cert-injection extension.

  // ─────────────────────────────────────────────────────────────
  // Custom helper functions
  // ─────────────────────────────────────────────────────────────
  functions: {
    isEnabled: (target) => boolean,
      // Override the default "is this build target enabled?" check.
      // Default: returns true if the target's output binary already exists.
  },
}

Path resolution rules

Paths are resolved in this order (from loadConfig.js):

  1. paths.config is set → paths.project defaults to its parent dir.
  2. paths.project is set → resolved as absolute via getAbsolutePath.
  3. Neither set → falls back to process.cwd().

Then everything else (base, cache, build, output, native, module, header, bridge, cmake) is resolved against paths.project using getAbsolutePath(project, value).

This means: always set paths.config: import.meta.url at minimum. Without it, cppjs build invoked from a different cwd will resolve paths against the wrong root.

Examples

Minimal app (consumes a prebuilt package)

// cppjs.config.js
import gdal from '@cpp.js/package-gdal/cppjs.config.js'

export default {
  general: { name: 'my-geo-app' },
  dependencies: [gdal],
  paths: { config: import.meta.url },
}

Multithread browser app

import gdal from '@cpp.js/package-gdal/cppjs.config.js'

export default {
  general: { name: 'my-fast-app' },
  dependencies: [gdal],
  paths: { config: import.meta.url },
  target: { runtime: 'mt' },
  // Remember: prod host needs COOP/COEP headers.
}

Library wrapping your own C++

export default {
  general: { name: 'mylib' },
  paths: {
    config: import.meta.url,
    native: ['src/native'],
    output: 'dist',
  },
  export: {
    type: 'cmake',
    libName: ['mylib'],
  },
}

Monorepo sample (above-workspace project root)

import Matrix from '@cpp.js/sample-lib-prebuilt-matrix/cppjs.config.js'

export default {
  general: { name: 'cppjs-sample-web-vue-vite' },
  dependencies: [Matrix],
  paths: {
    config: import.meta.url,
    base: '../..',  // points above the workspace boundary
  },
}

See also

  • init.md — runtime API. cppjs.config.js produces the artifacts that initCppJs(opts) loads.
  • cppjs-build.md — sibling file used by package authors only.
  • threading.mdtarget.runtime: 'mt' requirements.
  • ADR-0002 — pnpm topological build order via dependencies.
  • ADR-0003 — function-typed env values.