Skip to content

Commit

Permalink
workaround cgo filenames, see #80
Browse files Browse the repository at this point in the history
  • Loading branch information
xhd2015 committed Apr 21, 2024
1 parent 4f58227 commit ca47e34
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 41 deletions.
6 changes: 3 additions & 3 deletions cmd/xgo/runtime_gen/core/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"os"
)

const VERSION = "1.0.26"
const REVISION = "d19c85ac922d26f26038dc99ae3049de0d91d2f6+1"
const NUMBER = 199
const VERSION = "1.0.27"
const REVISION = "4f58227acb703c893cc78dd39c09f0fe5d15565c+1"
const NUMBER = 200

// these fields will be filled by compiler
const XGO_VERSION = ""
Expand Down
103 changes: 73 additions & 30 deletions cmd/xgo/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,11 @@ func addBlankImports(goroot string, goBinary string, projectDir string, pkgArgs
// list files, add init
// NOTE: go build tag applies,
// ignored files will be placed to IgnoredGoFiles

// meanings:
// TestGoFiles []string // _test.go files in package
// XTestGoFiles []string // _test.go files outside package
// XTestGoFiles are files with another package name, such as api_test for api
listArgs := []string{"list", "-json"}
listArgs = append(listArgs, pkgArgs...)
output, err := cmd.Dir(projectDir).Env([]string{
Expand All @@ -384,53 +389,82 @@ func addBlankImports(goroot string, goBinary string, projectDir string, pkgArgs
replace = make(map[string]string)
for _, pkg := range pkgs {
if pkg.Standard {
// skip standarding packages
continue
}
// already has trace?
var hasDep bool
for _, dep := range pkg.Deps {
if dep == RUNTIME_TRACE_PKG {
hasDep = true
break
}
type pkgInfo struct {
imports []string
files []string
addForAllFiles bool
}
if hasDep {
continue
var pkgInfos []pkgInfo

// no matter test or not,adding to the
// original package is always fine.
// it is a catch-all workaround
// when there is no source files, then we add to all tests
// the fact is: go allows duplicate blank imports
if len(pkg.GoFiles) > 0 {
pkgInfos = append(pkgInfos, pkgInfo{pkg.Imports, pkg.GoFiles, false})
} else {
pkgInfos = append(pkgInfos, pkgInfo{nil, pkg.TestGoFiles, true})
pkgInfos = append(pkgInfos, pkgInfo{nil, pkg.XTestGoFiles, true})
}
var file string
if test && len(pkg.TestGoFiles) > 0 {
file = pkg.TestGoFiles[0]
} else if len(pkg.GoFiles) > 0 {
file = pkg.GoFiles[0]
for _, p := range pkgInfos {
mapping, err := addBlankImportForPackage(pkg.Dir, tmpProjectDir, p.imports, p.files, p.addForAllFiles)
if err != nil {
return nil, err
}
for srcFile, dstFile := range mapping {
replace[srcFile] = dstFile
}
}
if file == "" {
// no files
continue
}
return replace, nil
}

func addBlankImportForPackage(srcDir string, dstDir string, imports []string, files []string, allFile bool) (map[string]string, error) {
if len(files) == 0 {
// no files
return nil, nil
}
if !allFile {
// check if already has trace
for _, imp := range imports {
if imp == RUNTIME_TRACE_PKG {
return nil, nil
}
}
srcFile := filepath.Join(pkg.Dir, file)
dstFile := filepath.Join(tmpProjectDir, srcFile)
// take the first one
files = files[0:1]
}

mapping := make(map[string]string, len(files))
for _, file := range files {
srcFile := filepath.Join(srcDir, file)
dstFile := filepath.Join(dstDir, srcFile)
err := filecopy.CopyFileAll(srcFile, dstFile)
if err != nil {
return nil, err
}
// add blank import
// NOTE: go allows duplicate blank imports
content, err := os.ReadFile(dstFile)
if err != nil {
return nil, err
}
newContent, ok := addBlankImport(string(content))
if !ok {
continue
return nil, nil
}
err = os.WriteFile(dstFile, []byte(newContent), 0755)
if err != nil {
return nil, err
}
replace[srcFile] = dstFile
mapping[srcFile] = dstFile
}
return replace, nil
return mapping, nil
}

func exists(path string) bool {
_, err := os.Stat(path)
return err == nil
Expand All @@ -444,14 +478,23 @@ func isDir(path string) bool {
return stat.IsDir()
}

// see go-release/go1.22.2/src/cmd/go/internal/list/list.go
type GoListPkg struct {
Dir string // real dir
ImportPath string
Root string // project root
Standard bool
GoFiles []string
TestGoFiles []string
Deps []string // all dependents
Dir string // real dir
ImportPath string
Root string // project root
Standard bool

GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
TestGoFiles []string
XTestGoFiles []string // _test.go files outside package

// Dependency information
Deps []string // all (recursively) imported dependencies
Imports []string // import paths used by this package
TestImports []string // imports from TestGoFiles
XTestImports []string // imports from XTestGoFiles

}

func addBlankImport(content string) (string, bool) {
Expand Down
6 changes: 3 additions & 3 deletions cmd/xgo/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package main

import "fmt"

const VERSION = "1.0.26"
const REVISION = "d19c85ac922d26f26038dc99ae3049de0d91d2f6+1"
const NUMBER = 199
const VERSION = "1.0.27"
const REVISION = "4f58227acb703c893cc78dd39c09f0fe5d15565c+1"
const NUMBER = 200

func getRevision() string {
revSuffix := ""
Expand Down
21 changes: 19 additions & 2 deletions patch/syntax/syntax.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"strconv"
"strings"

Expand Down Expand Up @@ -284,6 +285,12 @@ func registerFuncs(fileList []*syntax.File, addFile func(name string, r io.Reade
// special when there are multiple files
fileNameBase += fmt.Sprintf("_%d", i)
}
if false {
// debug
dir := filepath.Join("/tmp/xgo_debug_gen", pkgPath)
os.MkdirAll(dir, 0755)
os.WriteFile(filepath.Join(dir, fileNameBase+".go"), []byte(fileCode), 0755)
}
addFile(fileNameBase+".go", strings.NewReader(fileCode))
if false && pkgPath == "main" {
// debug
Expand Down Expand Up @@ -490,17 +497,25 @@ func getFuncDecls(files []*syntax.File, varTrap bool) []*DeclInfo {
var declFuncs []*DeclInfo
for i, f := range files {
var file string
var trimmed bool
if base.Flag.Std && false {
file = f.Pos().RelFilename()
} else if TrimFilename != nil {
// >= go1.18
file = TrimFilename(f.Pos().Base())
trimmed = true
} else if AbsFilename != nil {
file = AbsFilename(f.Pos().Base().Filename())
trimmed = true
} else {
// fallback to default
file = f.Pos().RelFilename()
}

// see https://github.com/xhd2015/xgo/issues/80
if trimmed && strings.HasPrefix(file, "_cgo") {
file = f.Pos().RelFilename()
}
for _, decl := range f.DeclList {
fnDecls := extractFuncDecls(i, f, file, decl, varTrap)
declFuncs = append(declFuncs, fnDecls...)
Expand Down Expand Up @@ -625,7 +640,9 @@ func extractFuncDecls(fileIndex int, f *syntax.File, file string, decl syntax.De

func getFuncDeclInfo(fileIndex int, f *syntax.File, file string, fn *syntax.FuncDecl) *DeclInfo {
line := fn.Pos().Line()
if fn.Name.Value == "init" {
fnName := fn.Name.Value
if fnName == "init" || strings.HasPrefix(fnName, "_cgo") || strings.HasPrefix(fnName, "_Cgo") {
// skip cgo also,see https://github.com/xhd2015/xgo/issues/80#issuecomment-2067976575
return nil
}
var genericFunc bool
Expand Down Expand Up @@ -676,7 +693,7 @@ func getFuncDeclInfo(fileIndex int, f *syntax.File, file string, fn *syntax.Func

return &DeclInfo{
FuncDecl: fn,
Name: fn.Name.Value,
Name: fnName,
RecvTypeName: recvTypeName,
RecvPtr: recvPtr,
Generic: genericFunc || genericRecv,
Expand Down
6 changes: 3 additions & 3 deletions runtime/core/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"os"
)

const VERSION = "1.0.26"
const REVISION = "d19c85ac922d26f26038dc99ae3049de0d91d2f6+1"
const NUMBER = 199
const VERSION = "1.0.27"
const REVISION = "4f58227acb703c893cc78dd39c09f0fe5d15565c+1"
const NUMBER = 200

// these fields will be filled by compiler
const XGO_VERSION = ""
Expand Down

0 comments on commit ca47e34

Please sign in to comment.