UNPKG

7.15 kBJavaScriptView Raw
1const spawn = require('child_process').spawn;
2const fs = require('fs-extra');
3const path = require('path');
4const tar = require('tar');
5const argv = require('minimist')(process.argv.slice(2), {
6 // Specify that these arguments should be a string
7 string: ['version', 'runtime', 'abi'],
8});
9const pkg = require('./package.json');
10const nodeAbi = require('node-abi');
11const { optionsFromPackage } = require('./helpers');
12
13let arch = process.env.ARCH
14 ? process.env.ARCH.replace('i686', 'ia32').replace('x86_64', 'x64')
15 : process.arch;
16
17let gypJsPath = path.join(
18 __dirname,
19 'node_modules',
20 '.bin',
21 process.platform === 'win32' ? 'node-gyp.cmd' : 'node-gyp'
22);
23
24let files = [];
25let targets;
26let chain = Promise.resolve();
27
28initBuild();
29
30function initBuild() {
31 // Check if a specific runtime has been specified from the command line
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 // If "--all", use those defined in package.json
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 // If no upload has been specified, don't attempt to upload
95 return;
96 }
97
98 return uploadFiles(files);
99 });
100
101 cpGyp();
102}
103
104function 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
134function 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
195function 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
230function 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}