Skip to content
This repository has been archived by the owner on May 18, 2024. It is now read-only.

Commit

Permalink
Config.Deps: use []*cmod.Package instead of []string
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Jul 25, 2022
1 parent f3889a8 commit 7019fa2
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 55 deletions.
9 changes: 7 additions & 2 deletions cl/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
goast "go/ast"

"github.com/goplus/c2go/clang/ast"
"github.com/goplus/c2go/clang/cmod"
"github.com/goplus/c2go/clang/types/parser"
"github.com/goplus/gox"
"github.com/goplus/gox/cpackages"
Expand Down Expand Up @@ -164,10 +165,11 @@ type Config struct {

// ProcDepPkg specifies how to process a dependent package.
// If ProcDepPkg is nil, it means nothing to do.
// It's for compiling depended pkgs (to gen c2go.a.pub file) if needed.
ProcDepPkg func(depPkgDir string)

// Deps specifies all dependent packages for the target Go package.
Deps []string
// Deps specifies all dependent packages.
Deps []*cmod.Package

// Include specifies include searching directories.
Include []string
Expand All @@ -181,6 +183,9 @@ type Config struct {
// BuiltinFuncMode sets compiling mode of builtin functions.
BuiltinFuncMode BFMode

// SkipLibcHeader specifies to ignore standard library headers.
SkipLibcHeader bool

// NeedPkgInfo allows to check dependencies and write them to c2go_autogen.go file.
NeedPkgInfo bool

Expand Down
56 changes: 6 additions & 50 deletions cl/multifiles.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package cl

import (
"encoding/json"
"go/token"
"go/types"
"log"
"os"
"path/filepath"
"strconv"
"strings"
Expand All @@ -15,7 +13,6 @@ import (

"github.com/goplus/c2go/clang/ast"
"github.com/goplus/gox"
"github.com/goplus/mod/gopmod"
)

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -209,32 +206,22 @@ func (p *depPkgs) init(baseDir string, conf *Config) {
if len(deps) == 0 {
return
}
p.skipLibcH = conf.SkipLibcHeader
p.incs = make(map[string]int)
for _, dir := range conf.Include {
dir = pathutil.Canonical(baseDir, dir)
p.incs[dir] = incInSelf
}
procDepPkg := conf.ProcDepPkg
gomod, _ := gopmod.Load(baseDir, 0)
for _, dep := range deps {
if dep == "C" {
p.skipLibcH = true
continue
for _, dir := range dep.Include {
p.incs[dir] = incInDeps
}
depPkgDir := findPkgDir(gomod, dep)
if procDepPkg != nil {
procDepPkg(depPkgDir)
}
depPkgIncs, err := findIncludeDirs(depPkgDir)
if err != nil {
log.Panicln("findIncludeDirs:", err)
procDepPkg(dep.Dir)
}
for _, dir := range depPkgIncs {
dir = pathutil.Canonical(depPkgDir, dir)
p.incs[dir] = incInDeps
}
pubfile := filepath.Join(depPkgDir, "c2go.a.pub")
p.loadPubFile(dep, pubfile)
pubfile := filepath.Join(dep.Dir, "c2go.a.pub")
p.loadPubFile(dep.Path, pubfile)
}
}

Expand All @@ -246,35 +233,4 @@ func (p *depPkgs) loadPubFile(path string, pubfile string) {
p.pkgs = append(p.pkgs, depPkg{path: path, pubs: pubs})
}

func findPkgDir(gomod *gopmod.Module, pkgPath string) (pkgDir string) {
if gomod == nil {
log.Panicln("findPkgDir TODO: no go.mod found")
}
pkg, err := gomod.Lookup(pkgPath)
if err != nil {
log.Panicln("gomod.Lookup:", err)
}
pkgDir, err = filepath.Abs(pkg.Dir)
if err != nil {
log.Panicln("filepath.Abs:", err)
}
return
}

func findIncludeDirs(pkgDir string) (incs []string, err error) {
var conf struct {
Include []string `json:"include"`
}
file := filepath.Join(pkgDir, "c2go.cfg")
b, err := os.ReadFile(file)
if err != nil {
return
}
err = json.Unmarshal(b, &conf)
if err != nil {
return
}
return conf.Include, nil
}

// -----------------------------------------------------------------------------
88 changes: 88 additions & 0 deletions clang/cmod/imp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package cmod

import (
"encoding/json"
"os"
"path/filepath"

"github.com/goplus/c2go/clang/pathutil"
"github.com/goplus/mod/gopmod"
"github.com/qiniu/x/errors"
)

var (
ErrGoModNotFound = errors.New("go.mod not found")
)

func LoadDeps(dir string, deps []string) (pkgs []*Package, err error) {
mod, err := gopmod.Load(dir, 0)
if err != nil {
err = errors.NewWith(err, `gopmod.Load(dir, 0)`, -2, "gopmod.Load", dir, 0)
return
}
return Imports(mod, deps)
}

type Module = gopmod.Module

func Imports(mod *Module, pkgPaths []string) (pkgs []*Package, err error) {
pkgs = make([]*Package, len(pkgPaths))
for i, pkgPath := range pkgPaths {
pkgs[i], err = Import(mod, pkgPath)
if err != nil {
err = errors.NewWith(err, `Import(mod, pkgPath)`, -2, "cmod.Import", mod, pkgPath)
return
}
}
return
}

type Package struct {
*gopmod.Package
Path string // package path
Dir string // absolue local path of the package
Include []string // absolute include paths
}

func Import(mod *Module, pkgPath string) (p *Package, err error) {
if mod == nil {
return nil, ErrGoModNotFound
}
pkg, err := mod.Lookup(pkgPath)
if err != nil {
err = errors.NewWith(err, `mod.Lookup(pkgPath)`, -2, "(*gopmod.Module).Lookup", pkgPath)
return
}
pkgDir, err := filepath.Abs(pkg.Dir)
if err != nil {
err = errors.NewWith(err, `filepath.Abs(pkg.Dir)`, -2, "filepath.Abs", pkg.Dir)
return
}
pkgIncs, err := findIncludeDirs(pkgDir)
if err != nil {
err = errors.NewWith(err, `findIncludeDirs(pkgDir)`, -2, "cmod.findIncludeDirs", pkgDir)
return
}
for i, dir := range pkgIncs {
pkgIncs[i] = pathutil.Canonical(pkgDir, dir)
}
return &Package{Package: pkg, Path: pkgPath, Dir: pkgDir, Include: pkgIncs}, nil
}

func findIncludeDirs(pkgDir string) (incs []string, err error) {
var conf struct {
Include []string `json:"include"`
}
file := filepath.Join(pkgDir, "c2go.cfg")
b, err := os.ReadFile(file)
if err != nil {
err = errors.NewWith(err, `os.ReadFile(file)`, -2, "os.ReadFile", file)
return
}
err = json.Unmarshal(b, &conf)
if err != nil {
err = errors.NewWith(err, `json.Unmarshal(b, &conf)`, -2, "json.Unmarshal", b, &conf)
return
}
return conf.Include, nil
}
37 changes: 34 additions & 3 deletions proj.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"strings"

"github.com/goplus/c2go/cl"
"github.com/goplus/c2go/clang/cmod"
"github.com/goplus/c2go/clang/parser"
"github.com/goplus/c2go/clang/pathutil"
"github.com/goplus/c2go/clang/preprocessor"
Expand Down Expand Up @@ -75,8 +76,12 @@ type c2goConf struct {

cl.Reused `json:"-"`

depPkgs []*cmod.Package `json:"-"`
allIncDirs []string `json:"-"`

dir string `json:"-"` // should be absolute path
public map[string]string `json:"-"`
skipLibcH bool `json:"-"`
needPkgInfo bool `json:"-"`

InLibC bool `json:"libc"` // bfm = BFM_InLibC
Expand All @@ -96,7 +101,9 @@ func execProj(projfile string, flags int, in *Config) {

base, _ := filepath.Split(projfile)
conf.needPkgInfo = (flags & FlagDepsAutoGen) != 0
conf.dir, _ = filepath.Abs(base)
conf.dir, err = filepath.Abs(base)
check(err)

noSource := len(conf.Source.Dirs) == 0 && len(conf.Source.Files) == 0
if noSource {
if len(conf.Target.Cmds) == 0 {
Expand Down Expand Up @@ -323,11 +330,34 @@ func ignoreFile(infile string, conf *c2goConf) bool {
func execProjFile(infile string, conf *c2goConf, flags int) {
fmt.Printf("==> Compiling %s ...\n", infile)

if len(conf.depPkgs) == 0 && len(conf.Deps) > 0 {
deps := conf.Deps
if len(deps) > 0 && deps[0] == "C" {
conf.skipLibcH = true
deps = deps[1:]
}
depPkgs, err := cmod.LoadDeps(conf.dir, deps)
check(err)

n := len(conf.Include)
for _, dep := range depPkgs {
n += len(dep.Include)
}
allIncDirs := make([]string, 0, n)
allIncDirs = append(allIncDirs, conf.Include...)
for _, dep := range depPkgs {
allIncDirs = append(allIncDirs, dep.Include...)
}

conf.depPkgs = depPkgs
conf.allIncDirs = allIncDirs
}

outfile := infile + ".i"
if (flags&FlagForcePreprocess) != 0 || !isFile(outfile) {
err := preprocessor.Do(infile, outfile, &preprocessor.Config{
BaseDir: conf.dir,
IncludeDirs: conf.Include,
IncludeDirs: conf.allIncDirs,
Defines: conf.Define,
Flags: conf.Flags,
PPFlag: conf.PPFlag,
Expand Down Expand Up @@ -367,13 +397,14 @@ func execProjFile(infile string, conf *c2goConf, flags int) {
PublicFrom: conf.Public.From,
NeedPkgInfo: conf.needPkgInfo,
Dir: conf.dir,
Deps: conf.Deps,
Deps: conf.depPkgs,
Include: conf.Include,
Ignored: conf.Source.Ignore.Names,
Reused: &conf.Reused,
TestMain: (flags & FlagTestMain) != 0,
// BuiltinFuncMode: compiling mode of builtin functions
BuiltinFuncMode: bfm,
SkipLibcHeader: conf.skipLibcH,
})
check(err)
}

0 comments on commit 7019fa2

Please sign in to comment.