cl.PkgLinkOnly; llgoRoot, llgoPkgLinkFile

This commit is contained in:
xushiwei
2024-05-07 08:05:56 +08:00
parent 0edeb5cfd0
commit 1136526e4c
3 changed files with 41 additions and 17 deletions

View File

@@ -123,6 +123,7 @@ const (
PkgLLGo PkgLLGo
PkgNoInit // noinit: a package that don't need to be initialized PkgNoInit // noinit: a package that don't need to be initialized
PkgDeclOnly // decl: a package that only have declarations PkgDeclOnly // decl: a package that only have declarations
PkgLinkOnly // link: a package that don't need to be compiled but need to be linked
) )
type pkgInfo struct { type pkgInfo struct {

View File

@@ -58,6 +58,8 @@ func PkgKindOf(pkg *types.Package) int {
// 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 "link":
return PkgLinkOnly
case "decl": case "decl":
return PkgDeclOnly return PkgDeclOnly
case "noinit": case "noinit":

View File

@@ -163,10 +163,26 @@ func buildAllPkgs(prog llssa.Program, initial []*packages.Package, mode Mode, ve
} }
fmt.Fprintln(os.Stderr, "cannot build SSA for package", errPkg) fmt.Fprintln(os.Stderr, "cannot build SSA for package", errPkg)
} }
for _, pkg := range pkgs { for _, aPkg := range pkgs {
buildPkg(prog, pkg, mode, verbose) pkg := aPkg.Package
if prog.NeedRuntime() { switch cl.PkgKindOf(pkg.Types) {
setNeedRuntime(pkg.Package) case cl.PkgDeclOnly:
// skip packages that only contain declarations
// and set no export file
pkg.ExportFile = ""
case cl.PkgLinkOnly:
// skip packages that don't need to be compiled but need to be linked
pkgPath := pkg.PkgPath
if isPkgInLLGo(pkgPath) {
pkg.ExportFile = strings.TrimSuffix(llgoPkgLinkFile(pkgPath), ".ll")
} else {
panic("todo")
}
default:
buildPkg(prog, aPkg, mode, verbose)
if prog.NeedRuntime() {
setNeedRuntime(pkg)
}
} }
} }
return return
@@ -236,12 +252,6 @@ func linkMainPkg(pkg *packages.Package, pkgs []*aPackage, runtimeFiles []string,
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)
@@ -342,11 +352,10 @@ func checkFlag(arg string, i *int, verbose *bool, swflags map[string]bool) {
func allLinkFiles(rt []*packages.Package) (outFiles []string) { func allLinkFiles(rt []*packages.Package) (outFiles []string) {
outFiles = make([]string, 0, len(rt)) outFiles = make([]string, 0, len(rt))
root := rootLLGo(rt[0])
packages.Visit(rt, nil, func(p *packages.Package) { packages.Visit(rt, nil, func(p *packages.Package) {
pkgPath := p.PkgPath pkgPath := p.PkgPath
if isRuntimePkg(pkgPath) { if isRuntimePkg(pkgPath) {
outFile := filepath.Join(root+pkgPath[len(llgoModPath):], "llgo_autogen.ll") outFile := llgoPkgLinkFile(pkgPath)
outFiles = append(outFiles, outFile) outFiles = append(outFiles, outFile)
} }
}) })
@@ -366,16 +375,29 @@ func isRuntimePkg(pkgPath string) bool {
return false return false
} }
// TODO(xsw): llgo root dir var (
func rootLLGo(runtime *packages.Package) string { rootDir string
return runtime.Module.Dir )
func llgoRoot() string {
if rootDir == "" {
root := os.Getenv("LLGOROOT")
if root == "" {
panic("todo: LLGOROOT not set")
}
rootDir, _ = filepath.Abs(root)
}
return rootDir
}
func llgoPkgLinkFile(pkgPath string) string {
return filepath.Join(llgoRoot()+pkgPath[len(llgoModPath):], "llgo_autogen.ll")
} }
const ( const (
llgoModPath = "github.com/goplus/llgo" llgoModPath = "github.com/goplus/llgo"
) )
/*
func isPkgInLLGo(pkgPath string) bool { func isPkgInLLGo(pkgPath string) bool {
return isPkgInMod(pkgPath, llgoModPath) return isPkgInMod(pkgPath, llgoModPath)
} }
@@ -387,7 +409,6 @@ func isPkgInMod(pkgPath, modPath string) bool {
} }
return false return false
} }
*/
func check(err error) { func check(err error) {
if err != nil { if err != nil {