cpp
cpp copied to clipboard
Docs on publishing of header-only C++ libs (include in node c++ modules)
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
filesparameter topackage.jsonso that only theinclude/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
The drawbacks of publishing C++ header-only libs in npm are:
- These modules get installed into
node_moduleseven 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.
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
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