Home | History | Annotate | Download | only in 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 	"os"
     10 	"runtime"
     11 	"strings"
     12 )
     13 
     14 var cmdEnv = &Command{
     15 	Run:       runEnv,
     16 	UsageLine: "env [var ...]",
     17 	Short:     "print Go environment information",
     18 	Long: `
     19 Env prints Go environment information.
     20 
     21 By default env prints information as a shell script
     22 (on Windows, a batch file).  If one or more variable
     23 names is given as arguments,  env prints the value of
     24 each named variable on its own line.
     25 	`,
     26 }
     27 
     28 type envVar struct {
     29 	name, value string
     30 }
     31 
     32 func mkEnv() []envVar {
     33 	var b builder
     34 	b.init()
     35 
     36 	env := []envVar{
     37 		{"GOARCH", goarch},
     38 		{"GOBIN", gobin},
     39 		{"GOEXE", exeSuffix},
     40 		{"GOHOSTARCH", runtime.GOARCH},
     41 		{"GOHOSTOS", runtime.GOOS},
     42 		{"GOOS", goos},
     43 		{"GOPATH", buildContext.GOPATH},
     44 		{"GORACE", os.Getenv("GORACE")},
     45 		{"GOROOT", goroot},
     46 		{"GOTOOLDIR", toolDir},
     47 
     48 		// disable escape codes in clang errors
     49 		{"TERM", "dumb"},
     50 	}
     51 
     52 	if gccgoBin != "" {
     53 		env = append(env, envVar{"GCCGO", gccgoBin})
     54 	} else {
     55 		env = append(env, envVar{"GCCGO", gccgoName})
     56 	}
     57 
     58 	switch goarch {
     59 	case "arm":
     60 		env = append(env, envVar{"GOARM", os.Getenv("GOARM")})
     61 	case "386":
     62 		env = append(env, envVar{"GO386", os.Getenv("GO386")})
     63 	}
     64 
     65 	cmd := b.gccCmd(".")
     66 	env = append(env, envVar{"CC", cmd[0]})
     67 	env = append(env, envVar{"GOGCCFLAGS", strings.Join(cmd[3:], " ")})
     68 	cmd = b.gxxCmd(".")
     69 	env = append(env, envVar{"CXX", cmd[0]})
     70 
     71 	if buildContext.CgoEnabled {
     72 		env = append(env, envVar{"CGO_ENABLED", "1"})
     73 	} else {
     74 		env = append(env, envVar{"CGO_ENABLED", "0"})
     75 	}
     76 
     77 	return env
     78 }
     79 
     80 func findEnv(env []envVar, name string) string {
     81 	for _, e := range env {
     82 		if e.name == name {
     83 			return e.value
     84 		}
     85 	}
     86 	return ""
     87 }
     88 
     89 // extraEnvVars returns environment variables that should not leak into child processes.
     90 func extraEnvVars() []envVar {
     91 	var b builder
     92 	b.init()
     93 	cppflags, cflags, cxxflags, fflags, ldflags := b.cflags(&Package{})
     94 	return []envVar{
     95 		{"PKG_CONFIG", b.pkgconfigCmd()},
     96 		{"CGO_CFLAGS", strings.Join(cflags, " ")},
     97 		{"CGO_CPPFLAGS", strings.Join(cppflags, " ")},
     98 		{"CGO_CXXFLAGS", strings.Join(cxxflags, " ")},
     99 		{"CGO_FFLAGS", strings.Join(fflags, " ")},
    100 		{"CGO_LDFLAGS", strings.Join(ldflags, " ")},
    101 	}
    102 }
    103 
    104 func runEnv(cmd *Command, args []string) {
    105 	env := newEnv
    106 	env = append(env, extraEnvVars()...)
    107 	if len(args) > 0 {
    108 		for _, name := range args {
    109 			fmt.Printf("%s\n", findEnv(env, name))
    110 		}
    111 		return
    112 	}
    113 
    114 	for _, e := range env {
    115 		if e.name != "TERM" {
    116 			switch runtime.GOOS {
    117 			default:
    118 				fmt.Printf("%s=\"%s\"\n", e.name, e.value)
    119 			case "plan9":
    120 				if strings.IndexByte(e.value, '\x00') < 0 {
    121 					fmt.Printf("%s='%s'\n", e.name, strings.Replace(e.value, "'", "''", -1))
    122 				} else {
    123 					v := strings.Split(e.value, "\x00")
    124 					fmt.Printf("%s=(", e.name)
    125 					for x, s := range v {
    126 						if x > 0 {
    127 							fmt.Printf(" ")
    128 						}
    129 						fmt.Printf("%s", s)
    130 					}
    131 					fmt.Printf(")\n")
    132 				}
    133 			case "windows":
    134 				fmt.Printf("set %s=%s\n", e.name, e.value)
    135 			}
    136 		}
    137 	}
    138 }
    139