compile.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. 'use strict';
  2. module.exports = exports;
  3. const fs = require('fs');
  4. const path = require('path');
  5. const win = process.platform === 'win32';
  6. const existsSync = fs.existsSync || path.existsSync;
  7. const cp = require('child_process');
  8. // try to build up the complete path to node-gyp
  9. /* priority:
  10. - node-gyp on ENV:npm_config_node_gyp (https://github.com/npm/npm/pull/4887)
  11. - node-gyp on NODE_PATH
  12. - node-gyp inside npm on NODE_PATH (ignore on iojs)
  13. - node-gyp inside npm beside node exe
  14. */
  15. function which_node_gyp() {
  16. let node_gyp_bin;
  17. if (process.env.npm_config_node_gyp) {
  18. try {
  19. node_gyp_bin = process.env.npm_config_node_gyp;
  20. if (existsSync(node_gyp_bin)) {
  21. return node_gyp_bin;
  22. }
  23. } catch (err) {
  24. // do nothing
  25. }
  26. }
  27. try {
  28. const node_gyp_main = require.resolve('node-gyp'); // eslint-disable-line node/no-missing-require
  29. node_gyp_bin = path.join(path.dirname(
  30. path.dirname(node_gyp_main)),
  31. 'bin/node-gyp.js');
  32. if (existsSync(node_gyp_bin)) {
  33. return node_gyp_bin;
  34. }
  35. } catch (err) {
  36. // do nothing
  37. }
  38. if (process.execPath.indexOf('iojs') === -1) {
  39. try {
  40. const npm_main = require.resolve('npm'); // eslint-disable-line node/no-missing-require
  41. node_gyp_bin = path.join(path.dirname(
  42. path.dirname(npm_main)),
  43. 'node_modules/node-gyp/bin/node-gyp.js');
  44. if (existsSync(node_gyp_bin)) {
  45. return node_gyp_bin;
  46. }
  47. } catch (err) {
  48. // do nothing
  49. }
  50. }
  51. const npm_base = path.join(path.dirname(
  52. path.dirname(process.execPath)),
  53. 'lib/node_modules/npm/');
  54. node_gyp_bin = path.join(npm_base, 'node_modules/node-gyp/bin/node-gyp.js');
  55. if (existsSync(node_gyp_bin)) {
  56. return node_gyp_bin;
  57. }
  58. }
  59. module.exports.run_gyp = function(args, opts, callback) {
  60. let shell_cmd = '';
  61. const cmd_args = [];
  62. if (opts.runtime && opts.runtime === 'node-webkit') {
  63. shell_cmd = 'nw-gyp';
  64. if (win) shell_cmd += '.cmd';
  65. } else {
  66. const node_gyp_path = which_node_gyp();
  67. if (node_gyp_path) {
  68. shell_cmd = process.execPath;
  69. cmd_args.push(node_gyp_path);
  70. } else {
  71. shell_cmd = 'node-gyp';
  72. if (win) shell_cmd += '.cmd';
  73. }
  74. }
  75. const final_args = cmd_args.concat(args);
  76. const cmd = cp.spawn(shell_cmd, final_args, { cwd: undefined, env: process.env, stdio: [0, 1, 2] });
  77. cmd.on('error', (err) => {
  78. if (err) {
  79. return callback(new Error("Failed to execute '" + shell_cmd + ' ' + final_args.join(' ') + "' (" + err + ')'));
  80. }
  81. callback(null, opts);
  82. });
  83. cmd.on('close', (code) => {
  84. if (code && code !== 0) {
  85. return callback(new Error("Failed to execute '" + shell_cmd + ' ' + final_args.join(' ') + "' (" + code + ')'));
  86. }
  87. callback(null, opts);
  88. });
  89. };