96 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			96 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
//===- context.go - Build context utilities for llgo ----------------------===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// 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
 | 
						|
}
 |