Skip to content

Using node-gyp (Experimental)

Currently node-gyp works on Linux only and don't support static library linking in cross-compiling. There are opened PRs to try to make node-gyp work fine.

If you experienced issues on Windows or macOS, please check the PRs for upstream changes detail and see emnapi-node-gyp-test for examples.

  • Variables

Arch: node-gyp configure --arch=<wasm32 | wasm64>

ts
// node-gyp configure -- -Dvariable_name=value

declare var OS: 'emscripten' | 'wasi' | 'unknown' | ''

/**
 * Enable async work and threadsafe-functions
 * @default 0
 */
declare var wasm_threads: 0 | 1

/** @default 1048576 */
declare var stack_size: number

/** @default 16777216 */
declare var initial_memory: number

/** @default 2147483648 */
declare var max_memory: number

/** @default path.join(path.dirname(commonGypiPath,'./dist/library_napi.js')) */
declare var emnapi_js_library: string

/** @default 0 */
declare var emnapi_manual_linking: 0 | 1
// node-gyp configure -- -Dvariable_name=value

declare var OS: 'emscripten' | 'wasi' | 'unknown' | ''

/**
 * Enable async work and threadsafe-functions
 * @default 0
 */
declare var wasm_threads: 0 | 1

/** @default 1048576 */
declare var stack_size: number

/** @default 16777216 */
declare var initial_memory: number

/** @default 2147483648 */
declare var max_memory: number

/** @default path.join(path.dirname(commonGypiPath,'./dist/library_napi.js')) */
declare var emnapi_js_library: string

/** @default 0 */
declare var emnapi_manual_linking: 0 | 1
  • Create binding.gyp
py
{
  "targets": [
    {
      "target_name": "hello",
      "sources": [
        "hello.c"
      ],
      "conditions": [
        ["OS == 'emscripten'", {
          "product_extension": "js", # required

          # Windows and Linux
          "cflags": [],
          "cflags_c": [],
          "cflags_cc": [],
          "ldflags": [],

          # macOS uses following config
          'xcode_settings': {
            "WARNING_CFLAGS": [], # cflags
            "OTHER_CFLAGS": [], # cflags_c
            "OTHER_CPLUSPLUSFLAGS": [], # cflags_cc
            "OTHER_LDFLAGS": [] # ldflags
          }
        }],
        ["OS == 'wasi'", {
          # ...
        }],
        ["OS == 'unknown' or OS == ''", {
          # ...
        }]
      ]
    }
  ]
}
{
  "targets": [
    {
      "target_name": "hello",
      "sources": [
        "hello.c"
      ],
      "conditions": [
        ["OS == 'emscripten'", {
          "product_extension": "js", # required

          # Windows and Linux
          "cflags": [],
          "cflags_c": [],
          "cflags_cc": [],
          "ldflags": [],

          # macOS uses following config
          'xcode_settings': {
            "WARNING_CFLAGS": [], # cflags
            "OTHER_CFLAGS": [], # cflags_c
            "OTHER_CPLUSPLUSFLAGS": [], # cflags_cc
            "OTHER_LDFLAGS": [] # ldflags
          }
        }],
        ["OS == 'wasi'", {
          # ...
        }],
        ["OS == 'unknown' or OS == ''", {
          # ...
        }]
      ]
    }
  ]
}
  • Add the following environment variables.
bash
# Linux or macOS
export GYP_CROSSCOMPILE=1

# emscripten
export AR_target="$EMSDK/upstream/emscripten/emar"
export CC_target="$EMSDK/upstream/emscripten/emcc"
export CXX_target="$EMSDK/upstream/emscripten/em++"

# wasi-sdk
export AR_target="$WASI_SDK_PATH/bin/ar"
export CC_target="$WASI_SDK_PATH/bin/clang"
export CXX_target="$WASI_SDK_PATH/bin/clang++"
# Linux or macOS
export GYP_CROSSCOMPILE=1

# emscripten
export AR_target="$EMSDK/upstream/emscripten/emar"
export CC_target="$EMSDK/upstream/emscripten/emcc"
export CXX_target="$EMSDK/upstream/emscripten/em++"

