{"id":17359124,"url":"https://github.com/nathanjhood/napiaddon","last_synced_at":"2025-03-27T16:17:20.175Z","repository":{"id":218816386,"uuid":"747384095","full_name":"nathanjhood/NapiAddon","owner":"nathanjhood","description":"Deprecated - please see my fork of cmake-js for the full implementation proposal instead (link below)","archived":false,"fork":false,"pushed_at":"2024-02-20T11:22:07.000Z","size":273,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-01T19:45:03.152Z","etag":null,"topics":["api","bindings","cmake","cmake-js","cpp","javascript","napi","node","node-addon","node-addon-api","nodejs","typescript"],"latest_commit_sha":null,"homepage":"","language":"CMake","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nathanjhood.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-23T20:25:27.000Z","updated_at":"2024-09-24T14:20:55.000Z","dependencies_parsed_at":null,"dependency_job_id":"7f29b2d0-570e-4ad6-be94-db2f93af850c","html_url":"https://github.com/nathanjhood/NapiAddon","commit_stats":null,"previous_names":["nathanjhood/napiaddon"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanjhood%2FNapiAddon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanjhood%2FNapiAddon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanjhood%2FNapiAddon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nathanjhood%2FNapiAddon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nathanjhood","download_url":"https://codeload.github.com/nathanjhood/NapiAddon/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245878925,"owners_count":20687297,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","bindings","cmake","cmake-js","cpp","javascript","napi","node","node-addon","node-addon-api","nodejs","typescript"],"created_at":"2024-10-15T19:08:15.826Z","updated_at":"2025-03-27T16:17:20.153Z","avatar_url":"https://github.com/nathanjhood.png","language":"CMake","readme":"# NapiAddon\n\n## Deprecated - [please see my fork of cmake-js for the full implementation proposal instead](https://github.com/nathanjhood/cmake-js/blob/master/share/cmake/README.md)\n\n[A proposed CMake API for cmake-js v8](https://github.com/cmake-js/cmake-js/issues/310) (including a demo consumer project).\n\n![CTest](https://github.com/nathanjhood/NapiAddon/actions/workflows/test.yaml/badge.svg)\n\nThe file of interest here is the one named [```CMakeJS.cmake```](https://github.com/nathanjhood/NapiAddon/blob/main/CMakeJS.cmake) - this file is a CMake module that builders can append to their project's ```CMAKE_MODULE_PATH```, and then easily create a new NodeJS C++ Addon as a CMake target by using [```cmakejs_create_napi_addon(\u003cNAME\u003e \u003cSOURCES\u003e)```](https://github.com/nathanjhood/NapiAddon/tree/main#minimal-setup), which creates a target with all the reasonable defaults taken care of for building a Napi Addon - but, intermediate/advanced users still have scope to override any of these defaults by using the usual ```target_compile_definitions()``` and such forth on their Addon target(s), if they so wish.\n\nThe proposed API also does not clash with any pre-existing projects, by not imposing itself on users unless they specifically call the function within their build script. Adoption of this proposed API would be entirely optional, and especially helpful for newcomers.\n\n```CMakeJS.cmake``` is fully compatible with the latest cmake-js release without any changes to source.\n\n## Minimal setup\n\nBuilders are able to get Addons to compile and run using a very minimal CMake build script:\n\n```.cmake\n# CMakeLists.txt\n\ncmake_minimum_required(VERSION 3.15)\n\n# path to CMakeJS.cmake\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_LIST_DIR}\")\n\ninclude(CMakeJS)\n\nproject (demo)\n\ncmakejs_create_napi_addon(\n  # NAME\n  addon\n  # SOURCES\n  src/demo/addon.cpp\n)\n\n```\n\n... and that's all you need!\n\n## Extended functionality\n\nThe module strives to be unopinionated by providing reasonable fallback behaviours that align closely with typical, expected CMake building conventions.\n\nOptionally, more Addon targets can be created from this API under one single project tree, and helpful variables may also be configured:\n\n```.cmake\ncmakejs_create_napi_addon (\n  # The 'NAME' arg given to the addon target defines 'CMAKEJS_ADDON_NAME'\n  addon_v7\n  # The 'NAPI_VERSION' arg defines 'NAPI_VERSION' directly. If not set, defaults to 8.\n  NAPI_VERSION 7\n  # The 'NAMESPACE' arg defines 'NAPI_CPP_CUSTOM_NAMESPACE'. If not set, the addon target name is used instead.\n  NAMESPACE v7\n  # The 'ALIAS' arg defines 'CMAKEJS_ADDON_ALIAS' for an alias target name. If not set, 'NAPI_CPP_CUSTOM_NAMESPACE' is used instead.\n  ALIAS addon::v7\n)\n\ncmakejs_napi_addon_add_sources (addon_v7\n  # Specify an exact directory for this addon's SOURCES\n  BASE_DIRS \"${PROJECT_SOURCE_DIR}/src\"\n  src/demo/addon.cpp\n)\n\ncmakejs_napi_addon_add_definitions (addon_v7\n  # 'PRIVATE', 'PUBLIC', and 'INTERFACE' definitions are all supported.\n  PRIVATE\n  # The Napi Addon API has several other useful pre-processor definitions.\n  # These can be specified here. Example:\n  NAPI_CPP_EXCEPTIONS_MAYBE\n  # (See '\u003cNapi.h\u003e' source file for the default exceptions policy handling.)\n)\n```\n\n## Backwards compatible\n\nProjects built with cmake-js that don't consume this proposed API would not be affected at all by this module's existence. So, the previous 'manual' way of creating addons with cmake-js will still work, and can even be mixed with targets that use the new API, under the same project tree. Even if the functions are not adopted, builders can still get a little extra help by linking with the ```cmake-js::cmake-js``` interface library:\n\n```.cmake\n# including the module will automatically make 'cmake-js::cmake-js' available...\ninclude(CMakeJS)\n\nadd_library(addon_v6 SHARED src/demo/addon.cpp)\nset_target_properties(addon_v6 PROPERTIES PREFIX \"\" SUFFIX \".node\")\ntarget_link_libraries(addon_v6 PRIVATE cmake-js::cmake-js) # link to resolve all dependencies!\n```\n\nThe above target should build, while leaving the rest of the target's manual implementation up to the builder.\n\n## Builds with either cmake-js or CMake\n\nAll that it takes to compile and run the above minimal build script is to call cmake-js from ```package.json```:\n\n```.sh\n$ npm run install\n```\n\nor\n\n```.sh\n$ yarn install\n```\n\n*However*, the ```CMakeJS.cmake``` script does *not depend on being executed by cmake-js*, and can build addons independently of npm/yarn, using just native CMake commands (see ```package.json``` for some more):\n\n```.sh\n$ cmake --fresh -S . -B ./build\n\n# ...\n\n$ cmake --build ./build\n```\n\nBecause of the above, IDE tooling integration should also be assured.\n\n## CTest and CPack\n\nCTest and CPack have also been carefully tested against the demo project, to confirm the proposed API's ability to support both.\n\n```.sh\n$ ctest -B ./build\n\n# addon tests output...\n```\n\n```.sh\n$ cpack -B ./build --config CPackConfig.cmake\n\n# doing zip/tar of addon build....\n\n$ cpack -B ./build --config CPackSourceConfig.cmake\n\n# doing zip/tar of addon source code....\n```\n\nSee [```package.json```](https://github.com/nathanjhood/NapiAddon/blob/main/package.json) for more native CMake/CTest/CPack commands, and how to automate them.\n\n## Deeper CMake integration\n\nBy exporting an interface library under cmake-js' own namespace - ```cmake-js::cmake-js```, the CMakeJS.cmake file can easily be shipped in the cmake-js package tree, making the NodeJS Addon API automatically available to builders by simply having the cmake-js CLI pass in ```-DCMAKE_MODULE_PATH:PATH=/path/to/CMakeJS.cmake```, as well as providing the usual/expected means of integration with vcpkg, and other conventional CMake module consumers.\n\nBuilders will also find that their cmake-js - powered Addon targets also work well with CMake's ```export()``` and ```install()``` routines, meaning that their Addon projects also work as CMake modules.\n\n```CMakeJS.cmake``` exports the following CMake targets for linkage options:\n\n```\ncmake-js::node-dev        // The NodeJS system installation developer files\ncmake-js::node-api        // The C Addon API\ncmake-js::node-addon-api  // The C++ Addon API\ncmake-js::cmake-js        // The full set of configured Addon API dependencies\n```\n\n## Intentions\n\n```CMakeJS.cmake``` as presented is rough/unrefined and missing several features it would be worth looking closer at (although quickly improving), but already presents a working UX proposal.\n\n```CMakeJS.cmake``` has been built against the latest releases of cmake-js and CMake, and tested against several LTS versions of NodeJS. No changes have been made to any of the existing source code for any other project; the API proposal is entirely contained within ```CMakeJS.cmake``` as a drop-in solution for building addons.\n\n## About the demo project\n\nAside from ```CMakeJS.cmake```, all other files here are presented solely as a 'hello world' demo of a 'typical' Node Addon project which uses the proposed ```CMakeJS.cmake``` API, from the perspective of an end-user. The ```CMakeLists.txt``` file which powers the demo build is kept intentionally minimal - 4 lines of CMake code is all that is required to build an Addon - to show the low barrier of entry, while additional (and entirely optional) extended functionality is also demonstrated as a further proof of concept.\n\nAs a bonus: it is possible to add this demo project to another NodeJS project, and watch it build itself automatically, showing the process is working fully. To do so, make a new NodeJS project, and add this repo's URL to the dependencies:\n\n```.json\n\"dependencies\": {\n  \"@nathanjhood/napi-addon\": \"https://github.com/nathanjhood/NapiAddon.git\"\n}\n```\n\nThen, try running the initial ```npm/yarn run install``` command as usual. The demo addon will be under ```node_modules/@nathanjhood/napi-addon/build/lib/addon.node``` ready for consuming.\n\nThe demo addon is then acquirable in your demo NodeJS project as you would expect:\n\n```.js\nconst nathan_napi_addon = require(\"@nathanjhood/napi-addon\")\n\nconsole.log(`Napi Status:  ${nathan_napi_addon.hello()}`);\nconsole.log(`Napi Version: ${nathan_napi_addon.version()}`);\n```\n\n### Some recent Napi Addons of mine\n\n- [nathanjhood/NodeRC](https://github.com/nathanjhood/noderc) - CMakeRC as a Napi Addon\n- [nathanjhood/base64](https://github.com/nathanjhood/base64) - An open-source base64 encode/decode tool as a Napi Addon\n- [hostconfig/modules](https://github.com/hostconfig/modules) - HTML content written and compiled in C++ served via Express as a Napi Addon\n\nHere is one using ```CMakeJS.cmake```'s targets and functions, alongside native CMake targets, in a single project.\n\n- [nathanjhood/njwt](https://github.com/nathanjhood/njwt) - JWT tool - under construction\n\nThanks for reading!\n\n[Nathan J. Hood](https://github.com/nathanjhood)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnathanjhood%2Fnapiaddon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnathanjhood%2Fnapiaddon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnathanjhood%2Fnapiaddon/lists"}