forked from rescript-lang/rescript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstall.js
executable file
·161 lines (142 loc) · 5.71 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
//@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 os_arch = os.arch()
var is_windows = !(os_type.indexOf('Windows') < 0)
var is_bsd = !(os_type.indexOf('BSD') < 0)
var root_dir = path.join(__dirname, '..')
var lib_dir = path.join(root_dir, 'lib')
var jscomp = path.join(root_dir, 'jscomp')
var working_dir = process.cwd()
console.log("Working dir", working_dir)
var jscomp_dir_config = { cwd: jscomp, stdio: [0, 1, 2] }
var root_dir_config = { cwd: root_dir, stdio: [0, 1, 2] }
var build_util = require('./build_util')
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
if (is_windows) {
ninja_os_path = path.join(ninja_build_dir, 'ninja.win')
} else if (os_type === 'Darwin') {
ninja_os_path = path.join(ninja_build_dir, 'ninja.darwin')
} else if (os_type === 'Linux') {
ninja_os_path = path.join(ninja_build_dir, 'ninja.linux64')
}
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 ""
}
}
// Add vendor bin path
// So that second try will work
process.env.PATH = path.join(__dirname, '..', 'vendor', 'ocaml', 'bin') + path.delimiter + process.env.PATH
var make = is_bsd ? 'gmake' : 'make';
function non_windows_npm_release() {
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.execSync(path.join(__dirname, 'buildocaml.sh')) // TODO: sh -c ? this will be wrong if we have white space in the path
} 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")
}
console.log("Build the compiler and runtime .. ")
child_process.execSync(make + " world", root_dir_config)
console.log("Installing")
child_process.execSync(make + ' VERBOSE=true install', root_dir_config)
}
if (is_windows) {
process.env.WIN32 = '1'
console.log("Installing on Windows")
var indeed_windows_release = 0
fs.readdirSync(lib_dir).forEach(function (f) {
var last_index = f.lastIndexOf('.win')
if (last_index !== -1) {
var new_file = f.slice(0, -4) + ".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
}
})
if (indeed_windows_release > 1) {
// Make it more fault tolerant
// =1 can still be okay (only ninja.win in this case)
child_process.execFileSync(path.join(__dirname, 'win_build.bat'), jscomp_dir_config)
// clean.clean()
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()
}