all: try more locations to find Clang built-in headers

This commit fixes the case where TinyGo was built with `go build` and
LLVM sources were never downloaded into the TinyGo source directory.
This commit is contained in:
Ayke van Laethem
2019-06-13 13:52:45 +02:00
committed by Ron Evans
parent 3e1c0d90c5
commit a3d1f1a514
4 changed files with 59 additions and 11 deletions
+48
View File
@@ -401,3 +401,51 @@ func getGorootVersion(goroot string) (major, minor int, err error) {
}
return
}
// getClangHeaderPath returns the path to the built-in Clang headers. It tries
// multiple locations, which should make it find the directory when installed in
// various ways.
func getClangHeaderPath(TINYGOROOT string) string {
// Check whether we're running from the source directory.
path := filepath.Join(TINYGOROOT, "llvm", "tools", "clang", "lib", "Headers")
if _, err := os.Stat(path); !os.IsNotExist(err) {
return path
}
// Check whether we're running from the installation directory.
path = filepath.Join(TINYGOROOT, "lib", "clang", "include")
if _, err := os.Stat(path); !os.IsNotExist(err) {
return path
}
// It looks like we are built with a system-installed LLVM. Do a last
// attempt: try to use Clang headers relative to the clang binary.
for _, cmdName := range commands["clang"] {
binpath, err := exec.LookPath(cmdName)
if err == nil {
// This should be the command that will also be used by
// execCommand. To avoid inconsistencies, make sure we use the
// headers relative to this command.
binpath, err = filepath.EvalSymlinks(binpath)
if err != nil {
// Unexpected.
return ""
}
// Example executable:
// /usr/lib/llvm-8/bin/clang
// Example include path:
// /usr/lib/llvm-8/lib/clang/8.0.1/include/
llvmRoot := filepath.Dir(filepath.Dir(binpath))
clangVersionRoot := filepath.Join(llvmRoot, "lib", "clang")
dirnames, err := ioutil.ReadDir(clangVersionRoot)
if err != nil || len(dirnames) != 1 {
// Unexpected.
return ""
}
return filepath.Join(clangVersionRoot, dirnames[0].Name(), "include")
}
}
// Could not find it.
return ""
}