github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/tools/syz-make/make.go (about) 1 // Copyright 2018 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 // syz-make provides information required to build native code for the Makefile. 5 package main 6 7 import ( 8 "fmt" 9 "os" 10 "runtime" 11 "strconv" 12 "strings" 13 14 "github.com/google/syzkaller/pkg/osutil" 15 "github.com/google/syzkaller/sys/targets" 16 ) 17 18 func main() { 19 vars, err := impl() 20 if err != nil { 21 fmt.Printf("export SYZERROR=%v\n", err) 22 os.Exit(1) 23 } 24 for _, v := range vars { 25 fmt.Printf("export %v=%v\\n", v.Name, v.Val) 26 } 27 } 28 29 type Var struct { 30 Name string 31 Val string 32 } 33 34 func impl() ([]Var, error) { 35 hostOS := or(os.Getenv("HOSTOS"), runtime.GOOS) 36 hostArch := or(os.Getenv("HOSTARCH"), runtime.GOARCH) 37 targetOS := or(os.Getenv("TARGETOS"), hostOS) 38 targetArch := or(os.Getenv("TARGETARCH"), hostArch) 39 targetVMArch := or(os.Getenv("TARGETVMARCH"), targetArch) 40 target := targets.Get(targetOS, targetArch) 41 if target == nil { 42 return nil, fmt.Errorf("unknown target %v/%v", targetOS, targetArch) 43 } 44 parallelism := runtime.NumCPU() 45 if os.Getenv("CI") != "" { 46 // Github actions VMs have 2 vCPUs (Standard_DS2_v2 class). So we don't get lots of speed up 47 // from make parallelism, but we are getting memory oversubscription and duplicated work 48 // because make invokes multiple go commands that potentially build same packages in parallel. 49 // Go command itself parallelizes compiler and test invocations. So disable make parallelism 50 // to avoid OOM kills. 51 parallelism = 1 52 } 53 if runtime.GOOS == targets.OpenBSD { 54 // Avoids too much concurrency on OpenBSD which can't handle this much. 55 parallelism = 1 56 } 57 if mem := osutil.SystemMemorySize(); mem != 0 { 58 // Ensure that we have at least 1GB per Go compiler/linker invocation. 59 // Go compiler/linker can consume significant amount of memory 60 // (observed to consume at least 600MB). See #1276 for context. 61 // And we have parallelization both on make and on go levels, 62 // this can severe oversubscribe RAM. 63 // Note: the result can be significantly lower than the CPU number, 64 // but this is fine because Go builds/tests are parallelized internally. 65 memLimit := int(mem / (1 << 30)) 66 for parallelism > 1 && parallelism*parallelism > memLimit { 67 parallelism-- 68 } 69 } 70 vars := []Var{ 71 {"BUILDOS", runtime.GOOS}, 72 {"NATIVEBUILDOS", target.BuildOS}, 73 {"HOSTOS", hostOS}, 74 {"HOSTARCH", hostArch}, 75 {"TARGETOS", targetOS}, 76 {"TARGETARCH", targetArch}, 77 {"TARGETVMARCH", targetVMArch}, 78 {"CC", target.CCompiler}, 79 {"ADDCFLAGS", strings.Join(target.CFlags, " ")}, 80 {"NCORES", strconv.Itoa(parallelism)}, 81 {"EXE", target.ExeExtension}, 82 {"NATIVEBUILDOS", target.BuildOS}, 83 {"NO_CROSS_COMPILER", target.BrokenCompiler}, 84 } 85 return vars, nil 86 } 87 88 func or(s1, s2 string) string { 89 if s1 != "" { 90 return s1 91 } 92 return s2 93 }