build: skip PkgDeclOnly
This commit is contained in:
@@ -36,10 +36,10 @@ func TestPkgNoInit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPkgKind(t *testing.T) {
|
func TestPkgKind(t *testing.T) {
|
||||||
if v := pkgKind("noinit"); v != pkgNoInit {
|
if v := pkgKind("noinit"); v != PkgNoInit {
|
||||||
t.Fatal("pkgKind:", v)
|
t.Fatal("pkgKind:", v)
|
||||||
}
|
}
|
||||||
if v := pkgKind(""); v != pkgNormal {
|
if v := pkgKind(""); v != PkgLLGo {
|
||||||
t.Fatal("pkgKind:", v)
|
t.Fatal("pkgKind:", v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ func (p *context) funcKind(vfn ssa.Value) int {
|
|||||||
func (p *context) pkgNoInit(pkg *types.Package) bool {
|
func (p *context) pkgNoInit(pkg *types.Package) bool {
|
||||||
p.ensureLoaded(pkg)
|
p.ensureLoaded(pkg)
|
||||||
if i, ok := p.loaded[pkg]; ok {
|
if i, ok := p.loaded[pkg]; ok {
|
||||||
return i.kind != pkgNormal
|
return i.kind >= PkgNoInit
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -119,9 +119,10 @@ type instrOrValue interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
pkgNormal = iota
|
PkgNormal = iota
|
||||||
pkgNoInit // noinit: a package that don't need to be initialized
|
PkgLLGo
|
||||||
pkgDeclOnly // decl: a package that only have declarations
|
PkgNoInit // noinit: a package that don't need to be initialized
|
||||||
|
PkgDeclOnly // decl: a package that only have declarations
|
||||||
)
|
)
|
||||||
|
|
||||||
type pkgInfo struct {
|
type pkgInfo struct {
|
||||||
@@ -494,7 +495,7 @@ func NewPackage(prog llssa.Program, pkg *ssa.Package, files []*ast.File) (ret ll
|
|||||||
link: make(map[string]string),
|
link: make(map[string]string),
|
||||||
vargs: make(map[*ssa.Alloc][]llssa.Expr),
|
vargs: make(map[*ssa.Alloc][]llssa.Expr),
|
||||||
loaded: map[*types.Package]*pkgInfo{
|
loaded: map[*types.Package]*pkgInfo{
|
||||||
types.Unsafe: {kind: pkgNoInit}, // TODO(xsw): pkgNoInit or pkgDeclOnly?
|
types.Unsafe: {kind: PkgDeclOnly}, // TODO(xsw): PkgNoInit or PkgDeclOnly?
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ctx.initFiles(pkgPath, files)
|
ctx.initFiles(pkgPath, files)
|
||||||
|
|||||||
40
cl/import.go
40
cl/import.go
@@ -44,27 +44,45 @@ func contentOf(m contentMap, file string) (lines contentLines, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PkgKindOf returns the kind of a package.
|
||||||
|
func PkgKindOf(pkg *types.Package) int {
|
||||||
|
scope := pkg.Scope()
|
||||||
|
kind := pkgKindByScope(scope)
|
||||||
|
if kind == PkgNormal {
|
||||||
|
kind = pkgKindByPath(pkg.Path())
|
||||||
|
}
|
||||||
|
return kind
|
||||||
|
}
|
||||||
|
|
||||||
// decl: a package that only contains declarations
|
// decl: a package that only contains declarations
|
||||||
// noinit: a package that does not need to be initialized
|
// noinit: a package that does not need to be initialized
|
||||||
func pkgKind(v string) int {
|
func pkgKind(v string) int {
|
||||||
switch v {
|
switch v {
|
||||||
case "decl":
|
case "decl":
|
||||||
return pkgDeclOnly
|
return PkgDeclOnly
|
||||||
case "noinit":
|
case "noinit":
|
||||||
return pkgNoInit
|
return PkgNoInit
|
||||||
}
|
}
|
||||||
return pkgNormal
|
return PkgLLGo
|
||||||
|
}
|
||||||
|
|
||||||
|
func pkgKindByScope(scope *types.Scope) int {
|
||||||
|
if v, ok := scope.Lookup("LLGoPackage").(*types.Const); ok {
|
||||||
|
if v := v.Val(); v.Kind() == constant.String {
|
||||||
|
return pkgKind(constant.StringVal(v))
|
||||||
|
}
|
||||||
|
return PkgLLGo
|
||||||
|
}
|
||||||
|
return PkgNormal
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *context) importPkg(pkg *types.Package, i *pkgInfo) {
|
func (p *context) importPkg(pkg *types.Package, i *pkgInfo) {
|
||||||
scope := pkg.Scope()
|
scope := pkg.Scope()
|
||||||
llpkg, ok := scope.Lookup("LLGoPackage").(*types.Const)
|
kind := pkgKindByScope(scope)
|
||||||
if !ok {
|
if kind == PkgNormal {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if v := llpkg.Val(); v.Kind() == constant.String {
|
i.kind = kind
|
||||||
i.kind = pkgKind(constant.StringVal(v))
|
|
||||||
}
|
|
||||||
fset := p.fset
|
fset := p.fset
|
||||||
names := scope.Names()
|
names := scope.Names()
|
||||||
contents := make(contentMap)
|
contents := make(contentMap)
|
||||||
@@ -199,8 +217,8 @@ func (p *context) ensureLoaded(pkgTypes *types.Package) *types.Package {
|
|||||||
|
|
||||||
func pkgKindByPath(pkgPath string) int {
|
func pkgKindByPath(pkgPath string) int {
|
||||||
switch pkgPath {
|
switch pkgPath {
|
||||||
case "syscall", "runtime/cgo":
|
case "syscall", "runtime/cgo", "unsafe":
|
||||||
return pkgNoInit
|
return PkgDeclOnly
|
||||||
}
|
}
|
||||||
return pkgNormal
|
return PkgNormal
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ func linkMainPkg(pkg *packages.Package, runtimeFiles []string, conf *Config, mod
|
|||||||
args[2] = "-Wno-override-module"
|
args[2] = "-Wno-override-module"
|
||||||
needRuntime := false
|
needRuntime := false
|
||||||
packages.Visit([]*packages.Package{pkg}, nil, func(p *packages.Package) {
|
packages.Visit([]*packages.Package{pkg}, nil, func(p *packages.Package) {
|
||||||
if p.PkgPath != "unsafe" { // TODO(xsw): maybe can remove this special case
|
if p.ExportFile != "" { // skip packages that only contain declarations
|
||||||
args = append(args, p.ExportFile+".ll")
|
args = append(args, p.ExportFile+".ll")
|
||||||
if !needRuntime {
|
if !needRuntime {
|
||||||
needRuntime = isNeedRuntime(p)
|
needRuntime = isNeedRuntime(p)
|
||||||
@@ -220,6 +220,12 @@ func linkMainPkg(pkg *packages.Package, runtimeFiles []string, conf *Config, mod
|
|||||||
|
|
||||||
func buildPkg(prog llssa.Program, aPkg aPackage, mode Mode, verbose bool) {
|
func buildPkg(prog llssa.Program, aPkg aPackage, mode Mode, verbose bool) {
|
||||||
pkg := aPkg.Package
|
pkg := aPkg.Package
|
||||||
|
if cl.PkgKindOf(pkg.Types) == cl.PkgDeclOnly {
|
||||||
|
// skip packages that only contain declarations
|
||||||
|
// and set no export file
|
||||||
|
pkg.ExportFile = ""
|
||||||
|
return
|
||||||
|
}
|
||||||
pkgPath := pkg.PkgPath
|
pkgPath := pkg.PkgPath
|
||||||
if verbose {
|
if verbose {
|
||||||
fmt.Fprintln(os.Stderr, pkgPath)
|
fmt.Fprintln(os.Stderr, pkgPath)
|
||||||
@@ -320,7 +326,7 @@ func allLinkFiles(rt []*packages.Package) (outFiles []string) {
|
|||||||
outFiles = make([]string, 0, len(rt))
|
outFiles = make([]string, 0, len(rt))
|
||||||
root := rootLLGo(rt[0])
|
root := rootLLGo(rt[0])
|
||||||
packages.Visit(rt, nil, func(p *packages.Package) {
|
packages.Visit(rt, nil, func(p *packages.Package) {
|
||||||
if isPkgInLLGo(p.PkgPath) {
|
if hasLinkFile(p) {
|
||||||
outFile := filepath.Join(root+p.PkgPath[len(llgoModPath):], "llgo_autogen.ll")
|
outFile := filepath.Join(root+p.PkgPath[len(llgoModPath):], "llgo_autogen.ll")
|
||||||
outFiles = append(outFiles, outFile)
|
outFiles = append(outFiles, outFile)
|
||||||
}
|
}
|
||||||
@@ -328,6 +334,13 @@ func allLinkFiles(rt []*packages.Package) (outFiles []string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hasLinkFile(pkg *packages.Package) bool {
|
||||||
|
if isPkgInLLGo(pkg.PkgPath) {
|
||||||
|
return cl.PkgKindOf(pkg.Types) != cl.PkgDeclOnly
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(xsw): llgo root dir
|
// TODO(xsw): llgo root dir
|
||||||
func rootLLGo(runtime *packages.Package) string {
|
func rootLLGo(runtime *packages.Package) string {
|
||||||
return runtime.Module.Dir
|
return runtime.Module.Dir
|
||||||
|
|||||||
Reference in New Issue
Block a user