github.com/aca02djr/gb@v0.4.1/package.go (about) 1 package gb 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strings" 8 9 "github.com/constabulary/gb/importer" 10 ) 11 12 // Package represents a resolved package from the Project with respect to the Context. 13 type Package struct { 14 *Context 15 *importer.Package 16 TestScope bool 17 ExtraIncludes string // hook for test 18 Stale bool // is the package out of date wrt. its cached copy 19 Imports []*Package 20 } 21 22 // newPackage creates a resolved Package without setting pkg.Stale. 23 func newPackage(ctx *Context, p *importer.Package) (*Package, error) { 24 pkg := &Package{ 25 Context: ctx, 26 Package: p, 27 } 28 for _, i := range p.Imports { 29 dep, ok := ctx.pkgs[i] 30 if !ok { 31 return nil, fmt.Errorf("newPackage(%q): could not locate dependant package %q ", p.Name, i) 32 } 33 pkg.Imports = append(pkg.Imports, dep) 34 } 35 return pkg, nil 36 } 37 38 // isMain returns true if this is a command, not being built in test scope, and 39 // not the testmain itself. 40 func (p *Package) isMain() bool { 41 if p.TestScope { 42 return strings.HasSuffix(p.ImportPath, "testmain") 43 } 44 return p.Name == "main" 45 } 46 47 func (p *Package) String() string { 48 return fmt.Sprintf("%v", struct { 49 Name, ImportPath, Dir string 50 }{ 51 p.Name, p.ImportPath, p.Dir, 52 }) 53 } 54 55 // Complete indicates if this is a pure Go package 56 func (p *Package) Complete() bool { 57 // If we're giving the compiler the entire package (no C etc files), tell it that, 58 // so that it can give good error messages about forward declarations. 59 // Exceptions: a few standard packages have forward declarations for 60 // pieces supplied behind-the-scenes by package runtime. 61 extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles) 62 if p.Standard { 63 switch p.ImportPath { 64 case "bytes", "net", "os", "runtime/pprof", "sync", "time": 65 extFiles++ 66 } 67 } 68 return extFiles == 0 69 } 70 71 // Binfile returns the destination of the compiled target of this command. 72 func (pkg *Package) Binfile() string { 73 // TODO(dfc) should have a check for package main, or should be merged in to objfile. 74 target := filepath.Join(pkg.Bindir(), binname(pkg)) 75 if pkg.TestScope { 76 target = filepath.Join(pkg.Workdir(), filepath.FromSlash(pkg.ImportPath), "_test", binname(pkg)) 77 } 78 79 // if this is a cross compile or GOOS/GOARCH are both defined or there are build tags, add ctxString. 80 if pkg.isCrossCompile() || (os.Getenv("GOOS") != "" && os.Getenv("GOARCH") != "") { 81 target += "-" + pkg.ctxString() 82 } else if len(pkg.buildtags) > 0 { 83 target += "-" + strings.Join(pkg.buildtags, "-") 84 } 85 86 if pkg.gotargetos == "windows" { 87 target += ".exe" 88 } 89 return target 90 }