@@ -11,29 +11,34 @@ console.log('Build dir is: ' + buildDir);
1111
1212const osName = os . type ( ) ;
1313
14- var lldbVersion ;
15- var lldbHeadersBranch ;
16- var lldbIncludeDir ;
14+ var lldbVersion ; // Similar to what `llvm-config --version` returns
15+ var lldbInstallDir ; // Where the lldb installation is, `llvm-config --prefix`
1716
1817// Need to determine:
1918// - What level of lldb we are running.
2019// - If we need the headers. (Linux may have them installed)
2120var lldbExe = 'lldb' ;
2221
2322if ( osName === 'Darwin' ) {
24-
2523 lldbVersion = getDarwinRelease ( ) ;
2624
2725 if ( lldbVersion === undefined ) {
2826 console . log ( 'Unable to locate lldb binary. llnode installation failed.' ) ;
2927 process . exit ( 1 ) ;
3028 }
3129
32- lldbHeadersBranch = lldbVersionToBranch ( lldbVersion ) ;
33- lldbIncludeDir = 'lldb-' + lldbVersion ;
34-
30+ console . log ( `Installing llnode for ${ lldbExe } , lldb version ${ lldbVersion } ` ) ;
31+ const installedDir = getDarwinInstallDir ( ) ;
32+ if ( installedDir === undefined ) {
33+ const lldbHeadersBranch = lldbVersionToBranch ( lldbVersion ) ;
34+ lldbInstallDir = 'lldb-' + lldbVersion ;
35+ cloneHeaders ( lldbHeadersBranch , lldbInstallDir , buildDir ) ;
36+ fs . writeFileSync ( 'options.gypi' , '{}' , 'utf-8' ) ;
37+ } else {
38+ lldbInstallDir = installedDir ;
39+ setDarwinBuildDir ( ) ;
40+ }
3541} else if ( osName === 'Linux' ) {
36-
3742 lldbExe = getLldbExecutable ( ) ;
3843 lldbVersion = getLinuxVersion ( lldbExe ) ;
3944
@@ -42,18 +47,17 @@ if (osName === 'Darwin') {
4247 process . exit ( 1 ) ;
4348 }
4449
45- // console.log('lldb_version is ' + lldb_version)
46- const installedHeadersDir = getLinuxHeadersDir ( lldbVersion ) ;
47- // console.log('installed_headers_dir is ' + installed_headers_dir);
48- if ( installedHeadersDir === undefined ) {
49- // Initialising lldb_headers_branch will cause us to clone them.
50- lldbHeadersBranch = lldbVersionToBranch ( lldbVersion ) ;
51- lldbIncludeDir = 'lldb-' + lldbVersion ;
50+ console . log ( `Installing llnode for ${ lldbExe } , lldb version ${ lldbVersion } ` ) ;
51+ const installedDir = getLinuxInstallDir ( lldbVersion ) ;
52+ if ( installedDir === undefined ) {
53+ const lldbHeadersBranch = lldbVersionToBranch ( lldbVersion ) ;
54+ lldbInstallDir = 'lldb-' + lldbVersion ;
55+ cloneHeaders ( lldbHeadersBranch , lldbInstallDir , buildDir ) ;
56+ fs . writeFileSync ( 'options.gypi' , '{}' , 'utf-8' ) ;
5257 } else {
53- lldbIncludeDir = installedHeadersDir ;
58+ lldbInstallDir = installedDir ;
5459 }
5560} else if ( osName === 'FreeBSD' ) {
56-
5761 lldbExe = getLldbExecutable ( ) ;
5862 lldbVersion = getFreeBSDVersion ( lldbExe ) ;
5963
@@ -62,43 +66,53 @@ if (osName === 'Darwin') {
6266 process . exit ( 1 ) ;
6367 }
6468
65- const installedHeadersDir = getFreeBSDHeadersDir ( lldbVersion ) ;
66- if ( installedHeadersDir === undefined ) {
69+ console . log ( `Installing llnode for ${ lldbExe } , lldb version ${ lldbVersion } ` ) ;
70+ const installedDir = getFreeBSDInstallDir ( lldbVersion ) ;
71+ if ( installedDir === undefined ) {
6772 // As this is a BSD we know this system is in an improper state
6873 // So we can exit with an error
6974 console . log ( 'The system isn\'t set up correcly.' ) ;
7075 console . log ( 'Try `pkg install llvm39' ) ;
7176 console . log ( 'And `ln -s /usr/local/bin/lldb39 /usr/bin/lldb`' ) ;
7277 process . exit ( 1 ) ;
7378 } else {
74- lldbIncludeDir = installedHeadersDir ;
79+ lldbInstallDir = installedDir ;
7580 }
76-
7781}
7882
79- console . log ( `Installing llnode for ${ lldbExe } , lldb version ${ lldbVersion } ` ) ;
83+ // This should be equivalent to `llvm-config --includedir`/lldb
84+ function getLldbHeadersPath ( lldbInstallDir ) {
85+ return path . join ( lldbInstallDir , 'include' , 'lldb' ) ;
86+ }
8087
81- // Check out source code of the LLDB that is compatible with OS X's default lldb
88+ // Check out source code of the LLDB for headers
8289// TODO: The llvm project is probably moving to github soon at that point we
8390// should stop using the mirror.
84- if ( lldbHeadersBranch != undefined ) {
85- console . log ( 'Cloning lldb from ' + lldbHeadersBranch ) ;
86- child_process . execSync ( `rm -rf ${ lldbIncludeDir } ` ) ;
87- child_process . execFileSync ( 'git' ,
88- [ 'clone' , '--depth=1' , '-b' , lldbHeadersBranch ,
89- 'https://github.com/llvm-mirror/lldb.git' , lldbIncludeDir ] ,
90- { cwd : buildDir } ) ;
91+ function cloneHeaders ( lldbHeadersBranch , lldbInstallDir , buildDir ) {
92+ const lldbHeaders = getLldbHeadersPath ( lldbInstallDir ) ;
93+ if ( ! fs . existsSync ( lldbInstallDir ) ) {
94+ console . log ( `Cloning lldb from ${ lldbHeadersBranch } to ${ lldbInstallDir } ` ) ;
95+ child_process . execFileSync ( 'git' ,
96+ [ 'clone' , '--depth=1' , '-b' , lldbHeadersBranch ,
97+ 'https://github.com/llvm-mirror/lldb.git' , lldbInstallDir ] ,
98+ {
99+ cwd : buildDir ,
100+ stdio : 'inherit' // show progress
101+ } ) ;
102+ } else {
103+ console . log ( `Skip cloning lldb headers because ${ lldbHeaders } exists` ) ;
104+ }
91105}
92106
93107// Link to the headers file so we can run gyp_llnode directly and don't need to
94108// setup parameters to pass it.
95- console . log ( `Linking lldb to include directory ${ lldbIncludeDir } ` ) ;
109+ console . log ( `Linking lldb to installation directory ${ lldbInstallDir } ` ) ;
96110try {
97111 fs . unlinkSync ( 'lldb' ) ;
98112} catch ( error ) {
99113 // File does not exist, no need to handle.
100114}
101- fs . symlinkSync ( lldbIncludeDir , 'lldb' ) ;
115+ fs . symlinkSync ( lldbInstallDir , 'lldb' ) ;
102116
103117// npm explore has a different root folder when using -g
104118// So we are tacking on the extra the additional subfolders
@@ -107,10 +121,10 @@ if (process.env.npm_config_global) {
107121 gypSubDir = 'npm/node_modules/node-gyp' ;
108122}
109123
110- // npm can be in a different location than the current
111- // location for global installs so we need find out where the npm is
112- var npmLocation = child_process . execFileSync ( 'which' , [ 'npm' ] ) ;
113- var npmModules = path . join ( npmLocation . toString ( ) , '../../lib/node_modules/npm' ) ;
124+ // npm can be in a different location than the current
125+ // location for global installs so we need find out where the npm is
126+ var npmLocation = child_process . execFileSync ( 'which' , [ 'npm' ] ) ;
127+ var npmModules = path . join ( npmLocation . toString ( ) , '../../lib/node_modules/npm' ) ;
114128
115129// Initialize GYP
116130// We can use the node-gyp that comes with npm.
@@ -136,17 +150,30 @@ function lldbVersionToBranch(version) {
136150
137151// On Mac the lldb version string doesn't match the original lldb versions.
138152function getDarwinRelease ( ) {
153+ var versionFromConfig ;
154+ try {
155+ versionFromConfig = child_process . execFileSync ( 'llvm-config' , [
156+ '--version'
157+ ] ) . toString ( ) . trim ( ) ;
158+ } catch ( err ) {
159+ // No llvm-config, try to get the version from xcodebuild
160+ }
161+ if ( versionFromConfig !== undefined ) {
162+ return versionFromConfig . split ( '.' ) . slice ( 0 , 2 ) . join ( '.' ) ;
163+ }
164+
139165 var xcodeStr ;
140166 try {
141- xcodeStr = child_process . execFileSync ( 'xcodebuild' , [ '-version' ] )
142- . toString ( ) ;
167+ xcodeStr = child_process . execFileSync ( 'xcodebuild' , [
168+ '-version'
169+ ] ) . toString ( ) ;
143170 } catch ( err ) {
144171 return undefined ;
145172 }
146173 var versionStr = '' ;
147174 var splitStr = xcodeStr . split ( os . EOL ) ;
148175 for ( var str of splitStr ) {
149- if ( str . indexOf ( 'Xcode' ) != - 1 ) {
176+ if ( str . includes ( 'Xcode' ) ) {
150177 versionStr = str . split ( ' ' ) [ 1 ] ;
151178 break ;
152179 }
@@ -163,6 +190,34 @@ function getDarwinRelease() {
163190 }
164191}
165192
193+ function setDarwinBuildDir ( ) {
194+ const prefix = child_process . execFileSync ( 'llvm-config' , [
195+ '--prefix'
196+ ] ) . toString ( ) . trim ( ) ;
197+ const options = JSON . stringify ( {
198+ variables : { 'lldb_build_dir%' : prefix }
199+ } , null , 2 ) ;
200+ fs . writeFileSync ( 'options.gypi' , options , 'utf-8' ) ;
201+ console . log ( 'Overwriting options.gypi with output from llvm-config:' ) ;
202+ console . log ( options ) ;
203+ }
204+
205+ function getDarwinInstallDir ( ) {
206+ var installedDir ;
207+ try {
208+ installedDir = child_process . execFileSync ( 'llvm-config' , [
209+ '--prefix'
210+ ] ) . toString ( ) . trim ( ) ;
211+ } catch ( err ) {
212+ // Return undefined, we will download the headers.
213+ }
214+ if ( installedDir !== undefined &&
215+ fs . existsSync ( getLldbHeadersPath ( installedDir ) ) ) {
216+ return installedDir ;
217+ }
218+ return undefined ;
219+ }
220+
166221// Find the 'best' lldb to use. Either:
167222// - the one specified by the user using npm --lldb_exe=... install llnode
168223// - the default lldb executable
@@ -171,8 +226,10 @@ function getDarwinRelease() {
171226function getLldbExecutable ( ) {
172227 var lldbExe = process . env . npm_config_lldb_exe ;
173228 if ( lldbExe === undefined ) {
174- var lldbExeNames = [ 'lldb' , 'lldb-5.0' , 'lldb-4.0' ,
175- 'lldb-3.9' , 'lldb-3.8' , 'lldb-3.7' , 'lldb-3.6' ] ;
229+ var lldbExeNames = [
230+ 'lldb' , 'lldb-5.0' , 'lldb-4.0' ,
231+ 'lldb-3.9' , 'lldb-3.8' , 'lldb-3.7' , 'lldb-3.6'
232+ ] ;
176233 for ( var lldbExeVersion of lldbExeNames ) {
177234 try {
178235 lldbExe = child_process . execSync ( 'which ' +
@@ -192,7 +249,6 @@ function getLldbExecutable() {
192249// There are multiple versions of lldb available for the various linux distos.
193250// Use the default unless --llnode_exe= has been set on the command line.
194251function getLinuxVersion ( lldbExe ) {
195-
196252 var lldbStr ;
197253 try {
198254 lldbStr = child_process . execFileSync ( lldbExe , [ '-v' ] ) . toString ( ) ;
@@ -209,42 +265,42 @@ function getLinuxVersion(lldbExe) {
209265
210266// Shim this for consistancy in OS naming
211267function getFreeBSDVersion ( lldbExe ) {
212- // Strip the dots for BSD
213- return getLinuxVersion ( lldbExe ) . replace ( '.' , '' ) ;
268+ // Strip the dots for BSD
269+ return getLinuxVersion ( lldbExe ) . replace ( '.' , '' ) ;
214270}
215271
216- function getFreeBSDHeadersDir ( version ) {
217-
272+ function getFreeBSDInstallDir ( version ) {
218273 console . log ( 'Checking for headers, version is ' + version ) ;
219274
220275 try {
221- var includeDir = child_process . execFileSync ( 'llvm-config' + version ,
276+ var installDir = child_process . execFileSync ( 'llvm-config' + version ,
222277 [ '--prefix' ] ) . toString ( ) . trim ( ) ;
223- if ( fs . existsSync ( includeDir + '/include/lldb' ) ) {
224- return includeDir ;
278+ if ( fs . existsSync ( installDir + '/include/lldb' ) ) {
279+ return installDir ;
225280 }
226281 } catch ( err ) {
227- console . log ( includeDir + '/include/lldb doesn\'nt exist' ) ;
282+ console . log ( installDir + '/include/lldb doesn\'nt exist' ) ;
228283 console . log ( 'Please see README.md' ) ;
229284 console . log ( err ) ;
230285 process . exit ( 1 ) ;
231286 }
232287 return undefined ;
233288}
234- function getLinuxHeadersDir ( version ) {
289+
290+ function getLinuxInstallDir ( version ) {
235291 // Get the directory which should contain the headers and
236292 // check if they are present.
237293 // (Using the installed headers will ensure we have the correct ones.)
238294 console . log ( 'Checking for headers, version is ' + version ) ;
239295 try {
240- var includeDir = child_process . execFileSync ( 'llvm-config-' + version ,
296+ var installDir = child_process . execFileSync ( 'llvm-config-' + version ,
241297 [ '--prefix' ] ) . toString ( ) . trim ( ) ;
242298 // console.log('Checking for directory ' + include_dir);
243299 // Include directory doesn't need include/lldb on the end but the llvm
244300 // headers can be installed without the lldb headers so check for them.
245- if ( fs . existsSync ( includeDir + '/include/lldb' ) ) {
301+ if ( fs . existsSync ( installDir + '/include/lldb' ) ) {
246302 // console.log('Found ' + include_dir);
247- return includeDir ;
303+ return installDir ;
248304 }
249305 } catch ( err ) {
250306 // Return undefined, we will download the headers.
@@ -257,7 +313,6 @@ function getLinuxHeadersDir(version) {
257313}
258314
259315function scriptText ( lldbExe ) {
260-
261316 let lib = 'llnode.so' ;
262317 if ( osName === 'Darwin' ) {
263318 lib = 'llnode.dylib' ;
278333
279334${ lldbExe } --one-line "plugin load $LLNODE_PLUGIN" --one-line "settings set prompt '(llnode) '" $@
280335` ;
281-
282336}
0 commit comments