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 $* (runtime.go and unsafe.go). 8 // Run this after changing runtime.go and 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 "bufio" 15 "fmt" 16 "io" 17 "log" 18 "os" 19 "os/exec" 20 "strings" 21 ) 22 23 func main() { 24 f, err := os.Create("builtin.go") 25 if err != nil { 26 log.Fatal(err) 27 } 28 defer f.Close() 29 w := bufio.NewWriter(f) 30 31 fmt.Fprintln(w, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT") 32 fmt.Fprintln(w, "") 33 fmt.Fprintln(w, "package gc") 34 35 for _, name := range os.Args[1:] { 36 mkbuiltin(w, name) 37 } 38 39 if err := w.Flush(); err != nil { 40 log.Fatal(err) 41 } 42 } 43 44 // Compile .go file, import data from .6 file, and write Go string version. 45 func mkbuiltin(w io.Writer, name string) { 46 if err := exec.Command("go", "tool", "compile", "-A", "builtin/"+name+".go").Run(); err != nil { 47 log.Fatal(err) 48 } 49 obj := name + ".o" 50 defer os.Remove(obj) 51 52 r, err := os.Open(obj) 53 if err != nil { 54 log.Fatal(err) 55 } 56 defer r.Close() 57 scanner := bufio.NewScanner(r) 58 59 // Look for $$ that introduces imports. 60 for scanner.Scan() { 61 if strings.Contains(scanner.Text(), "$$") { 62 goto Begin 63 } 64 } 65 log.Fatal("did not find beginning of imports") 66 67 Begin: 68 initfunc := fmt.Sprintf("init_%s_function", name) 69 70 fmt.Fprintf(w, "\nconst %simport = \"\" +\n", name) 71 72 // sys.go claims to be in package PACKAGE to avoid 73 // conflicts during "go tool compile sys.go". Rename PACKAGE to $2. 74 replacer := strings.NewReplacer("PACKAGE", name) 75 76 // Process imports, stopping at $$ that closes them. 77 for scanner.Scan() { 78 p := scanner.Text() 79 if strings.Contains(p, "$$") { 80 goto End 81 } 82 83 // Chop leading white space. 84 p = strings.TrimLeft(p, " \t") 85 86 // Cut out decl of init_$1_function - it doesn't exist. 87 if strings.Contains(p, initfunc) { 88 continue 89 } 90 91 fmt.Fprintf(w, "\t%q +\n", replacer.Replace(p)+"\n") 92 } 93 log.Fatal("did not find end of imports") 94 95 End: 96 fmt.Fprintf(w, "\t\"$$\\n\"\n") 97 } 98