Skip to content

All: Add binary support for node 4 and 6 #103

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

Closed
wants to merge 1 commit into from

Conversation

gabrielschulhof
Copy link
Contributor

This is the first pass at achieving never-compile-again. I've tested it on Linux and I've made sure that it continues to work as before on Windows.

Many things can still be improved. For example, there is no need to build n-api-implem.node except when building via prebuild, however, I cannot distinguish in binding.gyp between a build initiated via npm install and a build initiated via prebuild.

@gabrielschulhof
Copy link
Contributor Author

@mcollina

@mcollina
Copy link
Member

mcollina commented Aug 5, 2017

This is fantastic work. If we could support windows as well, it would be superb. I will test this asap, have you got the prebuilts uploaded somewhere?

@gabrielschulhof
Copy link
Contributor Author

@mcollina prebuilds are kind of a problem, actually. As it stands, the binaries containing the N-API implementations for 4 and for 6 would show up as tarballs at https://github.com/nodejs/node-addon-api/releases and the npm install for this package would download them from there.

When I was testing this I forked the repo and changed all references to https://github.com/nodejs/node-addon-api in package.json to my personal clone at https://github.com/gabrielschulhof/node-addon-api, so when I ran prebuild it put the tarballs into the releases section of my personal clone.

I do not wish to pollute the release stream for this upstream repo with tarballs unless we all agree that we should perform the test.

