1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package main
16
17 import (
18 "flag"
19 "fmt"
20 "go/build"
21 "os"
22 "path/filepath"
23 "regexp"
24 "strings"
25 )
26
27
28 func stdlib(args []string) error {
29
30 flags := flag.NewFlagSet("stdlib", flag.ExitOnError)
31 goenv := envFlags(flags)
32 out := flags.String("out", "", "Path to output go root")
33 race := flags.Bool("race", false, "Build in race mode")
34 shared := flags.Bool("shared", false, "Build in shared mode")
35 dynlink := flags.Bool("dynlink", false, "Build in dynlink mode")
36 pgoprofile := flags.String("pgoprofile", "", "Build with pgo using the given pprof file")
37 var packages multiFlag
38 flags.Var(&packages, "package", "Packages to build")
39 var gcflags quoteMultiFlag
40 flags.Var(&gcflags, "gcflags", "Go compiler flags")
41 if err := flags.Parse(args); err != nil {
42 return err
43 }
44 if err := goenv.checkFlags(); err != nil {
45 return err
46 }
47 goroot := os.Getenv("GOROOT")
48 if goroot == "" {
49 return fmt.Errorf("GOROOT not set")
50 }
51 output := abs(*out)
52
53
54 if os.Getenv("CGO_ENABLED") == "1" && filepath.Base(os.Getenv("CC")) == "vc_installation_error.bat" {
55 return fmt.Errorf(`cgo is required, but a C toolchain has not been configured.
56 You may need to use the flags --cpu=x64_windows --compiler=mingw-gcc.`)
57 }
58
59
60 if err := replicate(goroot, output, replicatePaths("src", "pkg/tool", "pkg/include")); err != nil {
61 return err
62 }
63
64 output, err := processPath(output)
65 if err != nil {
66 return err
67 }
68
69
70 os.Setenv("GOROOT", output)
71
72
73
74 cachePath := filepath.Join(output, ".gocache")
75 os.Setenv("GOCACHE", cachePath)
76 defer os.RemoveAll(cachePath)
77
78
79
80
81 os.Setenv("GO111MODULE", "off")
82
83
84 os.Setenv("CC", quotePathIfNeeded(abs(os.Getenv("CC"))))
85
86
87 absPaths := []string{}
88 for _, path := range filepath.SplitList(os.Getenv("PATH")) {
89 absPaths = append(absPaths, abs(path))
90 }
91 os.Setenv("PATH", strings.Join(absPaths, string(os.PathListSeparator)))
92
93 sandboxPath := abs(".")
94
95
96 os.Setenv("CGO_CFLAGS", os.Getenv("CGO_CFLAGS")+" "+strings.Join(defaultCFlags(output), " "))
97 os.Setenv("CGO_LDFLAGS", os.Getenv("CGO_LDFLAGS")+" "+strings.Join(defaultLdFlags(), " "))
98
99
100
101 var b strings.Builder
102 sep := ""
103 cgoLdflags, _ := splitQuoted(os.Getenv("CGO_LDFLAGS"))
104 for _, f := range cgoLdflags {
105 b.WriteString(sep)
106 sep = "|"
107 b.WriteString(regexp.QuoteMeta(f))
108
109
110 if f == "-framework" {
111 sep = " "
112 }
113 }
114 os.Setenv("CGO_LDFLAGS_ALLOW", b.String())
115 os.Setenv("GODEBUG", "installgoroot=all")
116
117
118
119
120
121
122
123 installArgs := goenv.goCmd("install", "-toolexec", abs(os.Args[0])+" filterbuildid")
124 if len(build.Default.BuildTags) > 0 {
125 installArgs = append(installArgs, "-tags", strings.Join(build.Default.BuildTags, ","))
126 }
127
128 ldflags := []string{"-trimpath", sandboxPath}
129 asmflags := []string{"-trimpath", output}
130 if *race {
131 installArgs = append(installArgs, "-race")
132 }
133 if *pgoprofile != "" {
134 installArgs = append(installArgs, "-pgo", abs(*pgoprofile))
135 }
136 if *shared {
137 gcflags = append(gcflags, "-shared")
138 ldflags = append(ldflags, "-shared")
139 asmflags = append(asmflags, "-shared")
140 }
141 if *dynlink {
142 gcflags = append(gcflags, "-dynlink")
143 ldflags = append(ldflags, "-dynlink")
144 asmflags = append(asmflags, "-dynlink")
145 }
146
147
148
149
150 allSlug := ""
151 for _, t := range build.Default.ReleaseTags {
152 if t == "go1.10" {
153 allSlug = "all="
154 break
155 }
156 }
157 installArgs = append(installArgs, "-gcflags="+allSlug+strings.Join(gcflags, " "))
158 installArgs = append(installArgs, "-ldflags="+allSlug+strings.Join(ldflags, " "))
159 installArgs = append(installArgs, "-asmflags="+allSlug+strings.Join(asmflags, " "))
160
161
162
163 if err := absEnv(cgoEnvVars, cgoAbsEnvFlags); err != nil {
164 return fmt.Errorf("error modifying cgo environment to absolute path: %v", err)
165 }
166
167 installArgs = append(installArgs, packages...)
168 if err := goenv.runCommand(installArgs); err != nil {
169 return err
170 }
171 return nil
172 }
173
View as plain text