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  }