Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add target_modules_version variable into generated config.gypi file #855

Closed
wants to merge 4 commits into from

Conversation

pmed
Copy link
Contributor

@pmed pmed commented Jan 7, 2016

It may be handy to have multiple native addon binaries for several Node.js versions (i.e. 0.12, 4.X, 5.X). Node.js has a value for the native modules version as process.versions.modules.

A particular C++ addon can be loaded in JavaScript depending on Node.js version like this:

  // loads 'addon_win32_x64_m47.node' for Node.js 5.0 on Windows x64
  // loads 'addon_linux_x64_m46.node' for Node.js 4.X on Linux x64
  var native = require('addon' + process.platform + '_'
              + process.arch + '_m' + process.versions.modules + '.node');

The target binary file name should be set with product_name directive in binding.gyp file in a such way:

  {
    'targets': [
      {
        'product_name': 'addon_<(target_platform)_<(target_arch)_m<(target_modules_version)'
        ... # rest of GYP directives
      }
    ]
  }

where target_platform is a configuration variable with value from Node.js process.platform property.

But the process.versions.modules value can't be used for target_modules_version since node-gyp can build targets for different Node.js versions specified with a --target command-line option.

To resolve this issue, a function getModulesVersion() was added on configure step to get a value of NODE_MODULE_VERSION defined in node_version.h file in a supplied directory with Node.js development files.


for (var i = 0; i < sources.length; ++i) {
try {
var source = fs.readFileSync(sources[i], { encoding: 'utf8'})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The try/catch should only be around this statement. Style nit: space before }.

@bnoordhuis
Copy link
Member

Can you add a couple of regression tests? You'll probably need to adjust the logic a little so you can test it without trying to read from disk (or make it use fixtures somehow.)

@pmed
Copy link
Contributor Author

pmed commented Jan 8, 2016

Reworked getModulesVersion() to read a particular file, depending on the target Node.js version.

No tests were added yet, because I don't know how to make appropriate fixtures for them.

@saper
Copy link
Contributor

saper commented Jan 8, 2016

Ideally this should be provided by node itself in it's config.gypi file.

pmed added 3 commits June 20, 2016 14:12
It may be handy to have multiple native addon binaries for several
Node.js versions (i.e. 0.12, 4.X, 5.X). Node.js has a value for the
native modules version as `process.versions.modules`.

A particular C++ addon can be loaded in JavaScript depending on Node.js
version like this:

  // loads 'addon_win32_x64_m47.node' for Node.js 5.0 on Windows x64
  // loads 'addon_linux_x64_m46.node' for Node.js 4.X on Linux x64
  var native = require(addon' + process.platform + '_'
              + process.arch + '_m' + process.versions.modules + '.node');

The target binary file name should be set with `product_name` directive
in binding.gyp file in a such way:

  {
    'targets': [
      {
        'product_name': 'addon_<(target_platform)_<(target_arch)_m<(target_modules_version)'
        ... # rest of GYP directives
      }
    ]
  }

where `target_platform` is a configuration variable with value from
Node.js `process.platform` property.

But the `process.versions.modules` value can't be used for `target_modules_version`
since node-gyp can build targets for different Node.js versions specified with
a `--target` command-line option.

To resolve this issue, a function getModulesVersion() was added on `configure`
step to get a value of `NODE_MODULE_VERSION` defined in `node_version.h` file
in a supplied directory with Node.js development files.
Use value of release.semver to determinate file name and location with NODE_MODULE_VERSION define,
and to read this file depending on target Node.js version.

Tested with Node.js versions: 0.8.4, 0.10.25, 0.11.4, 0.11.5, 0.12.0, iojs-1.0.0, iojs-2.0.0, iojs-3.0.0, 4.X, 5.X

Added verbose log messages for the target_arch, target_platform, and target_modules_version variables.
Rename getModulesVersion to nodeModulesVersion function and move it out of
configure() function for testing purpose. Expose nodeModulesVersion() function
in  `configure.test` to call it tests.

Run tests for the current Node release and for all installed targets.
@pmed
Copy link
Contributor Author

pmed commented Jun 20, 2016

Renamed function to nodeModulesVersion() added tests for it.

@pmed
Copy link
Contributor Author

pmed commented Jul 16, 2016

@bnoordhuis could you review recent changes please?


// set the target modules version
variables.target_modules_version = nodeModulesVersion(nodeDir)
log.verbose('build/' + configFilename, 'modules version: ' + variables.target_modules_version)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you wrap lines at 80 columns? I realize there are long lines elsewhere but I'd like to avoid introducing new ones.

@bnoordhuis
Copy link
Member

This needs more tests, there are quite a few cases that aren't covered yet. For example, the use case of node-gyp --nodedir /path/to/master configure (i.e., no version number in the path) should be tested because I'm quite sure that's broken now.

If you make the fs.readFileSync call pluggable, e.g. by making it an optional argument to nodeModulesVersion(), you can unit test it more easily.

@pmed
Copy link
Contributor Author

pmed commented Jul 16, 2016

@bnoordhuis thank you very much! I will think on more tests.

'target arch: ' + variables.target_arch)

