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.
5 // Package envcmd implements the ``go env'' command.
15 "cmd/go/internal/base"
16 "cmd/go/internal/cache"
18 "cmd/go/internal/load"
19 "cmd/go/internal/work"
22 var CmdEnv
= &base
.Command
{
23 UsageLine
: "env [-json] [var ...]",
24 Short
: "print Go environment information",
26 Env prints Go environment information.
28 By default env prints information as a shell script
29 (on Windows, a batch file). If one or more variable
30 names is given as arguments, env prints the value of
31 each named variable on its own line.
33 The -json flag prints the environment in JSON format
34 instead of as a shell script.
36 For more about environment variables, see 'go help environment'.
41 CmdEnv
.Run
= runEnv
// break init cycle
44 var envJson
= CmdEnv
.Flag
.Bool("json", false, "")
46 func MkEnv() []cfg
.EnvVar
{
51 {Name
: "GOARCH", Value
: cfg
.Goarch
},
52 {Name
: "GOBIN", Value
: cfg
.GOBIN
},
53 {Name
: "GOCACHE", Value
: cache
.DefaultDir()},
54 {Name
: "GOEXE", Value
: cfg
.ExeSuffix
},
55 {Name
: "GOHOSTARCH", Value
: runtime
.GOARCH
},
56 {Name
: "GOHOSTOS", Value
: runtime
.GOOS
},
57 {Name
: "GOOS", Value
: cfg
.Goos
},
58 {Name
: "GOPATH", Value
: cfg
.BuildContext
.GOPATH
},
59 {Name
: "GORACE", Value
: os
.Getenv("GORACE")},
60 {Name
: "GOROOT", Value
: cfg
.GOROOT
},
61 {Name
: "GOTMPDIR", Value
: os
.Getenv("GOTMPDIR")},
62 {Name
: "GOTOOLDIR", Value
: base
.ToolDir
},
64 // disable escape codes in clang errors
65 {Name
: "TERM", Value
: "dumb"},
68 if work
.GccgoBin
!= "" {
69 env
= append(env
, cfg
.EnvVar
{Name
: "GCCGO", Value
: work
.GccgoBin
})
71 env
= append(env
, cfg
.EnvVar
{Name
: "GCCGO", Value
: work
.GccgoName
})
76 env
= append(env
, cfg
.EnvVar
{Name
: "GOARM", Value
: cfg
.GOARM
})
78 env
= append(env
, cfg
.EnvVar
{Name
: "GO386", Value
: cfg
.GO386
})
79 case "mips", "mipsle":
80 env
= append(env
, cfg
.EnvVar
{Name
: "GOMIPS", Value
: cfg
.GOMIPS
})
83 cc
:= cfg
.DefaultCC(cfg
.Goos
, cfg
.Goarch
)
84 if env
:= strings
.Fields(os
.Getenv("CC")); len(env
) > 0 {
87 cxx
:= cfg
.DefaultCXX(cfg
.Goos
, cfg
.Goarch
)
88 if env
:= strings
.Fields(os
.Getenv("CXX")); len(env
) > 0 {
91 env
= append(env
, cfg
.EnvVar
{Name
: "CC", Value
: cc
})
92 env
= append(env
, cfg
.EnvVar
{Name
: "CXX", Value
: cxx
})
94 if cfg
.BuildContext
.CgoEnabled
{
95 env
= append(env
, cfg
.EnvVar
{Name
: "CGO_ENABLED", Value
: "1"})
97 env
= append(env
, cfg
.EnvVar
{Name
: "CGO_ENABLED", Value
: "0"})
103 func findEnv(env
[]cfg
.EnvVar
, name
string) string {
104 for _
, e
:= range env
{
112 // ExtraEnvVars returns environment variables that should not leak into child processes.
113 func ExtraEnvVars() []cfg
.EnvVar
{
116 cppflags
, cflags
, cxxflags
, fflags
, ldflags
, err
:= b
.CFlags(&load
.Package
{})
118 // Should not happen - b.CFlags was given an empty package.
119 fmt
.Fprintf(os
.Stderr
, "go: invalid cflags: %v\n", err
)
122 cmd
:= b
.GccCmd(".", "")
124 // Note: Update the switch in runEnv below when adding to this list.
125 {Name
: "CGO_CFLAGS", Value
: strings
.Join(cflags
, " ")},
126 {Name
: "CGO_CPPFLAGS", Value
: strings
.Join(cppflags
, " ")},
127 {Name
: "CGO_CXXFLAGS", Value
: strings
.Join(cxxflags
, " ")},
128 {Name
: "CGO_FFLAGS", Value
: strings
.Join(fflags
, " ")},
129 {Name
: "CGO_LDFLAGS", Value
: strings
.Join(ldflags
, " ")},
130 {Name
: "PKG_CONFIG", Value
: b
.PkgconfigCmd()},
131 {Name
: "GOGCCFLAGS", Value
: strings
.Join(cmd
[3:], " ")},
135 func runEnv(cmd
*base
.Command
, args
[]string) {
138 // Do we need to call ExtraEnvVars, which is a bit expensive?
139 // Only if we're listing all environment variables ("go env")
140 // or the variables being requested are in the extra list.
144 for _
, arg
:= range args
{
158 env
= append(env
, ExtraEnvVars()...)
164 for _
, name
:= range args
{
165 e
:= cfg
.EnvVar
{Name
: name
, Value
: findEnv(env
, name
)}
170 for _
, name
:= range args
{
171 fmt
.Printf("%s\n", findEnv(env
, name
))
182 for _
, e
:= range env
{
183 if e
.Name
!= "TERM" {
184 switch runtime
.GOOS
{
186 fmt
.Printf("%s=\"%s\"\n", e
.Name
, e
.Value
)
188 if strings
.IndexByte(e
.Value
, '\x00') < 0 {
189 fmt
.Printf("%s='%s'\n", e
.Name
, strings
.Replace(e
.Value
, "'", "''", -1))
191 v
:= strings
.Split(e
.Value
, "\x00")
192 fmt
.Printf("%s=(", e
.Name
)
193 for x
, s
:= range v
{
202 fmt
.Printf("set %s=%s\n", e
.Name
, e
.Value
)
208 func printEnvAsJSON(env
[]cfg
.EnvVar
) {
209 m
:= make(map[string]string)
210 for _
, e
:= range env
{
211 if e
.Name
== "TERM" {
216 enc
:= json
.NewEncoder(os
.Stdout
)
217 enc
.SetIndent("", "\t")
218 if err
:= enc
.Encode(m
); err
!= nil {
219 base
.Fatalf("%s", err
)