So, if you wish to test this, I would recommend that you

  1. clone the source repo for this PR (my personal clone at https://github.com/gabrielschulhof/node-addon-api), including the branch called "binary" into https://github.com/mcollina/node-addon-api, but not using github's "Fork", but rather by creating a new repo on Github and then pushing this to it.
  2. Change all https://github.com/nodejs/node-addon-api in package.json to https://github.com/mcollina/node-addon-api
  3. Follow the steps in https://github.com/gabrielschulhof/node-addon-api/blob/binary/PREBUILD.md to upload the prebuilds to the releases stream of your personal clone
  4. Have the module with which you wish to test this depend on
...
"node-addon-api": "git+https://github.com/mcollina/node-addon-api#binary"
...

and then simply do this with your module:

nvm use 4
npm install
node -p 'something that causes your module to load and output something'
nvm use 6
node -p 'something that causes your module to load and output something'
nvm use 8
node -p 'something that causes your module to load and output something'

You should be able to run npm install on any node version 4, 6, or 8, and move to any other node version 4, 6, or 8.

@gabrielschulhof
Copy link
Contributor Author

I guess we need more than just this PR. We also need a workflow to accompany the creation of a new node-addon-api release, which includes producing the prebuilds and storing them on the repo's "Releases" page.

@mcollina
Copy link
Member

mcollina commented Aug 5, 2017

@gabrielschulhof yes! Also, we need some way to make all of this setup work in Node releases between 8.0.0 and 8.x.0, when we drop the flag. But we can think about those releases later on.

I will test this on Mac OS X early next week.

@gabrielschulhof
Copy link
Contributor Author

gabrielschulhof commented Aug 5, 2017

@mcollina

I have managed to simplify the usage a bit. You need no longer make your own clone. It is now sufficient to depend on

...
"node-addon-api": "git+https://github.com/gabrielschulhof/node-addon-api#test-release"
...

When you do that, it will still do some compiling, but only the loader that does the dlopen(3) "magic". Aside from that, it will fetch the N-API implementations as stored on github.

A further refinement could be to store the loader on github in binary form as well, so that npm install of node-addon-api does not entail any compilation at all.

@gabrielschulhof
Copy link
Contributor Author

gabrielschulhof commented Aug 7, 2017

@mcollina I have now uploaded prebuilds for OSX. I built them using the procedure for which I added documentation in the PR.

So,

...
"node-addon-api": "git+https://github.com/gabrielschulhof/node-addon-api#test-release"
...

followed by

nvm use 4
npm install
node -p 'something that causes your module to load and output something'
nvm use 6
node -p 'something that causes your module to load and output something'
nvm use 8
node -p 'something that causes your module to load and output something'

should now Just Work™ on OSX as well.

@mcollina
Copy link
Member

mcollina commented Aug 8, 2017

So it's working, but I'm hitting #101 as well when switching versions, it seems working fine, as I can run a binary built on Node 4 on Node 6.

For me it's a big 👍 and LGTM really.

We need to sort out the prebuilt story for this, ideally before landing. Can we do the builds using our CI? cc @mhdawson.

I've opened prebuild/prebuild#184 to track down how to remove the Personal Access Token requirement, it does not seem hard or impossible.

@mhdawson
Copy link
Member

I'd like to validate on AIX as well.

@mhdawson
Copy link
Member

I'm guessing this relies of linux exporting all symbols by default, AIX does not do that so it will probably require some extra steps like we had to do for the node executable itself.

@mhdawson
Copy link
Member

mhdawson commented Sep 8, 2017

@gabrielschulhof can we put this on the agenda to discuss in the next meeting, would like to better understand and define next steps that we need to complete.

@gabrielschulhof
Copy link
Contributor Author

gabrielschulhof commented Sep 8, 2017 via email

@gabrielschulhof gabrielschulhof force-pushed the binary branch 8 times, most recently from 627cf2e to 24bb8c6 Compare October 18, 2017 17:02
@gabrielschulhof
Copy link
Contributor Author

gabrielschulhof commented Oct 18, 2017

@nodejs/addon-api, @mcollina I made it upload binaries to https://github.com/napi-binary-upload/upload/. That's pretty secure. We now need to test extensively with many different architectures. I couldn't get prebuild to work with Node.js between 8.0.0 and before 8.6.0, because a subsequently loaded shared library cannot eclipse the symbols of the loaded executable.

Here's the built/runs result for the node-addon-api test suite:

Linux
runs on 4.0.0 6.0.0 8.0.0 8.7.0
built on
4.0.0
6.0.0
8.0.0 💣
8.7.0
Windows
runs on 4.0.0 6.0.0 8.0.0 8.7.0
built on
4.0.0
6.0.0
8.0.0
8.7.0 💣

I renamed the pretest npm script to preparetest so it doesn't rebuild the test bindings whenever it runs npm test. That way we can switch node versions and run npm test again without rebuilding.

I used the following procedure for testing:
edit: `Follow the prebuild instructions to upload prebuilds for the given platform/arch, or make sure that prebuilds for that platform/arch are available. Then,

  1. nvm use 4.0.0
  2. git clean -x -d -f -f && npm install && npm preparetest
  3. npm test
  4. nvm use 6.0.0
  5. npm test
  6. nvm use 8.0.0
  7. npm test
  8. nvm use 8.7.0
  9. npm test

@gabrielschulhof
Copy link
Contributor Author

On Linux, building on 8.0.0 and running on 8.7.0 is successful, but there's an unresolved symbol.

On Windows, building on 8.0.0 fails at the link stage, because the same symbol is available in two places.

@gabrielschulhof
Copy link
Contributor Author

OSX
runs on 4.0.0 6.0.0 8.0.0 8.7.0
built on
4.0.0 💣
6.0.0 💣
8.0.0 💣
8.7.0 💣

@gabrielschulhof
Copy link
Contributor Author

Note that for each table the result on the diagonal is the same as without prebuild. Only the off-diagonal checkmarks are made possible by using the prebuilds.

I also edited the test procedure to mention the fact that prebuilds for the given platform/arch must be available before testing can be done.

@gabrielschulhof
Copy link
Contributor Author

gabrielschulhof commented Oct 19, 2017

This is a departure from the way node-addon-api currently works because it never links node-api.a into the module unless it's on Windows or on Node.js between 8.0.0 and less than 8.6.0. Conversely, outside of Windows or on Node.js between 8.0.0 and less than 8.6.0 it always downloads the prebuilds and loads the module via the RTLD_GLOBAL mechanism, no matter how the module was built.

* Introduce infrastructure for creating prebuilds and uploading them to
  a github repo.
* Use prebuilds on all platforms except Windows and except Node.js >=
  8.0.0 and < 8.6.0.
* Update documentation to reflect requirement to load native addon
  `loadModule()` provided by index.js instead of `require()`.
* Update tests to use `loadModule()`.
@mhdawson
Copy link
Member

mhdawson commented Apr 9, 2018

I believe we discussed this in the last N-API meeting and this is no longer applicable, closing. @gabrielschulhof please re-open if that is not the case.

@mhdawson mhdawson closed this Apr 9, 2018
@gabrielschulhof gabrielschulhof deleted the binary branch December 27, 2018 18:01
@gabrielschulhof gabrielschulhof restored the binary branch December 28, 2018 20:27
@gabrielschulhof gabrielschulhof deleted the binary branch February 13, 2019 23:28
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.

3 participants