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
 | |
| }
 |