github.com/gocuntian/go@v0.0.0-20160610041250-fee02d270bf8/src/cmd/compile/internal/gc/mkbuiltin.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build ignore 6 7 // Generate builtin.go from builtin/runtime.go and builtin/unsafe.go. 8 // Run this after changing builtin/runtime.go and builtin/unsafe.go 9 // or after changing the export metadata format in the compiler. 10 // Either way, you need to have a working compiler binary first. 11 // See bexport.go for how to make an export metadata format change. 12 package main 13 14 import ( 15 "bytes" 16 "flag" 17 "fmt" 18 "io" 19 "io/ioutil" 20 "log" 21 "os" 22 "os/exec" 23 ) 24 25 var stdout = flag.Bool("stdout", false, "write to stdout instead of builtin.go") 26 27 func main() { 28 flag.Parse() 29 30 var b bytes.Buffer 31 fmt.Fprintln(&b, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT") 32 fmt.Fprintln(&b, "") 33 fmt.Fprintln(&b, "package gc") 34 35 mkbuiltin(&b, "runtime") 36 mkbuiltin(&b, "unsafe") 37 38 var err error 39 if *stdout { 40 _, err = os.Stdout.Write(b.Bytes()) 41 } else { 42 err = ioutil.WriteFile("builtin.go", b.Bytes(), 0666) 43 } 44 if err != nil { 45 log.Fatal(err) 46 } 47 } 48 49 // Compile .go file, import data from .o file, and write Go string version. 50 func mkbuiltin(w io.Writer, name string) { 51 args := []string{"tool", "compile", "-A"} 52 if name == "runtime" { 53 args = append(args, "-u") 54 } 55 args = append(args, "builtin/"+name+".go") 56 57 if err := exec.Command("go", args...).Run(); err != nil { 58 log.Fatal(err) 59 } 60 obj := name + ".o" 61 defer os.Remove(obj) 62 63 b, err := ioutil.ReadFile(obj) 64 if err != nil { 65 log.Fatal(err) 66 } 67 68 // Look for $$B that introduces binary export data. 69 textual := false // TODO(gri) remove once we switched to binary export format 70 i := bytes.Index(b, []byte("\n$$B\n")) 71 if i < 0 { 72 // Look for $$ that introduces textual export data. 73 i = bytes.Index(b, []byte("\n$$\n")) 74 if i < 0 { 75 log.Fatal("did not find beginning of export data") 76 } 77 textual = true 78 i-- // textual data doesn't have B 79 } 80 b = b[i+5:] 81 82 // Look for $$ that closes export data. 83 i = bytes.Index(b, []byte("\n$$\n")) 84 if i < 0 { 85 log.Fatal("did not find end of export data") 86 } 87 b = b[:i+4] 88 89 // Process and reformat export data. 90 fmt.Fprintf(w, "\nconst %simport = \"\"", name) 91 if textual { 92 for _, p := range bytes.SplitAfter(b, []byte("\n")) { 93 // Chop leading white space. 94 p = bytes.TrimLeft(p, " \t") 95 if len(p) == 0 { 96 continue 97 } 98 99 fmt.Fprintf(w, " +\n\t%q", p) 100 } 101 } else { 102 const n = 40 // number of bytes per line 103 for len(b) > 0 { 104 i := len(b) 105 if i > n { 106 i = n 107 } 108 fmt.Fprintf(w, " +\n\t%q", b[:i]) 109 b = b[i:] 110 } 111 } 112 fmt.Fprintf(w, "\n") 113 }