@@ -191,6 +191,7 @@ def configure(ctx):
191191 print ((('!' * 50 )+ '\n ' )* 3 )
192192 print ('--use-system-clang is deprecated. Please specify --llvm-config, e.g. /usr/bin/llvm-config llvm-config-6.0' )
193193
194+ # Do not use bundled clang+llvm
194195 if ctx .options .llvm_config is not None :
195196 # Ask llvm-config for cflags and ldflags
196197 ctx .find_program (ctx .options .llvm_config , msg = 'checking for llvm-config' , var = 'LLVM_CONFIG' , mandatory = False )
@@ -215,6 +216,38 @@ def configure(ctx):
215216 # using the provided info so far.
216217 ctx .check_cxx (lib = libname ('clang' ), uselib_store = 'clang' , use = 'clang' )
217218
219+ # If the user passed `--llvm-config=` (setting `llvm-config` to
220+ # the empty string) to the configure phase, we should not try to
221+ # run it.
222+ if len (ctx .options .llvm_config ):
223+ ctx .env .rpath = [str (subprocess .check_output (
224+ [ctx .options .llvm_config , '--libdir' ],
225+ stderr = subprocess .STDOUT ).decode ()).strip ()]
226+ else :
227+ ctx .env .rpath = []
228+
229+ # Use CXX set by --check-cxx-compiler if it is "clang".
230+ # See https://github.com/jacobdufault/cquery/issues/237
231+ clang = ctx .env .get_flat ('CXX' )
232+ if 'clang' not in clang :
233+ # Otherwise, infer the clang executable path with llvm-config --bindir
234+ output = str (subprocess .check_output (
235+ [ctx .options .llvm_config , '--bindir' ],
236+ stderr = subprocess .STDOUT ).decode ()).strip ()
237+ clang = os .path .join (output , 'clang' )
238+
239+ # Use the detected clang executable to infer resource directory
240+ # Use `clang -### -xc /dev/null` instead of `clang -print-resource-dir` because the option is unavailable in 4.0.0
241+ devnull = '/dev/null' if sys .platform != 'win32' else 'NUL'
242+ output = subprocess .check_output (
243+ [clang , '-###' , '-xc' , devnull ],
244+ stderr = subprocess .STDOUT ).decode ()
245+ match = re .search (r'"-resource-dir" "([^"]*)"' , output , re .M )
246+ if match :
247+ ctx .env .default_resource_directory = match .group (1 )
248+ else :
249+ bld .fatal ("Failed to found system clang resource directory." )
250+
218251 else :
219252 global CLANG_TARBALL_NAME , CLANG_TARBALL_EXT
220253
@@ -258,6 +291,31 @@ def configure(ctx):
258291 libpath = clang_node .find_dir ('lib' ).abspath (),
259292 lib = libname ('clang' ))
260293
294+ clang_tarball_name = os .path .basename (os .path .dirname (ctx .env ['LIBPATH_clang' ][0 ]))
295+ ctx .env .clang_tarball_name = clang_tarball_name
296+ ctx .env .default_resource_directory = '../lib/{}/lib/clang/{}' .format (clang_tarball_name , ctx .env .bundled_clang )
297+
298+ if sys .platform .startswith ('freebsd' ) or sys .platform .startswith ('linux' ):
299+ ctx .env .rpath = ['$ORIGIN/../lib/' + clang_tarball_name + '/lib' ]
300+ elif sys .platform == 'darwin' :
301+ ctx .env .rpath = ['@loader_path/../lib/' + clang_tarball_name + '/lib' ]
302+ elif sys .platform == 'win32' :
303+ ctx .env .rpath = [] # Unsupported
304+ name = os .path .basename (os .path .dirname (ctx .env ['LIBPATH_clang' ][0 ]))
305+ # Poor Windows users' RPATH
306+ out_clang_dll = os .path .join (ctx .path .get_bld ().abspath (), 'bin' , 'libclang.dll' )
307+ try :
308+ os .makedirs (os .path .dirname (out_clang_dll ))
309+ except OSError :
310+ pass
311+ try :
312+ dst = os .path .join (ctx .path .get_bld ().abspath (), 'lib' , name , 'bin' , 'libclang.dll' )
313+ os .symlink (dst , out_clang_dll )
314+ except (OSError , NotImplementedError ):
315+ shutil .copy (dst , out_clang_dll )
316+ else :
317+ ctx .env .rpath = ctx .env ['LIBPATH_clang' ]
318+
261319 ctx .msg ('Clang includes' , ctx .env .INCLUDES_clang )
262320 ctx .msg ('Clang library dir' , ctx .env .LIBPATH_clang )
263321
@@ -306,64 +364,6 @@ def build(bld):
306364
307365 lib .append ('ncurses' )
308366
309- if bld .env ['use_system_clang' ]:
310- # If the user passed `--llvm-config=` (setting `llvm-config` to
311- # the empty string) to the configure phase, we should not try to
312- # run it.
313- if bld .env ['llvm_config' ]:
314- rpath = str (subprocess .check_output (
315- [bld .env ['llvm_config' ], '--libdir' ],
316- stderr = subprocess .STDOUT ).decode ()).strip ()
317- else :
318- rpath = []
319-
320- # Use CXX set by --check-cxx-compiler if it is "clang".
321- # See https://github.com/jacobdufault/cquery/issues/237
322- clang = bld .env .get_flat ('CXX' )
323- if 'clang' not in clang :
324- # Otherwise, infer the clang executable path with llvm-config --bindir
325- output = str (subprocess .check_output (
326- [bld .env ['llvm_config' ], '--bindir' ],
327- stderr = subprocess .STDOUT ).decode ()).strip ()
328- clang = os .path .join (output , 'clang' )
329-
330- # Use the detected clang executable to infer resource directory
331- # Use `clang -### -xc /dev/null` instead of `clang -print-resource-dir` because the option is unavailable in 4.0.0
332- devnull = '/dev/null' if sys .platform != 'win32' else 'NUL'
333- output = subprocess .check_output (
334- [clang , '-###' , '-xc' , devnull ],
335- stderr = subprocess .STDOUT ).decode ()
336- match = re .search (r'"-resource-dir" "([^"]*)"' , output , re .M )
337- if match :
338- default_resource_directory = match .group (1 )
339- else :
340- bld .fatal ("Failed to found system clang resource directory." )
341-
342- else :
343- clang_tarball_name = os .path .basename (os .path .dirname (bld .env ['LIBPATH_clang' ][0 ]))
344- default_resource_directory = '../lib/{}/lib/clang/{}' .format (clang_tarball_name , bld .env ['bundled_clang' ])
345-
346- if sys .platform .startswith ('freebsd' ) or sys .platform .startswith ('linux' ):
347- rpath = '$ORIGIN/../lib/' + clang_tarball_name + '/lib'
348- elif sys .platform == 'darwin' :
349- rpath = '@loader_path/../lib/' + clang_tarball_name + '/lib'
350- elif sys .platform == 'win32' :
351- rpath = [] # Unsupported
352- name = os .path .basename (os .path .dirname (bld .env ['LIBPATH_clang' ][0 ]))
353- # Poor Windows users' RPATH
354- out_clang_dll = os .path .join (bld .path .get_bld ().abspath (), 'bin' , 'libclang.dll' )
355- try :
356- os .makedirs (os .path .dirname (out_clang_dll ))
357- except OSError :
358- pass
359- try :
360- dst = os .path .join (bld .path .get_bld ().abspath (), 'lib' , name , 'bin' , 'libclang.dll' )
361- os .symlink (dst , out_clang_dll )
362- except (OSError , NotImplementedError ):
363- shutil .copy (dst , out_clang_dll )
364- else :
365- rpath = bld .env ['LIBPATH_clang' ]
366-
367367 # FIXME Figure out how to mix C and C++ source files and change it back to .c
368368 bld .objects (name = 'siphash' , source = 'third_party/siphash.cc' )
369369
@@ -384,17 +384,19 @@ def build(bld):
384384 'LOGURU_WITH_STREAMS=1' ,
385385 'LOGURU_FILENAME_WIDTH=18' ,
386386 'LOGURU_THREADNAME_WIDTH=13' ,
387- 'DEFAULT_RESOURCE_DIRECTORY="' + default_resource_directory + '"' ] +
387+ 'DEFAULT_RESOURCE_DIRECTORY="' + bld . env . get_flat ( ' default_resource_directory' ) + '"' ] +
388388 (['USE_CLANG_CXX=1' , 'LOGURU_RTTI=0' ]
389389 if bld .env ['use_clang_cxx' ]
390390 else []),
391391 lib = lib ,
392- rpath = rpath ,
392+ rpath = bld . env . rpath ,
393393 target = 'bin/cquery' )
394394
395- if not bld .env ['use_system_clang' ] and sys .platform != 'win32' :
396- bld .install_files ('${PREFIX}/lib/' + clang_tarball_name + '/lib' , bld .path .get_bld ().ant_glob ('lib/' + clang_tarball_name + '/lib/libclang.(dylib|so.[4-9])' , quiet = True ))
395+ #from IPython import embed; embed()
396+ if sys .platform != 'win32' :
397+ clang_tarball_name = bld .env .clang_tarball_name
397398 if bld .cmd == 'install' :
399+ bld .install_files ('${PREFIX}/lib/' + clang_tarball_name + '/lib' , bld .path .get_bld ().ant_glob ('lib/' + clang_tarball_name + '/lib/libclang.(dylib|so.[4-9])' , quiet = True ))
398400 # TODO This may be cached and cannot be re-triggered. Use proper shell escape.
399401 bld (rule = 'rsync -rtR {}/./lib/{}/lib/clang/*/include {}/' .format (bld .path .get_bld (), clang_tarball_name , bld .env ['PREFIX' ]))
400402
0 commit comments