github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/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 package main 12 13 import ( 14 "bytes" 15 "flag" 16 "fmt" 17 "io" 18 "io/ioutil" 19 "log" 20 "os" 21 "os/exec" 22 ) 23 24 var stdout = flag.Bool("stdout", false, "write to stdout instead of builtin.go") 25 26 func main() { 27 flag.Parse() 28 29 var b bytes.Buffer 30 fmt.Fprintln(&b, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT") 31 fmt.Fprintln(&b, "") 32 fmt.Fprintln(&b, "package gc") 33 34 mkbuiltin(&b, "runtime") 35 mkbuiltin(&b, "unsafe") 36 37 var err error 38 if *stdout { 39 _, err = os.Stdout.Write(b.Bytes()) 40 } else { 41 err = ioutil.WriteFile("builtin.go", b.Bytes(), 0666) 42 } 43 if err != nil { 44 log.Fatal(err) 45 } 46 } 47 48 // Compile .go file, import data from .o file, and write Go string version. 49 func mkbuiltin(w io.Writer, name string) { 50 args := []string{"tool", "compile", "-A"} 51 if name == "runtime" { 52 args = append(args, "-u") 53 } 54 args = append(args, "builtin/"+name+".go") 55 56 if err := exec.Command("go", args...).Run(); err != nil { 57 log.Fatal(err) 58 } 59 obj := name + ".o" 60 defer os.Remove(obj) 61 62 b, err := ioutil.ReadFile(obj) 63 if err != nil { 64 log.Fatal(err) 65 } 66 67 // Look for $$B that introduces binary export data. 68 textual := false // TODO(gri) remove once we switched to binary export format 69 i := bytes.Index(b, []byte("\n$$B\n")) 70 if i < 0 { 71 // Look for $$ that introduces textual export data. 72 i = bytes.Index(b, []byte("\n$$\n")) 73 if i < 0 { 74 log.Fatal("did not find beginning of export data") 75 } 76 textual = true 77 i-- // textual data doesn't have B 78 } 79 b = b[i+5:] 80 81 // Look for $$ that closes export data. 82 i = bytes.Index(b, []byte("\n$$\n")) 83 if i < 0 { 84 log.Fatal("did not find end of export data") 85 } 86 b = b[:i+4] 87 88 // Process and reformat export data. 89 fmt.Fprintf(w, "\nconst %simport = \"\"", name) 90 if textual { 91 for _, p := range bytes.SplitAfter(b, []byte("\n")) { 92 // Chop leading white space. 93 p = bytes.TrimLeft(p, " \t") 94 if len(p) == 0 { 95 continue 96 } 97 98 fmt.Fprintf(w, " +\n\t%q", p) 99 } 100 } else { 101 const n = 40 // number of bytes per line 102 for len(b) > 0 { 103 i := len(b) 104 if i > n { 105 i = n 106 } 107 fmt.Fprintf(w, " +\n\t%q", b[:i]) 108 b = b[i:] 109 } 110 } 111 fmt.Fprintf(w, "\n") 112 }