OLD | NEW |
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 build | 5 package build |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "errors" | 9 "errors" |
10 "fmt" | 10 "fmt" |
11 "go/ast" | 11 "go/ast" |
12 "go/doc" | 12 "go/doc" |
13 "go/parser" | 13 "go/parser" |
14 "go/token" | 14 "go/token" |
15 "io/ioutil" | 15 "io/ioutil" |
16 "log" | 16 "log" |
17 "os" | 17 "os" |
18 "path" | 18 "path" |
19 "path/filepath" | 19 "path/filepath" |
20 "runtime" | 20 "runtime" |
21 "sort" | 21 "sort" |
22 "strconv" | 22 "strconv" |
23 "strings" | 23 "strings" |
24 "unicode" | 24 "unicode" |
25 ) | 25 ) |
26 | 26 |
27 // A Context specifies the supporting context for a build. | 27 // A Context specifies the supporting context for a build. |
28 type Context struct { | 28 type Context struct { |
29 » GOARCH string // target architecture | 29 » GOARCH string // target architecture |
30 » GOOS string // target operating system | 30 » GOOS string // target operating system |
| 31 » CgoEnabled bool // whether cgo can be used |
31 // TODO(rsc,adg): GOPATH | 32 // TODO(rsc,adg): GOPATH |
32 | 33 |
33 // By default, ScanDir uses the operating system's | 34 // By default, ScanDir uses the operating system's |
34 // file system calls to read directories and files. | 35 // file system calls to read directories and files. |
35 // Callers can override those calls to provide other | 36 // Callers can override those calls to provide other |
36 // ways to read data by setting ReadDir and ReadFile. | 37 // ways to read data by setting ReadDir and ReadFile. |
37 // ScanDir does not make any assumptions about the | 38 // ScanDir does not make any assumptions about the |
38 // format of the strings dir and file: they can be | 39 // format of the strings dir and file: they can be |
39 // slash-separated, backslash-separated, even URLs. | 40 // slash-separated, backslash-separated, even URLs. |
40 | 41 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 } | 74 } |
74 | 75 |
75 // The DefaultContext is the default Context for builds. | 76 // The DefaultContext is the default Context for builds. |
76 // It uses the GOARCH and GOOS environment variables | 77 // It uses the GOARCH and GOOS environment variables |
77 // if set, or else the compiled code's GOARCH and GOOS. | 78 // if set, or else the compiled code's GOARCH and GOOS. |
78 var DefaultContext = Context{ | 79 var DefaultContext = Context{ |
79 GOARCH: envOr("GOARCH", runtime.GOARCH), | 80 GOARCH: envOr("GOARCH", runtime.GOARCH), |
80 GOOS: envOr("GOOS", runtime.GOOS), | 81 GOOS: envOr("GOOS", runtime.GOOS), |
81 } | 82 } |
82 | 83 |
| 84 func init() { |
| 85 s := os.Getenv("CGO_ENABLED") |
| 86 switch s { |
| 87 case "1": |
| 88 DefaultContext.CgoEnabled = true |
| 89 return |
| 90 case "0": |
| 91 DefaultContext.CgoEnabled = false |
| 92 return |
| 93 } |
| 94 if DefaultContext.GOARCH == "arm" { |
| 95 DefaultContext.CgoEnabled = false |
| 96 return |
| 97 } |
| 98 if DefaultContext.GOOS == "openbsd" || DefaultContext.GOOS == "netbsd" { |
| 99 DefaultContext.CgoEnabled = false |
| 100 return |
| 101 } |
| 102 |
| 103 // Default is to allow cgo. |
| 104 DefaultContext.CgoEnabled = true |
| 105 } |
| 106 |
83 func envOr(name, def string) string { | 107 func envOr(name, def string) string { |
84 s := os.Getenv(name) | 108 s := os.Getenv(name) |
85 if s == "" { | 109 if s == "" { |
86 return def | 110 return def |
87 } | 111 } |
88 return s | 112 return s |
89 } | 113 } |
90 | 114 |
91 type DirInfo struct { | 115 type DirInfo struct { |
92 Package string // Name of package in dir | 116 Package string // Name of package in dir |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 if cg != nil { | 281 if cg != nil { |
258 if err := ctxt.saveCgo(filename,
&di, cg); err != nil { | 282 if err := ctxt.saveCgo(filename,
&di, cg); err != nil { |
259 return nil, err | 283 return nil, err |
260 } | 284 } |
261 } | 285 } |
262 isCgo = true | 286 isCgo = true |
263 } | 287 } |
264 } | 288 } |
265 } | 289 } |
266 if isCgo { | 290 if isCgo { |
267 » » » di.CgoFiles = append(di.CgoFiles, name) | 291 » » » if ctxt.CgoEnabled { |
| 292 » » » » di.CgoFiles = append(di.CgoFiles, name) |
| 293 » » » } |
268 } else if isTest { | 294 } else if isTest { |
269 if pkg == string(pf.Name.Name) { | 295 if pkg == string(pf.Name.Name) { |
270 di.TestGoFiles = append(di.TestGoFiles, name) | 296 di.TestGoFiles = append(di.TestGoFiles, name) |
271 } else { | 297 } else { |
272 di.XTestGoFiles = append(di.XTestGoFiles, name) | 298 di.XTestGoFiles = append(di.XTestGoFiles, name) |
273 } | 299 } |
274 } else { | 300 } else { |
275 di.GoFiles = append(di.GoFiles, name) | 301 di.GoFiles = append(di.GoFiles, name) |
276 } | 302 } |
277 } | 303 } |
(...skipping 21 matching lines...) Expand all Loading... |
299 sort.Strings(di.SFiles) | 325 sort.Strings(di.SFiles) |
300 } | 326 } |
301 | 327 |
302 // File name lists are sorted because ReadDir sorts. | 328 // File name lists are sorted because ReadDir sorts. |
303 sort.Strings(di.Imports) | 329 sort.Strings(di.Imports) |
304 sort.Strings(di.TestImports) | 330 sort.Strings(di.TestImports) |
305 return &di, nil | 331 return &di, nil |
306 } | 332 } |
307 | 333 |
308 var slashslash = []byte("//") | 334 var slashslash = []byte("//") |
309 var plusBuild = []byte("+build") | |
310 | 335 |
311 // shouldBuild reports whether it is okay to use this file, | 336 // shouldBuild reports whether it is okay to use this file, |
312 // The rule is that in the file's leading run of // comments | 337 // The rule is that in the file's leading run of // comments |
313 // and blank lines, which must be followed by a blank line | 338 // and blank lines, which must be followed by a blank line |
314 // (to avoid including a Go package clause doc comment), | 339 // (to avoid including a Go package clause doc comment), |
315 // lines beginning with '// +build' are taken as build directives. | 340 // lines beginning with '// +build' are taken as build directives. |
316 // | 341 // |
317 // The file is accepted only if each such line lists something | 342 // The file is accepted only if each such line lists something |
318 // matching the file. For example: | 343 // matching the file. For example: |
319 // | 344 // |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 } else if escaped { | 545 } else if escaped { |
521 err = errors.New("unfinished escaping") | 546 err = errors.New("unfinished escaping") |
522 } | 547 } |
523 return args, err | 548 return args, err |
524 } | 549 } |
525 | 550 |
526 // matchOSArch returns true if the name is one of: | 551 // matchOSArch returns true if the name is one of: |
527 // | 552 // |
528 // $GOOS | 553 // $GOOS |
529 // $GOARCH | 554 // $GOARCH |
530 //» $GOOS/$GOARCH | 555 //» cgo (if cgo is enabled) |
| 556 //» nocgo (if cgo is disabled) |
| 557 //» a slash-separated list of any of these |
531 // | 558 // |
532 func (ctxt *Context) matchOSArch(name string) bool { | 559 func (ctxt *Context) matchOSArch(name string) bool { |
| 560 if ctxt.CgoEnabled && name == "cgo" { |
| 561 return true |
| 562 } |
| 563 if !ctxt.CgoEnabled && name == "nocgo" { |
| 564 return true |
| 565 } |
533 if name == ctxt.GOOS || name == ctxt.GOARCH { | 566 if name == ctxt.GOOS || name == ctxt.GOARCH { |
534 return true | 567 return true |
535 } | 568 } |
536 i := strings.Index(name, "/") | 569 i := strings.Index(name, "/") |
537 » return i >= 0 && name[:i] == ctxt.GOOS && name[i+1:] == ctxt.GOARCH | 570 » return i >= 0 && ctxt.matchOSArch(name[:i]) && ctxt.matchOSArch(name[i+1
:]) |
538 } | 571 } |
539 | 572 |
540 // goodOSArchFile returns false if the name contains a $GOOS or $GOARCH | 573 // goodOSArchFile returns false if the name contains a $GOOS or $GOARCH |
541 // suffix which does not match the current system. | 574 // suffix which does not match the current system. |
542 // The recognized name formats are: | 575 // The recognized name formats are: |
543 // | 576 // |
544 // name_$(GOOS).* | 577 // name_$(GOOS).* |
545 // name_$(GOARCH).* | 578 // name_$(GOARCH).* |
546 // name_$(GOOS)_$(GOARCH).* | 579 // name_$(GOOS)_$(GOARCH).* |
547 // name_$(GOOS)_test.* | 580 // name_$(GOOS)_test.* |
(...skipping 25 matching lines...) Expand all Loading... |
573 var knownArch = make(map[string]bool) | 606 var knownArch = make(map[string]bool) |
574 | 607 |
575 func init() { | 608 func init() { |
576 for _, v := range strings.Fields(goosList) { | 609 for _, v := range strings.Fields(goosList) { |
577 knownOS[v] = true | 610 knownOS[v] = true |
578 } | 611 } |
579 for _, v := range strings.Fields(goarchList) { | 612 for _, v := range strings.Fields(goarchList) { |
580 knownArch[v] = true | 613 knownArch[v] = true |
581 } | 614 } |
582 } | 615 } |
OLD | NEW |