Skip to content

Commit c9303d7

Browse files
committed
See issue #960 Added initial `gyp.js` support with --gypjs command line option. Environment variable `npm_config_gypjs` also turns this option on. Update configure and build usage strings depending on `npm_config_gypjs` environment variable. Set `npm_config_gypjs` env variable if `--gypjs` command-line option was set to affect usage text for `configure` and `build` commands. Update usage strings if `--gypjs` command-line option was supplied
1 parent 8db9e57 commit c9303d7

File tree

7 files changed

+160
-94
lines changed

7 files changed

+160
-94
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ Command Options
181181
| `--python=$path` | Set path to the python (2) binary
182182
| `--msvs_version=$version` | Set Visual Studio version (win)
183183
| `--solution=$solution` | Set Visual Studio Solution version (win)
184+
| `--gypjs` | Use gyp.js instead of gyp
184185

185186

186187
License

gyp/gyp.bat

100755100644
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
@rem Copyright (c) 2009 Google Inc. All rights reserved.
2-
@rem Use of this source code is governed by a BSD-style license that can be
3-
@rem found in the LICENSE file.
4-
5-
@python "%~dp0gyp_main.py" %*
1+
@rem Copyright (c) 2009 Google Inc. All rights reserved.
2+
@rem Use of this source code is governed by a BSD-style license that can be
3+
@rem found in the LICENSE file.
4+
5+
@python "%~dp0gyp_main.py" %*

gyp/samples/samples.bat

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
@rem Copyright (c) 2009 Google Inc. All rights reserved.
2-
@rem Use of this source code is governed by a BSD-style license that can be
3-
@rem found in the LICENSE file.
4-
5-
@python %~dp0/samples %*
1+
@rem Copyright (c) 2009 Google Inc. All rights reserved.
2+
@rem Use of this source code is governed by a BSD-style license that can be
3+
@rem found in the LICENSE file.
4+
5+
@python %~dp0/samples %*

lib/build.js

Lines changed: 93 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var fs = require('graceful-fs')
1515
, processRelease = require('./process-release')
1616
, win = process.platform == 'win32'
1717

18-
exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'
18+
exports.usage = 'Invokes `' + (process.env.npm_config_gypjs? 'ninja' : (win ? 'msbuild' : 'make')) + '` and builds the module'
1919

