@dry-software/cmake-js 7.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +402 -0
- package/bin/cmake-js +343 -0
- package/changelog.md +225 -0
- package/lib/appCMakeJSConfig.js +58 -0
- package/lib/buildSystem.js +123 -0
- package/lib/cMake.js +362 -0
- package/lib/cmLog.js +61 -0
- package/lib/cpp/win_delay_load_hook.cc +52 -0
- package/lib/dist.js +176 -0
- package/lib/downloader.js +92 -0
- package/lib/environment.js +97 -0
- package/lib/import/Find-VisualStudio.cs +250 -0
- package/lib/import/LICENSE +24 -0
- package/lib/import/README +6 -0
- package/lib/import/find-visualstudio.js +439 -0
- package/lib/import/util.js +70 -0
- package/lib/index.js +12 -0
- package/lib/locateNAN.js +63 -0
- package/lib/locateNodeApi.js +18 -0
- package/lib/npmConfig.js +31 -0
- package/lib/processHelpers.js +53 -0
- package/lib/runtimePaths.js +95 -0
- package/lib/targetOptions.js +33 -0
- package/lib/toolset.js +224 -0
- package/package.json +76 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const CMake = require('./cMake')
|
|
3
|
+
const Dist = require('./dist')
|
|
4
|
+
const CMLog = require('./cmLog')
|
|
5
|
+
const appCMakeJSConfig = require('./appCMakeJSConfig')
|
|
6
|
+
const npmConfig = require('./npmConfig')
|
|
7
|
+
const path = require('path')
|
|
8
|
+
const Toolset = require('./toolset')
|
|
9
|
+
|
|
10
|
+
function isNodeApi(log, projectRoot) {
|
|
11
|
+
try {
|
|
12
|
+
const projectPkgJson = require(path.join(projectRoot, 'package.json'))
|
|
13
|
+
// Make sure the property exists
|
|
14
|
+
return !!projectPkgJson?.binary?.napi_versions
|
|
15
|
+
} catch (e) {
|
|
16
|
+
log.silly('CFG', "'package.json' not found.")
|
|
17
|
+
return false
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
class BuildSystem {
|
|
22
|
+
constructor(options) {
|
|
23
|
+
this.options = options || {}
|
|
24
|
+
this.options.directory = path.resolve(this.options.directory || process.cwd())
|
|
25
|
+
this.options.out = path.resolve(this.options.out || path.join(this.options.directory, 'build'))
|
|
26
|
+
this.log = new CMLog(this.options)
|
|
27
|
+
this.options.isNodeApi = isNodeApi(this.log, this.options.directory)
|
|
28
|
+
const appConfig = appCMakeJSConfig(this.options.directory, this.log)
|
|
29
|
+
const npmOptions = npmConfig(this.log)
|
|
30
|
+
|
|
31
|
+
if (npmOptions && typeof npmOptions === 'object' && Object.keys(npmOptions).length) {
|
|
32
|
+
this.options.runtimeDirectory = npmOptions['nodedir']
|
|
33
|
+
this.options.msvsVersion = npmOptions['msvs_version']
|
|
34
|
+
}
|
|
35
|
+
if (appConfig && typeof appConfig === 'object' && Object.keys(appConfig).length) {
|
|
36
|
+
this.log.verbose('CFG', 'Applying CMake.js config from root package.json:')
|
|
37
|
+
this.log.verbose('CFG', JSON.stringify(appConfig))
|
|
38
|
+
// Applying applications's config, if there is no explicit runtime related options specified
|
|
39
|
+
this.options.runtime = this.options.runtime || appConfig.runtime
|
|
40
|
+
this.options.runtimeVersion = this.options.runtimeVersion || appConfig.runtimeVersion
|
|
41
|
+
this.options.arch = this.options.arch || appConfig.arch
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.log.verbose('CFG', 'Build system options:')
|
|
45
|
+
this.log.verbose('CFG', JSON.stringify(this.options))
|
|
46
|
+
this.cmake = new CMake(this.options)
|
|
47
|
+
this.dist = new Dist(this.options)
|
|
48
|
+
this.toolset = new Toolset(this.options)
|
|
49
|
+
}
|
|
50
|
+
async _ensureInstalled() {
|
|
51
|
+
try {
|
|
52
|
+
await this.toolset.initialize(true)
|
|
53
|
+
if (!this.options.isNodeApi) {
|
|
54
|
+
await this.dist.ensureDownloaded()
|
|
55
|
+
}
|
|
56
|
+
} catch (e) {
|
|
57
|
+
this._showError(e)
|
|
58
|
+
throw e
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
_showError(e) {
|
|
62
|
+
if (this.log === undefined) {
|
|
63
|
+
// handle internal errors (init failed)
|
|
64
|
+
console.error('OMG', e.stack)
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
if (this.log.level === 'verbose' || this.log.level === 'silly') {
|
|
68
|
+
this.log.error('OMG', e.stack)
|
|
69
|
+
} else {
|
|
70
|
+
this.log.error('OMG', e.message)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
install() {
|
|
74
|
+
return this._ensureInstalled()
|
|
75
|
+
}
|
|
76
|
+
async _invokeCMake(method) {
|
|
77
|
+
try {
|
|
78
|
+
await this._ensureInstalled()
|
|
79
|
+
return await this.cmake[method]()
|
|
80
|
+
} catch (e) {
|
|
81
|
+
this._showError(e)
|
|
82
|
+
throw e
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
getConfigureCommand() {
|
|
86
|
+
return this._invokeCMake('getConfigureCommand')
|
|
87
|
+
}
|
|
88
|
+
getCmakeJsLibString() {
|
|
89
|
+
return this._invokeCMake('getCmakeJsLibString')
|
|
90
|
+
}
|
|
91
|
+
getCmakeJsIncludeString() {
|
|
92
|
+
return this._invokeCMake('getCmakeJsIncludeString')
|
|
93
|
+
}
|
|
94
|
+
getCmakeJsSrcString() {
|
|
95
|
+
return this._invokeCMake('getCmakeJsSrcString')
|
|
96
|
+
}
|
|
97
|
+
configure() {
|
|
98
|
+
return this._invokeCMake('configure')
|
|
99
|
+
}
|
|
100
|
+
getBuildCommand() {
|
|
101
|
+
return this._invokeCMake('getBuildCommand')
|
|
102
|
+
}
|
|
103
|
+
build() {
|
|
104
|
+
return this._invokeCMake('build')
|
|
105
|
+
}
|
|
106
|
+
getCleanCommand() {
|
|
107
|
+
return this._invokeCMake('getCleanCommand')
|
|
108
|
+
}
|
|
109
|
+
clean() {
|
|
110
|
+
return this._invokeCMake('clean')
|
|
111
|
+
}
|
|
112
|
+
reconfigure() {
|
|
113
|
+
return this._invokeCMake('reconfigure')
|
|
114
|
+
}
|
|
115
|
+
rebuild() {
|
|
116
|
+
return this._invokeCMake('rebuild')
|
|
117
|
+
}
|
|
118
|
+
compile() {
|
|
119
|
+
return this._invokeCMake('compile')
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
module.exports = BuildSystem
|
package/lib/cMake.js
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const which = require('which')
|
|
3
|
+
const fs = require('fs-extra')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const environment = require('./environment')
|
|
6
|
+
const Dist = require('./dist')
|
|
7
|
+
const CMLog = require('./cmLog')
|
|
8
|
+
const TargetOptions = require('./targetOptions')
|
|
9
|
+
const processHelpers = require('./processHelpers')
|
|
10
|
+
const locateNAN = require('./locateNAN')
|
|
11
|
+
const locateNodeApi = require('./locateNodeApi')
|
|
12
|
+
const npmConfigData = require('rc')('npm')
|
|
13
|
+
const Toolset = require('./toolset')
|
|
14
|
+
const headers = require('node-api-headers')
|
|
15
|
+
|
|
16
|
+
class CMake {
|
|
17
|
+
get path() {
|
|
18
|
+
return this.options.cmakePath || 'cmake'
|
|
19
|
+
}
|
|
20
|
+
get isAvailable() {
|
|
21
|
+
if (this._isAvailable === null) {
|
|
22
|
+
this._isAvailable = CMake.isAvailable(this.options)
|
|
23
|
+
}
|
|
24
|
+
return this._isAvailable
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
constructor(options) {
|
|
28
|
+
this.options = options || {}
|
|
29
|
+
this.log = new CMLog(this.options)
|
|
30
|
+
this.dist = new Dist(this.options)
|
|
31
|
+
this.projectRoot = path.resolve(this.options.directory || process.cwd())
|
|
32
|
+
this.workDir = path.resolve(this.options.out || path.join(this.projectRoot, 'build'))
|
|
33
|
+
this.config = this.options.config || (this.options.debug ? 'Debug' : 'Release')
|
|
34
|
+
this.buildDir = path.join(this.workDir, this.config)
|
|
35
|
+
this._isAvailable = null
|
|
36
|
+
this.targetOptions = new TargetOptions(this.options)
|
|
37
|
+
this.toolset = new Toolset(this.options)
|
|
38
|
+
this.cMakeOptions = this.options.cMakeOptions || {}
|
|
39
|
+
this.extraCMakeArgs = this.options.extraCMakeArgs || []
|
|
40
|
+
this.silent = !!options.silent
|
|
41
|
+
}
|
|
42
|
+
static isAvailable(options) {
|
|
43
|
+
options = options || {}
|
|
44
|
+
try {
|
|
45
|
+
if (options.cmakePath) {
|
|
46
|
+
const stat = fs.lstatSync(options.cmakePath)
|
|
47
|
+
return !stat.isDirectory()
|
|
48
|
+
} else {
|
|
49
|
+
which.sync('cmake')
|
|
50
|
+
return true
|
|
51
|
+
}
|
|
52
|
+
} catch (e) {
|
|
53
|
+
// Ignore
|
|
54
|
+
}
|
|
55
|
+
return false
|
|
56
|
+
}
|
|
57
|
+
static async getGenerators(options, log) {
|
|
58
|
+
const arch = ' [arch]'
|
|
59
|
+
options = options || {}
|
|
60
|
+
const gens = []
|
|
61
|
+
if (CMake.isAvailable(options)) {
|
|
62
|
+
// try parsing machine-readable capabilities (available since CMake 3.7)
|
|
63
|
+
try {
|
|
64
|
+
const stdout = await processHelpers.execFile([options.cmakePath || 'cmake', '-E', 'capabilities'])
|
|
65
|
+
const capabilities = JSON.parse(stdout)
|
|
66
|
+
return capabilities.generators.map((x) => x.name)
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (log) {
|
|
69
|
+
log.verbose('TOOL', 'Failed to query CMake capabilities (CMake is probably older than 3.7)')
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// fall back to parsing help text
|
|
74
|
+
const stdout = await processHelpers.execFile([options.cmakePath || 'cmake', '--help'])
|
|
75
|
+
const hasCr = stdout.includes('\r\n')
|
|
76
|
+
const output = hasCr ? stdout.split('\r\n') : stdout.split('\n')
|
|
77
|
+
let on = false
|
|
78
|
+
output.forEach(function (line, i) {
|
|
79
|
+
if (on) {
|
|
80
|
+
const parts = line.split('=')
|
|
81
|
+
if (
|
|
82
|
+
(parts.length === 2 && parts[0].trim()) ||
|
|
83
|
+
(parts.length === 1 && i !== output.length - 1 && output[i + 1].trim()[0] === '=')
|
|
84
|
+
) {
|
|
85
|
+
let gen = parts[0].trim()
|
|
86
|
+
if (gen.endsWith(arch)) {
|
|
87
|
+
gen = gen.substr(0, gen.length - arch.length)
|
|
88
|
+
}
|
|
89
|
+
gens.push(gen)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (line.trim() === 'Generators') {
|
|
93
|
+
on = true
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
} else {
|
|
97
|
+
throw new Error('CMake is not installed. Install CMake.')
|
|
98
|
+
}
|
|
99
|
+
return gens
|
|
100
|
+
}
|
|
101
|
+
verifyIfAvailable() {
|
|
102
|
+
if (!this.isAvailable) {
|
|
103
|
+
throw new Error(
|
|
104
|
+
"CMake executable is not found. Please use your system's package manager to install it, or you can get installers from there: http://cmake.org.",
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async getConfigureCommand() {
|
|
109
|
+
// Create command:
|
|
110
|
+
let command = [this.path, this.projectRoot, '--no-warn-unused-cli']
|
|
111
|
+
|
|
112
|
+
const D = []
|
|
113
|
+
|
|
114
|
+
// CMake.js watermark
|
|
115
|
+
D.push({ CMAKE_JS_VERSION: environment.cmakeJsVersion })
|
|
116
|
+
|
|
117
|
+
// Build configuration:
|
|
118
|
+
D.push({ CMAKE_BUILD_TYPE: this.config })
|
|
119
|
+
if (environment.isWin) {
|
|
120
|
+
D.push({ CMAKE_RUNTIME_OUTPUT_DIRECTORY: this.workDir })
|
|
121
|
+
} else if (this.workDir.endsWith(this.config)) {
|
|
122
|
+
D.push({ CMAKE_LIBRARY_OUTPUT_DIRECTORY: this.workDir })
|
|
123
|
+
} else {
|
|
124
|
+
D.push({ CMAKE_LIBRARY_OUTPUT_DIRECTORY: this.buildDir })
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// In some configurations MD builds will crash upon attempting to free memory.
|
|
128
|
+
// This tries to encourage MT builds which are larger but less likely to have this crash.
|
|
129
|
+
D.push({ CMAKE_MSVC_RUNTIME_LIBRARY: 'MultiThreaded$<$<CONFIG:Debug>:Debug>' })
|
|
130
|
+
|
|
131
|
+
// Includes:
|
|
132
|
+
const includesString = await this.getCmakeJsIncludeString()
|
|
133
|
+
D.push({ CMAKE_JS_INC: includesString })
|
|
134
|
+
|
|
135
|
+
// Sources:
|
|
136
|
+
const srcsString = this.getCmakeJsSrcString()
|
|
137
|
+
D.push({ CMAKE_JS_SRC: srcsString })
|
|
138
|
+
|
|
139
|
+
// Runtime:
|
|
140
|
+
D.push({ NODE_RUNTIME: this.targetOptions.runtime })
|
|
141
|
+
D.push({ NODE_RUNTIMEVERSION: this.targetOptions.runtimeVersion })
|
|
142
|
+
D.push({ NODE_ARCH: this.targetOptions.arch })
|
|
143
|
+
|
|
144
|
+
if (environment.isOSX) {
|
|
145
|
+
if (this.targetOptions.arch) {
|
|
146
|
+
let xcodeArch = this.targetOptions.arch
|
|
147
|
+
if (xcodeArch === 'x64') xcodeArch = 'x86_64'
|
|
148
|
+
D.push({ CMAKE_OSX_ARCHITECTURES: xcodeArch })
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Custom options
|
|
153
|
+
for (const [key, value] of Object.entries(this.cMakeOptions)) {
|
|
154
|
+
D.push({ [key]: value })
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Toolset:
|
|
158
|
+
await this.toolset.initialize(false)
|
|
159
|
+
|
|
160
|
+
const libsString = this.getCmakeJsLibString()
|
|
161
|
+
D.push({ CMAKE_JS_LIB: libsString })
|
|
162
|
+
|
|
163
|
+
if (environment.isWin) {
|
|
164
|
+
const nodeLibDefPath = this.getNodeLibDefPath()
|
|
165
|
+
if (nodeLibDefPath) {
|
|
166
|
+
const nodeLibPath = path.join(this.workDir, 'node.lib')
|
|
167
|
+
D.push({ CMAKE_JS_NODELIB_DEF: nodeLibDefPath })
|
|
168
|
+
D.push({ CMAKE_JS_NODELIB_TARGET: nodeLibPath })
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (this.toolset.generator) {
|
|
173
|
+
command.push('-G', this.toolset.generator)
|
|
174
|
+
}
|
|
175
|
+
if (this.toolset.platform) {
|
|
176
|
+
command.push('-A', this.toolset.platform)
|
|
177
|
+
}
|
|
178
|
+
if (this.toolset.toolset) {
|
|
179
|
+
command.push('-T', this.toolset.toolset)
|
|
180
|
+
}
|
|
181
|
+
if (this.toolset.cppCompilerPath) {
|
|
182
|
+
D.push({ CMAKE_CXX_COMPILER: this.toolset.cppCompilerPath })
|
|
183
|
+
}
|
|
184
|
+
if (this.toolset.cCompilerPath) {
|
|
185
|
+
D.push({ CMAKE_C_COMPILER: this.toolset.cCompilerPath })
|
|
186
|
+
}
|
|
187
|
+
if (this.toolset.compilerFlags.length) {
|
|
188
|
+
D.push({ CMAKE_CXX_FLAGS: this.toolset.compilerFlags.join(' ') })
|
|
189
|
+
}
|
|
190
|
+
if (this.toolset.linkerFlags.length) {
|
|
191
|
+
D.push({ CMAKE_SHARED_LINKER_FLAGS: this.toolset.linkerFlags.join(' ') })
|
|
192
|
+
}
|
|
193
|
+
if (this.toolset.makePath) {
|
|
194
|
+
D.push({ CMAKE_MAKE_PROGRAM: this.toolset.makePath })
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Load NPM config
|
|
198
|
+
for (const [key, value] of Object.entries(npmConfigData)) {
|
|
199
|
+
if (key.startsWith('cmake_')) {
|
|
200
|
+
const sk = key.substr(6)
|
|
201
|
+
if (sk && value) {
|
|
202
|
+
D.push({ [sk]: value })
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
command = command.concat(
|
|
208
|
+
D.map(function (p) {
|
|
209
|
+
return '-D' + Object.keys(p)[0] + '=' + Object.values(p)[0]
|
|
210
|
+
}),
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
return command.concat(this.extraCMakeArgs)
|
|
214
|
+
}
|
|
215
|
+
getCmakeJsLibString() {
|
|
216
|
+
const libs = []
|
|
217
|
+
if (environment.isWin) {
|
|
218
|
+
const nodeLibDefPath = this.getNodeLibDefPath()
|
|
219
|
+
if (nodeLibDefPath) {
|
|
220
|
+
libs.push(path.join(this.workDir, 'node.lib'))
|
|
221
|
+
} else {
|
|
222
|
+
libs.push(...this.dist.winLibs)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return libs.join(';')
|
|
226
|
+
}
|
|
227
|
+
async getCmakeJsIncludeString() {
|
|
228
|
+
let incPaths = []
|
|
229
|
+
if (!this.options.isNodeApi) {
|
|
230
|
+
// Include and lib:
|
|
231
|
+
if (this.dist.headerOnly) {
|
|
232
|
+
incPaths = [path.join(this.dist.internalPath, '/include/node')]
|
|
233
|
+
} else {
|
|
234
|
+
const nodeH = path.join(this.dist.internalPath, '/src')
|
|
235
|
+
const v8H = path.join(this.dist.internalPath, '/deps/v8/include')
|
|
236
|
+
const uvH = path.join(this.dist.internalPath, '/deps/uv/include')
|
|
237
|
+
incPaths = [nodeH, v8H, uvH]
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// NAN
|
|
241
|
+
const nanH = await locateNAN(this.projectRoot)
|
|
242
|
+
if (nanH) {
|
|
243
|
+
incPaths.push(nanH)
|
|
244
|
+
}
|
|
245
|
+
} else {
|
|
246
|
+
// Base headers
|
|
247
|
+
const apiHeaders = require('node-api-headers')
|
|
248
|
+
incPaths.push(apiHeaders.include_dir)
|
|
249
|
+
|
|
250
|
+
// Node-api
|
|
251
|
+
const napiH = await locateNodeApi(this.projectRoot)
|
|
252
|
+
if (napiH) {
|
|
253
|
+
incPaths.push(napiH)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return incPaths.join(';')
|
|
258
|
+
}
|
|
259
|
+
getCmakeJsSrcString() {
|
|
260
|
+
const srcPaths = []
|
|
261
|
+
if (environment.isWin) {
|
|
262
|
+
const delayHook = path.normalize(path.join(__dirname, 'cpp', 'win_delay_load_hook.cc'))
|
|
263
|
+
|
|
264
|
+
srcPaths.push(delayHook.replace(/\\/gm, '/'))
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return srcPaths.join(';')
|
|
268
|
+
}
|
|
269
|
+
getNodeLibDefPath() {
|
|
270
|
+
return environment.isWin && this.options.isNodeApi ? headers.def_paths.node_api_def : undefined
|
|
271
|
+
}
|
|
272
|
+
async configure() {
|
|
273
|
+
this.verifyIfAvailable()
|
|
274
|
+
|
|
275
|
+
this.log.info('CMD', 'CONFIGURE')
|
|
276
|
+
const listPath = path.join(this.projectRoot, 'CMakeLists.txt')
|
|
277
|
+
const command = await this.getConfigureCommand()
|
|
278
|
+
|
|
279
|
+
try {
|
|
280
|
+
await fs.lstat(listPath)
|
|
281
|
+
} catch (e) {
|
|
282
|
+
throw new Error("'" + listPath + "' not found.")
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
try {
|
|
286
|
+
await fs.ensureDir(this.workDir)
|
|
287
|
+
} catch (e) {
|
|
288
|
+
// Ignore
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const cwd = process.cwd()
|
|
292
|
+
process.chdir(this.workDir)
|
|
293
|
+
try {
|
|
294
|
+
await this._run(command)
|
|
295
|
+
} finally {
|
|
296
|
+
process.chdir(cwd)
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async ensureConfigured() {
|
|
300
|
+
try {
|
|
301
|
+
await fs.lstat(path.join(this.workDir, 'CMakeCache.txt'))
|
|
302
|
+
} catch (e) {
|
|
303
|
+
await this.configure()
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
getBuildCommand() {
|
|
307
|
+
const command = [this.path, '--build', this.workDir, '--config', this.config]
|
|
308
|
+
if (this.options.target) {
|
|
309
|
+
command.push('--target', this.options.target)
|
|
310
|
+
}
|
|
311
|
+
if (this.options.parallel) {
|
|
312
|
+
command.push('--parallel', this.options.parallel)
|
|
313
|
+
}
|
|
314
|
+
return Promise.resolve(command.concat(this.extraCMakeArgs))
|
|
315
|
+
}
|
|
316
|
+
async build() {
|
|
317
|
+
this.verifyIfAvailable()
|
|
318
|
+
|
|
319
|
+
await this.ensureConfigured()
|
|
320
|
+
const buildCommand = await this.getBuildCommand()
|
|
321
|
+
this.log.info('CMD', 'BUILD')
|
|
322
|
+
await this._run(buildCommand)
|
|
323
|
+
}
|
|
324
|
+
getCleanCommand() {
|
|
325
|
+
return [this.path, '-E', 'remove_directory', this.workDir].concat(this.extraCMakeArgs)
|
|
326
|
+
}
|
|
327
|
+
clean() {
|
|
328
|
+
this.verifyIfAvailable()
|
|
329
|
+
|
|
330
|
+
this.log.info('CMD', 'CLEAN')
|
|
331
|
+
return this._run(this.getCleanCommand())
|
|
332
|
+
}
|
|
333
|
+
async reconfigure() {
|
|
334
|
+
this.extraCMakeArgs = []
|
|
335
|
+
await this.clean()
|
|
336
|
+
await this.configure()
|
|
337
|
+
}
|
|
338
|
+
async rebuild() {
|
|
339
|
+
this.extraCMakeArgs = []
|
|
340
|
+
await this.clean()
|
|
341
|
+
await this.build()
|
|
342
|
+
}
|
|
343
|
+
async compile() {
|
|
344
|
+
this.extraCMakeArgs = []
|
|
345
|
+
try {
|
|
346
|
+
await this.build()
|
|
347
|
+
} catch (e) {
|
|
348
|
+
this.log.info('REP', 'Build has been failed, trying to do a full rebuild.')
|
|
349
|
+
await this.rebuild()
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
_run(command) {
|
|
353
|
+
this.log.info('RUN', command)
|
|
354
|
+
return processHelpers.run(command, { silent: this.silent })
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async getGenerators() {
|
|
358
|
+
return CMake.getGenerators(this.options, this.log)
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
module.exports = CMake
|
package/lib/cmLog.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
const log = require('npmlog')
|
|
3
|
+
|
|
4
|
+
class CMLog {
|
|
5
|
+
get level() {
|
|
6
|
+
if (this.options.noLog) {
|
|
7
|
+
return 'silly'
|
|
8
|
+
} else {
|
|
9
|
+
return log.level
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.options = options || {}
|
|
15
|
+
this.debug = require('debug')(this.options.logName || 'cmake-js')
|
|
16
|
+
}
|
|
17
|
+
silly(cat, msg) {
|
|
18
|
+
if (this.options.noLog) {
|
|
19
|
+
this.debug(cat + ': ' + msg)
|
|
20
|
+
} else {
|
|
21
|
+
log.silly(cat, msg)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
verbose(cat, msg) {
|
|
25
|
+
if (this.options.noLog) {
|
|
26
|
+
this.debug(cat + ': ' + msg)
|
|
27
|
+
} else {
|
|
28
|
+
log.verbose(cat, msg)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
info(cat, msg) {
|
|
32
|
+
if (this.options.noLog) {
|
|
33
|
+
this.debug(cat + ': ' + msg)
|
|
34
|
+
} else {
|
|
35
|
+
log.info(cat, msg)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
warn(cat, msg) {
|
|
39
|
+
if (this.options.noLog) {
|
|
40
|
+
this.debug(cat + ': ' + msg)
|
|
41
|
+
} else {
|
|
42
|
+
log.warn(cat, msg)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
http(cat, msg) {
|
|
46
|
+
if (this.options.noLog) {
|
|
47
|
+
this.debug(cat + ': ' + msg)
|
|
48
|
+
} else {
|
|
49
|
+
log.http(cat, msg)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
error(cat, msg) {
|
|
53
|
+
if (this.options.noLog) {
|
|
54
|
+
this.debug(cat + ': ' + msg)
|
|
55
|
+
} else {
|
|
56
|
+
log.error(cat, msg)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = CMLog
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* When this file is linked to a DLL, it sets up a delay-load hook that
|
|
3
|
+
* intervenes when the DLL is trying to load 'node.exe' or 'iojs.exe'
|
|
4
|
+
* dynamically. Instead of trying to locate the .exe file it'll just return
|
|
5
|
+
* a handle to the process image.
|
|
6
|
+
*
|
|
7
|
+
* This allows compiled addons to work when node.exe or iojs.exe is renamed.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
#ifdef _MSC_VER
|
|
11
|
+
|
|
12
|
+
#ifndef WIN32_LEAN_AND_MEAN
|
|
13
|
+
#define WIN32_LEAN_AND_MEAN
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
#include <windows.h>
|
|
17
|
+
|
|
18
|
+
#include <delayimp.h>
|
|
19
|
+
#include <string.h>
|
|
20
|
+
|
|
21
|
+
static HMODULE node_dll = NULL;
|
|
22
|
+
static HMODULE nw_dll = NULL;
|
|
23
|
+
|
|
24
|
+
static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo* info) {
|
|
25
|
+
if (event == dliNotePreGetProcAddress) {
|
|
26
|
+
FARPROC ret = NULL;
|
|
27
|
+
ret = GetProcAddress(node_dll, info->dlp.szProcName);
|
|
28
|
+
if (ret)
|
|
29
|
+
return ret;
|
|
30
|
+
ret = GetProcAddress(nw_dll, info->dlp.szProcName);
|
|
31
|
+
return ret;
|
|
32
|
+
}
|
|
33
|
+
if (event == dliStartProcessing) {
|
|
34
|
+
node_dll = GetModuleHandleA("node.dll");
|
|
35
|
+
nw_dll = GetModuleHandleA("nw.dll");
|
|
36
|
+
return NULL;
|
|
37
|
+
}
|
|
38
|
+
if (event != dliNotePreLoadLibrary)
|
|
39
|
+
return NULL;
|
|
40
|
+
|
|
41
|
+
if (_stricmp(info->szDll, "node.exe") != 0)
|
|
42
|
+
return NULL;
|
|
43
|
+
|
|
44
|
+
// Fall back to the current process
|
|
45
|
+
if(!node_dll) node_dll = GetModuleHandleA(NULL);
|
|
46
|
+
|
|
47
|
+
return (FARPROC) node_dll;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
decltype(__pfnDliNotifyHook2) __pfnDliNotifyHook2 = load_exe_hook;
|
|
51
|
+
|
|
52
|
+
#endif
|