cpp icon indicating copy to clipboard operation
cpp copied to clipboard

Docs on publishing of header-only C++ libs (include in node c++ modules)

Open springmeyer opened this issue 8 years ago • 3 comments
trafficstars

rational

We are increasingly working on small node C++ modules that depend on header-only C++ libs. Node.js's Nan module has pioneered a best practice for how to include header only C++ libs in node C++ addons by simply adding a package.json and include_dirs.js file to the root of the project. I think we should follow the lead of howNan does this and package all our C++ header only libs in npm as well as mason. I think publishing in two places is worth it because it makes including the libraries from node modules very easy and consistent with how JS modules work.

method

Add:

  • package.json
  • include_dirs.js
  • files parameter to package.json so that only the include/ directory is included

Example:

{
    "name": "@mapbox/geometry-hpp",
    "version": "0.9.0",
    "description": "A C++ header only geometry type library",
    "main": "./include_dirs.js",
    "repository"   :  {
      "type" : "git",
      "url"  : "git://github.com/mapbox/geometry.hpp.git"
    },
    "files": [
         "include"
    ]
}

Then test that only the right files are going to be packaged:

npm pack
tar -ztvf *tgz

^^ that should list just the headers and the default files npm includes like README.md and package.json etc

Examples:

  • https://github.com/mapbox/protozero/pull/59
  • https://github.com/osmcode/libosmium/pull/186

Example use case:

  • https://github.com/springmeyer/node-osmium-count/blob/master/package.json#L17

springmeyer avatar Jan 10 '17 21:01 springmeyer

The drawbacks of publishing C++ header-only libs in npm are:

  • These modules get installed into node_modules even when deployment is done with binaries (and they are essentially unused in that case)
  • Publishing two places adds burden for C++ maintainers
  • More likelihood of package name clashes like https://github.com/mapbox/vector-tile-js/issues/52 when ports of similar functionality are named similarly (by design) and published to the same place.

These are downsides enough that npm publishing of C++ headers is not the ideal method / best practice at Mapbox.

Instead we'll need to come up with some other method to recommend and consistently use via node c++ modules, like using a shell script + mason like carmen-cache does to install rocksdb (https://github.com/mapbox/carmen-cache/blob/1aaf88413be2243e3e3c772b1a9c777ea527578c/binding.gyp#L3-L16 + https://github.com/mapbox/carmen-cache/blob/4182501f748e2ca2635485cbd51e17b6c49329f1/install_mason.sh. This would have the added benefit that it would work for both header only libs and dependencies that are precompiled libs.

springmeyer avatar Jan 12 '17 00:01 springmeyer

Nice @springmeyer! You may have a look over at hpp-skel as well, which implements some of the features you mention above. The README has a brief description of publishing as well.

https://github.com/mapbox/hpp-skel

mapsam avatar Jan 26 '17 18:01 mapsam

Instead we'll need to come up with some other method to recommend and consistently use via node c++ modules, like using a shell script + mason like carmen-cache does

This is now implemented in node-cpp-skel. To recap the idea is:

  • We no longer publish any header only C++ projects to npm
  • We only publish to mason
  • To include these header only C++ projects we integration mason into the node build system
  • An example of this is now built into node-cpp-skel: https://github.com/mapbox/node-cpp-skel/pull/43

Now that the best practice is in place the remaining actions are:

  • Unblock this approach working on windows by solving https://github.com/mapbox/mason/issues/396
  • Document this as a best practice

springmeyer avatar Jun 30 '17 22:06 springmeyer