1 | const spawn = require('child_process').spawn;
|
2 | const fs = require('fs-extra');
|
3 | const path = require('path');
|
4 | const tar = require('tar');
|
5 | const argv = require('minimist')(process.argv.slice(2), {
|
6 |
|
7 | string: ['version', 'runtime', 'abi'],
|
8 | });
|
9 | const pkg = require('./package.json');
|
10 | const nodeAbi = require('node-abi');
|
11 | const { optionsFromPackage } = require('./helpers');
|
12 |
|
13 | let arch = process.env.ARCH
|
14 | ? process.env.ARCH.replace('i686', 'ia32').replace('x86_64', 'x64')
|
15 | : process.arch;
|
16 |
|
17 | let gypJsPath = path.join(
|
18 | __dirname,
|
19 | 'node_modules',
|
20 | '.bin',
|
21 | process.platform === 'win32' ? 'node-gyp.cmd' : 'node-gyp'
|
22 | );
|
23 |
|
24 | let files = [];
|
25 | let targets;
|
26 | let chain = Promise.resolve();
|
27 |
|
28 | initBuild();
|
29 |
|
30 | function initBuild() {
|
31 |
|
32 | if ('runtime' in argv && 'version' in argv && 'abi' in argv) {
|
33 | targets = [[argv['runtime'], argv['version'], argv['abi']]];
|
34 | } else if ('all' in argv) {
|
35 |
|
36 | targets = require('./package.json').supportedTargets;
|
37 | } else {
|
38 | const options = optionsFromPackage();
|
39 | if (process.env.npm_config_targets) {
|
40 | options.targets = options.targets.concat(
|
41 | process.env.npm_config_targets.split(',')
|
42 | );
|
43 | }
|
44 | options.targets = options.targets.map((targetStr) => targetStr.split('-'));
|
45 | if (process.env.npm_config_targets === 'all') {
|
46 | options.targets = supportedTargets.map((arr) => [arr[0], arr[2]]);
|
47 | options.platforms = ['win32', 'darwin', 'linux'];
|
48 | options.arches = ['x64', 'ia32'];
|
49 | }
|
50 | if (process.env.npm_config_platforms) {
|
51 | options.platforms = options.platforms.concat(
|
52 | process.env.npm_config_platforms.split(',')
|
53 | );
|
54 | }
|
55 | if (process.env.npm_config_arches) {
|
56 | options.arches = options.arches.concat(
|
57 | process.env.npm_config_arches.split(',')
|
58 | );
|
59 | }
|
60 |
|
61 | if (options.targets.length > 0) {
|
62 | targets = options.targets.map((e) => [
|
63 | e[0],
|
64 | nodeAbi.getTarget(e[1], e[0]),
|
65 | e[1],
|
66 | ]);
|
67 | } else {
|
68 | const runtime = process.versions['electron'] ? 'electron' : 'node';
|
69 | const version = process.versions.node;
|
70 | const abi = process.versions.modules;
|
71 | targets = [[runtime, version, abi]];
|
72 | }
|
73 | }
|
74 |
|
75 | targets.forEach((parts) => {
|
76 | let runtime = parts[0];
|
77 | let version = parts[1];
|
78 | let abi = parts[2];
|
79 | chain = chain
|
80 | .then(function () {
|
81 | return build(runtime, version, abi);
|
82 | })
|
83 | .then(function () {
|
84 | return tarGz(runtime, abi);
|
85 | })
|
86 | .catch((err) => {
|
87 | console.error(err);
|
88 | process.exit(1);
|
89 | });
|
90 | });
|
91 |
|
92 | chain = chain.then(function () {
|
93 | if ('upload' in argv && argv['upload'] === 'false') {
|
94 |
|
95 | return;
|
96 | }
|
97 |
|
98 | return uploadFiles(files);
|
99 | });
|
100 |
|
101 | cpGyp();
|
102 | }
|
103 |
|
104 | function cpGyp() {
|
105 | try {
|
106 | fs.unlinkSync(path.join(__dirname, 'binding.gyp'));
|
107 | fs.unlinkSync(path.join(__dirname, 'uiohook.gyp'));
|
108 | } catch (e) {}
|
109 | switch (process.platform) {
|
110 | case 'win32':
|
111 | case 'darwin':
|
112 | fs.copySync(
|
113 | path.join(__dirname, 'build_def', process.platform, 'binding.gyp'),
|
114 | path.join(__dirname, 'binding.gyp')
|
115 | );
|
116 | fs.copySync(
|
117 | path.join(__dirname, 'build_def', process.platform, 'uiohook.gyp'),
|
118 | path.join(__dirname, 'uiohook.gyp')
|
119 | );
|
120 | break;
|
121 | default:
|
122 | fs.copySync(
|
123 | path.join(__dirname, 'build_def', 'linux', 'binding.gyp'),
|
124 | path.join(__dirname, 'binding.gyp')
|
125 | );
|
126 | fs.copySync(
|
127 | path.join(__dirname, 'build_def', 'linux', 'uiohook.gyp'),
|
128 | path.join(__dirname, 'uiohook.gyp')
|
129 | );
|
130 | break;
|
131 | }
|
132 | }
|
133 |
|
134 | function build(runtime, version, abi) {
|
135 | return new Promise(function (resolve, reject) {
|
136 | let args = [
|
137 | 'configure',
|
138 | 'rebuild',
|
139 | '--target=' + version,
|
140 | '--arch=' + arch,
|
141 | ];
|
142 |
|
143 | if (/^electron/i.test(runtime)) {
|
144 | args.push('--dist-url=https://atom.io/download/electron');
|
145 | }
|
146 |
|
147 | if (parseInt(abi) >= 80) {
|
148 | if (arch === 'x64') {
|
149 | args.push('--v8_enable_pointer_compression=1');
|
150 | } else {
|
151 | args.push('--v8_enable_pointer_compression=0');
|
152 | args.push('--v8_enable_31bit_smis_on_64bit_arch=1');
|
153 | }
|
154 | }
|
155 | if (process.platform !== 'win32') {
|
156 | if (parseInt(abi) >= 64) {
|
157 | args.push('--build_v8_with_gn=false');
|
158 | }
|
159 | if (parseInt(abi) >= 67) {
|
160 | args.push('--enable_lto=false');
|
161 | }
|
162 | }
|
163 |
|
164 | console.log('Building iohook for ' + runtime + ' v' + version + '>>>>');
|
165 | if (process.platform === 'win32') {
|
166 | if (version.split('.')[0] >= 4) {
|
167 | process.env.msvs_toolset = 15;
|
168 | process.env.msvs_version = argv.msvs_version || 2017;
|
169 | } else {
|
170 | process.env.msvs_toolset = 12;
|
171 | process.env.msvs_version = 2013;
|
172 | }
|
173 | args.push('--msvs_version=' + process.env.msvs_version);
|
174 | } else {
|
175 | process.env.gyp_iohook_runtime = runtime;
|
176 | process.env.gyp_iohook_abi = abi;
|
177 | process.env.gyp_iohook_platform = process.platform;
|
178 | process.env.gyp_iohook_arch = arch;
|
179 | }
|
180 |
|
181 | let proc = spawn(gypJsPath, args, {
|
182 | env: process.env,
|
183 | });
|
184 | proc.stdout.pipe(process.stdout);
|
185 | proc.stderr.pipe(process.stderr);
|
186 | proc.on('exit', function (code, sig) {
|
187 | if (code === 1) {
|
188 | return reject(new Error('Failed to build...'));
|
189 | }
|
190 | resolve();
|
191 | });
|
192 | });
|
193 | }
|
194 |
|
195 | function tarGz(runtime, abi) {
|
196 | const FILES_TO_ARCHIVE = {
|
197 | win32: ['build/Release/iohook.node', 'build/Release/uiohook.dll'],
|
198 | linux: ['build/Release/iohook.node', 'build/Release/uiohook.so'],
|
199 | darwin: ['build/Release/iohook.node', 'build/Release/uiohook.dylib'],
|
200 | };
|
201 | const tarPath =
|
202 | 'prebuilds/iohook-v' +
|
203 | pkg.version +
|
204 | '-' +
|
205 | runtime +
|
206 | '-v' +
|
207 | abi +
|
208 | '-' +
|
209 | process.platform +
|
210 | '-' +
|
211 | arch +
|
212 | '.tar.gz';
|
213 |
|
214 | files.push(tarPath);
|
215 |
|
216 | if (!fs.existsSync(path.dirname(tarPath))) {
|
217 | fs.mkdirSync(path.dirname(tarPath));
|
218 | }
|
219 |
|
220 | tar.c(
|
221 | {
|
222 | gzip: true,
|
223 | file: tarPath,
|
224 | sync: true,
|
225 | },
|
226 | FILES_TO_ARCHIVE[process.platform]
|
227 | );
|
228 | }
|
229 |
|
230 | function uploadFiles(files) {
|
231 | const upload = require('prebuild/upload');
|
232 | return new Promise(function (resolve, reject) {
|
233 | console.log(
|
234 | 'Uploading ' + files.length + ' prebuilds(s) to Github releases'
|
235 | );
|
236 | let opts = {
|
237 | pkg: pkg,
|
238 | files: files,
|
239 | 'tag-prefix': 'v',
|
240 | upload: process.env.GITHUB_ACCESS_TOKEN,
|
241 | };
|
242 | upload(opts, function (err, result) {
|
243 | if (err) {
|
244 | return reject(err);
|
245 | }
|
246 | console.log('Found ' + result.old.length + ' prebuild(s) on Github');
|
247 | if (result.old.length) {
|
248 | result.old.forEach(function (build) {
|
249 | console.log('-> ' + build);
|
250 | });
|
251 | }
|
252 | console.log(
|
253 | 'Uploaded ' + result.new.length + ' new prebuild(s) to Github'
|
254 | );
|
255 | if (result.new.length) {
|
256 | result.new.forEach(function (build) {
|
257 | console.log('-> ' + build);
|
258 | });
|
259 | }
|
260 | resolve();
|
261 | });
|
262 | });
|
263 | }
|