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 support for AIX #753

Closed
wants to merge 1 commit into from
Closed

Add support for AIX #753

wants to merge 1 commit into from

Conversation

mhdawson
Copy link
Member

@mhdawson mhdawson commented Oct 2, 2015

For AIX we need to use gmake

For AIX we need to set up the path to the exp file
which contains the symbols needed for linking.
The file will either be in one of the following
depeding on whether are are in installed or
development environment:

  • the include/node directory
  • the out/Release directory

The work to add the required node.exp file is being covered in this PR nodejs/node#3114

@mhdawson
Copy link
Member Author

mhdawson commented Oct 2, 2015

I've tested this in a build of Node from master. I've looked through the readme for node-gyp to see how changes are normally tested but I've not found any instructions. Can somebody point me at were it is documented what testing should be done ?

@bnoordhuis - as discussed can you take a look

@@ -21,6 +21,7 @@ exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the mod
function build (gyp, argv, callback) {
var release = processRelease(argv, gyp, process.version, process.release)
, makeCommand = gyp.opts.make || process.env.MAKE
|| (process.platform.indexOf('aix') != -1 && 'gmake')
Copy link
Member

Choose a reason for hiding this comment

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

the mixed use of && and the ternary operator below makes this a bit confusing, the duplicate resolving of gmake suggests redundancy, and, shouldn't it just be aix when it's AIX? the indexOf is for the *bsd variants I think.

Can I suggest squashing both these lines to: ((/(^aix$)|bsd/).test(process.platform) ? 'gmake' : 'make')

Copy link
Member

Choose a reason for hiding this comment

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

Maybe platform-specific overrides are better done in parseArgv / parseOpts in lib/node-gyp.js.

Copy link
Member Author

Choose a reason for hiding this comment

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

it is kind of of ugly. What do you think of this. It's more verbose but also more obvious whats going on

function build (gyp, argv, callback) {
var platformMake = 'make';
if (process.platform == 'aix') {
platformMake = 'gmake';
} else if (process.platform.indexOf('bsd') != -1) {
platformMake = 'gmake');
}

var release = processRelease(argv, gyp, process.version, process.release)
, makeCommand = gyp.opts.make || process.env.MAKE || platformMake
, command = win ? 'msbuild' : makeCommand
, buildDir = path.resolve('build')
, configPath = path.resolve(buildDir, 'config.gypi')
, jobs = gyp.opts.jobs || process.env.JOBS
, buildType
, config
, arch
, nodeDir
, copyDevLib

@rvagg
Copy link
Member

rvagg commented Oct 3, 2015

I'm pretty sure the findNodeRootDirectory() approach is wrong here and makes too many unsafe assumptions. Can you have a look at how it finds config.gypi and emulate that instead? I understand the problem of finding node.exp when using --nodedir but that's only a minor case, the most important one being finding the file in ~/.node-gyp/version/include/node/node.exp.

@rvagg
Copy link
Member

rvagg commented Oct 3, 2015

re tests, there isn't much in the way of tests here. There are some docker tests you can run in test/docker.sh but obviously only for Linux but it's worth making sure you haven't broken anything else. Other testing has to be manual, which can be quite tricky when we haven't got any headers tarballs on nodejs.org that you can trial with! Once we get an AIX machine (or two, or three, whatever) in CI then we could produce tarballs for releases || nightlies with node.exp in it and test with that.

But, that raises another question, is node.exp specific to the arch used? Does it need a new one for BE, LE, 32-bit, 64-bit? If so, then it can't go into the headers tarball and you're going to need to scrap a lot of this code and emulate the node.lib download process we have for Windows and we're going to need to set up new directories in nodejs.org/download/ to contain node.exp for all of the different architectures.

@rvagg
Copy link
Member

rvagg commented Oct 3, 2015

OK, another rethink on this, backing up on what I've just said I realise your approach now is to find node.exp as it's been installed on the system along with node from a binary tarball or some other official package, not necessarily have it in the headers or download from nodejs.org like node.lib. This is something that many of us have talked about for some time now wrt general headers because they are installed on many systems but node-gyp will always download them again anyway. A disparity that's existed since 0.10.

In that case, perhaps this is the right approach, but I personally don't want to see this logic baked in to node-gyp and would rather see it split off to a separate module that can locate the Node include dir on any system if it exists. That way it can be independently tested and iterated on rather than becoming part of the big logic puzzle that node-gyp currently is. I know that's not the expedient path here but as it is there's no clear way to test this logic in here. Perhaps a middle ground is to do what I did with process-release.js (which I would also like to extract to a separate package) and treat it as independent and test it independently.

if (process.platform == 'aix') {
var node_root_dir = findNodeRootDirectory();
node_exp_file = path.resolve(node_root_dir, 'include/node/node.exp')
if (!fs.existsSync(node_exp_file)) {
Copy link
Member

Choose a reason for hiding this comment

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

fs.existsSync() emits deprecation warnings.

Copy link
Member Author

Choose a reason for hiding this comment

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

Noted will replace with one of the suggested alternates

@mhdawson
Copy link
Member Author

Sorry for taking so long to get back to this one. First part in Node is now in so will be moving on to this one soon. I am out at a conference this week but it will my priority after that.

@mhdawson
Copy link
Member Author

mhdawson commented Nov 6, 2015

Have updates to reflect the comments in my local repo, just need to test now

@mhdawson
Copy link
Member Author

mhdawson commented Nov 9, 2015

@bnoordhuis @rvagg updated to address review comments

if (process.platform == 'aix') {
platformMake = 'gmake';
} else if (process.platform.indexOf('bsd') != -1) {
platformMake = 'gmake';
Copy link
Member

Choose a reason for hiding this comment

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

Style nits: no trailing semicolons (for better or worse)

EDIT: And maybe use strict inequality while you're here.

Copy link
Member Author

Choose a reason for hiding this comment

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

k

@mhdawson
Copy link
Member Author

@bnoordhuis updated to address your latest comments. Added the unit tests and took a closer look as you had found a place were the code was obviously stale. I fixed up the initial checks to be for 'node_modules' and 'deps' and validated directories on windows and fixed a few issues there as well. I've kicked off tests on my local system and of course once we have agreement I'll do a full CI run before landing.

t.equal(
findNodeDirectory('/y/lib/node_modules/npm/node_modules/node-gyp/lib',
processObj), path.join('/y'));
}
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 test both branches here? I.e., rewrite it so it's called once with processObj.platform === 'win32' and once without?

Copy link
Member

Choose a reason for hiding this comment

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

I'd recommend doing that everywhere where you call findNodeDirectory() with { platform: process.platform }. The idea is that all code paths are tested on all platforms.

var processObj = {execPath: '/x/y/bin/node', platform: process.platform}
t.equal(
findNodeDirectory('/x/deps/npm/node_modules/node-gyp/lib', processObj),
path.join('/x'));
Copy link
Member

Choose a reason for hiding this comment

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

There are a few stray semicolons in this file.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks its hard to stomp out that habit.

@mhdawson
Copy link
Member Author

@bnoordhuis @thefourtheye updated to address latest comments

@bnoordhuis
Copy link
Member

LGTM. @thefourtheye WDYT?

// for AIX we need to set up the path to the exp file
// which contains the symbols needed for linking.
// The file will either be in one of the following
// depeding on whether are are in installed or
Copy link
Contributor

Choose a reason for hiding this comment

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

depending on whether it is

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

@thefourtheye
Copy link
Contributor

Have few minor comments but overall change LGTM

@mhdawson
Copy link
Member Author

@thefourtheye addressed your comments. If it looks ok to you I can squash into one commit

fs.accessSync(node_exp_file, fs.R_OK)
// exp file found, stop looking
break
} catch (exception) {
Copy link
Contributor

Choose a reason for hiding this comment

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

If the file is not found anywhere, node_exp_file will still be node.exp at the end of the loop. Is that okay or you want to reset to empty string here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think its ok as if this does occur I don't think its going to be any clearer what the problem is with it set to an empty string.

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool, let's land it then. LGTM

For AIX we need to use gmake

For AIX we need to set up the path to the exp file
which contains the symbols needed for linking.
The file will either be in one of the following
depeding on whether are are in installed or
development environment:
  - the include/node directory
  - the out/Release directory
@mhdawson
Copy link
Member Author

Squashed down to a single commit

mhdawson added a commit that referenced this pull request Nov 18, 2015
For AIX we need to use gmake.

For AIX we need to set up the path to the exp file which contains the
symbols needed for linking.  The file will either be in one of the
following depeding on whether are are in installed or development
environment:

  - the include/node directory
  - the out/Release directory

PR-URL: #753
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
@bnoordhuis
Copy link
Member

Thanks Michael, landed in 9bfa087.

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