github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/build/context.go (about) 1 //===- context.go - Build context utilities for llgo ----------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Build context utilities for llgo. 11 // 12 //===----------------------------------------------------------------------===// 13 14 package build 15 16 import ( 17 "errors" 18 "go/build" 19 "regexp" 20 "strings" 21 ) 22 23 type Context struct { 24 build.Context 25 26 // LLVM triple 27 Triple string 28 } 29 30 // ContextFromTriple returns a new go/build.Context with GOOS and GOARCH 31 // configured from the given triple. 32 func ContextFromTriple(triple string) (*Context, error) { 33 goos, goarch, err := parseTriple(triple) 34 if err != nil { 35 return nil, err 36 } 37 ctx := &Context{Context: build.Default, Triple: triple} 38 ctx.GOOS = goos 39 ctx.GOARCH = goarch 40 ctx.BuildTags = append(ctx.BuildTags, "llgo") 41 if triple == "pnacl" { 42 ctx.BuildTags = append(ctx.BuildTags, "pnacl") 43 } 44 return ctx, nil 45 } 46 47 func parseTriple(triple string) (goos string, goarch string, err error) { 48 if strings.ToLower(triple) == "pnacl" { 49 return "nacl", "le32", nil 50 } 51 52 type REs struct{ re, out string } 53 // reference: http://llvm.org/docs/doxygen/html/Triple_8cpp_source.html 54 goarchREs := []REs{ 55 {"amd64|x86_64", "amd64"}, 56 {"i[3-9]86", "386"}, 57 {"xscale|((arm|thumb)(v.*)?)", "arm"}, 58 } 59 goosREs := []REs{ 60 {"linux.*", "linux"}, 61 {"(darwin|macosx|ios).*", "darwin"}, 62 {"k?freebsd.*", "freebsd"}, 63 {"netbsd.*", "netbsd"}, 64 {"openbsd.*", "openbsd"}, 65 } 66 match := func(list []REs, s string) string { 67 for _, t := range list { 68 if matched, _ := regexp.MatchString(t.re, s); matched { 69 return t.out 70 } 71 } 72 return "" 73 } 74 75 s := strings.Split(triple, "-") 76 switch l := len(s); l { 77 default: 78 return "", "", errors.New("triple should be made up of 2, 3, or 4 parts.") 79 case 2, 3: // ARCHITECTURE-(VENDOR-)OPERATING_SYSTEM 80 goarch = s[0] 81 goos = s[l-1] 82 case 4: // ARCHITECTURE-VENDOR-OPERATING_SYSTEM-ENVIRONMENT 83 goarch = s[0] 84 goos = s[2] 85 } 86 goarch = match(goarchREs, goarch) 87 if goarch == "" { 88 return "", "", errors.New("unknown architecture in triple") 89 } 90 goos = match(goosREs, goos) 91 if goos == "" { 92 return "", "", errors.New("unknown OS in triple") 93 } 94 return goos, goarch, nil 95 }