diff --git a/cmd/internal/clean/clean.go b/cmd/internal/clean/clean.go new file mode 100644 index 00000000..f0b12fe2 --- /dev/null +++ b/cmd/internal/clean/clean.go @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Package clean implements the "llgo clean" command. +package clean + +import ( + "github.com/goplus/llgo/cmd/internal/base" + "github.com/goplus/llgo/internal/build" +) + +// llgo build +var Cmd = &base.Command{ + UsageLine: "llgo clean [clean flags] [build flags] [packages]", + Short: "Remove object files and cached files", +} + +func init() { + Cmd.Run = runCmd +} + +func runCmd(cmd *base.Command, args []string) { + conf := build.NewDefaultConf(0) + build.Clean(args, conf) +} diff --git a/cmd/llgo/llgo.go b/cmd/llgo/llgo.go index 24e4b67e..85304dd1 100644 --- a/cmd/llgo/llgo.go +++ b/cmd/llgo/llgo.go @@ -26,6 +26,7 @@ import ( "github.com/goplus/llgo/cmd/internal/base" "github.com/goplus/llgo/cmd/internal/build" + "github.com/goplus/llgo/cmd/internal/clean" "github.com/goplus/llgo/cmd/internal/help" "github.com/goplus/llgo/cmd/internal/install" "github.com/goplus/llgo/cmd/internal/run" @@ -42,6 +43,7 @@ func init() { build.Cmd, install.Cmd, run.Cmd, + clean.Cmd, } } diff --git a/internal/build/clean.go b/internal/build/clean.go new file mode 100644 index 00000000..225d3b0d --- /dev/null +++ b/internal/build/clean.go @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package build + +import ( + "fmt" + "os" + "path" + "path/filepath" + + "golang.org/x/tools/go/packages" +) + +func Clean(args []string, conf *Config) { + flags, patterns, verbose := parseArgs(args) + cfg := &packages.Config{ + Mode: loadSyntax | packages.NeedExportFile, + BuildFlags: flags, + } + + if patterns == nil { + patterns = []string{"."} + } + initial, err := packages.Load(cfg, patterns...) + check(err) + + cleanPkgs(initial, verbose) + + for _, pkg := range initial { + if pkg.Name == "main" { + cleanMainPkg(pkg, conf, verbose) + } + } +} + +func cleanMainPkg(pkg *packages.Package, conf *Config, verbose bool) { + pkgPath := pkg.PkgPath + name := path.Base(pkgPath) + fname := name + conf.AppExt + app := filepath.Join(conf.BinPath, fname) + removeFile(app, verbose) + if len(pkg.CompiledGoFiles) > 0 { + dir := filepath.Dir(pkg.CompiledGoFiles[0]) + buildApp := filepath.Join(dir, fname) + removeFile(buildApp, verbose) + } +} + +func cleanPkgs(initial []*packages.Package, verbose bool) { + packages.Visit(initial, nil, func(p *packages.Package) { + file := p.ExportFile + ".ll" + removeFile(file, verbose) + }) +} + +func removeFile(file string, verbose bool) { + if _, err := os.Stat(file); os.IsNotExist(err) { + return + } + if verbose { + fmt.Fprintln(os.Stderr, "Remove", file) + } + os.Remove(file) +}