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  }