Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: go clean does not remove .exe file for main built by "go build sub/pkg" #52979

Open
plastikfan opened this issue May 18, 2022 · 12 comments
Labels
Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@plastikfan
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.18.2 windows/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
λ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Plastikfan\AppData\Local\go-build
set GOENV=C:\Users\Plastikfan\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\Plastikfan\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\Plastikfan\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.18.2
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Users\Plastikfan\dev\github\go\snivilised\squif\go.mod
set GOWORK=
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\PLASTI~1\AppData\Local\Temp\go-build1040139346=/tmp/go-build -gno-record-gcc-switches

What did you do?

A module with a main package in a sub package at ./src/app.

foo module structure

/foo
│   go.mod
│
└───src
    └───app
            main.go

go.mod:

module github.com/plastikfan/bar

go 1.18

main.go:

package main

import "fmt"

func main() {
	fmt.Printf("hello")
}

go build ./src/app

This should create app.exe at the root:

/foo
│   app.exe
│   go.mod
│
└───src
    └───app
            main.go

Then run

go clean

Nothing happens

Use the -n option:

go clean -n

go clean -n
cd C:\Users\Plastikfan\dev\go\foo
rm -f foo.test foo.test.exe ..test ..test.exe

So where is app.exe in this list? Why does this not work for a sub-package?

If this is by design, then what is the correct way of doing the clean for sub-packages.

Referring to the go docs at go clean, does not shed any light on this issue.

The following additional options have been tried:

  • -i: "The -i flag causes clean to remove the corresponding installed archive or binary (what 'go install' would create)."
  • -r: "The -r flag causes clean to be applied recursively to all the dependencies of the packages named by the import paths."

... has no effect

The other options modcache, cache and testcache all seem like nuclear options

Googling around for this has served up no effective solution, so raising this issue is my last resort.

What did you expect to see?

Built exe file to be deleted

What did you see instead?

already explained above

@seankhliao
Copy link
Member

I don't think this is expected to work, go clean is limited to cleaning output that is located in the same source directory.
Matching any package name seems too inaccurate to be safe for general use.
From go help clean:

	DIR(.exe)        from go build

DIR represents the final path element of the directory

@plastikfan
Copy link
Author

This is a somewhat terse reply. What is the user expected to do with this? DIR? So how is that supposed to be used? PLease be a little more helpful

@ianlancetaylor
Copy link
Contributor

ianlancetaylor commented May 18, 2022

It sounds like you want go clean ./...

@plastikfan
Copy link
Author

Thanks @ianlancetaylor, tried that, didn't work for me unfortunately

@plastikfan
Copy link
Author

If this doesnt work, I don't see why this issue was closed so swiftly without proper investigation and explanation, especially when information is lacking in the docs. How does one remove an exe built from a target not in the root dir of a module?

@ianlancetaylor
Copy link
Contributor

The tool is behaving as documented.

But I see what you mean. go build sub/pkg puts the executable in the current directory, and go clean sub/pkg does not remove that executable.

Reopening.

CC @bcmills @matloob

@ianlancetaylor ianlancetaylor changed the title affected/package: go clean does not remove .exe file for main built from sub-package cmd/go: go clean does not remove .exe file for main built by "go build sub/pkg" May 18, 2022
@plastikfan
Copy link
Author

Thanks @ianlancetaylor.

@plastikfan
Copy link
Author

I've tried using trying other build tools (like make or go-task) to do this, but they all depend on go clean working.

@bcmills bcmills added this to the Backlog milestone May 18, 2022
@bcmills bcmills added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Documentation labels May 18, 2022
@bcmills
Copy link
Contributor

bcmills commented May 18, 2022

This is definitely in line with the documentation (https://cs.opensource.google/go/go/+/master:src/cmd/go/internal/clean/clean.go;l=37-39;drc=d60ad1e068263832c711aaf17b6ccb1b7f71b000).

Emphasis mine:

If a package argument is given or the -i or -r flag is set,
clean removes the following files from each of the
source directories corresponding to the import paths
:

None of the entries in the list includes subpackages.

It would be possible to expand that list, of course, but I think it's already too aggressive (and the go clean command is somewhat awkwardly overloaded).

Other options you might consider are:

  • Using the go build -o to choose a different output directory, and then using rm -r or similar on that directory.
  • Using go list -f to output a list of main packages and then invoking basename on each entry in that list.

For example:

~/src/golang.org/x/build$ for target in $(go list -f '{{if eq .Name "main"}}{{.Target}}{{end}}' ./...); do basename $target; done
buildlet
stage0
testssh
buildstats
cl
coordinator
debugnewvm
docker2boot
fetchlogs
genbootstrap
genbuilderkey
gerritbot
gitmirror
gomote
gopherbot
gopherstats
makemac
perfrun
pubsubhelper
racebuild
release
releaselet
releasebot
relnote
relui
retrybuilds
rmplaysnippet
rundockerbuildlet
runqemubuildlet
updatecontrib
updatedisks
updatestd
upload
xb
devapp
files
influx
gostats
maintnerd
maintq
maintwatch
perf
appengine
localperfdata
vcweb

@plastikfan
Copy link
Author

Thanks @bcmills. I will take a look at your directory solution (I'm giving up on trying building on windows, windows support just seem to be lacking in so many areas, and is a second class citizen, so I'll have to use WSL instead). That link you posted does not appear to be open source, I just get permission denied when I follow it. Is there another open source link which porvides access to this documentation that I should probably read?

@ZekeLu
Copy link
Contributor

ZekeLu commented May 19, 2022

The corresponding link on github:

If a package argument is given or the -i or -r flag is set,
clean removes the following files from each of the
source directories corresponding to the import paths:

@seankhliao
Copy link
Member

A potentially expensive way of doing this: read the buildinfo out of any file that we might want to remove, and verify it matches a (main) package in the current module

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants