Skip to content

Commit 9bfa087

Browse files
mhdawsonbnoordhuis
authored andcommitted
Add support for AIX
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 <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]>
1 parent a8d441a commit 9bfa087

File tree

5 files changed

+221
-2
lines changed

5 files changed

+221
-2
lines changed

addon.gypi

+5
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@
6565
'DYLIB_INSTALL_NAME_BASE': '@rpath'
6666
},
6767
}],
68+
[ 'OS=="aix"', {
69+
'ldflags': [
70+
'-Wl,-bimport:<(node_exp_file)'
71+
],
72+
}],
6873
[ 'OS=="win"', {
6974
'libraries': [
7075
'-lkernel32.lib',

lib/build.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@ var fs = require('graceful-fs')
1919
exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'
2020

2121
function build (gyp, argv, callback) {
22+
var platformMake = 'make'
23+
if (process.platform === 'aix') {
24+
platformMake = 'gmake'
25+
} else if (process.platform.indexOf('bsd') !== -1) {
26+
platformMake = 'gmake'
27+
}
28+
2229
var release = processRelease(argv, gyp, process.version, process.release)
23-
, makeCommand = gyp.opts.make || process.env.MAKE
24-
|| (process.platform.indexOf('bsd') != -1 ? 'gmake' : 'make')
30+
, makeCommand = gyp.opts.make || process.env.MAKE || platformMake
2531
, command = win ? 'msbuild' : makeCommand
2632
, buildDir = path.resolve('build')
2733
, configPath = path.resolve(buildDir, 'config.gypi')

lib/configure.js

+32
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var fs = require('graceful-fs')
1919
, spawn = cp.spawn
2020
, execFile = cp.execFile
2121
, win = process.platform == 'win32'
22+
, findNodeDirectory = require('./find-node-directory')
2223

2324
exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' for the current module'
2425

@@ -299,6 +300,34 @@ function configure (gyp, argv, callback) {
299300
argv.push('-I', config)
300301
})
301302

303+
// for AIX we need to set up the path to the exp file
304+
// which contains the symbols needed for linking.
305+
// The file will either be in one of the following
306+
// depending on whether it is an installed or
307+
// development environment:
308+
// - the include/node directory
309+
// - the out/Release directory
310+
// - the out/Debug directory
311+
// - the root directory
312+
var node_exp_file = ''
313+
if (process.platform === 'aix') {
314+
var node_root_dir = findNodeDirectory()
315+
var candidates = ['include/node/node.exp',
316+
'out/Release/node.exp',
317+
'out/Debug/node.exp',
318+
'node.exp']
319+
for (var next = 0; next < candidates.length; next++) {
320+
node_exp_file = path.resolve(node_root_dir, candidates[next])
321+
try {
322+
fs.accessSync(node_exp_file, fs.R_OK)
323+
// exp file found, stop looking
324+
break
325+
} catch (exception) {
326+
// this candidate was not found or not readable, do nothing
327+
}
328+
}
329+
}
330+
302331
// this logic ported from the old `gyp_addon` python file
303332
var gyp_script = path.resolve(__dirname, '..', 'gyp', 'gyp_main.py')
304333
var addon_gypi = path.resolve(__dirname, '..', 'addon.gypi')
@@ -319,6 +348,9 @@ function configure (gyp, argv, callback) {
319348
argv.push('-Dlibrary=shared_library')
320349
argv.push('-Dvisibility=default')
321350
argv.push('-Dnode_root_dir=' + nodeDir)
351+
if (process.platform === 'aix') {
352+
argv.push('-Dnode_exp_file=' + node_exp_file)
353+
}
322354
argv.push('-Dnode_gyp_dir=' + nodeGypDir)
323355
argv.push('-Dnode_lib_file=' + release.name + '.lib')
324356
argv.push('-Dmodule_root_dir=' + process.cwd())

lib/find-node-directory.js

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
var path = require('path')
2+
, log = require('npmlog')
3+
4+
function findNodeDirectory(scriptLocation, processObj) {
5+
// set dirname and process if not passed in
6+
// this facilitates regression tests
7+
if (scriptLocation === undefined) {
8+
scriptLocation = __dirname
9+
}
10+
if (processObj === undefined) {
11+
processObj = process
12+
}
13+
14+
// Have a look to see what is above us, to try and work out where we are
15+
npm_parent_directory = path.join(scriptLocation, '../../../..')
16+
log.verbose('node-gyp root', 'npm_parent_directory is '
17+
+ path.basename(npm_parent_directory))
18+
node_root_dir = ""
19+
20+
log.verbose('node-gyp root', 'Finding node root directory')
21+
if (path.basename(npm_parent_directory) === 'deps') {
22+
// We are in a build directory where this script lives in
23+
// deps/npm/node_modules/node-gyp/lib
24+
node_root_dir = path.join(npm_parent_directory, '..')
25+
log.verbose('node-gyp root', 'in build directory, root = '
26+
+ node_root_dir)
27+
} else if (path.basename(npm_parent_directory) === 'node_modules') {
28+
// We are in a node install directory where this script lives in
29+
// lib/node_modules/npm/node_modules/node-gyp/lib or
30+
// node_modules/npm/node_modules/node-gyp/lib depending on the
31+
// platform
32+
if (processObj.platform === 'win32') {
33+
node_root_dir = path.join(npm_parent_directory, '..')
34+
} else {
35+
node_root_dir = path.join(npm_parent_directory, '../..')
36+
}
37+
log.verbose('node-gyp root', 'in install directory, root = '
38+
+ node_root_dir)
39+
} else {
40+
// We don't know where we are, try working it out from the location
41+
// of the node binary
42+
var node_dir = path.dirname(processObj.execPath)
43+
var directory_up = path.basename(node_dir)
44+
if (directory_up === 'bin') {
45+
node_root_dir = path.join(node_dir, '..')
46+
} else if (directory_up === 'Release' || directory_up === 'Debug') {
47+
// If we are a recently built node, and the directory structure
48+
// is that of a repository. If we are on Windows then we only need
49+
// to go one level up, everything else, two
50+
if (processObj.platform === 'win32') {
51+
node_root_dir = path.join(node_dir, '..')
52+
} else {
53+
node_root_dir = path.join(node_dir, '../..')
54+
}
55+
}
56+
// Else return the default blank, "".
57+
}
58+
return node_root_dir
59+
}
60+
61+
module.exports = findNodeDirectory

test/test-find-node-directory.js

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
var test = require('tape')
2+
var path = require('path')
3+
var findNodeDirectory = require('../lib/find-node-directory')
4+
5+
var platforms = ['darwin', 'freebsd', 'linux', 'sunos', 'win32', 'aix']
6+
7+
// we should find the directory based on the directory
8+
// the script is running in and it should match the layout
9+
// in a build tree where npm is installed in
10+
// .... /deps/npm
11+
test('test find-node-directory - node install', function (t) {
12+
t.plan(platforms.length)
13+
for (var next = 0; next < platforms.length; next++) {
14+
var processObj = {execPath: '/x/y/bin/node', platform: platforms[next]}
15+
t.equal(
16+
findNodeDirectory('/x/deps/npm/node_modules/node-gyp/lib', processObj),
17+
path.join('/x'))
18+
}
19+
})
20+
21+
// we should find the directory based on the directory
22+
// the script is running in and it should match the layout
23+
// in an installed tree where npm is installed in
24+
// .... /lib/node_modules/npm or .../node_modules/npm
25+
// depending on the patform
26+
test('test find-node-directory - node build', function (t) {
27+
t.plan(platforms.length)
28+
for (var next = 0; next < platforms.length; next++) {
29+
var processObj = {execPath: '/x/y/bin/node', platform: platforms[next]}
30+
if (platforms[next] === 'win32') {
31+
t.equal(
32+
findNodeDirectory('/y/node_modules/npm/node_modules/node-gyp/lib',
33+
processObj), path.join('/y'))
34+
} else {
35+
t.equal(
36+
findNodeDirectory('/y/lib/node_modules/npm/node_modules/node-gyp/lib',
37+
processObj), path.join('/y'))
38+
}
39+
}
40+
})
41+
42+
// we should find the directory based on the execPath
43+
// for node and match because it was in the bin directory
44+
test('test find-node-directory - node in bin directory', function (t) {
45+
t.plan(platforms.length)
46+
for (var next = 0; next < platforms.length; next++) {
47+
var processObj = {execPath: '/x/y/bin/node', platform: platforms[next]}
48+
t.equal(
49+
findNodeDirectory('/nothere/npm/node_modules/node-gyp/lib', processObj),
50+
path.join('/x/y'))
51+
}
52+
})
53+
54+
// we should find the directory based on the execPath
55+
// for node and match because it was in the Release directory
56+
test('test find-node-directory - node in build release dir', function (t) {
57+
t.plan(platforms.length)
58+
for (var next = 0; next < platforms.length; next++) {
59+
var processObj
60+
if (platforms[next] === 'win32') {
61+
processObj = {execPath: '/x/y/Release/node', platform: platforms[next]}
62+
} else {
63+
processObj = {execPath: '/x/y/out/Release/node',
64+
platform: platforms[next]}
65+
}
66+
67+
t.equal(
68+
findNodeDirectory('/nothere/npm/node_modules/node-gyp/lib', processObj),
69+
path.join('/x/y'))
70+
}
71+
})
72+
73+
// we should find the directory based on the execPath
74+
// for node and match because it was in the Debug directory
75+
test('test find-node-directory - node in Debug release dir', function (t) {
76+
t.plan(platforms.length)
77+
for (var next = 0; next < platforms.length; next++) {
78+
var processObj
79+
if (platforms[next] === 'win32') {
80+
processObj = {execPath: '/a/b/Debug/node', platform: platforms[next]}
81+
} else {
82+
processObj = {execPath: '/a/b/out/Debug/node', platform: platforms[next]}
83+
}
84+
85+
t.equal(
86+
findNodeDirectory('/nothere/npm/node_modules/node-gyp/lib', processObj),
87+
path.join('/a/b'))
88+
}
89+
})
90+
91+
// we should not find it as it will not match based on the execPath nor
92+
// the directory from which the script is running
93+
test('test find-node-directory - not found', function (t) {
94+
t.plan(platforms.length)
95+
for (var next = 0; next < platforms.length; next++) {
96+
var processObj = {execPath: '/x/y/z/y', platform:next}
97+
t.equal(findNodeDirectory('/a/b/c/d', processObj), '')
98+
}
99+
})
100+
101+
// we should find the directory based on the directory
102+
// the script is running in and it should match the layout
103+
// in a build tree where npm is installed in
104+
// .... /deps/npm
105+
// same test as above but make sure additional directory entries
106+
// don't cause an issue
107+
test('test find-node-directory - node install', function (t) {
108+
t.plan(platforms.length)
109+
for (var next = 0; next < platforms.length; next++) {
110+
var processObj = {execPath: '/x/y/bin/node', platform: platforms[next]}
111+
t.equal(
112+
findNodeDirectory('/x/y/z/a/b/c/deps/npm/node_modules/node-gyp/lib',
113+
processObj), path.join('/x/y/z/a/b/c'))
114+
}
115+
})

0 commit comments

Comments
 (0)