llgo build/install/run: SkipArgs bugfix

This commit is contained in:
xushiwei
2024-04-27 06:39:09 +08:00
parent ea8ddc6451
commit 3cc83b8ec4
4 changed files with 82 additions and 30 deletions

View File

@@ -33,8 +33,13 @@ func init() {
} }
func runCmd(cmd *base.Command, args []string) { func runCmd(cmd *base.Command, args []string) {
build.Do(args, &build.Config{ conf := &build.Config{
Mode: build.ModeBuild, Mode: build.ModeBuild,
AppExt: build.DefaultAppExt(), AppExt: build.DefaultAppExt(),
}) }
if len(args) >= 2 && args[0] == "-o" {
conf.OutFile = args[1]
args = args[2:]
}
build.Do(args, conf)
} }

View File

@@ -20,7 +20,6 @@ package run
import ( import (
"errors" "errors"
"path/filepath" "path/filepath"
"strings"
"github.com/goplus/llgo/cmd/internal/base" "github.com/goplus/llgo/cmd/internal/base"
"github.com/goplus/llgo/internal/build" "github.com/goplus/llgo/internal/build"
@@ -49,7 +48,7 @@ func runCmd(cmd *base.Command, args []string) {
} }
func parseRunArgs(args []string) ([]string, []string, error) { func parseRunArgs(args []string) ([]string, []string, error) {
n := parseArgs(args) n := build.SkipArgs(args)
if n < 0 { if n < 0 {
return nil, nil, errNoProj return nil, nil, errNoProj
} }
@@ -65,15 +64,6 @@ func parseRunArgs(args []string) ([]string, []string, error) {
return args[:n+1], args[n+1:], nil return args[:n+1], args[n+1:], nil
} }
func parseArgs(args []string) int {
for i, arg := range args {
if !strings.HasPrefix(arg, "-") {
return i
}
}
return -1
}
func isGoFile(fname string) bool { func isGoFile(fname string) bool {
return filepath.Ext(fname) == ".go" return filepath.Ext(fname) == ".go"
} }

View File

@@ -50,8 +50,9 @@ func needLLFile(mode Mode) bool {
type Config struct { type Config struct {
BinPath string BinPath string
AppExt string // ".exe" on Windows, empty on Unix AppExt string // ".exe" on Windows, empty on Unix
RunArgs []string OutFile string // only valid for ModeBuild when len(pkgs) == 1
RunArgs []string // only valid for ModeRun
Mode Mode Mode Mode
} }
@@ -85,7 +86,7 @@ const (
) )
func Do(args []string, conf *Config) { func Do(args []string, conf *Config) {
flags, patterns, verbose := parseArgs(args) flags, patterns, verbose := ParseArgs(args, buildFlags)
cfg := &packages.Config{ cfg := &packages.Config{
Mode: loadSyntax | packages.NeedDeps | packages.NeedExportFile, Mode: loadSyntax | packages.NeedDeps | packages.NeedExportFile,
BuildFlags: flags, BuildFlags: flags,
@@ -116,22 +117,25 @@ func Do(args []string, conf *Config) {
mode = ModeInstall mode = ModeInstall
} }
for _, pkg := range pkgs { for _, pkg := range pkgs {
buildPkg(prog, pkg, mode) buildPkg(prog, pkg, mode, verbose)
} }
if mode != ModeBuild { if mode != ModeBuild {
for _, pkg := range initial { for _, pkg := range initial {
if pkg.Name == "main" { if pkg.Name == "main" {
linkMainPkg(pkg, conf, mode) linkMainPkg(pkg, conf, mode, verbose)
} }
} }
} }
} }
func linkMainPkg(pkg *packages.Package, conf *Config, mode Mode) { func linkMainPkg(pkg *packages.Package, conf *Config, mode Mode, verbose bool) {
pkgPath := pkg.PkgPath pkgPath := pkg.PkgPath
name := path.Base(pkgPath) name := path.Base(pkgPath)
app := filepath.Join(conf.BinPath, name+conf.AppExt) app := conf.OutFile
if app == "" {
app = filepath.Join(conf.BinPath, name+conf.AppExt)
}
const N = 3 const N = 3
args := make([]string, N, len(pkg.Imports)+(N+1)) args := make([]string, N, len(pkg.Imports)+(N+1))
args[0] = "-o" args[0] = "-o"
@@ -145,7 +149,9 @@ func linkMainPkg(pkg *packages.Package, conf *Config, mode Mode) {
// TODO(xsw): show work // TODO(xsw): show work
// fmt.Fprintln(os.Stderr, "clang", args) // fmt.Fprintln(os.Stderr, "clang", args)
fmt.Fprintln(os.Stderr, "#", pkgPath) if verbose {
fmt.Fprintln(os.Stderr, "#", pkgPath)
}
err := clang.New("").Exec(args...) err := clang.New("").Exec(args...)
check(err) check(err)
@@ -158,10 +164,10 @@ func linkMainPkg(pkg *packages.Package, conf *Config, mode Mode) {
} }
} }
func buildPkg(prog llssa.Program, aPkg aPackage, mode Mode) { func buildPkg(prog llssa.Program, aPkg aPackage, mode Mode, verbose bool) {
pkg := aPkg.Package pkg := aPkg.Package
pkgPath := pkg.PkgPath pkgPath := pkg.PkgPath
if mode != ModeRun { if verbose {
fmt.Fprintln(os.Stderr, pkgPath) fmt.Fprintln(os.Stderr, pkgPath)
} }
if pkgPath == "unsafe" { // TODO(xsw): maybe can remove this special case if pkgPath == "unsafe" { // TODO(xsw): maybe can remove this special case
@@ -198,20 +204,64 @@ func allPkgs(initial []*packages.Package, mode ssa.BuilderMode) (prog *ssa.Progr
return return
} }
func parseArgs(args []string) (flags, patterns []string, verbose bool) { var (
for i, arg := range args { // TODO(xsw): complete build flags
if !strings.HasPrefix(arg, "-") { buildFlags = map[string]bool{
"-C": true, // -C dir: Change to dir before running the command
"-a": false, // -a: force rebuilding of packages that are already up-to-date
"-n": false, // -n: print the commands but do not run them
"-p": true, // -p n: the number of programs to run in parallel
"-race": false, // -race: enable data race detection
"-cover": false, // -cover: enable coverage analysis
"-covermode": true, // -covermode mode: set the mode for coverage analysis
"-v": false, // -v: print the names of packages as they are compiled
"-work": false, // -work: print the name of the temporary work directory and do not delete it when exiting
"-x": false, // -x: print the commands
"-tags": true, // -tags 'tag,list': a space-separated list of build tags to consider satisfied during the build
"-pkgdir": true, // -pkgdir dir: install and load all packages from dir instead of the usual locations
}
)
func ParseArgs(args []string, swflags map[string]bool) (flags, patterns []string, verbose bool) {
n := len(args)
for i := 0; i < n; i++ {
arg := args[i]
if strings.HasPrefix(arg, "-") {
checkFlag(arg, &i, &verbose, swflags)
} else {
flags, patterns = args[:i], args[i:] flags, patterns = args[:i], args[i:]
return return
} }
if arg == "-v" {
verbose = true
}
} }
flags = args flags = args
return return
} }
func SkipArgs(args []string) int {
n := len(args)
for i := 0; i < n; i++ {
arg := args[i]
if strings.HasPrefix(arg, "-") {
checkFlag(arg, &i, nil, buildFlags)
} else {
return i
}
}
return -1
}
func checkFlag(arg string, i *int, verbose *bool, swflags map[string]bool) {
if hasarg, ok := swflags[arg]; ok {
if hasarg {
*i++
} else if verbose != nil && arg == "-v" {
*verbose = true
}
} else {
panic("unknown flag: " + arg)
}
}
func check(err error) { func check(err error) {
if err != nil { if err != nil {
panic(err) panic(err)

View File

@@ -25,8 +25,15 @@ import (
"golang.org/x/tools/go/packages" "golang.org/x/tools/go/packages"
) )
var (
// TODO(xsw): complete clean flags
cleanFlags = map[string]bool{
"-v": false, // -v: print the paths of packages as they are clean
}
)
func Clean(args []string, conf *Config) { func Clean(args []string, conf *Config) {
flags, patterns, verbose := parseArgs(args) flags, patterns, verbose := ParseArgs(args, cleanFlags)
cfg := &packages.Config{ cfg := &packages.Config{
Mode: loadSyntax | packages.NeedExportFile, Mode: loadSyntax | packages.NeedExportFile,
BuildFlags: flags, BuildFlags: flags,