Source file src/cmd/dist/buildgo.go

     1  // Copyright 2012 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  package main
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  	"path/filepath"
    11  	"sort"
    12  	"strings"
    13  )
    14  
    15  /*
    16   * Helpers for building cmd/go and cmd/cgo.
    17   */
    18  
    19  // generatedHeader is the string that all source files generated by dist start with.
    20  //
    21  // DO NOT CHANGE THIS STRING. If this string is changed then during
    22  //
    23  //	./make.bash
    24  //	git checkout other-rev
    25  //	./make.bash
    26  //
    27  // the second make.bash will not find the files generated by the first make.bash
    28  // and will not clean up properly.
    29  const generatedHeader = "// Code generated by go tool dist; DO NOT EDIT.\n\n"
    30  
    31  // writeHeader emits the standard "generated by" header for all files generated
    32  // by dist.
    33  func writeHeader(w io.Writer) {
    34  	fmt.Fprint(w, generatedHeader)
    35  }
    36  
    37  // mkzdefaultcc writes zdefaultcc.go:
    38  //
    39  //	package main
    40  //	const defaultCC = <defaultcc>
    41  //	const defaultCXX = <defaultcxx>
    42  //	const defaultPkgConfig = <defaultpkgconfig>
    43  //
    44  // It is invoked to write cmd/go/internal/cfg/zdefaultcc.go
    45  // but we also write cmd/cgo/zdefaultcc.go
    46  func mkzdefaultcc(dir, file string) {
    47  	if strings.Contains(file, filepath.FromSlash("go/internal/cfg")) {
    48  		var buf strings.Builder
    49  		writeHeader(&buf)
    50  		fmt.Fprintf(&buf, "package cfg\n")
    51  		fmt.Fprintln(&buf)
    52  		fmt.Fprintf(&buf, "const DefaultPkgConfig = `%s`\n", defaultpkgconfig)
    53  		buf.WriteString(defaultCCFunc("DefaultCC", defaultcc))
    54  		buf.WriteString(defaultCCFunc("DefaultCXX", defaultcxx))
    55  		writefile(buf.String(), file, writeSkipSame)
    56  		return
    57  	}
    58  
    59  	var buf strings.Builder
    60  	writeHeader(&buf)
    61  	fmt.Fprintf(&buf, "package main\n")
    62  	fmt.Fprintln(&buf)
    63  	fmt.Fprintf(&buf, "const defaultPkgConfig = `%s`\n", defaultpkgconfig)
    64  	buf.WriteString(defaultCCFunc("defaultCC", defaultcc))
    65  	buf.WriteString(defaultCCFunc("defaultCXX", defaultcxx))
    66  	writefile(buf.String(), file, writeSkipSame)
    67  }
    68  
    69  func defaultCCFunc(name string, defaultcc map[string]string) string {
    70  	var buf strings.Builder
    71  
    72  	fmt.Fprintf(&buf, "func %s(goos, goarch string) string {\n", name)
    73  	fmt.Fprintf(&buf, "\tswitch goos+`/`+goarch {\n")
    74  	var keys []string
    75  	for k := range defaultcc {
    76  		if k != "" {
    77  			keys = append(keys, k)
    78  		}
    79  	}
    80  	sort.Strings(keys)
    81  	for _, k := range keys {
    82  		fmt.Fprintf(&buf, "\tcase %s:\n\t\treturn %s\n", quote(k), quote(defaultcc[k]))
    83  	}
    84  	fmt.Fprintf(&buf, "\t}\n")
    85  	if cc := defaultcc[""]; cc != "" {
    86  		fmt.Fprintf(&buf, "\treturn %s\n", quote(cc))
    87  	} else {
    88  		clang, gcc := "clang", "gcc"
    89  		if strings.HasSuffix(name, "CXX") {
    90  			clang, gcc = "clang++", "g++"
    91  		}
    92  		fmt.Fprintf(&buf, "\tswitch goos {\n")
    93  		fmt.Fprintf(&buf, "\tcase ")
    94  		for i, os := range clangos {
    95  			if i > 0 {
    96  				fmt.Fprintf(&buf, ", ")
    97  			}
    98  			fmt.Fprintf(&buf, "%s", quote(os))
    99  		}
   100  		fmt.Fprintf(&buf, ":\n")
   101  		fmt.Fprintf(&buf, "\t\treturn %s\n", quote(clang))
   102  		fmt.Fprintf(&buf, "\t}\n")
   103  		fmt.Fprintf(&buf, "\treturn %s\n", quote(gcc))
   104  	}
   105  	fmt.Fprintf(&buf, "}\n")
   106  
   107  	return buf.String()
   108  }
   109  
   110  // mktzdata src/time/tzdata/zzipdata.go:
   111  //
   112  //	package tzdata
   113  //	const zipdata = "PK..."
   114  func mktzdata(dir, file string) {
   115  	zip := readfile(filepath.Join(dir, "../../../lib/time/zoneinfo.zip"))
   116  
   117  	var buf strings.Builder
   118  	writeHeader(&buf)
   119  	fmt.Fprintf(&buf, "package tzdata\n")
   120  	fmt.Fprintln(&buf)
   121  	fmt.Fprintf(&buf, "const zipdata = %s\n", quote(zip))
   122  
   123  	writefile(buf.String(), file, writeSkipSame)
   124  }
   125  
   126  // quote is like strconv.Quote but simpler and has output
   127  // that does not depend on the exact Go bootstrap version.
   128  func quote(s string) string {
   129  	const hex = "0123456789abcdef"
   130  	var out strings.Builder
   131  	out.WriteByte('"')
   132  	for i := 0; i < len(s); i++ {
   133  		c := s[i]
   134  		if 0x20 <= c && c <= 0x7E && c != '"' && c != '\\' {
   135  			out.WriteByte(c)
   136  		} else {
   137  			out.WriteByte('\\')
   138  			out.WriteByte('x')
   139  			out.WriteByte(hex[c>>4])
   140  			out.WriteByte(hex[c&0xf])
   141  		}
   142  	}
   143  	out.WriteByte('"')
   144  	return out.String()
   145  }
   146  

View as plain text