Files
edgetx-gx12/radio/util/find_clang.py
T

118 lines
3.7 KiB
Python

#
# Most of this code is from clang_complete:
# https://github.com/xavierd/clang_complete/blob/master/plugin/libclang.py
#
import os
import sys
from clang.cindex import *
# Check if libclang is able to find the builtin include files.
#
# libclang sometimes fails to correctly locate its builtin include files. This
# happens especially if libclang is not installed at a standard location. This
# function checks if the builtin includes are available.
def canFindBuiltinHeaders(index, args = []):
flags = 0
currentFile = ("test.c", '#include "stddef.h"')
try:
tu = index.parse("test.c", args, [currentFile], flags)
except TranslationUnitLoadError as e:
return 0
return len(tu.diagnostics) == 0
# Derive path to clang builtin headers.
#
# This function tries to derive a path to clang's builtin header files. We are
# just guessing, but the guess is very educated. In fact, we should be right
# for all manual installations (the ones where the builtin header path problem
# is very common) as well as a set of very common distributions.
def getBuiltinHeaderPath(library_path):
if os.path.isfile(library_path):
library_path = os.path.dirname(library_path)
knownPaths = [
library_path + "/../lib/clang", # default value
library_path + "/../clang", # gentoo
library_path + "/clang", # opensuse
library_path + "/", # Google
"/usr/lib64/clang", # x86_64 (openSUSE, Fedora)
"/usr/lib/clang"
]
for path in knownPaths:
try:
subDirs = [f for f in os.listdir(path) if os.path.isdir(path + "/" + f)]
subDirs = sorted(subDirs) or ['.']
path = path + "/" + subDirs[-1] + "/include"
#print("searching builtins in " + path)
if canFindBuiltinHeaders(index, ["-I" + path]):
return path
except:
pass
return None
def findLibClang():
if sys.platform == "darwin":
knownPaths = [
"/usr/local/Cellar/llvm/6.0.0/lib",
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib",
"/Library/Developer/CommandLineTools/usr/lib"
]
libSuffix = ".dylib"
elif sys.platform.startswith("linux"):
knownPaths = [
"/usr/lib/llvm-7/lib",
"/usr/lib/llvm-6.0/lib",
"/usr/lib/llvm-3.8/lib",
"/usr/local/lib",
"/usr/lib",
"/usr/lib64"
]
libSuffix = ".so"
elif sys.platform == "win32" or sys.platform == "msys":
knownPaths = os.environ.get("PATH").split(os.pathsep)
libSuffix = ".dll"
else:
# Unsupported platform
return None
for path in knownPaths:
# print("trying " + path)
if os.path.exists(path + "/libclang" + libSuffix):
return path
return None
def initLibClang():
global index
library_path = findLibClang()
if library_path:
#print("libclang found: " + library_path)
if os.path.isdir(library_path):
Config.set_library_path(library_path)
else:
Config.set_library_file(library_path)
else:
print("ERROR: libclang not found!", file=sys.stderr)
return False
Config.set_compatibility_check(False)
try:
index = Index.create()
except Exception as e:
print("ERROR: could not load libclang from '%s'." % library_path, file=sys.stderr)
return False
global builtin_hdr_path
builtin_hdr_path = getBuiltinHeaderPath(library_path)
if not builtin_hdr_path:
print("ERROR: builtin header path not found", file=sys.stderr)
return False
# Everything is OK, libclang can be used
return True