1
1
#!/usr/bin/env python3
2
2
3
3
import argparse
4
+ import collections
4
5
import functools
5
6
import os
6
7
import platform
22
23
'https://prereleases.llvm.org/{version}/rc{release_candidate}' )
23
24
LLVM_SOURCE = 'llvm-{version}.src'
24
25
CLANG_SOURCE = 'cfe-{version}.src'
26
+ CLANG_TOOLS_SOURCE = 'clang-tools-extra-{version}.src'
25
27
BUNDLE_NAME = 'clang+llvm-{version}-{target}'
26
28
TARGET_REGEX = re .compile ( '^Target: (?P<target>.*)$' )
27
29
GITHUB_BASE_URL = 'https://api.github.com/'
@@ -125,24 +127,14 @@ def GetBundleVersion( args ):
125
127
return args .version
126
128
127
129
128
- def DownloadLlvmSource ( llvm_url , llvm_source ):
129
- llvm_archive = llvm_source + '.tar.xz'
130
+ def DownloadSource ( url , source ):
131
+ archive = source + '.tar.xz'
130
132
131
- if not os .path .exists ( llvm_archive ):
132
- Download ( llvm_url + '/' + llvm_archive )
133
+ if not os .path .exists ( archive ):
134
+ Download ( url + '/' + archive )
133
135
134
- if not os .path .exists ( llvm_source ):
135
- Extract ( llvm_archive )
136
-
137
-
138
- def DownloadClangSource ( llvm_url , clang_source ):
139
- clang_archive = clang_source + '.tar.xz'
140
-
141
- if not os .path .exists ( clang_archive ):
142
- Download ( llvm_url + '/' + clang_archive )
143
-
144
- if not os .path .exists ( clang_source ):
145
- Extract ( clang_archive )
136
+ if not os .path .exists ( source ):
137
+ Extract ( archive )
146
138
147
139
148
140
def MoveClangSourceToLlvm ( clang_source , llvm_source ):
@@ -153,6 +145,14 @@ def MoveClangSourceToLlvm( clang_source, llvm_source ):
153
145
)
154
146
155
147
148
+ def MoveClangToolsSourceToLlvm ( clang_tools_source , llvm_source ):
149
+ os .rename ( clang_tools_source , 'extra' )
150
+ shutil .move (
151
+ os .path .join ( DIR_OF_THIS_SCRIPT , 'extra' ),
152
+ os .path .join ( DIR_OF_THIS_SCRIPT , llvm_source , 'tools' , 'clang' , 'tools' )
153
+ )
154
+
155
+
156
156
def BuildLlvm ( build_dir , install_dir , llvm_source ):
157
157
try :
158
158
os .chdir ( build_dir )
@@ -182,14 +182,11 @@ def BuildLlvm( build_dir, install_dir, llvm_source ):
182
182
os .chdir ( DIR_OF_THIS_SCRIPT )
183
183
184
184
185
- def CheckLlvm ( install_dir ):
186
- print ( 'Checking LLVM dependencies.' )
185
+ def CheckDependencies ( name , path , versions ):
187
186
dependencies = []
188
187
objdump = shutil .which ( 'objdump' )
189
- output = subprocess .check_output (
190
- [ objdump , '-p' , os .path .join ( install_dir , 'lib' , 'libclang.so' ) ],
188
+ output = subprocess .check_output ( [ objdump , '-p' , path ],
191
189
stderr = subprocess .STDOUT ).decode ( 'utf8' )
192
- max_versions = {}
193
190
for line in output .splitlines ():
194
191
match = OBJDUMP_NEEDED_REGEX .search ( line )
195
192
if match :
@@ -199,17 +196,24 @@ def CheckLlvm( install_dir ):
199
196
if match :
200
197
library = match .group ( 'library' )
201
198
version = Version ( match .group ( 'version' ) )
202
- max_version = max_versions .get ( library )
203
- if not max_version or version > max_version :
204
- max_versions [ library ] = version
199
+ versions [ library ].append ( version )
205
200
206
- print ( 'List of dependencies:' )
201
+ print ( 'List of {} dependencies:' . format ( name ) )
207
202
for dependency in dependencies :
208
203
print ( dependency )
209
204
205
+
206
+ def CheckLlvm ( install_dir ):
207
+ print ( 'Checking LLVM dependencies.' )
208
+ versions = collections .defaultdict ( list )
209
+ CheckDependencies (
210
+ 'libclang' , os .path .join ( install_dir , 'lib' , 'libclang.so' ), versions )
211
+ CheckDependencies (
212
+ 'clangd' , os .path .join ( install_dir , 'bin' , 'clangd' ), versions )
213
+
210
214
print ( 'Maximum versions required:' )
211
- for library , version in max_versions .items ():
212
- print ( library + ' ' + str ( version ) )
215
+ for library , values in versions .items ():
216
+ print ( library + ' ' + str ( max ( values ) ) )
213
217
214
218
215
219
def GetTarget ( install_dir ):
@@ -353,14 +357,19 @@ def Main():
353
357
args = ParseArguments ()
354
358
llvm_url = GetLlvmBaseUrl ( args )
355
359
llvm_version = GetLlvmVersion ( args )
356
- clang_source = CLANG_SOURCE .format ( version = llvm_version )
357
360
llvm_source = LLVM_SOURCE .format ( version = llvm_version )
361
+ clang_source = CLANG_SOURCE .format ( version = llvm_version )
362
+ clang_tools_source = CLANG_TOOLS_SOURCE .format ( version = llvm_version )
358
363
if not os .path .exists ( os .path .join ( DIR_OF_THIS_SCRIPT , llvm_source ) ):
359
- DownloadLlvmSource ( llvm_url , llvm_source )
364
+ DownloadSource ( llvm_url , llvm_source )
360
365
if not os .path .exists ( os .path .join ( DIR_OF_THIS_SCRIPT , llvm_source ,
361
366
'tools' , 'clang' ) ):
362
- DownloadClangSource ( llvm_url , clang_source )
367
+ DownloadSource ( llvm_url , clang_source )
363
368
MoveClangSourceToLlvm ( clang_source , llvm_source )
369
+ if not os .path .exists ( os .path .join ( DIR_OF_THIS_SCRIPT , llvm_source ,
370
+ 'tools' , 'clang' , 'tools' , 'extra' ) ):
371
+ DownloadSource ( llvm_url , clang_tools_source )
372
+ MoveClangToolsSourceToLlvm ( clang_tools_source , llvm_source )
364
373
build_dir = os .path .join ( DIR_OF_THIS_SCRIPT , 'build' )
365
374
install_dir = os .path .join ( DIR_OF_THIS_SCRIPT , 'install' )
366
375
if not os .path .exists ( build_dir ):
0 commit comments