2020
function build (gyp, argv, callback) {
2121
var platformMake = 'make'
@@ -35,7 +35,11 @@ function build (gyp, argv, callback) {
3535
, config
3636
, arch
3737
, nodeDir
38+
, vcDir
3839

40+
if (gyp.opts.gypjs) {
41+
command = gyp.opts.ninja || process.env.NINJA || 'ninja'
42+
}
3943
loadConfigGypi()
4044

4145
/**
@@ -71,13 +75,40 @@ function build (gyp, argv, callback) {
7175
log.verbose('node dev dir', nodeDir)
7276

7377
if (win) {
74-
findSolutionFile()
78+
gyp.opts.gypjs? findMSVS() : findSolutionFile()
7579
} else {
7680
doWhich()
7781
}
7882
})
7983
}
8084

85+
/**
86+
* On Windows, find Visual C++ toolset
87+
*/
88+
89+
function findMSVS () {
90+
var msvs_version = gyp.opts.msvs_version || 'auto'
91+
var vs_versions = (msvs_version === 'auto'? [14, 12, 10] : [msvs_version])
92+
vs_versions.find(function(version) {
93+
var vscomntools = process.env['VS' + version + '0COMNTOOLS']
94+
if (vscomntools) {
95+
// remove quotes to work with path.join()
96+
if (vscomntools.substr(0, 1) === '"' && vscomntools.substr(-1, 1) === '"') {
97+
vscomntools = vscomntools.substr(1, vscomntools.length - 2)
98+
}
99+
vcDir = path.join(vscomntools, '..', '..', 'VC')
100+
if (vcDir) {
101+
log.verbose('found Visual C++ in ', vcDir)
102+
return true
103+
}
104+
}
105+
})
106+
if (!vcDir) {
107+
callback(new Error('Visual C++ not found, please setup a C++ compiler toolset'))
108+
}
109+
doWhich()
110+
}
111+
81112
/**
82113
* On Windows, find the first build/*.sln file.
83114
*/
@@ -102,7 +133,7 @@ function build (gyp, argv, callback) {
102133
// First make sure we have the build command in the PATH
103134
which(command, function (err, execPath) {
104135
if (err) {
105-
if (win && /not found/.test(err.message)) {
136+
if (win && !gyp.opts.gypjs && /not found/.test(err.message)) {
106137
// On windows and no 'msbuild' found. Let's guess where it is
107138
findMsbuild()
108139
} else {
@@ -185,54 +216,74 @@ function build (gyp, argv, callback) {
185216

186217
// Enable Verbose build
187218
var verbose = log.levels[log.level] <= log.levels.verbose
188-
if (!win && verbose) {
189-
argv.push('V=1')
190-
}
191-
if (win && !verbose) {
192-
argv.push('/clp:Verbosity=minimal')
193-
}
219+
if (!gyp.opts.gypjs) {
220+
if (!win && verbose) {
221+
argv.push('V=1')
222+
}
223+
if (win && !verbose) {
224+
argv.push('/clp:Verbosity=minimal')
225+
}
194226

195-
if (win) {
196-
// Turn off the Microsoft logo on Windows
197-
argv.push('/nologo')
198-
}
227+
if (win) {
228+
// Turn off the Microsoft logo on Windows
229+
argv.push('/nologo')
230+
}
199231

200-
// Specify the build type, Release by default
201-
if (win) {
202-
var p = arch === 'x64' ? 'x64' : 'Win32'
203-
argv.push('/p:Configuration=' + buildType + ';Platform=' + p)
204-
if (jobs) {
205-
var j = parseInt(jobs, 10)
206-
if (!isNaN(j) && j > 0) {
207-
argv.push('/m:' + j)
208-
} else if (jobs.toUpperCase() === 'MAX') {
209-
argv.push('/m:' + require('os').cpus().length)
232+
// Specify the build type, Release by default
233+
if (win) {
234+
var p = arch === 'x64' ? 'x64' : 'Win32'
235+
argv.push('/p:Configuration=' + buildType + ';Platform=' + p)
236+
if (jobs) {
237+
var j = parseInt(jobs, 10)
238+
if (!isNaN(j) && j > 0) {
239+
argv.push('/m:' + j)
240+
} else if (jobs.toUpperCase() === 'MAX') {
241+
argv.push('/m:' + require('os').cpus().length)
242+
}
243+
}
244+
} else {
245+
argv.push('BUILDTYPE=' + buildType)
246+
// Invoke the Makefile in the 'build' dir.
247+
argv.push('-C')
248+
argv.push('build')
249+
if (jobs) {
250+
var j = parseInt(jobs, 10)
251+
if (!isNaN(j) && j > 0) {
252+
argv.push('--jobs')
253+
argv.push(j)
254+
} else if (jobs.toUpperCase() === 'MAX') {
255+
argv.push('--jobs')
256+
argv.push(require('os').cpus().length)
257+
}
258+
}
259+
}
260+
261+
if (win) {
262+
// did the user specify their own .sln file?
263+
var hasSln = argv.some(function (arg) {
264+
return path.extname(arg) == '.sln'
265+
})
266+
if (!hasSln) {
267+
argv.unshift(gyp.opts.solution || guessedSolution)
210268
}
211269
}
212270
} else {
213-
argv.push('BUILDTYPE=' + buildType)
214-
// Invoke the Makefile in the 'build' dir.
215-
argv.push('-C')
216-
argv.push('build')
271+
// build with ninja
272+
if (verbose) {
273+
argv.push('-v')
274+
}
275+
// Specify the build type, Release by default
276+
argv.push('-C', path.join('build', buildType))
217277
if (jobs) {
218-
var j = parseInt(jobs, 10)
278+
var j = jobs.toUpperCase() === 'MAX'? require('os').cpus().length : parseInt(jobs, 10)
219279
if (!isNaN(j) && j > 0) {
220-
argv.push('--jobs')
221-
argv.push(j)
222-
} else if (jobs.toUpperCase() === 'MAX') {
223-
argv.push('--jobs')
224-
argv.push(require('os').cpus().length)
280+
argv.push('-j' + j)
225281
}
226282
}
227-
}
228-
229-
if (win) {
230-
// did the user specify their own .sln file?
231-
var hasSln = argv.some(function (arg) {
232-
return path.extname(arg) == '.sln'
233-
})
234-
if (!hasSln) {
235-
argv.unshift(gyp.opts.solution || guessedSolution)
283+
// invoke vcvarsall.bat before build
284+
if (win && vcDir) {
285+
argv.unshift(arch === 'ia32'? 'x86' : arch, '&', command)
286+
command = path.join(vcDir, 'vcvarsall.bat')
236287
}
237288
}
238289

lib/configure.js

Lines changed: 51 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ var fs = require('graceful-fs')
2121
, execFile = cp.execFile
2222
, win = process.platform == 'win32'
2323
, findNodeDirectory = require('./find-node-directory')
24-
, msgFormat = require('util').format
24+
, gypjs = require('gyp.js')
2525

26-
exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' for the current module'
26+
exports.usage = 'Generates ' + (process.env.npm_config_gypjs? 'ninja build files' : (win ? 'MSVC project files' : 'a Makefile')) + ' for the current module'
2727

2828
function configure (gyp, argv, callback) {
2929

@@ -34,14 +34,18 @@ function configure (gyp, argv, callback) {
3434
, nodeDir
3535
, release = processRelease(argv, gyp, process.version, process.release)
3636

37-
findPython(python, function (err, found) {
38-
if (err) {
39-
callback(err)
40-
} else {
41-
python = found
42-
getNodeDir()
43-
}
44-
})
37+
if (!gyp.opts.gypjs) {
38+
findPython(python, function (err, found) {
39+
if (err) {
40+
callback(err)
41+
} else {
42+
python = found
43+
getNodeDir()
44+
}
45+
})
46+
} else {
47+
getNodeDir()
48+
}
4549

4650
function getNodeDir () {
4751

@@ -185,35 +189,37 @@ function configure (gyp, argv, callback) {
185189
function runGyp (err) {
186190
if (err) return callback(err)
187191

188-
if (!~argv.indexOf('-f') && !~argv.indexOf('--format')) {
189-
if (win) {
190-
log.verbose('gyp', 'gyp format was not specified; forcing "msvs"')
191-
// force the 'make' target for non-Windows
192-
argv.push('-f', 'msvs')
193-
} else {
194-
log.verbose('gyp', 'gyp format was not specified; forcing "make"')
195-
// force the 'make' target for non-Windows
196-
argv.push('-f', 'make')
192+
if (!gyp.opts.gypjs) {
193+
if (!~argv.indexOf('-f') && !~argv.indexOf('--format')) {
194+
if (win) {
195+
log.verbose('gyp', 'gyp format was not specified; forcing "msvs"')
196+
// force the 'make' target for non-Windows
197+
argv.push('-f', 'msvs')
198+
} else {
199+
log.verbose('gyp', 'gyp format was not specified; forcing "make"')
200+
// force the 'make' target for non-Windows
201+
argv.push('-f', 'make')
202+
}
197203
}
198-
}
199204

200-
function hasMsvsVersion () {
201-
return argv.some(function (arg) {
202-
return arg.indexOf('msvs_version') === 0
203-
})
204-
}
205+
function hasMsvsVersion () {
206+
return argv.some(function (arg) {
207+
return arg.indexOf('msvs_version') === 0
208+
})
209+
}
205210

206-
if (win && !hasMsvsVersion()) {
207-
if ('msvs_version' in gyp.opts) {
208-
argv.push('-G', 'msvs_version=' + gyp.opts.msvs_version)
209-
} else {
210-
argv.push('-G', 'msvs_version=auto')
211+
if (win && !hasMsvsVersion()) {
212+
if ('msvs_version' in gyp.opts) {
213+
argv.push('-G', 'msvs_version=' + gyp.opts.msvs_version)
214+
} else {
215+
argv.push('-G', 'msvs_version=auto')
216+
}
211217
}
212218
}
213219

214220
// include all the ".gypi" files that were found
215221
configs.forEach(function (config) {
216-
argv.push('-I', config)
222+
argv.push('-I' + config)
217223
})
218224

219225
// for AIX we need to set up the path to the exp file
@@ -237,9 +243,8 @@ function configure (gyp, argv, callback) {
237243
if (node_exp_file !== undefined) {
238244
log.verbose(logprefix, 'Found exports file: %s', node_exp_file)
239245
} else {
240-
var msg = msgFormat('Could not find node.exp file in %s', node_root_dir)
241246
log.error(logprefix, 'Could not find exports file')
242-
return callback(new Error(msg))
247+
return callback(new Error('Could not find node.exp file in ' + node_root_dir))
243248
}
244249
}
245250

@@ -258,8 +263,8 @@ function configure (gyp, argv, callback) {
258263
}
259264
var nodeGypDir = path.resolve(__dirname, '..')
260265

261-
argv.push('-I', addon_gypi)
262-
argv.push('-I', common_gypi)
266+
argv.push('-I' + addon_gypi)
267+
argv.push('-I' + common_gypi)
263268
argv.push('-Dlibrary=shared_library')
264269
argv.push('-Dvisibility=default')
265270
argv.push('-Dnode_root_dir=' + nodeDir)
@@ -281,15 +286,19 @@ function configure (gyp, argv, callback) {
281286
// enforce use of the "binding.gyp" file
282287
argv.unshift('binding.gyp')
283288

284-
// execute `gyp` from the current target nodedir
285-
argv.unshift(gyp_script)
289+
if (!gyp.opts.gypjs) {
290+
// execute `gyp` from the current target nodedir
291+
argv.unshift(gyp_script)
286292

287-
// make sure python uses files that came with this particular node package
288-
var pypath = new PathArray(process.env, 'PYTHONPATH')
289-
pypath.unshift(path.join(__dirname, '..', 'gyp', 'pylib'))
293+
// make sure python uses files that came with this particular node package
294+
var pypath = new PathArray(process.env, 'PYTHONPATH')
295+
pypath.unshift(path.join(__dirname, '..', 'gyp', 'pylib'))
290296

291-
var cp = gyp.spawn(python, argv)
292-
cp.on('exit', onCpExit)
297+
var cp = gyp.spawn(python, argv)
298+
cp.on('exit', onCpExit)
299+
} else {
300+
onCpExit(gypjs.main(argv))
301+
}
293302
})
294303
}
295304

lib/node-gyp.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ proto.configDefs = {
9999
, 'tarball': String // 'install'
100100
, jobs: String // 'build'
101101
, thin: String // 'configure'
102+
, gypjs: Boolean // 'configure', 'build'
102103
}
103104

104105
/**
@@ -175,6 +176,9 @@ proto.parseArgv = function parseOpts (argv) {
175176
if (this.opts.loglevel) {
176177
log.level = this.opts.loglevel
177178
}
179+
if (this.opts.gypjs) {
180+
process.env[npm_config_prefix + 'gypjs'] = true
181+
}
178182
log.resume()
179183
}
180184

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"fstream": "^1.0.0",
2626
"glob": "^7.0.3",
2727
"graceful-fs": "^4.1.2",
28+
"gyp.js": "^1.1.1",
2829
"minimatch": "1",
2930
"mkdirp": "^0.5.0",
3031
"nopt": "2 || 3",

0 commit comments

Comments
 (0)