11#!/usr/bin/env python3
22
33import argparse
4+ import collections
45import functools
56import os
67import platform
2223 'https://prereleases.llvm.org/{version}/rc{release_candidate}' )
2324LLVM_SOURCE = 'llvm-{version}.src'
2425CLANG_SOURCE = 'cfe-{version}.src'
26+ CLANG_TOOLS_SOURCE = 'clang-tools-extra-{version}.src'
2527BUNDLE_NAME = 'clang+llvm-{version}-{target}'
2628TARGET_REGEX = re .compile ( '^Target: (?P<target>.*)$' )
2729GITHUB_BASE_URL = 'https://api.github.com/'
@@ -125,24 +127,14 @@ def GetBundleVersion( args ):
125127 return args .version
126128
127129
128- def DownloadLlvmSource ( llvm_url , llvm_source ):
129- llvm_archive = llvm_source + '.tar.xz'
130+ def DownloadSource ( url , source ):
131+ archive = source + '.tar.xz'
130132
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 )
133135
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 )
146138
147139
148140def MoveClangSourceToLlvm ( clang_source , llvm_source ):
@@ -153,6 +145,14 @@ def MoveClangSourceToLlvm( clang_source, llvm_source ):
153145 )
154146
155147
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+
156156def BuildLlvm ( build_dir , install_dir , llvm_source ):
157157 try :
158158 os .chdir ( build_dir )
@@ -182,14 +182,11 @@ def BuildLlvm( build_dir, install_dir, llvm_source ):
182182 os .chdir ( DIR_OF_THIS_SCRIPT )
183183
184184
185- def CheckLlvm ( install_dir ):
186- print ( 'Checking LLVM dependencies.' )
185+ def CheckDependencies ( name , path , versions ):
187186 dependencies = []
188187 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 ],
191189 stderr = subprocess .STDOUT ).decode ( 'utf8' )
192- max_versions = {}
193190 for line in output .splitlines ():
194191 match = OBJDUMP_NEEDED_REGEX .search ( line )
195192 if match :
@@ -199,17 +196,24 @@ def CheckLlvm( install_dir ):
199196 if match :
200197 library = match .group ( 'library' )
201198 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 )
205200
206- print ( 'List of dependencies:' )
201+ print ( 'List of {} dependencies:' . format ( name ) )
207202 for dependency in dependencies :
208203 print ( dependency )
209204
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+
210214 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 ) ) )
213217
214218
215219def GetTarget ( install_dir ):
@@ -353,14 +357,19 @@ def Main():
353357 args = ParseArguments ()
354358 llvm_url = GetLlvmBaseUrl ( args )
355359 llvm_version = GetLlvmVersion ( args )
356- clang_source = CLANG_SOURCE .format ( version = llvm_version )
357360 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 )
358363 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 )
360365 if not os .path .exists ( os .path .join ( DIR_OF_THIS_SCRIPT , llvm_source ,
361366 'tools' , 'clang' ) ):
362- DownloadClangSource ( llvm_url , clang_source )
367+ DownloadSource ( llvm_url , clang_source )
363368 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 )
364373 build_dir = os .path .join ( DIR_OF_THIS_SCRIPT , 'build' )
365374 install_dir = os .path .join ( DIR_OF_THIS_SCRIPT , 'install' )
366375 if not os .path .exists ( build_dir ):
0 commit comments