build: PkgLinkExtern
This commit is contained in:
@@ -140,16 +140,19 @@ func TestPkgNoInit(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPkgKind(t *testing.T) {
|
||||
if v := pkgKind("noinit"); v != PkgNoInit {
|
||||
if v, _ := pkgKind("link: hello.a"); v != PkgLinkExtern {
|
||||
t.Fatal("pkgKind:", v)
|
||||
}
|
||||
if v := pkgKind(""); v != PkgLLGo {
|
||||
if v, _ := pkgKind("noinit"); v != PkgNoInit {
|
||||
t.Fatal("pkgKind:", v)
|
||||
}
|
||||
if v, _ := pkgKind(""); v != PkgLLGo {
|
||||
t.Fatal("pkgKind:", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPkgKindOf(t *testing.T) {
|
||||
if v := PkgKindOf(types.Unsafe); v != PkgDeclOnly {
|
||||
if v, _ := PkgKindOf(types.Unsafe); v != PkgDeclOnly {
|
||||
t.Fatal("PkgKindOf unsafe:", v)
|
||||
}
|
||||
pkg := types.NewPackage("foo", "foo")
|
||||
@@ -158,7 +161,7 @@ func TestPkgKindOf(t *testing.T) {
|
||||
0, pkg, "LLGoPackage", types.Typ[types.String],
|
||||
constant.MakeString("noinit")),
|
||||
)
|
||||
if v := PkgKindOf(pkg); v != PkgNoInit {
|
||||
if v, _ := PkgKindOf(pkg); v != PkgNoInit {
|
||||
t.Fatal("PkgKindOf foo:", v)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@ const (
|
||||
PkgNoInit // noinit: a package that don't need to be initialized
|
||||
PkgDeclOnly // decl: a package that only have declarations
|
||||
PkgLinkIR // link llvm ir (.ll)
|
||||
PkgLinkExtern // link external object (.a/.so/.dll/.dylib/etc.)
|
||||
// PkgLinkBitCode // link bitcode (.bc)
|
||||
)
|
||||
|
||||
|
||||
32
cl/import.go
32
cl/import.go
@@ -77,44 +77,48 @@ func (p *pkgSymInfo) initLinknames(ctx *context) {
|
||||
}
|
||||
|
||||
// PkgKindOf returns the kind of a package.
|
||||
func PkgKindOf(pkg *types.Package) int {
|
||||
func PkgKindOf(pkg *types.Package) (int, string) {
|
||||
scope := pkg.Scope()
|
||||
kind := pkgKindByScope(scope)
|
||||
kind, param := pkgKindByScope(scope)
|
||||
if kind == PkgNormal {
|
||||
kind = pkgKindByPath(pkg.Path())
|
||||
}
|
||||
return kind
|
||||
return kind, param
|
||||
}
|
||||
|
||||
// decl: a package that only contains declarations
|
||||
// noinit: a package that does not need to be initialized
|
||||
func pkgKind(v string) int {
|
||||
func pkgKind(v string) (int, string) {
|
||||
switch v {
|
||||
case "link":
|
||||
return PkgLinkIR
|
||||
return PkgLinkIR, ""
|
||||
case "decl":
|
||||
return PkgDeclOnly, ""
|
||||
case "noinit":
|
||||
return PkgNoInit, ""
|
||||
default:
|
||||
// case "link:bc":
|
||||
// return PkgLinkBitCode
|
||||
case "decl":
|
||||
return PkgDeclOnly
|
||||
case "noinit":
|
||||
return PkgNoInit
|
||||
if strings.HasPrefix(v, "link:") { // "link: <libpath>"
|
||||
return PkgLinkExtern, v[5:]
|
||||
}
|
||||
return PkgLLGo
|
||||
}
|
||||
return PkgLLGo, ""
|
||||
}
|
||||
|
||||
func pkgKindByScope(scope *types.Scope) int {
|
||||
func pkgKindByScope(scope *types.Scope) (int, string) {
|
||||
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 PkgLLGo, ""
|
||||
}
|
||||
return PkgNormal
|
||||
return PkgNormal, ""
|
||||
}
|
||||
|
||||
func (p *context) importPkg(pkg *types.Package, i *pkgInfo) {
|
||||
scope := pkg.Scope()
|
||||
kind := pkgKindByScope(scope)
|
||||
kind, _ := pkgKindByScope(scope)
|
||||
if kind == PkgNormal {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -167,12 +167,12 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve
|
||||
}
|
||||
for _, aPkg := range pkgs {
|
||||
pkg := aPkg.Package
|
||||
switch kind := cl.PkgKindOf(pkg.Types); kind {
|
||||
switch kind, param := cl.PkgKindOf(pkg.Types); kind {
|
||||
case cl.PkgDeclOnly:
|
||||
// skip packages that only contain declarations
|
||||
// and set no export file
|
||||
pkg.ExportFile = ""
|
||||
case cl.PkgLinkIR: // cl.PkgLinkBitCode:
|
||||
case cl.PkgLinkIR:
|
||||
// skip packages that don't need to be compiled but need to be linked
|
||||
pkgPath := pkg.PkgPath
|
||||
if isPkgInLLGo(pkgPath) {
|
||||
@@ -180,6 +180,15 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve
|
||||
} else {
|
||||
panic("todo")
|
||||
}
|
||||
case cl.PkgLinkExtern:
|
||||
// skip packages that don't need to be compiled but need to be linked with external library
|
||||
linkFile := os.ExpandEnv(strings.TrimSpace(param))
|
||||
dir, lib := filepath.Split(linkFile)
|
||||
command := " -l " + lib
|
||||
if dir != "" {
|
||||
command += " -L " + dir
|
||||
}
|
||||
pkg.ExportFile = command
|
||||
default:
|
||||
buildPkg(prog, aPkg, mode, verbose)
|
||||
if prog.NeedRuntime() {
|
||||
|
||||
Reference in New Issue
Block a user