"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/node-gyp/lib/build.js" (8 Mar 2017, 8020 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 
    2 module.exports = exports = build
    3 
    4 /**
    5  * Module dependencies.
    6  */
    7 
    8 var fs = require('graceful-fs')
    9   , rm = require('rimraf')
   10   , path = require('path')
   11   , glob = require('glob')
   12   , log = require('npmlog')
   13   , which = require('which')
   14   , mkdirp = require('mkdirp')
   15   , exec = require('child_process').exec
   16   , processRelease = require('./process-release')
   17   , win = process.platform == 'win32'
   18 
   19 exports.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'
   20 
   21 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 
   29   var release = processRelease(argv, gyp, process.version, process.release)
   30     , makeCommand = gyp.opts.make || process.env.MAKE || platformMake
   31     , command = win ? 'msbuild' : makeCommand
   32     , buildDir = path.resolve('build')
   33     , configPath = path.resolve(buildDir, 'config.gypi')
   34     , jobs = gyp.opts.jobs || process.env.JOBS
   35     , buildType
   36     , config
   37     , arch
   38     , nodeDir
   39     , copyDevLib
   40 
   41   loadConfigGypi()
   42 
   43   /**
   44    * Load the "config.gypi" file that was generated during "configure".
   45    */
   46 
   47   function loadConfigGypi () {
   48     fs.readFile(configPath, 'utf8', function (err, data) {
   49       if (err) {
   50         if (err.code == 'ENOENT') {
   51           callback(new Error('You must run `node-gyp configure` first!'))
   52         } else {
   53           callback(err)
   54         }
   55         return
   56       }
   57       config = JSON.parse(data.replace(/\#.+\n/, ''))
   58 
   59       // get the 'arch', 'buildType', and 'nodeDir' vars from the config
   60       buildType = config.target_defaults.default_configuration
   61       arch = config.variables.target_arch
   62       nodeDir = config.variables.nodedir
   63       copyDevLib = config.variables.copy_dev_lib == 'true'
   64 
   65       if ('debug' in gyp.opts) {
   66         buildType = gyp.opts.debug ? 'Debug' : 'Release'
   67       }
   68       if (!buildType) {
   69         buildType = 'Release'
   70       }
   71 
   72       log.verbose('build type', buildType)
   73       log.verbose('architecture', arch)
   74       log.verbose('node dev dir', nodeDir)
   75 
   76       if (win) {
   77         findSolutionFile()
   78       } else {
   79         doWhich()
   80       }
   81     })
   82   }
   83 
   84   /**
   85    * On Windows, find the first build/*.sln file.
   86    */
   87 
   88   function findSolutionFile () {
   89     glob('build/*.sln', function (err, files) {
   90       if (err) return callback(err)
   91       if (files.length === 0) {
   92         return callback(new Error('Could not find *.sln file. Did you run "configure"?'))
   93       }
   94       guessedSolution = files[0]
   95       log.verbose('found first Solution file', guessedSolution)
   96       doWhich()
   97     })
   98   }
   99 
  100   /**
  101    * Uses node-which to locate the msbuild / make executable.
  102    */
  103 
  104   function doWhich () {
  105     // First make sure we have the build command in the PATH
  106     which(command, function (err, execPath) {
  107       if (err) {
  108         if (win && /not found/.test(err.message)) {
  109           // On windows and no 'msbuild' found. Let's guess where it is
  110           findMsbuild()
  111         } else {
  112           // Some other error or 'make' not found on Unix, report that to the user
  113           callback(err)
  114         }
  115         return
  116       }
  117       log.verbose('`which` succeeded for `' + command + '`', execPath)
  118       copyNodeLib()
  119     })
  120   }
  121 
  122   /**
  123    * Search for the location of "msbuild.exe" file on Windows.
  124    */
  125 
  126   function findMsbuild () {
  127     log.verbose('could not find "msbuild.exe" in PATH - finding location in registry')
  128     var notfoundErr = 'Can\'t find "msbuild.exe". Do you have Microsoft Visual Studio C++ 2008+ installed?'
  129     var cmd = 'reg query "HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions" /s'
  130     if (process.arch !== 'ia32')
  131       cmd += ' /reg:32'
  132     exec(cmd, function (err, stdout, stderr) {
  133       if (err) {
  134         return callback(new Error(err.message + '\n' + notfoundErr))
  135       }
  136       var reVers = /ToolsVersions\\([^\\]+)$/i
  137         , rePath = /\r\n[ \t]+MSBuildToolsPath[ \t]+REG_SZ[ \t]+([^\r]+)/i
  138         , msbuilds = []
  139         , r
  140         , msbuildPath
  141       stdout.split('\r\n\r\n').forEach(function(l) {
  142         if (!l) return
  143         l = l.trim()
  144         if (r = reVers.exec(l.substring(0, l.indexOf('\r\n')))) {
  145           var ver = parseFloat(r[1], 10)
  146           if (ver >= 3.5) {
  147             if (r = rePath.exec(l)) {
  148               msbuilds.push({
  149                 version: ver,
  150                 path: r[1]
  151               })
  152             }
  153           }
  154         }
  155       })
  156       msbuilds.sort(function (x, y) {
  157         return (x.version < y.version ? -1 : 1)
  158       })
  159       ;(function verifyMsbuild () {
  160         if (!msbuilds.length) return callback(new Error(notfoundErr))
  161         msbuildPath = path.resolve(msbuilds.pop().path, 'msbuild.exe')
  162         fs.stat(msbuildPath, function (err, stat) {
  163           if (err) {
  164             if (err.code == 'ENOENT') {
  165               if (msbuilds.length) {
  166                 return verifyMsbuild()
  167               } else {
  168                 callback(new Error(notfoundErr))
  169               }
  170             } else {
  171               callback(err)
  172             }
  173             return
  174           }
  175           command = msbuildPath
  176           copyNodeLib()
  177         })
  178       })()
  179     })
  180   }
  181 
  182   /**
  183    * Copies the node.lib file for the current target architecture into the
  184    * current proper dev dir location.
  185    */
  186 
  187   function copyNodeLib () {
  188     if (!win || !copyDevLib) return doBuild()
  189 
  190     var buildDir = path.resolve(nodeDir, buildType)
  191       , archNodeLibPath = path.resolve(nodeDir, arch, release.name + '.lib')
  192       , buildNodeLibPath = path.resolve(buildDir, release.name + '.lib')
  193 
  194     mkdirp(buildDir, function (err, isNew) {
  195       if (err) return callback(err)
  196       log.verbose('"' + buildType + '" dir needed to be created?', isNew)
  197       var rs = fs.createReadStream(archNodeLibPath)
  198         , ws = fs.createWriteStream(buildNodeLibPath)
  199       log.verbose('copying "' + release.name + '.lib" for ' + arch, buildNodeLibPath)
  200       rs.pipe(ws)
  201       rs.on('error', callback)
  202       ws.on('error', callback)
  203       rs.on('end', doBuild)
  204     })
  205   }
  206 
  207   /**
  208    * Actually spawn the process and compile the module.
  209    */
  210 
  211   function doBuild () {
  212 
  213     // Enable Verbose build
  214     var verbose = log.levels[log.level] <= log.levels.verbose
  215     if (!win && verbose) {
  216       argv.push('V=1')
  217     }
  218     if (win && !verbose) {
  219       argv.push('/clp:Verbosity=minimal')
  220     }
  221 
  222     if (win) {
  223       // Turn off the Microsoft logo on Windows
  224       argv.push('/nologo')
  225     }
  226 
  227     // Specify the build type, Release by default
  228     if (win) {
  229       var p = arch === 'x64' ? 'x64' : 'Win32'
  230       argv.push('/p:Configuration=' + buildType + ';Platform=' + p)
  231       if (jobs) {
  232         var j = parseInt(jobs, 10)
  233         if (!isNaN(j) && j > 0) {
  234           argv.push('/m:' + j)
  235         } else if (jobs.toUpperCase() === 'MAX') {
  236           argv.push('/m:' + require('os').cpus().length)
  237         }
  238       }
  239     } else {
  240       argv.push('BUILDTYPE=' + buildType)
  241       // Invoke the Makefile in the 'build' dir.
  242       argv.push('-C')
  243       argv.push('build')
  244       if (jobs) {
  245         var j = parseInt(jobs, 10)
  246         if (!isNaN(j) && j > 0) {
  247           argv.push('--jobs')
  248           argv.push(j)
  249         } else if (jobs.toUpperCase() === 'MAX') {
  250           argv.push('--jobs')
  251           argv.push(require('os').cpus().length)
  252         }
  253       }
  254     }
  255 
  256     if (win) {
  257       // did the user specify their own .sln file?
  258       var hasSln = argv.some(function (arg) {
  259         return path.extname(arg) == '.sln'
  260       })
  261       if (!hasSln) {
  262         argv.unshift(gyp.opts.solution || guessedSolution)
  263       }
  264     }
  265 
  266     var proc = gyp.spawn(command, argv)
  267     proc.on('exit', onExit)
  268   }
  269 
  270   /**
  271    * Invoked after the make/msbuild command exits.
  272    */
  273 
  274   function onExit (code, signal) {
  275     if (code !== 0) {
  276       return callback(new Error('`' + command + '` failed with exit code: ' + code))
  277     }
  278     if (signal) {
  279       return callback(new Error('`' + command + '` got signal: ' + signal))
  280     }
  281     callback()
  282   }
  283 
  284 }