// set the target_platform variable
variables.target_platform = process.platform
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should allow manual override here as well? What about cross-platform builds?

@bnoordhuis
Copy link
Member

needs more tests, there are quite a few cases that aren't covered yet

Something that just came to mind: building for electron / nw.js / node-webkit.

Also, it's perhaps worth pointing out that node.js v6.3.0 introduced the node_module_version gyp variable, at least partially obviating this PR.

@saper
Copy link
Contributor

saper commented Jul 17, 2016

@bnoordhuis do you think that node_module_version will be backported to the older release trains?

@bnoordhuis
Copy link
Member

Maybe to v4 but not to v0.10 and v0.12. Those are near their end of life anyway, though.

@MylesBorins
Copy link
Contributor

@bnoordhuis should we open an issue on @nodejs/lts?

@bnoordhuis
Copy link
Member

@thealphanerd Sure, go ahead.

@saper
Copy link
Contributor

saper commented Jul 20, 2016

Having this in some final releases of 0.10 and 0.12 would be ultra cool.

Actually this patch could become a separate npm module which kicks in as a fallback if module version is not available via the gypi files.

@bnoordhuis
Copy link
Member

The node_modules_version variable was introduced as a set of bigger changes that make it possible to build node as a shared library. That is not going to get back-ported but if you want to take a stab at back-porting just the variable, you're welcome.

Caveat emptor though, v0.10 and v0.12 are in maintenance mode. Normally only security fixes and critical fixes are accepted but since node_modules_version is useful for building add-ons across versions, I think we can make an exception.

saper added a commit to saper/node that referenced this pull request Aug 18, 2016
Enable targetting of a different node version than
the currently running one when building binary modules.

Based on nodejs/node@410296c37

PR-URL: nodejs#7808
Ref: nodejs/node-gyp#855
saper added a commit to saper/node that referenced this pull request Aug 18, 2016
Enable targetting of a different node version than
the currently running one when building binary modules.

Based on nodejs/node@410296c37

PR-URL: nodejs#8027
Ref: nodejs#7808
Ref: nodejs/node-gyp#855
saper added a commit to saper/node that referenced this pull request Aug 19, 2016
Enable targetting of a different node version than
the currently running one when building binary modules.

Based on nodejs/node@410296c37

PR-URL: nodejs#8171
Ref: nodejs#8027
Ref: nodejs#7808
Ref: nodejs/node-gyp#855
jasnell pushed a commit to nodejs/node that referenced this pull request Aug 22, 2016
Enable targetting of a different node version than
the currently running one when building binary modules.

Based on 410296c37

PR-URL: #8171
Ref: #8027
Ref: #7808
Ref: nodejs/node-gyp#855
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
MylesBorins pushed a commit to nodejs/node that referenced this pull request Sep 28, 2016
Enable targetting of a different node version than
the currently running one when building binary modules.

Based on 410296c37

PR-URL: #8171
Ref: #8027
Ref: #7808
Ref: nodejs/node-gyp#855
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
@bnoordhuis
Copy link
Member

@pmed Do you think this PR is still necessary?

@pmed
Copy link
Contributor Author

pmed commented Oct 7, 2016

As I understand, the variable node_module_version has been added into config.gypi in Node versions 4.x and 6.x

I think there is no more need to do the same thing in node-gyp, so let's close this PR.

@bnoordhuis
Copy link
Member

Okay thanks, I'll close.

@bnoordhuis bnoordhuis closed this Oct 7, 2016
rvagg pushed a commit to nodejs/node that referenced this pull request Oct 18, 2016
Enable targetting of a different node version than
the currently running one when building binary modules.

Based on 410296c37

PR-URL: #8171
Ref: #8027
Ref: #7808
Ref: nodejs/node-gyp#855
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
MylesBorins pushed a commit to nodejs/node that referenced this pull request Oct 26, 2016
Enable targetting of a different node version than
the currently running one when building binary modules.

Based on 410296c37

PR-URL: #8171
Ref: #8027
Ref: #7808
Ref: nodejs/node-gyp#855
Reviewed-By: Ben Noordhuis <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
saper added a commit to saper/node that referenced this pull request Dec 20, 2016
Enable targetting of a different node version than
the currently running one when building binary modules.

Based on nodejs/node@410296c37

PR-URL: nodejs#8027
Ref: nodejs#7808
Ref: nodejs/node-gyp#855
bnoordhuis pushed a commit to bnoordhuis/io.js that referenced this pull request Dec 20, 2016
Enable targetting of a different node version than
the currently running one when building binary modules.

Based on nodejs/node@410296c37

PR-URL: nodejs#8027
Ref: nodejs#7808
Ref: nodejs/node-gyp#855
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants