blob: c1ed935e5643a16df5fa87b5c9eabf99f519bcdb [file] [log] [blame]
Peter Collingbournead9841e2014-11-27 00:06:42 +00001//===- 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
14package build
15
16import (
17 "errors"
18 "go/build"
19 "regexp"
20 "strings"
21)
22
23type 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.
32func 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
47func 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}