cmake-js

repository·master·Indexed 21 days ago

https://github.com/cmake-js/cmake-js

A Node.js native addon build tool that leverages the CMake build system as an alternative to node-gyp. It provides out-of-the-box support for Node.js (14.15+), NW.js, and Electron, and includes a CLI for managing the build lifecycle (configure, build, clean, compile). The tool supports Node-API and node-addon-api modules and can be configured via the command line, package.json, or npm config.

Tokens
7K
Snippets
21
Records
33
Agent score
75%

What's inside cmake-js

  1. Overview of CMake.js

    master

    CMake.js is a build tool for Node.js native addons that uses the CMake build system instead of gyp. It is designed to work similarly to node-gyp but provides better integration with CMake-based projects.

    Supported Runtimes

    • Node.js: Version 14.15+ (for older runtimes, use an earlier version of CMake.js).
    • NW.js: Compatible out-of-the-box without extra magic.
    • Electron: Out-of-the-box build support with no post-build steps required.

    Note: If your module uses node-api instead of nan, it can typically run on all the above runtimes without needing separate builds for each.

  2. Detect CMake.js in CMakeLists.txt

    master

    CMake.js provides a CMAKE_JS_VERSION variable. You can use this to conditionally include subdirectories or logic specifically for CMake.js based builds.

    if (CMAKE_JS_VERSION)
        add_subdirectory(node_addon)
    else()
        add_subdirectory(other_subproject)
    endif()
  3. Configure CMake.js via NPM config

    master

    CMake.js automatically picks up configuration from your .npmrc or NPM configuration. Any key starting with cmake_js_ is converted into a CLI option.

    • If the option name is a single character, it is treated as a short flag (e.g., cmake_js_d becomes -d).
    • Otherwise, it is treated as a long flag (e.g., cmake_js_directory becomes --directory).
    # In .npmrc
    cmake_js_debug=true
    cmake_js_runtime=node18
  4. Set up a new native module with CMake.js

    master

    To create a new native module using CMake.js, follow these steps:

    1. Install cmake-js: Add it as a dependency to your module.
      npm install --save cmake-js
    2. Create a CMakeLists.txt: Place this in your module root. A minimal configuration for a Node-API module looks like this:
      cmake_minimum_required(VERSION 3.15...3.31)
      project(your-addon-name-here)
      
      add_compile_definitions(NAPI_VERSION=4)
      
      file(GLOB SOURCE_FILES "your-source-files-location-here")
      
      add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})
      set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "" SUFFIX ".node")
      target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_JS_INC})
      target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_JS_LIB})
      target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
      
      if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
        # Generate node.lib
        execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
      endif()
    3. Configure package.json scripts: Add a compile command to your install script.
      "scripts": {
          "install": "cmake-js compile"
      }
    4. Configure package.json binary settings: For Node-API modules, specify the supported versions to skip downloading Node.js headers.
      "binary": {
          "napi_versions": [7]
      }
    npm install --save cmake-js
  5. Deploying to Heroku

    master

    Standard Node.js buildpacks on Heroku provide node-gyp but not CMake. To use CMake.js on Heroku, use the heroku-buildpack-multi facility.

    1. Set the application's buildpack to: https://github.com/heroku/heroku-buildpack-multi.git
    2. Create a .buildpacks file in your root directory with these two lines:
      https://github.com/brave/heroku-cmake-buildpack.git
      https://github.com/heroku/heroku-buildpack-nodejs.git
    3. Deploy your application.
    https://github.com/brave/heroku-cmake-buildpack.git
    https://github.com/heroku/heroku-buildpack-nodejs.git
  6. Compile Node-API and node-addon-api modules

    master

    Plain C Node-API

    To compile a module using only plain C Node-API calls, follow the standard node native module instructions.

    Windows Requirement: To ensure successful builds on Windows, you must include the following block in your CMakeLists.txt to generate node.lib:

    if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
      # Generate node.lib
      execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
    endif()

    C++ Wrapper (node-addon-api)

    To use the node-addon-api header-only C++ wrapper:

    1. Install the package: npm install --save node-addon-api.
    2. CMake.js will automatically add it to the include search path.
    3. Ensure your package.json includes the binary.napi_versions field so CMake.js knows to skip downloading Node.js headers:
    "binary": {
        "napi_versions": [7]
    }
  7. Electron and NW.js Compatibility

    master

    Electron

    On Windows, native modules require the win_delay_load_hook to be embedded to load correctly in the render process.

    How to enable: CMake.js will automatically add this hook if your CMakeLists.txt contains the library ${CMAKE_JS_SRC}.

    NW.js

    CMake.js modules are compatible with NW.js out-of-the-box. To make an NW.js application compatible with any NAN-based CMake.js modules, configure the application's package.json as follows:

    {
      "cmake-js": {
        "runtime": "nw",
        "runtimeVersion": "nw.js-version-here",
        "arch": "appropriate-architecture"
      }
    }
  8. Requirements for using CMake.js

    master

    To use CMake.js, you must have the following installed on your system:

    Core Requirements

    • CMake: The build system itself.
    • C/C++ Compiler Toolchain:
      • Windows: Visual C++ Build Tools. You can install these via the Node.js installer or via Chocolatey using choco install visualstudio2017-workload-vctools.
      • Unix/Posix: Clang or GCC, and Ninja or Make (Ninja is preferred if both are present).

    Windows Specifics

    If you have multiple versions of Visual Studio installed, you can select a specific version using npm configuration (this also affects node-gyp): npm config set msvs_version 2017

  9. Use the CMake.js CLI

    master

    The cmake-js CLI is the primary interface for managing the lifecycle of a C++ Node.js addon project. It handles installing Node.js distribution files, configuring CMake projects, building, cleaning, and more. If no command is provided, it defaults to build.

    # Build the project (default command)
    cmake-js build
    
    # Install Node.js distribution files
    cmake-js install
    
    # Configure the project
    cmake-js configure
    
    # Clean the project directory
    cmake-js clean
  10. Pass custom arguments to CMake

    master

    To pass custom definitions to the underlying CMake process, use the --CD flag with an equals sign. The format must be --CD<key>=<value>.

    # Example: Passing a custom CMake definition
    cmake-js build --CDMY_CUSTOM_OPTION=ON
  11. Use NPM configuration for CMake settings

    master

    CMake.js automatically integrates with NPM configuration. Any NPM config setting prefixed with cmake_ is automatically converted into a CMake definition (-D).

    For example, an NPM config entry cmake_MY_SETTING=true will be passed to CMake as -D MY_SETTING=true.