Skip to content

Commit b3bd891

Browse files
QuLogicaykevl
authored andcommitted
Make lib64 clang include path check more robust.
On Fedora 33+, there is a buggy package that installs to `/usr/lib64/clang/{version}/lib`, even on 32-bit systems. The original code sees the `/usr/lib64/clang/{version}` directory, checks for an `include` subdirectory, and then gives up because it doesn't exist. To be more robust, check both `/usr/lib64/clang/{version}/include` and `/usr/lib/clang/{version}/include`, and only allow versions that match the LLVM major version used to build tinygo.
1 parent 387bca8 commit b3bd891

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

builder/env.go

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"os/exec"
77
"path/filepath"
88
"sort"
9+
"strings"
10+
11+
"tinygo.org/x/go-llvm"
912
)
1013

1114
// getClangHeaderPath returns the path to the built-in Clang headers. It tries
@@ -26,6 +29,7 @@ func getClangHeaderPath(TINYGOROOT string) string {
2629

2730
// It looks like we are built with a system-installed LLVM. Do a last
2831
// attempt: try to use Clang headers relative to the clang binary.
32+
llvmMajor := strings.Split(llvm.Version, ".")[0]
2933
for _, cmdName := range commands["clang"] {
3034
binpath, err := exec.LookPath(cmdName)
3135
if err == nil {
@@ -43,25 +47,35 @@ func getClangHeaderPath(TINYGOROOT string) string {
4347
// /usr/lib/llvm-9/lib64/clang/9.0.1/include/
4448
llvmRoot := filepath.Dir(filepath.Dir(binpath))
4549
clangVersionRoot := filepath.Join(llvmRoot, "lib64", "clang")
46-
dirs, err := ioutil.ReadDir(clangVersionRoot)
47-
if err != nil {
48-
// Example include path:
49-
// /usr/lib/llvm-9/lib/clang/9.0.1/include/
50-
clangVersionRoot = filepath.Join(llvmRoot, "lib", "clang")
51-
dirs, err = ioutil.ReadDir(clangVersionRoot)
52-
if err != nil {
53-
// Unexpected.
54-
continue
50+
dirs64, err64 := ioutil.ReadDir(clangVersionRoot)
51+
// Example include path:
52+
// /usr/lib/llvm-9/lib/clang/9.0.1/include/
53+
clangVersionRoot = filepath.Join(llvmRoot, "lib", "clang")
54+
dirs32, err32 := ioutil.ReadDir(clangVersionRoot)
55+
if err64 != nil && err32 != nil {
56+
// Unexpected.
57+
continue
58+
}
59+
dirnames := make([]string, len(dirs64)+len(dirs32))
60+
dirCount := 0
61+
for _, d := range dirs32 {
62+
name := d.Name()
63+
if name == llvmMajor || strings.HasPrefix(name, llvmMajor+".") {
64+
dirnames[dirCount] = filepath.Join(llvmRoot, "lib", "clang", name)
65+
dirCount++
5566
}
5667
}
57-
dirnames := make([]string, len(dirs))
58-
for i, d := range dirs {
59-
dirnames[i] = d.Name()
68+
for _, d := range dirs64 {
69+
name := d.Name()
70+
if name == llvmMajor || strings.HasPrefix(name, llvmMajor+".") {
71+
dirnames[dirCount] = filepath.Join(llvmRoot, "lib64", "clang", name)
72+
dirCount++
73+
}
6074
}
6175
sort.Strings(dirnames)
6276
// Check for the highest version first.
63-
for i := len(dirnames) - 1; i >= 0; i-- {
64-
path := filepath.Join(clangVersionRoot, dirnames[i], "include")
77+
for i := dirCount - 1; i >= 0; i-- {
78+
path := filepath.Join(dirnames[i], "include")
6579
_, err := os.Stat(filepath.Join(path, "stdint.h"))
6680
if err == nil {
6781
return path

0 commit comments

Comments
 (0)