# wasi-sdk
export AR_target="$WASI_SDK_PATH/bin/ar"
export CC_target="$WASI_SDK_PATH/bin/clang"
export CXX_target="$WASI_SDK_PATH/bin/clang++"
bat
@REM Windows

set GYP_CROSSCOMPILE=1

@REM emscripten
call set AR_target=%%EMSDK:\=/%%/upstream/emscripten/emar.bat
call set CC_target=%%EMSDK:\=/%%/upstream/emscripten/emcc.bat
call set CXX_target=%%EMSDK:\=/%%/upstream/emscripten/em++.bat

@REM wasi-sdk
call set AR_target=%%WASI_SDK_PATH:\=/%%/bin/ar.exe
call set CC_target=%%WASI_SDK_PATH:\=/%%/bin/clang.exe
call set CXX_target=%%WASI_SDK_PATH:\=/%%/bin/clang++.exe
@REM Windows

set GYP_CROSSCOMPILE=1

@REM emscripten
call set AR_target=%%EMSDK:\=/%%/upstream/emscripten/emar.bat
call set CC_target=%%EMSDK:\=/%%/upstream/emscripten/emcc.bat
call set CXX_target=%%EMSDK:\=/%%/upstream/emscripten/em++.bat

@REM wasi-sdk
call set AR_target=%%WASI_SDK_PATH:\=/%%/bin/ar.exe
call set CC_target=%%WASI_SDK_PATH:\=/%%/bin/clang.exe
call set CXX_target=%%WASI_SDK_PATH:\=/%%/bin/clang++.exe
  • Build
bash
# Linux or macOS

# emscripten
emmake node-gyp rebuild \
  --arch=wasm32 \
  --nodedir=./node_modules/emnapi \
  -- -f make-linux -DOS=emscripten # -Dwasm_threads=1

# wasi
node-gyp rebuild \
  --arch=wasm32 \
  --nodedir=./node_modules/emnapi \
  -- -f make-linux -DOS=wasi # -Dwasm_threads=1

# bare wasm32
node-gyp rebuild \
  --arch=wasm32 \
  --nodedir=./node_modules/emnapi \
  -- -f make-linux -DOS=unknown # -Dwasm_threads=1
# Linux or macOS

# emscripten
emmake node-gyp rebuild \
  --arch=wasm32 \
  --nodedir=./node_modules/emnapi \
  -- -f make-linux -DOS=emscripten # -Dwasm_threads=1

# wasi
node-gyp rebuild \
  --arch=wasm32 \
  --nodedir=./node_modules/emnapi \
  -- -f make-linux -DOS=wasi # -Dwasm_threads=1

# bare wasm32
node-gyp rebuild \
  --arch=wasm32 \
  --nodedir=./node_modules/emnapi \
  -- -f make-linux -DOS=unknown # -Dwasm_threads=1
bat
@REM Use make generator on Windows
@REM Run the bat file in POSIX-like environment (e.g. Cygwin)

@REM emscripten
call npx.cmd node-gyp configure --arch=wasm32 --nodedir=./node_modules/emnapi -- -f make-linux -DOS=emscripten
call emmake.bat make -C %~dp0build

@REM wasi
call npx.cmd node-gyp configure --arch=wasm32 --nodedir=./node_modules/emnapi -- -f make-linux -DOS=wasi
make -C %~dp0build

@REM bare wasm32
call npx.cmd node-gyp configure --arch=wasm32 --nodedir=./node_modules/emnapi -- -f make-linux -DOS=unknown
make -C %~dp0build
@REM Use make generator on Windows
@REM Run the bat file in POSIX-like environment (e.g. Cygwin)

@REM emscripten
call npx.cmd node-gyp configure --arch=wasm32 --nodedir=./node_modules/emnapi -- -f make-linux -DOS=emscripten
call emmake.bat make -C %~dp0build

@REM wasi
call npx.cmd node-gyp configure --arch=wasm32 --nodedir=./node_modules/emnapi -- -f make-linux -DOS=wasi
make -C %~dp0build

@REM bare wasm32
call npx.cmd node-gyp configure --arch=wasm32 --nodedir=./node_modules/emnapi -- -f make-linux -DOS=unknown
make -C %~dp0build

Released under the MIT License.