github.com/flyinox/gosm@v0.0.0-20171117061539-16768cb62077/src/cmd/go/internal/envcmd/env.go (about) 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 envcmd implements the ``go env'' command. 6 package envcmd 7 8 import ( 9 "encoding/json" 10 "fmt" 11 "os" 12 "runtime" 13 "strings" 14 15 "cmd/go/internal/base" 16 "cmd/go/internal/cfg" 17 "cmd/go/internal/load" 18 "cmd/go/internal/work" 19 ) 20 21 var CmdEnv = &base.Command{ 22 UsageLine: "env [-json] [var ...]", 23 Short: "print Go environment information", 24 Long: ` 25 Env prints Go environment information. 26 27 By default env prints information as a shell script 28 (on Windows, a batch file). If one or more variable 29 names is given as arguments, env prints the value of 30 each named variable on its own line. 31 32 The -json flag prints the environment in JSON format 33 instead of as a shell script. 34 `, 35 } 36 37 func init() { 38 CmdEnv.Run = runEnv // break init cycle 39 } 40 41 var envJson = CmdEnv.Flag.Bool("json", false, "") 42 43 func MkEnv() []cfg.EnvVar { 44 var b work.Builder 45 b.Init() 46 47 env := []cfg.EnvVar{ 48 {Name: "GOARCH", Value: cfg.Goarch}, 49 {Name: "GOBIN", Value: cfg.GOBIN}, 50 {Name: "GOEXE", Value: cfg.ExeSuffix}, 51 {Name: "GOHOSTARCH", Value: runtime.GOARCH}, 52 {Name: "GOHOSTOS", Value: runtime.GOOS}, 53 {Name: "GOOS", Value: cfg.Goos}, 54 {Name: "GOPATH", Value: cfg.BuildContext.GOPATH}, 55 {Name: "GORACE", Value: os.Getenv("GORACE")}, 56 {Name: "GOROOT", Value: cfg.GOROOT}, 57 {Name: "GOTOOLDIR", Value: base.ToolDir}, 58 59 // disable escape codes in clang errors 60 {Name: "TERM", Value: "dumb"}, 61 } 62 63 if work.GccgoBin != "" { 64 env = append(env, cfg.EnvVar{Name: "GCCGO", Value: work.GccgoBin}) 65 } else { 66 env = append(env, cfg.EnvVar{Name: "GCCGO", Value: work.GccgoName}) 67 } 68 69 switch cfg.Goarch { 70 case "arm": 71 env = append(env, cfg.EnvVar{Name: "GOARM", Value: cfg.GOARM}) 72 case "386": 73 env = append(env, cfg.EnvVar{Name: "GO386", Value: cfg.GO386}) 74 } 75 76 cmd := b.GccCmd(".") 77 env = append(env, cfg.EnvVar{Name: "CC", Value: cmd[0]}) 78 env = append(env, cfg.EnvVar{Name: "GOGCCFLAGS", Value: strings.Join(cmd[3:], " ")}) 79 cmd = b.GxxCmd(".") 80 env = append(env, cfg.EnvVar{Name: "CXX", Value: cmd[0]}) 81 82 if cfg.BuildContext.CgoEnabled { 83 env = append(env, cfg.EnvVar{Name: "CGO_ENABLED", Value: "1"}) 84 } else { 85 env = append(env, cfg.EnvVar{Name: "CGO_ENABLED", Value: "0"}) 86 } 87 88 return env 89 } 90 91 func findEnv(env []cfg.EnvVar, name string) string { 92 for _, e := range env { 93 if e.Name == name { 94 return e.Value 95 } 96 } 97 return "" 98 } 99 100 // ExtraEnvVars returns environment variables that should not leak into child processes. 101 func ExtraEnvVars() []cfg.EnvVar { 102 var b work.Builder 103 b.Init() 104 cppflags, cflags, cxxflags, fflags, ldflags := b.CFlags(&load.Package{}) 105 return []cfg.EnvVar{ 106 {Name: "CGO_CFLAGS", Value: strings.Join(cflags, " ")}, 107 {Name: "CGO_CPPFLAGS", Value: strings.Join(cppflags, " ")}, 108 {Name: "CGO_CXXFLAGS", Value: strings.Join(cxxflags, " ")}, 109 {Name: "CGO_FFLAGS", Value: strings.Join(fflags, " ")}, 110 {Name: "CGO_LDFLAGS", Value: strings.Join(ldflags, " ")}, 111 {Name: "PKG_CONFIG", Value: b.PkgconfigCmd()}, 112 } 113 } 114 115 func runEnv(cmd *base.Command, args []string) { 116 env := cfg.CmdEnv 117 env = append(env, ExtraEnvVars()...) 118 if len(args) > 0 { 119 if *envJson { 120 var es []cfg.EnvVar 121 for _, name := range args { 122 e := cfg.EnvVar{Name: name, Value: findEnv(env, name)} 123 es = append(es, e) 124 } 125 printEnvAsJSON(es) 126 } else { 127 for _, name := range args { 128 fmt.Printf("%s\n", findEnv(env, name)) 129 } 130 } 131 return 132 } 133 134 if *envJson { 135 printEnvAsJSON(env) 136 return 137 } 138 139 for _, e := range env { 140 if e.Name != "TERM" { 141 switch runtime.GOOS { 142 default: 143 fmt.Printf("%s=\"%s\"\n", e.Name, e.Value) 144 case "plan9": 145 if strings.IndexByte(e.Value, '\x00') < 0 { 146 fmt.Printf("%s='%s'\n", e.Name, strings.Replace(e.Value, "'", "''", -1)) 147 } else { 148 v := strings.Split(e.Value, "\x00") 149 fmt.Printf("%s=(", e.Name) 150 for x, s := range v { 151 if x > 0 { 152 fmt.Printf(" ") 153 } 154 fmt.Printf("%s", s) 155 } 156 fmt.Printf(")\n") 157 } 158 case "windows": 159 fmt.Printf("set %s=%s\n", e.Name, e.Value) 160 } 161 } 162 } 163 } 164 165 func printEnvAsJSON(env []cfg.EnvVar) { 166 m := make(map[string]string) 167 for _, e := range env { 168 if e.Name == "TERM" { 169 continue 170 } 171 m[e.Name] = e.Value 172 } 173 enc := json.NewEncoder(os.Stdout) 174 enc.SetIndent("", "\t") 175 if err := enc.Encode(m); err != nil { 176 base.Fatalf("%s", err) 177 } 178 }