@flun/nodejs-mobile-gyp 1.0.1
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/CHANGELOG.md +36 -0
- package/LICENSE +29 -0
- package/README.md +252 -0
- package/addon.gypi +209 -0
- package/bin/node-gyp.js +144 -0
- package/gyp/LICENSE +28 -0
- package/gyp/README.md +30 -0
- package/gyp/data/win/large-pdb-shim.cc +12 -0
- package/gyp/gyp +8 -0
- package/gyp/gyp.bat +5 -0
- package/gyp/gyp_main.py +45 -0
- package/gyp/pylib/gyp/MSVSNew.py +365 -0
- package/gyp/pylib/gyp/MSVSProject.py +206 -0
- package/gyp/pylib/gyp/MSVSSettings.py +1270 -0
- package/gyp/pylib/gyp/MSVSToolFile.py +59 -0
- package/gyp/pylib/gyp/MSVSUserFile.py +153 -0
- package/gyp/pylib/gyp/MSVSUtil.py +271 -0
- package/gyp/pylib/gyp/MSVSVersion.py +574 -0
- package/gyp/pylib/gyp/__init__.py +692 -0
- package/gyp/pylib/gyp/common.py +654 -0
- package/gyp/pylib/gyp/easy_xml.py +169 -0
- package/gyp/pylib/gyp/flock_tool.py +55 -0
- package/gyp/pylib/gyp/generator/__init__.py +0 -0
- package/gyp/pylib/gyp/generator/analyzer.py +804 -0
- package/gyp/pylib/gyp/generator/android.py +1173 -0
- package/gyp/pylib/gyp/generator/cmake.py +1318 -0
- package/gyp/pylib/gyp/generator/compile_commands_json.py +123 -0
- package/gyp/pylib/gyp/generator/dump_dependency_json.py +103 -0
- package/gyp/pylib/gyp/generator/eclipse.py +461 -0
- package/gyp/pylib/gyp/generator/gypd.py +89 -0
- package/gyp/pylib/gyp/generator/gypsh.py +58 -0
- package/gyp/pylib/gyp/generator/make.py +2710 -0
- package/gyp/pylib/gyp/generator/msvs.py +3981 -0
- package/gyp/pylib/gyp/generator/ninja.py +2933 -0
- package/gyp/pylib/gyp/generator/xcode.py +1397 -0
- package/gyp/pylib/gyp/input.py +3115 -0
- package/gyp/pylib/gyp/mac_tool.py +771 -0
- package/gyp/pylib/gyp/msvs_emulation.py +1262 -0
- package/gyp/pylib/gyp/ninja_syntax.py +174 -0
- package/gyp/pylib/gyp/simple_copy.py +61 -0
- package/gyp/pylib/gyp/win_tool.py +373 -0
- package/gyp/pylib/gyp/xcode_emulation.py +1935 -0
- package/gyp/pylib/gyp/xcode_ninja.py +302 -0
- package/gyp/pylib/gyp/xcodeproj_file.py +3198 -0
- package/gyp/pylib/gyp/xml_fix.py +65 -0
- package/gyp/pylib/packaging/LICENSE +3 -0
- package/gyp/pylib/packaging/LICENSE.APACHE +177 -0
- package/gyp/pylib/packaging/LICENSE.BSD +23 -0
- package/gyp/pylib/packaging/__init__.py +15 -0
- package/gyp/pylib/packaging/_elffile.py +108 -0
- package/gyp/pylib/packaging/_manylinux.py +252 -0
- package/gyp/pylib/packaging/_musllinux.py +83 -0
- package/gyp/pylib/packaging/_parser.py +359 -0
- package/gyp/pylib/packaging/_structures.py +61 -0
- package/gyp/pylib/packaging/_tokenizer.py +192 -0
- package/gyp/pylib/packaging/markers.py +252 -0
- package/gyp/pylib/packaging/metadata.py +825 -0
- package/gyp/pylib/packaging/py.typed +0 -0
- package/gyp/pylib/packaging/requirements.py +90 -0
- package/gyp/pylib/packaging/specifiers.py +1030 -0
- package/gyp/pylib/packaging/tags.py +553 -0
- package/gyp/pylib/packaging/utils.py +172 -0
- package/gyp/pylib/packaging/version.py +563 -0
- package/lib/Find-VisualStudio.cs +250 -0
- package/lib/build.js +221 -0
- package/lib/clean.js +19 -0
- package/lib/configure.js +295 -0
- package/lib/create-config-gypi.js +163 -0
- package/lib/download.js +44 -0
- package/lib/find-node-directory.js +62 -0
- package/lib/find-python.js +303 -0
- package/lib/find-visualstudio.js +448 -0
- package/lib/install.js +419 -0
- package/lib/list.js +30 -0
- package/lib/log.js +174 -0
- package/lib/node-gyp.js +201 -0
- package/lib/process-release.js +144 -0
- package/lib/rebuild.js +14 -0
- package/lib/remove.js +47 -0
- package/lib/util.js +83 -0
- package/package.json +72 -0
- package/src/win_delay_load_hook.cc +39 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
// Copyright 2017 - Refael Ackermann
|
|
2
|
+
// Distributed under MIT style license
|
|
3
|
+
// See accompanying file LICENSE at https://github.com/node4good/windows-autoconf
|
|
4
|
+
|
|
5
|
+
// Usage:
|
|
6
|
+
// powershell -ExecutionPolicy Unrestricted -Command "Add-Type -Path Find-VisualStudio.cs; [VisualStudioConfiguration.Main]::PrintJson()"
|
|
7
|
+
// This script needs to be compatible with PowerShell v2 to run on Windows 2008R2 and Windows 7.
|
|
8
|
+
|
|
9
|
+
using System;
|
|
10
|
+
using System.Text;
|
|
11
|
+
using System.Runtime.InteropServices;
|
|
12
|
+
using System.Collections.Generic;
|
|
13
|
+
|
|
14
|
+
namespace VisualStudioConfiguration
|
|
15
|
+
{
|
|
16
|
+
[Flags]
|
|
17
|
+
public enum InstanceState : uint
|
|
18
|
+
{
|
|
19
|
+
None = 0,
|
|
20
|
+
Local = 1,
|
|
21
|
+
Registered = 2,
|
|
22
|
+
NoRebootRequired = 4,
|
|
23
|
+
NoErrors = 8,
|
|
24
|
+
Complete = 4294967295,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
[Guid("6380BCFF-41D3-4B2E-8B2E-BF8A6810C848")]
|
|
28
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
29
|
+
[ComImport]
|
|
30
|
+
public interface IEnumSetupInstances
|
|
31
|
+
{
|
|
32
|
+
|
|
33
|
+
void Next([MarshalAs(UnmanagedType.U4), In] int celt,
|
|
34
|
+
[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface), Out] ISetupInstance[] rgelt,
|
|
35
|
+
[MarshalAs(UnmanagedType.U4)] out int pceltFetched);
|
|
36
|
+
|
|
37
|
+
void Skip([MarshalAs(UnmanagedType.U4), In] int celt);
|
|
38
|
+
|
|
39
|
+
void Reset();
|
|
40
|
+
|
|
41
|
+
[return: MarshalAs(UnmanagedType.Interface)]
|
|
42
|
+
IEnumSetupInstances Clone();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
|
|
46
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
47
|
+
[ComImport]
|
|
48
|
+
public interface ISetupConfiguration
|
|
49
|
+
{
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
[Guid("26AAB78C-4A60-49D6-AF3B-3C35BC93365D")]
|
|
53
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
54
|
+
[ComImport]
|
|
55
|
+
public interface ISetupConfiguration2 : ISetupConfiguration
|
|
56
|
+
{
|
|
57
|
+
|
|
58
|
+
[return: MarshalAs(UnmanagedType.Interface)]
|
|
59
|
+
IEnumSetupInstances EnumInstances();
|
|
60
|
+
|
|
61
|
+
[return: MarshalAs(UnmanagedType.Interface)]
|
|
62
|
+
ISetupInstance GetInstanceForCurrentProcess();
|
|
63
|
+
|
|
64
|
+
[return: MarshalAs(UnmanagedType.Interface)]
|
|
65
|
+
ISetupInstance GetInstanceForPath([MarshalAs(UnmanagedType.LPWStr), In] string path);
|
|
66
|
+
|
|
67
|
+
[return: MarshalAs(UnmanagedType.Interface)]
|
|
68
|
+
IEnumSetupInstances EnumAllInstances();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
[Guid("B41463C3-8866-43B5-BC33-2B0676F7F42E")]
|
|
72
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
73
|
+
[ComImport]
|
|
74
|
+
public interface ISetupInstance
|
|
75
|
+
{
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
[Guid("89143C9A-05AF-49B0-B717-72E218A2185C")]
|
|
79
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
80
|
+
[ComImport]
|
|
81
|
+
public interface ISetupInstance2 : ISetupInstance
|
|
82
|
+
{
|
|
83
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
84
|
+
string GetInstanceId();
|
|
85
|
+
|
|
86
|
+
[return: MarshalAs(UnmanagedType.Struct)]
|
|
87
|
+
System.Runtime.InteropServices.ComTypes.FILETIME GetInstallDate();
|
|
88
|
+
|
|
89
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
90
|
+
string GetInstallationName();
|
|
91
|
+
|
|
92
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
93
|
+
string GetInstallationPath();
|
|
94
|
+
|
|
95
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
96
|
+
string GetInstallationVersion();
|
|
97
|
+
|
|
98
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
99
|
+
string GetDisplayName([MarshalAs(UnmanagedType.U4), In] int lcid);
|
|
100
|
+
|
|
101
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
102
|
+
string GetDescription([MarshalAs(UnmanagedType.U4), In] int lcid);
|
|
103
|
+
|
|
104
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
105
|
+
string ResolvePath([MarshalAs(UnmanagedType.LPWStr), In] string pwszRelativePath);
|
|
106
|
+
|
|
107
|
+
[return: MarshalAs(UnmanagedType.U4)]
|
|
108
|
+
InstanceState GetState();
|
|
109
|
+
|
|
110
|
+
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
|
|
111
|
+
ISetupPackageReference[] GetPackages();
|
|
112
|
+
|
|
113
|
+
ISetupPackageReference GetProduct();
|
|
114
|
+
|
|
115
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
116
|
+
string GetProductPath();
|
|
117
|
+
|
|
118
|
+
[return: MarshalAs(UnmanagedType.VariantBool)]
|
|
119
|
+
bool IsLaunchable();
|
|
120
|
+
|
|
121
|
+
[return: MarshalAs(UnmanagedType.VariantBool)]
|
|
122
|
+
bool IsComplete();
|
|
123
|
+
|
|
124
|
+
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_UNKNOWN)]
|
|
125
|
+
ISetupPropertyStore GetProperties();
|
|
126
|
+
|
|
127
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
128
|
+
string GetEnginePath();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
[Guid("DA8D8A16-B2B6-4487-A2F1-594CCCCD6BF5")]
|
|
132
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
133
|
+
[ComImport]
|
|
134
|
+
public interface ISetupPackageReference
|
|
135
|
+
{
|
|
136
|
+
|
|
137
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
138
|
+
string GetId();
|
|
139
|
+
|
|
140
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
141
|
+
string GetVersion();
|
|
142
|
+
|
|
143
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
144
|
+
string GetChip();
|
|
145
|
+
|
|
146
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
147
|
+
string GetLanguage();
|
|
148
|
+
|
|
149
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
150
|
+
string GetBranch();
|
|
151
|
+
|
|
152
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
153
|
+
string GetType();
|
|
154
|
+
|
|
155
|
+
[return: MarshalAs(UnmanagedType.BStr)]
|
|
156
|
+
string GetUniqueId();
|
|
157
|
+
|
|
158
|
+
[return: MarshalAs(UnmanagedType.VariantBool)]
|
|
159
|
+
bool GetIsExtension();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
[Guid("c601c175-a3be-44bc-91f6-4568d230fc83")]
|
|
163
|
+
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
164
|
+
[ComImport]
|
|
165
|
+
public interface ISetupPropertyStore
|
|
166
|
+
{
|
|
167
|
+
|
|
168
|
+
[return: MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
|
|
169
|
+
string[] GetNames();
|
|
170
|
+
|
|
171
|
+
object GetValue([MarshalAs(UnmanagedType.LPWStr), In] string pwszName);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
[Guid("42843719-DB4C-46C2-8E7C-64F1816EFD5B")]
|
|
175
|
+
[CoClass(typeof(SetupConfigurationClass))]
|
|
176
|
+
[ComImport]
|
|
177
|
+
public interface SetupConfiguration : ISetupConfiguration2, ISetupConfiguration
|
|
178
|
+
{
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
[Guid("177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D")]
|
|
182
|
+
[ClassInterface(ClassInterfaceType.None)]
|
|
183
|
+
[ComImport]
|
|
184
|
+
public class SetupConfigurationClass
|
|
185
|
+
{
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
public static class Main
|
|
189
|
+
{
|
|
190
|
+
public static void PrintJson()
|
|
191
|
+
{
|
|
192
|
+
ISetupConfiguration query = new SetupConfiguration();
|
|
193
|
+
ISetupConfiguration2 query2 = (ISetupConfiguration2)query;
|
|
194
|
+
IEnumSetupInstances e = query2.EnumAllInstances();
|
|
195
|
+
|
|
196
|
+
int pceltFetched;
|
|
197
|
+
ISetupInstance2[] rgelt = new ISetupInstance2[1];
|
|
198
|
+
List<string> instances = new List<string>();
|
|
199
|
+
while (true)
|
|
200
|
+
{
|
|
201
|
+
e.Next(1, rgelt, out pceltFetched);
|
|
202
|
+
if (pceltFetched <= 0)
|
|
203
|
+
{
|
|
204
|
+
Console.WriteLine(String.Format("[{0}]", string.Join(",", instances.ToArray())));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
try
|
|
209
|
+
{
|
|
210
|
+
instances.Add(InstanceJson(rgelt[0]));
|
|
211
|
+
}
|
|
212
|
+
catch (COMException)
|
|
213
|
+
{
|
|
214
|
+
// Ignore instances that can't be queried.
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private static string JsonString(string s)
|
|
220
|
+
{
|
|
221
|
+
return "\"" + s.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\"";
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
private static string InstanceJson(ISetupInstance2 setupInstance2)
|
|
225
|
+
{
|
|
226
|
+
// Visual Studio component directory:
|
|
227
|
+
// https://docs.microsoft.com/en-us/visualstudio/install/workload-and-component-ids
|
|
228
|
+
|
|
229
|
+
StringBuilder json = new StringBuilder();
|
|
230
|
+
json.Append("{");
|
|
231
|
+
|
|
232
|
+
string path = JsonString(setupInstance2.GetInstallationPath());
|
|
233
|
+
json.Append(String.Format("\"path\":{0},", path));
|
|
234
|
+
|
|
235
|
+
string version = JsonString(setupInstance2.GetInstallationVersion());
|
|
236
|
+
json.Append(String.Format("\"version\":{0},", version));
|
|
237
|
+
|
|
238
|
+
List<string> packages = new List<string>();
|
|
239
|
+
foreach (ISetupPackageReference package in setupInstance2.GetPackages())
|
|
240
|
+
{
|
|
241
|
+
string id = JsonString(package.GetId());
|
|
242
|
+
packages.Add(id);
|
|
243
|
+
}
|
|
244
|
+
json.Append(String.Format("\"packages\":[{0}]", string.Join(",", packages.ToArray())));
|
|
245
|
+
|
|
246
|
+
json.Append("}");
|
|
247
|
+
return json.ToString();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
package/lib/build.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import gracefulFs from 'graceful-fs'
|
|
2
|
+
import path from 'path'
|
|
3
|
+
import { glob } from 'glob'
|
|
4
|
+
import * as log from './log.js'
|
|
5
|
+
import which from 'which'
|
|
6
|
+
import os from 'os'
|
|
7
|
+
|
|
8
|
+
const fs = gracefulFs.promises
|
|
9
|
+
const win = process.platform === 'win32'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 调用 make/msbuild 构建原生模块
|
|
13
|
+
*/
|
|
14
|
+
const build = async (gyp, argv) => {
|
|
15
|
+
let platformMake = 'make'
|
|
16
|
+
if (process.platform === 'aix') {
|
|
17
|
+
platformMake = 'gmake'
|
|
18
|
+
} else if (process.platform === 'os400') {
|
|
19
|
+
platformMake = 'gmake'
|
|
20
|
+
} else if (process.platform.indexOf('bsd') !== -1) {
|
|
21
|
+
platformMake = 'gmake'
|
|
22
|
+
} else if (win && argv.length > 0) {
|
|
23
|
+
argv = argv.map(function (target) {
|
|
24
|
+
return '/t:' + target
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const makeCommand = gyp.opts.make || process.env.MAKE || platformMake
|
|
29
|
+
let command = win ? 'msbuild' : makeCommand
|
|
30
|
+
const jobs = gyp.opts.jobs || process.env.JOBS
|
|
31
|
+
let buildType
|
|
32
|
+
let config
|
|
33
|
+
let arch
|
|
34
|
+
let nodeDir
|
|
35
|
+
let guessedSolution
|
|
36
|
+
let python
|
|
37
|
+
let buildBinsDir
|
|
38
|
+
|
|
39
|
+
await loadConfigGypi()
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 加载 configure 阶段生成的 config.gypi
|
|
43
|
+
*/
|
|
44
|
+
async function loadConfigGypi () {
|
|
45
|
+
let data
|
|
46
|
+
try {
|
|
47
|
+
const configPath = path.resolve('build', 'config.gypi')
|
|
48
|
+
data = await fs.readFile(configPath, 'utf8')
|
|
49
|
+
} catch (err) {
|
|
50
|
+
if (err.code === 'ENOENT') {
|
|
51
|
+
throw new Error('You must run `node-gyp configure` first!')
|
|
52
|
+
} else {
|
|
53
|
+
throw err
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
config = JSON.parse(data.replace(/#.+\n/, ''))
|
|
58
|
+
|
|
59
|
+
// 从 config 中取出 arch、buildType、nodeDir
|
|
60
|
+
buildType = config.target_defaults.default_configuration
|
|
61
|
+
arch = config.variables.target_arch
|
|
62
|
+
nodeDir = config.variables.nodedir
|
|
63
|
+
python = config.variables.python
|
|
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
|
+
log.verbose('python', python)
|
|
76
|
+
|
|
77
|
+
if (win) {
|
|
78
|
+
await findSolutionFile()
|
|
79
|
+
} else {
|
|
80
|
+
await doWhich()
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Windows 下查找第一个 build/*.sln 文件
|
|
86
|
+
*/
|
|
87
|
+
async function findSolutionFile () {
|
|
88
|
+
const files = await glob('build/*.sln')
|
|
89
|
+
if (files.length === 0) {
|
|
90
|
+
throw new Error('Could not find *.sln file. Did you run "configure"?')
|
|
91
|
+
}
|
|
92
|
+
guessedSolution = files[0]
|
|
93
|
+
log.verbose('found first Solution file', guessedSolution)
|
|
94
|
+
await doWhich()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 用 node-which 定位 msbuild / make 可执行文件
|
|
99
|
+
*/
|
|
100
|
+
async function doWhich () {
|
|
101
|
+
// Windows 使用 node-gyp configure 提供的 msbuild
|
|
102
|
+
if (win) {
|
|
103
|
+
if (!config.variables.msbuild_path) {
|
|
104
|
+
throw new Error('MSBuild is not set, please run `node-gyp configure`.')
|
|
105
|
+
}
|
|
106
|
+
command = config.variables.msbuild_path
|
|
107
|
+
log.verbose('using MSBuild:', command)
|
|
108
|
+
await doBuild()
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 先确认构建命令在 PATH 中
|
|
113
|
+
const execPath = await which(command)
|
|
114
|
+
log.verbose('`which` succeeded for `' + command + '`', execPath)
|
|
115
|
+
await doBuild()
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* 真正启动子进程并编译模块
|
|
120
|
+
*/
|
|
121
|
+
async function doBuild () {
|
|
122
|
+
// 启用 verbose 构建
|
|
123
|
+
const verbose = log.logger.isVisible('verbose')
|
|
124
|
+
let j
|
|
125
|
+
|
|
126
|
+
if (!win && verbose) {
|
|
127
|
+
argv.push('V=1')
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (win && !verbose) {
|
|
131
|
+
argv.push('/clp:Verbosity=minimal')
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (win) {
|
|
135
|
+
// Windows 上关闭 Microsoft logo
|
|
136
|
+
argv.push('/nologo')
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// 指定构建类型,默认 Release
|
|
140
|
+
if (win) {
|
|
141
|
+
// 把 .gypi 配置中的 target_arch 转换为 MSBuild 的 /Platform
|
|
142
|
+
// 因为表示"32 位 Intel"的方式很多,默认按此处理
|
|
143
|
+
// 注意:msbuild 的 Condition 字符串相等比较不区分大小写
|
|
144
|
+
const archLower = arch.toLowerCase()
|
|
145
|
+
const p = archLower === 'x64'
|
|
146
|
+
? 'x64'
|
|
147
|
+
: (archLower === 'arm'
|
|
148
|
+
? 'ARM'
|
|
149
|
+
: (archLower === 'arm64' ? 'ARM64' : 'Win32'))
|
|
150
|
+
argv.push('/p:Configuration=' + buildType + ';Platform=' + p)
|
|
151
|
+
if (jobs) {
|
|
152
|
+
j = parseInt(jobs, 10)
|
|
153
|
+
if (!isNaN(j) && j > 0) {
|
|
154
|
+
argv.push('/m:' + j)
|
|
155
|
+
} else if (jobs.toUpperCase() === 'MAX') {
|
|
156
|
+
argv.push('/m:' + os.cpus().length)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
argv.push('BUILDTYPE=' + buildType)
|
|
161
|
+
// 调用 build 目录下的 Makefile
|
|
162
|
+
argv.push('-C')
|
|
163
|
+
argv.push('build')
|
|
164
|
+
if (jobs) {
|
|
165
|
+
j = parseInt(jobs, 10)
|
|
166
|
+
if (!isNaN(j) && j > 0) {
|
|
167
|
+
argv.push('--jobs')
|
|
168
|
+
argv.push(j)
|
|
169
|
+
} else if (jobs.toUpperCase() === 'MAX') {
|
|
170
|
+
argv.push('--jobs')
|
|
171
|
+
argv.push(os.cpus().length)
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (win) {
|
|
177
|
+
// 用户是否指定了自己的 .sln 文件?
|
|
178
|
+
const hasSln = argv.some(function (arg) {
|
|
179
|
+
return path.extname(arg) === '.sln'
|
|
180
|
+
})
|
|
181
|
+
if (!hasSln) {
|
|
182
|
+
argv.unshift(gyp.opts.solution || guessedSolution)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (!win) {
|
|
187
|
+
// 把构建期依赖的符号链接(如 Python)加入 PATH
|
|
188
|
+
buildBinsDir = path.resolve('build', 'node_gyp_bins')
|
|
189
|
+
process.env.PATH = `${buildBinsDir}:${process.env.PATH}`
|
|
190
|
+
await fs.mkdir(buildBinsDir, { recursive: true })
|
|
191
|
+
const symlinkDestination = path.join(buildBinsDir, 'python3')
|
|
192
|
+
try {
|
|
193
|
+
await fs.unlink(symlinkDestination)
|
|
194
|
+
} catch (err) {
|
|
195
|
+
if (err.code !== 'ENOENT') throw err
|
|
196
|
+
}
|
|
197
|
+
await fs.symlink(python, symlinkDestination)
|
|
198
|
+
log.verbose('bin symlinks', `created symlink to "${python}" in "${buildBinsDir}" and added to PATH`)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const proc = gyp.spawn(command, argv)
|
|
202
|
+
await new Promise((resolve, reject) => proc.on('exit', async (code, signal) => {
|
|
203
|
+
if (buildBinsDir) {
|
|
204
|
+
// 清理构建期依赖的符号链接:
|
|
205
|
+
await fs.rm(buildBinsDir, { recursive: true })
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (code !== 0) {
|
|
209
|
+
return reject(new Error('`' + command + '` failed with exit code: ' + code))
|
|
210
|
+
}
|
|
211
|
+
if (signal) {
|
|
212
|
+
return reject(new Error('`' + command + '` got signal: ' + signal))
|
|
213
|
+
}
|
|
214
|
+
resolve()
|
|
215
|
+
}))
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
build.usage = 'Invokes `' + (win ? 'msbuild' : 'make') + '` and builds the module'
|
|
220
|
+
|
|
221
|
+
export { build }
|
package/lib/clean.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import gracefulFs from 'graceful-fs'
|
|
2
|
+
import * as log from './log.js'
|
|
3
|
+
|
|
4
|
+
const fs = gracefulFs.promises
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 清理:删除 build 目录
|
|
8
|
+
*/
|
|
9
|
+
const clean = async (gyp, argv) => {
|
|
10
|
+
// 删除 build 目录
|
|
11
|
+
const buildDir = 'build'
|
|
12
|
+
|
|
13
|
+
log.verbose('clean', 'removing "%s" directory', buildDir)
|
|
14
|
+
await fs.rm(buildDir, { recursive: true, force: true })
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
clean.usage = 'Removes any generated build files and the "out" dir'
|
|
18
|
+
|
|
19
|
+
export { clean }
|