source: node_modules/node-gyp/lib/configure.js@ 81bc7da

finki-main main
Last change on this file since 81bc7da was 81bc7da, checked in by Klimentina Efremova <klimentina08642@…>, 3 months ago

Initial commit

  • Property mode set to 100644
File size: 9.2 KB
RevLine 
[81bc7da]1'use strict'
2
3const fs = require('graceful-fs')
4const path = require('path')
5const log = require('npmlog')
6const os = require('os')
7const processRelease = require('./process-release')
8const win = process.platform === 'win32'
9const findNodeDirectory = require('./find-node-directory')
10const createConfigGypi = require('./create-config-gypi')
11const msgFormat = require('util').format
12var findPython = require('./find-python')
13if (win) {
14 var findVisualStudio = require('./find-visualstudio')
15}
16
17function configure (gyp, argv, callback) {
18 var python
19 var buildDir = path.resolve('build')
20 var configNames = ['config.gypi', 'common.gypi']
21 var configs = []
22 var nodeDir
23 var release = processRelease(argv, gyp, process.version, process.release)
24
25 findPython(gyp.opts.python, function (err, found) {
26 if (err) {
27 callback(err)
28 } else {
29 python = found
30 getNodeDir()
31 }
32 })
33
34 function getNodeDir () {
35 // 'python' should be set by now
36 process.env.PYTHON = python
37
38 if (gyp.opts.nodedir) {
39 // --nodedir was specified. use that for the dev files
40 nodeDir = gyp.opts.nodedir.replace(/^~/, os.homedir())
41
42 log.verbose('get node dir', 'compiling against specified --nodedir dev files: %s', nodeDir)
43 createBuildDir()
44 } else {
45 // if no --nodedir specified, ensure node dependencies are installed
46 if ('v' + release.version !== process.version) {
47 // if --target was given, then determine a target version to compile for
48 log.verbose('get node dir', 'compiling against --target node version: %s', release.version)
49 } else {
50 // if no --target was specified then use the current host node version
51 log.verbose('get node dir', 'no --target version specified, falling back to host node version: %s', release.version)
52 }
53
54 if (!release.semver) {
55 // could not parse the version string with semver
56 return callback(new Error('Invalid version number: ' + release.version))
57 }
58
59 // If the tarball option is set, always remove and reinstall the headers
60 // into devdir. Otherwise only install if they're not already there.
61 gyp.opts.ensure = !gyp.opts.tarball
62
63 gyp.commands.install([release.version], function (err) {
64 if (err) {
65 return callback(err)
66 }
67 log.verbose('get node dir', 'target node version installed:', release.versionDir)
68 nodeDir = path.resolve(gyp.devDir, release.versionDir)
69 createBuildDir()
70 })
71 }
72 }
73
74 function createBuildDir () {
75 log.verbose('build dir', 'attempting to create "build" dir: %s', buildDir)
76 fs.mkdir(buildDir, { recursive: true }, function (err, isNew) {
77 if (err) {
78 return callback(err)
79 }
80 log.verbose(
81 'build dir', '"build" dir needed to be created?', isNew ? 'Yes' : 'No'
82 )
83 if (win) {
84 findVisualStudio(release.semver, gyp.opts.msvs_version,
85 createConfigFile)
86 } else {
87 createConfigFile()
88 }
89 })
90 }
91
92 function createConfigFile (err, vsInfo) {
93 if (err) {
94 return callback(err)
95 }
96 if (process.platform === 'win32') {
97 process.env.GYP_MSVS_VERSION = Math.min(vsInfo.versionYear, 2015)
98 process.env.GYP_MSVS_OVERRIDE_PATH = vsInfo.path
99 }
100 createConfigGypi({ gyp, buildDir, nodeDir, vsInfo }).then(configPath => {
101 configs.push(configPath)
102 findConfigs()
103 }).catch(err => {
104 callback(err)
105 })
106 }
107
108 function findConfigs () {
109 var name = configNames.shift()
110 if (!name) {
111 return runGyp()
112 }
113 var fullPath = path.resolve(name)
114
115 log.verbose(name, 'checking for gypi file: %s', fullPath)
116 fs.stat(fullPath, function (err) {
117 if (err) {
118 if (err.code === 'ENOENT') {
119 findConfigs() // check next gypi filename
120 } else {
121 callback(err)
122 }
123 } else {
124 log.verbose(name, 'found gypi file')
125 configs.push(fullPath)
126 findConfigs()
127 }
128 })
129 }
130
131 function runGyp (err) {
132 if (err) {
133 return callback(err)
134 }
135
136 if (!~argv.indexOf('-f') && !~argv.indexOf('--format')) {
137 if (win) {
138 log.verbose('gyp', 'gyp format was not specified; forcing "msvs"')
139 // force the 'make' target for non-Windows
140 argv.push('-f', 'msvs')
141 } else {
142 log.verbose('gyp', 'gyp format was not specified; forcing "make"')
143 // force the 'make' target for non-Windows
144 argv.push('-f', 'make')
145 }
146 }
147
148 // include all the ".gypi" files that were found
149 configs.forEach(function (config) {
150 argv.push('-I', config)
151 })
152
153 // For AIX and z/OS we need to set up the path to the exports file
154 // which contains the symbols needed for linking.
155 var nodeExpFile
156 if (process.platform === 'aix' || process.platform === 'os390') {
157 var ext = process.platform === 'aix' ? 'exp' : 'x'
158 var nodeRootDir = findNodeDirectory()
159 var candidates
160
161 if (process.platform === 'aix') {
162 candidates = [
163 'include/node/node',
164 'out/Release/node',
165 'out/Debug/node',
166 'node'
167 ].map(function (file) {
168 return file + '.' + ext
169 })
170 } else {
171 candidates = [
172 'out/Release/obj.target/libnode',
173 'out/Debug/obj.target/libnode',
174 'lib/libnode'
175 ].map(function (file) {
176 return file + '.' + ext
177 })
178 }
179
180 var logprefix = 'find exports file'
181 nodeExpFile = findAccessibleSync(logprefix, nodeRootDir, candidates)
182 if (nodeExpFile !== undefined) {
183 log.verbose(logprefix, 'Found exports file: %s', nodeExpFile)
184 } else {
185 var msg = msgFormat('Could not find node.%s file in %s', ext, nodeRootDir)
186 log.error(logprefix, 'Could not find exports file')
187 return callback(new Error(msg))
188 }
189 }
190
191 // this logic ported from the old `gyp_addon` python file
192 var gypScript = path.resolve(__dirname, '..', 'gyp', 'gyp_main.py')
193 var addonGypi = path.resolve(__dirname, '..', 'addon.gypi')
194 var commonGypi = path.resolve(nodeDir, 'include/node/common.gypi')
195 fs.stat(commonGypi, function (err) {
196 if (err) {
197 commonGypi = path.resolve(nodeDir, 'common.gypi')
198 }
199
200 var outputDir = 'build'
201 if (win) {
202 // Windows expects an absolute path
203 outputDir = buildDir
204 }
205 var nodeGypDir = path.resolve(__dirname, '..')
206
207 var nodeLibFile = path.join(nodeDir,
208 !gyp.opts.nodedir ? '<(target_arch)' : '$(Configuration)',
209 release.name + '.lib')
210
211 argv.push('-I', addonGypi)
212 argv.push('-I', commonGypi)
213 argv.push('-Dlibrary=shared_library')
214 argv.push('-Dvisibility=default')
215 argv.push('-Dnode_root_dir=' + nodeDir)
216 if (process.platform === 'aix' || process.platform === 'os390') {
217 argv.push('-Dnode_exp_file=' + nodeExpFile)
218 }
219 argv.push('-Dnode_gyp_dir=' + nodeGypDir)
220
221 // Do this to keep Cygwin environments happy, else the unescaped '\' gets eaten up,
222 // resulting in bad paths, Ex c:parentFolderfolderanotherFolder instead of c:\parentFolder\folder\anotherFolder
223 if (win) {
224 nodeLibFile = nodeLibFile.replace(/\\/g, '\\\\')
225 }
226 argv.push('-Dnode_lib_file=' + nodeLibFile)
227 argv.push('-Dmodule_root_dir=' + process.cwd())
228 argv.push('-Dnode_engine=' +
229 (gyp.opts.node_engine || process.jsEngine || 'v8'))
230 argv.push('--depth=.')
231 argv.push('--no-parallel')
232
233 // tell gyp to write the Makefile/Solution files into output_dir
234 argv.push('--generator-output', outputDir)
235
236 // tell make to write its output into the same dir
237 argv.push('-Goutput_dir=.')
238
239 // enforce use of the "binding.gyp" file
240 argv.unshift('binding.gyp')
241
242 // execute `gyp` from the current target nodedir
243 argv.unshift(gypScript)
244
245 // make sure python uses files that came with this particular node package
246 var pypath = [path.join(__dirname, '..', 'gyp', 'pylib')]
247 if (process.env.PYTHONPATH) {
248 pypath.push(process.env.PYTHONPATH)
249 }
250 process.env.PYTHONPATH = pypath.join(win ? ';' : ':')
251
252 var cp = gyp.spawn(python, argv)
253 cp.on('exit', onCpExit)
254 })
255 }
256
257 function onCpExit (code) {
258 if (code !== 0) {
259 callback(new Error('`gyp` failed with exit code: ' + code))
260 } else {
261 // we're done
262 callback()
263 }
264 }
265}
266
267/**
268 * Returns the first file or directory from an array of candidates that is
269 * readable by the current user, or undefined if none of the candidates are
270 * readable.
271 */
272function findAccessibleSync (logprefix, dir, candidates) {
273 for (var next = 0; next < candidates.length; next++) {
274 var candidate = path.resolve(dir, candidates[next])
275 try {
276 var fd = fs.openSync(candidate, 'r')
277 } catch (e) {
278 // this candidate was not found or not readable, do nothing
279 log.silly(logprefix, 'Could not open %s: %s', candidate, e.message)
280 continue
281 }
282 fs.closeSync(fd)
283 log.silly(logprefix, 'Found readable %s', candidate)
284 return candidate
285 }
286
287 return undefined
288}
289
290module.exports = configure
291module.exports.test = {
292 findAccessibleSync: findAccessibleSync
293}
294module.exports.usage = 'Generates ' + (win ? 'MSVC project files' : 'a Makefile') + ' for the current module'
Note: See TracBrowser for help on using the repository browser.