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