forked from rescript-lang/rescript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstall.js
executable file
·178 lines (158 loc) · 6.01 KB
/
install.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
//@ts-check
// For Windows, we distribute a prebuilt bsc.exe
// To build on windows, we still need figure out constructing config.ml
// from existing compiler
// For other OSes, we detect
// if there is other compiler installed and the version matches,
// we get the config.ml from existing OCaml compiler and build whole_compiler
// Otherwise, we build the compiler shipped with Buckle and use the
// old compiler.ml
// This will be run in npm postinstall, don't use too fancy features here
var child_process = require('child_process')
var fs = require('fs')
var path = require('path')
var os = require('os')
var os_type = os.type()
var root_dir = path.join(__dirname, '..')
var lib_dir = path.join(root_dir, 'lib')
var root_dir_config = { cwd: root_dir, stdio: [0, 1, 2] }
var config = require('./config.js')
var make = config.make
var is_windows = config.is_windows
var sys_extension = config.sys_extension
// Add vendor bin path
// So that second try will work
process.env.PATH =
path.join(__dirname, '..', 'vendor', 'ocaml', 'bin') +
path.delimiter +
process.env.PATH
function setUpNinja() {
var vendor_ninja_version = '1.8.2'
var ninja_bin_output = path.join(root_dir, 'lib', 'ninja.exe')
var ninja_source_dir = path.join(root_dir, 'vendor', 'ninja')
var ninja_build_dir = path.join(root_dir, 'vendor', 'ninja-build')
function build_ninja() {
console.log('No prebuilt Ninja, building Ninja now')
var build_ninja_command = "./configure.py --bootstrap"
child_process.execSync(build_ninja_command, { cwd: ninja_source_dir, stdio: [0, 1, 2] })
fs.renameSync(path.join(ninja_source_dir, 'ninja'), ninja_bin_output)
console.log('ninja binary is ready: ', ninja_bin_output)
}
// sanity check to make sure the binary actually runs. Used for Linux. Too many variants
function test_ninja_compatible(binary_path) {
var version;
try {
version = child_process.execSync(JSON.stringify(binary_path) + ' --version', {
encoding: 'utf8',
stdio: ['pipe', 'pipe', 'ignore'] // execSync outputs to stdout even if we catch the error. Silent it here
}).trim();
} catch (e) {
console.log('ninja not compatible?', String(e))
return false;
}
return version === vendor_ninja_version;
};
var ninja_os_path = path.join(ninja_build_dir, 'ninja' + sys_extension)
if (fs.existsSync(ninja_bin_output) && test_ninja_compatible(ninja_bin_output)) {
console.log("ninja binary is already cached: ", ninja_bin_output)
}
else if (fs.existsSync(ninja_os_path)) {
fs.renameSync(ninja_os_path, ninja_bin_output)
if (test_ninja_compatible(ninja_bin_output)) {
console.log("ninja binary is copied from pre-distribution")
} else {
build_ninja()
}
} else {
build_ninja()
}
}
/**
* raise an exception if not matched
*/
function matchedCompilerExn() {
var output = child_process.execSync('ocamlc.opt -v', { encoding: 'ascii' })
if (output.indexOf("4.02.3") >= 0) {
console.log(output)
console.log("Use the compiler above")
} else {
console.log("No matched compiler found, may re-try")
throw ""
}
}
function tryToProvideOCamlCompiler() {
try {
if (process.env.BS_ALWAYS_BUILD_YOUR_COMPILER) {
throw 'FORCED TO REBUILD'
}
matchedCompilerExn()
} catch (e) {
console.log('Build a local version of OCaml compiler, it may take a couple of minutes')
try {
child_process.execFileSync(path.join(__dirname, 'buildocaml.sh'))
} catch (e) {
console.log(e.stdout.toString());
console.log(e.stderr.toString());
console.log('Building a local version of the OCaml compiler failed, check the outut above for more information. A possible problem is that you don\'t have a compiler installed');
throw e;
}
console.log('configure again with local ocaml installed')
matchedCompilerExn()
console.log("config finished")
}
}
// copy all [*.sys_extension] files into [*.exe]
function copyBinToExe() {
var indeed_windows_release = 0
fs.readdirSync(lib_dir).forEach(function (f) {
var last_index = f.lastIndexOf(sys_extension)
if (last_index !== -1) {
var new_file = f.slice(0, - sys_extension.length) + ".exe"
build_util.poor_copy_sync(path.join(lib_dir, f), path.join(lib_dir, new_file));
// we do have .win file which means windows npm release
++indeed_windows_release
}
})
return indeed_windows_release > 1
}
function checkPrebuilt() {
try {
var version = child_process.execFileSync(path.join(lib_dir, 'bsc' + sys_extension), ['-v'])
console.log("checkoutput:", String(version))
return copyBinToExe()
} catch (e) {
console.log("No working prebuilt compiler")
return false
}
}
function non_windows_npm_release() {
if (fs.existsSync(path.join(lib_dir, 'bsc.exe'))) {
console.log('Found bsc.exe, assume it was already built')
return true // already built before
}
if (checkPrebuilt()) {
child_process.execSync(make + " libs && " + make + " install", root_dir_config)
} else {
tryToProvideOCamlCompiler()
child_process.execSync(make + " world && " + make + " install", root_dir_config)
}
}
var build_util = require('./build_util.js')
setUpNinja()
if (is_windows) {
if (copyBinToExe()) {
child_process.execFileSync(
path.join(__dirname, 'win_build.bat'),
{ cwd: path.join(root_dir, 'jscomp'), stdio: [0, 1, 2] }
)
console.log("Installing")
build_util.install()
} else {
// Cygwin
console.log("It is on windows, but seems to be that you are building against master branch, so we are going to depend on cygwin on master")
non_windows_npm_release()
}
}
else {
non_windows_npm_release()
}