build.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*!
  2. * node-sass: scripts/build.js
  3. */
  4. var fs = require('fs'),
  5. path = require('path'),
  6. spawn = require('cross-spawn'),
  7. sass = require('../lib/extensions');
  8. /**
  9. * After build
  10. *
  11. * @param {Object} options
  12. * @api private
  13. */
  14. function afterBuild(options) {
  15. var install = sass.getBinaryPath();
  16. var target = path.join(__dirname, '..', 'build',
  17. options.debug ? 'Debug' :
  18. process.config.target_defaults
  19. ? process.config.target_defaults.default_configuration
  20. : 'Release',
  21. 'binding.node');
  22. fs.mkdir(path.dirname(install), {recursive: true}, function(err) {
  23. if (err && err.code !== 'EEXIST') {
  24. console.error(err.message);
  25. return;
  26. }
  27. fs.stat(target, function(err) {
  28. if (err) {
  29. console.error('Build succeeded but target not found');
  30. return;
  31. }
  32. fs.rename(target, install, function(err) {
  33. if (err) {
  34. console.error(err.message);
  35. return;
  36. }
  37. console.log('Installed to', install);
  38. });
  39. });
  40. });
  41. }
  42. /**
  43. * Build
  44. *
  45. * @param {Object} options
  46. * @api private
  47. */
  48. function build(options) {
  49. var args = [require.resolve(path.join('node-gyp', 'bin', 'node-gyp.js')), 'rebuild', '--verbose'].concat(
  50. ['libsass_ext', 'libsass_cflags', 'libsass_ldflags', 'libsass_library'].map(function(subject) {
  51. return ['--', subject, '=', process.env[subject.toUpperCase()] || ''].join('');
  52. })).concat(options.args);
  53. console.log('Building:', [process.execPath].concat(args).join(' '));
  54. var proc = spawn(process.execPath, args, {
  55. stdio: [0, 1, 2]
  56. });
  57. proc.on('exit', function(errorCode) {
  58. if (!errorCode) {
  59. afterBuild(options);
  60. return;
  61. }
  62. if (errorCode === 127 ) {
  63. console.error('node-gyp not found!');
  64. } else {
  65. console.error('Build failed with error code:', errorCode);
  66. }
  67. process.exit(1);
  68. });
  69. }
  70. /**
  71. * Parse arguments
  72. *
  73. * @param {Array} args
  74. * @api private
  75. */
  76. function parseArgs(args) {
  77. var options = {
  78. arch: process.arch,
  79. platform: process.platform,
  80. force: process.env.npm_config_force === 'true',
  81. };
  82. options.args = args.filter(function(arg) {
  83. if (arg === '-f' || arg === '--force') {
  84. options.force = true;
  85. return false;
  86. } else if (arg.substring(0, 13) === '--target_arch') {
  87. options.arch = arg.substring(14);
  88. } else if (arg === '-d' || arg === '--debug') {
  89. options.debug = true;
  90. } else if (arg.substring(0, 13) === '--libsass_ext' && arg.substring(14) !== 'no') {
  91. options.libsassExt = true;
  92. }
  93. return true;
  94. });
  95. return options;
  96. }
  97. /**
  98. * Test for pre-built library
  99. *
  100. * @param {Object} options
  101. * @api private
  102. */
  103. function testBinary(options) {
  104. if (options.force || process.env.SASS_FORCE_BUILD) {
  105. return build(options);
  106. }
  107. if (!sass.hasBinary(sass.getBinaryPath())) {
  108. return build(options);
  109. }
  110. console.log('Binary found at', sass.getBinaryPath());
  111. console.log('Testing binary');
  112. try {
  113. require('../').renderSync({
  114. data: 's { a: ss }'
  115. });
  116. console.log('Binary is fine');
  117. } catch (e) {
  118. console.log('Binary has a problem:', e);
  119. console.log('Building the binary locally');
  120. return build(options);
  121. }
  122. }
  123. /**
  124. * Apply arguments and run
  125. */
  126. testBinary(parseArgs(process.argv.slice(2)));