From edfe08dc7bbe547004e9bcd53e9b8ab43f1fe036 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Sun, 18 Oct 2020 13:54:30 +0200 Subject: sys/targets: add support for gcc&clang at the same time Add GetEx function that allow to specify gcc/clang. Update #2171 --- sys/targets/targets.go | 71 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/sys/targets/targets.go b/sys/targets/targets.go index f580a88d8..28ee5b376 100644 --- a/sys/targets/targets.go +++ b/sys/targets/targets.go @@ -14,7 +14,6 @@ import ( ) type Target struct { - init sync.Once osCommon OS string Arch string @@ -38,6 +37,11 @@ type Target struct { NeedSyscallDefine func(nr uint64) bool HostEndian binary.ByteOrder SyscallTrampolines map[string]string + + init *sync.Once + initOther *sync.Once + // Target for the other compiler. If SYZ_CLANG says to use gcc, this will be clang. Or the other way around. + other *Target } type osCommon struct { @@ -75,12 +79,26 @@ type osCommon struct { } func Get(OS, arch string) *Target { + return GetEx(OS, arch, useClang) +} + +func GetEx(OS, arch string, clang bool) *Target { target := List[OS][arch] if target == nil { return nil } - target.init.Do(target.lazyInit) - return target + if clang == useClang { + target.init.Do(target.lazyInit) + return target + } + target.initOther.Do(func() { + other := new(Target) + *other = *target + other.setCompiler(clang) + other.lazyInit() + target.other = other + }) + return target.other } // nolint: lll @@ -502,6 +520,8 @@ func initTarget(target *Target, OS, arch string) { if common, ok := oses[OS]; ok { target.osCommon = common } + target.init = new(sync.Once) + target.initOther = new(sync.Once) target.OS = OS target.Arch = arch if target.NeedSyscallDefine == nil { @@ -531,19 +551,7 @@ func initTarget(target *Target, OS, arch string) { target.Triple = "" } if target.CCompiler == "" { - target.CCompiler = "gcc" - if target.Triple != "" { - target.CCompiler = target.Triple + "-" + target.CCompiler - } - } - if useClang { - target.CCompiler = "clang" - target.KernelCompiler = "clang" - target.KernelLinker = "ld.lld" - if target.Triple != "" { - target.CFlags = append(target.CFlags, "--target="+target.Triple) - } - target.CFlags = append(target.CFlags, "-ferror-limit=0") + target.setCompiler(useClang) } if target.CPP == "" { target.CPP = "cpp" @@ -579,6 +587,37 @@ func initTarget(target *Target, OS, arch string) { } } +func (target *Target) setCompiler(clang bool) { + // setCompiler may be called effectively twice for target.other, + // so first we remove flags the previous call may have added. + pos := 0 + for _, flag := range target.CFlags { + if flag == "-ferror-limit=0" || + strings.HasPrefix(flag, "--target=") { + continue + } + target.CFlags[pos] = flag + pos++ + } + target.CFlags = target.CFlags[:pos] + if clang { + target.CCompiler = "clang" + target.KernelCompiler = "clang" + target.KernelLinker = "ld.lld" + if target.Triple != "" { + target.CFlags = append(target.CFlags, "--target="+target.Triple) + } + target.CFlags = append(target.CFlags, "-ferror-limit=0") + } else { + target.CCompiler = "gcc" + target.KernelCompiler = "" + target.KernelLinker = "" + if target.Triple != "" { + target.CCompiler = target.Triple + "-" + target.CCompiler + } + } +} + func (target *Target) replaceSourceDir(param *string, sourceDir string) { if !strings.Contains(*param, sourceDirVar) { return -- cgit mrf-deployment