Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(226)

Delta Between Two Patch Sets: src/cmd/go/build.go

Issue 5495055: code review 5495055: go: implement test command (Closed)
Left Patch Set: Created 13 years, 3 months ago
Right Patch Set: diff -r e4e0c7c99d9d https://go.googlecode.com/hg/ Created 13 years, 3 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « src/cmd/go/Makefile ('k') | src/cmd/go/main.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2011 The Go Authors. All rights reserved. 1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 package main 5 package main
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "fmt" 9 "fmt"
10 "go/build" 10 "go/build"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 98
99 // A builder holds global state about a build. 99 // A builder holds global state about a build.
100 // It does not hold per-package state, because eventually we will 100 // It does not hold per-package state, because eventually we will
101 // build packages in parallel, and the builder will be shared. 101 // build packages in parallel, and the builder will be shared.
102 type builder struct { 102 type builder struct {
103 work string // the temporary work directory (ends i n filepath.Separator) 103 work string // the temporary work directory (ends i n filepath.Separator)
104 aflag bool // the -a flag 104 aflag bool // the -a flag
105 nflag bool // the -n flag 105 nflag bool // the -n flag
106 vflag bool // the -v flag 106 vflag bool // the -v flag
107 arch string // e.g., "6" 107 arch string // e.g., "6"
108 goroot string // the $GOROOT
108 actionCache map[cacheKey]*action // a cache of already-constructed actio ns 109 actionCache map[cacheKey]*action // a cache of already-constructed actio ns
109 } 110 }
110 111
111 // An action represents a single action in the action graph. 112 // An action represents a single action in the action graph.
112 type action struct { 113 type action struct {
113 f func(*builder, *action) error // the action itself 114 f func(*builder, *action) error // the action itself
114 115
115 » p *Package // the package this action works on 116 » p *Package // the package this action works on
116 » deps []*action // actions that must happen before this one 117 » deps []*action // actions that must happen before this one
117 » done bool // whether the action is done (might have failed) 118 » done bool // whether the action is done (might have failed)
118 » failed bool // whether the action failed 119 » failed bool // whether the action failed
120 » pkgdir string // the -I or -L argument to use when importing this package
121 » ignoreFail bool // whether to run f even if dependencies fail
119 122
120 // Results left for communication with other code. 123 // Results left for communication with other code.
121 pkgobj string // the built .a file 124 pkgobj string // the built .a file
122 pkgbin string // the built a.out file, if one exists 125 pkgbin string // the built a.out file, if one exists
123 } 126 }
124 127
125 // cacheKey is the key for the action cache. 128 // cacheKey is the key for the action cache.
126 type cacheKey struct { 129 type cacheKey struct {
127 mode buildMode 130 mode buildMode
128 p *Package 131 p *Package
129 } 132 }
130 133
131 // buildMode specifies the build mode: 134 // buildMode specifies the build mode:
132 // are we just building things or also installing the results? 135 // are we just building things or also installing the results?
133 type buildMode int 136 type buildMode int
134 137
135 const ( 138 const (
136 modeBuild buildMode = iota 139 modeBuild buildMode = iota
137 modeInstall 140 modeInstall
138 ) 141 )
139 142
140 func (b *builder) init(aflag, nflag, vflag bool) { 143 func (b *builder) init(aflag, nflag, vflag bool) {
141 var err error 144 var err error
142 b.aflag = aflag 145 b.aflag = aflag
143 b.nflag = nflag 146 b.nflag = nflag
144 b.vflag = vflag 147 b.vflag = vflag
145 b.actionCache = make(map[cacheKey]*action) 148 b.actionCache = make(map[cacheKey]*action)
149 b.goroot = runtime.GOROOT()
146 150
147 b.arch, err = build.ArchChar(build.DefaultContext.GOARCH) 151 b.arch, err = build.ArchChar(build.DefaultContext.GOARCH)
148 if err != nil { 152 if err != nil {
149 fatalf("%s", err) 153 fatalf("%s", err)
150 } 154 }
151 155
152 if nflag { 156 if nflag {
153 b.work = "$WORK" 157 b.work = "$WORK"
154 } else { 158 } else {
155 b.work, err = ioutil.TempDir("", "go-build") 159 b.work, err = ioutil.TempDir("", "go-build")
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 206
203 // action returns the action for applying the given operation (mode) to the pack age. 207 // action returns the action for applying the given operation (mode) to the pack age.
204 // depMode is the action to use when building dependencies. 208 // depMode is the action to use when building dependencies.
205 func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action { 209 func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
206 key := cacheKey{mode, p} 210 key := cacheKey{mode, p}
207 a := b.actionCache[key] 211 a := b.actionCache[key]
208 if a != nil { 212 if a != nil {
209 return a 213 return a
210 } 214 }
211 215
212 » a = &action{p: p} 216 » a = &action{p: p, pkgdir: p.t.PkgDir()}
217 » if p.pkgdir != "" { // overrides p.t
218 » » a.pkgdir = p.pkgdir
219 » }
220
213 b.actionCache[key] = a 221 b.actionCache[key] = a
214 222
215 switch mode { 223 switch mode {
216 case modeBuild, modeInstall: 224 case modeBuild, modeInstall:
225 for _, p1 := range p.imports {
226 a.deps = append(a.deps, b.action(depMode, depMode, p1))
227 }
228
217 if !needInstall(p) && !b.aflag { 229 if !needInstall(p) && !b.aflag {
230 // TODO: This is not right if the deps above
231 // are not all no-ops too. If fmt is up to date
232 // wrt its own source files, but strconv has
233 // changed, then fmt is not up to date.
218 a.f = (*builder).nop 234 a.f = (*builder).nop
219 return a 235 return a
220 } 236 }
221 if p.Standard { 237 if p.Standard {
222 switch p.ImportPath { 238 switch p.ImportPath {
223 case "runtime", "runtime/cgo": 239 case "runtime", "runtime/cgo":
224 // Too complex - can't build. 240 // Too complex - can't build.
225 a.f = (*builder).nop 241 a.f = (*builder).nop
226 return a 242 return a
227 case "builtin", "unsafe": 243 case "builtin", "unsafe":
228 // Fake packages - nothing to build. 244 // Fake packages - nothing to build.
229 a.f = (*builder).nop 245 a.f = (*builder).nop
230 return a 246 return a
231 } 247 }
232 } 248 }
233 249
234 if mode == modeInstall { 250 if mode == modeInstall {
235 a.f = (*builder).install 251 a.f = (*builder).install
236 a.deps = []*action{b.action(modeBuild, depMode, p)} 252 a.deps = []*action{b.action(modeBuild, depMode, p)}
237 return a 253 return a
238 } 254 }
239 255
240 a.f = (*builder).build 256 a.f = (*builder).build
241 for _, p1 := range p.imports {
242 a.deps = append(a.deps, b.action(depMode, depMode, p1))
243 }
244 } 257 }
245 258
246 return a 259 return a
247 } 260 }
248 261
249 // needInstall reports whether p needs to be built and installed. 262 // needInstall reports whether p needs to be built and installed.
250 // That is only true if some source file is newer than the installed package bin ary. 263 // That is only true if some source file is newer than the installed package bin ary.
251 func needInstall(p *Package) bool { 264 func needInstall(p *Package) bool {
252 if p.targ == "" { 265 if p.targ == "" {
253 return true 266 return true
(...skipping 27 matching lines...) Expand all
281 294
282 // do runs the action graph rooted at a. 295 // do runs the action graph rooted at a.
283 func (b *builder) do(a *action) { 296 func (b *builder) do(a *action) {
284 if a.done { 297 if a.done {
285 return 298 return
286 } 299 }
287 for _, a1 := range a.deps { 300 for _, a1 := range a.deps {
288 b.do(a1) 301 b.do(a1)
289 if a1.failed { 302 if a1.failed {
290 a.failed = true 303 a.failed = true
291 » » » a.done = true 304 » » » if !a.ignoreFail {
292 » » » return 305 » » » » a.done = true
306 » » » » return
307 » » » }
293 } 308 }
294 } 309 }
295 if err := a.f(b, a); err != nil { 310 if err := a.f(b, a); err != nil {
296 errorf("%s", err) 311 errorf("%s", err)
297 a.failed = true 312 a.failed = true
298 } 313 }
299 a.done = true 314 a.done = true
300 } 315 }
301 316
302 func (b *builder) nop(a *action) error { 317 func (b *builder) nop(a *action) error {
303 return nil 318 return nil
304 } 319 }
305 320
306 // build is the action for building a single package. 321 // build is the action for building a single package or command.
307 func (b *builder) build(a *action) error { 322 func (b *builder) build(a *action) error {
308 obj := filepath.Join(b.work, filepath.FromSlash(a.p.ImportPath+"/_obj")) + string(filepath.Separator) 323 obj := filepath.Join(b.work, filepath.FromSlash(a.p.ImportPath+"/_obj")) + string(filepath.Separator)
309 » a.pkgobj = filepath.Join(b.work, filepath.FromSlash(a.p.ImportPath+".a") ) 324 » if a.pkgobj == "" {
325 » » a.pkgobj = filepath.Join(b.work, filepath.FromSlash(a.p.ImportPa th+".a"))
326 » }
310 327
311 // make build directory 328 // make build directory
312 if err := b.mkdir(obj); err != nil { 329 if err := b.mkdir(obj); err != nil {
313 return err 330 return err
314 } 331 }
315 332
316 var objects []string 333 var objects []string
317 var gofiles []string 334 var gofiles []string
318 gofiles = append(gofiles, a.p.GoFiles...) 335 gofiles = append(gofiles, a.p.GoFiles...)
319 336
320 // run cgo 337 // run cgo
321 if len(a.p.CgoFiles) > 0 { 338 if len(a.p.CgoFiles) > 0 {
322 outGo, outObj, err := b.cgo(a.p.Dir, obj, a.p.info) 339 outGo, outObj, err := b.cgo(a.p.Dir, obj, a.p.info)
323 if err != nil { 340 if err != nil {
324 return err 341 return err
325 } 342 }
326 objects = append(objects, outObj...) 343 objects = append(objects, outObj...)
327 gofiles = append(gofiles, outGo...) 344 gofiles = append(gofiles, outGo...)
328 } 345 }
329 346
330 // prepare Go import path list 347 // prepare Go import path list
331 var inc []string 348 var inc []string
332 inc = append(inc, "-I", b.work) 349 inc = append(inc, "-I", b.work)
333 incMap := map[string]bool{} 350 incMap := map[string]bool{}
334 for _, a1 := range a.deps { 351 for _, a1 := range a.deps {
335 » » p1 := a1.p 352 » » pkgdir := a1.pkgdir
336 » » if p1.t.Goroot { 353 » » if pkgdir == build.Path[0].PkgDir() || pkgdir == "" {
337 continue 354 continue
338 } 355 }
339 pkgdir := p1.t.PkgDir()
340 if !incMap[pkgdir] { 356 if !incMap[pkgdir] {
341 incMap[pkgdir] = true 357 incMap[pkgdir] = true
342 inc = append(inc, "-I", pkgdir) 358 inc = append(inc, "-I", pkgdir)
343 } 359 }
344 } 360 }
345 361
346 // compile Go 362 // compile Go
347 if len(gofiles) > 0 { 363 if len(gofiles) > 0 {
348 out := "_go_.6" 364 out := "_go_.6"
349 if err := b.gc(a.p.Dir, obj+out, a.p.ImportPath, inc, gofiles); err != nil { 365 if err := b.gc(a.p.Dir, obj+out, a.p.ImportPath, inc, gofiles); err != nil {
(...skipping 29 matching lines...) Expand all
379 if err := b.ld(a.p.Dir, a.pkgbin, inc, a.pkgobj); err != nil { 395 if err := b.ld(a.p.Dir, a.pkgbin, inc, a.pkgobj); err != nil {
380 return err 396 return err
381 } 397 }
382 } 398 }
383 399
384 return nil 400 return nil
385 } 401 }
386 402
387 // install is the action for installing a single package. 403 // install is the action for installing a single package.
388 func (b *builder) install(a *action) error { 404 func (b *builder) install(a *action) error {
389 » if err := b.build(a); err != nil { 405 » a1 := a.deps[0]
390 » » return err
391 » }
392
393 var src string 406 var src string
394 var perm uint32 407 var perm uint32
395 » if a.pkgbin != "" { 408 » if a1.pkgbin != "" {
396 » » src = a.pkgbin 409 » » src = a1.pkgbin
397 perm = 0777 410 perm = 0777
398 } else { 411 } else {
399 » » src = a.pkgobj 412 » » src = a1.pkgobj
400 perm = 0666 413 perm = 0666
401 } 414 }
402 415
403 // make target directory 416 // make target directory
404 dst := a.p.targ 417 dst := a.p.targ
405 dir, _ := filepath.Split(dst) 418 dir, _ := filepath.Split(dst)
406 if dir != "" { 419 if dir != "" {
407 if err := b.mkdir(dir); err != nil { 420 if err := b.mkdir(dir); err != nil {
408 return err 421 return err
409 } 422 }
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 626
614 // cc _cgo_import.ARCH 627 // cc _cgo_import.ARCH
615 importObj := obj + "_cgo_import." + b.arch 628 importObj := obj + "_cgo_import." + b.arch
616 if err := b.cc(dir, importObj, importC); err != nil { 629 if err := b.cc(dir, importObj, importC); err != nil {
617 return nil, nil, err 630 return nil, nil, err
618 } 631 }
619 outObj = append(outObj, importObj) 632 outObj = append(outObj, importObj)
620 633
621 return outGo, outObj, nil 634 return outGo, outObj, nil
622 } 635 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b