github.com/metux/go-metabuild@v0.0.0-20240118143255-d9ed5ab697f9/util/compiler/probe/cc.go (about) 1 package probe 2 3 import ( 4 "log" 5 "os" 6 "strings" 7 8 cmdrun "github.com/metux/go-metabuild/util/cmd" 9 "github.com/metux/go-metabuild/util/compiler/base" 10 ) 11 12 func probeCC(ci *base.CompilerInfo, envvar string, prefix string) bool { 13 ci.Language = base.LangC 14 15 if fromenv := cmdrun.EnvCmdline(envvar); len(fromenv) != 0 { 16 return probeCCcmd(ci, fromenv) 17 } 18 19 compilers := []string{"gcc", "clang", "cc"} 20 for _, c := range compilers { 21 if probeCCcmd(ci, cmdrun.StrCmdline(prefix+c)) { 22 return true 23 } 24 } 25 return false 26 } 27 28 func probeCCcmd(ci *base.CompilerInfo, cmd []string) bool { 29 if len(cmd) == 0 || cmd[0] == "" { 30 return false 31 } 32 ci.Command = cmd 33 34 // try to guess from help output 35 36 out, err := cmdrun.RunOutOne(append(ci.Command, "--help"), false) 37 if err != nil { 38 log.Println("probeCompilerId: cant get help page") 39 return false 40 } 41 if strings.Contains(out, "clang LLVM compiler") { 42 return probeClang(ci) 43 } 44 if probeGCC(ci) { 45 return true 46 } 47 48 // cant detect it 49 log.Println("neither gcc nor clang") 50 return false 51 } 52 53 func DetectCC() (base.CompilerInfo, base.CompilerInfo, error) { 54 55 crossPrefix, crossCompile := CheckCross() 56 57 infoTarget := base.CompilerInfo{Language: base.LangC, CrossForHost: crossCompile, CrossPrefix: crossPrefix} 58 infoHost := base.CompilerInfo{Language: base.LangC, CrossForBuild: crossCompile} 59 60 if !probeCC(&infoTarget, "CC", crossPrefix) { 61 return infoTarget, infoHost, base.ErrNoUsableCompiler 62 } 63 64 if crossCompile { 65 if os.Getenv("HOST_CC") != "" { 66 if !probeCC(&infoHost, "HOST_CC", "") { 67 return base.CompilerInfo{}, base.CompilerInfo{}, base.ErrNoUsableCompiler 68 } 69 } else if crossPrefix != "" { 70 if !probeCC(&infoHost, "", "") { 71 return base.CompilerInfo{}, base.CompilerInfo{}, base.ErrNoUsableCompiler 72 } 73 } else { 74 return infoTarget, infoHost, base.ErrCrossMissingCC 75 } 76 } 77 78 // no cross, so return the target compiler twice 79 return infoTarget, infoTarget, nil 80 }