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

"filename or extension is too long" when building many source files #572

Open
SaigyoujiYuyuko233 opened this issue Aug 26, 2022 · 5 comments

Comments

@SaigyoujiYuyuko233
Copy link

SaigyoujiYuyuko233 commented Aug 26, 2022

What version of Garble and Go are you using?

$ garble version
mvdan.cc/garble v0.7.0

Build settings:
       -compiler gc
     CGO_ENABLED 0
          GOARCH amd64
            GOOS windows
         GOAMD64 v1
$ go version
go version go1.18.2 windows/amd64

What environment are you running Garble on?

go env Output
$ go env
set GO111MODULE=on
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Administrator\AppData\Local\go-build
set GOENV=C:\Users\Administrator\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=D:\Storage\Caches\gopath\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=D:\Storage\Caches\gopath
set GOPRIVATE=
set GOPROXY=https://goproxy.cn,direct
set GOROOT=D:\Storage\Go-1.18.2\go1.18.2
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=D:\Storage\Go-1.18.2\go1.18.2\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=0
set GOMOD=D:\GoProject\Test\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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\ADMINI~1\AppData\Local\Temp\go-build464808010=/tmp/go-build -gno-record-gcc-switches

What did you do?

I tried to complie a project with lib github.com/gotd/td but there is a error occure.

go build github.com/gotd/td/tg: D:\Storage\Caches\gopath\bin\garble.exe: fork/exec D:\Storage\Caches\gopath\bin\garble.exe: The filename or extension is too long.

What did you expect to see?

Compile successfully

What did you see instead?

Error above

I notice that the command works fine in Linux. Then I found out that the error The filename or extension is too long will be throw when a command has more than 32k byte exec in Windows.
This probably is Windows' fault but I still want to post this here and try to find solution together!

Any help would be much appreciated!
English is not my first language, sorry for that.

@mvdan
Copy link
Member

mvdan commented Aug 31, 2022

Thanks for reporting. I think this is because we replace paths to Go source with temporary paths, so the command

/GOROOT/pkg/tool/linux_amd64/compile [flags] /your/pwd/foo.go /your/pwd/bar.go /your/pwd/baz.go

becomes

/GOROOT/pkg/tool/linux_amd64/compile [flags] /tmpdir/garble-shared12345678/package/import/path/foo.go /tmpdir/garble-shared12345678/package/import/path/bar.go /tmpdir/garble-shared12345678/package/import/path/baz.go

You can see how this can balloon the size of each invocation of the compiler, which is likely how you are running into a command size limit of 32KiB.

It seems like some regular Go builds can already run into this, like golang/go#47235.

I'm not sure if we have a good and easy fix for this. We don't want to modify the source files in-place, because that could easily lead to data loss or races with other processes. We likely don't want to os.Chdir into the temporary directory, as that might break the Go toolchain, but perhaps we could try.

@mvdan
Copy link
Member

mvdan commented Aug 31, 2022

Ah, upstream Go does support "response files" as arguments to the toolchain, which are just lists of arguments written to a single file to sidestep the limit. See golang/go#18468.

We're running into the issue because go build will only use these if the argument list reaches ~30KiB. But if go build invokes compile with ~20KiB of arguments it won't choose to use a response file, and our replacing of paths could expand those ~20KiB to be large enough to go over the system's limit.

@mvdan
Copy link
Member

mvdan commented Aug 31, 2022

I think our best bet is to copy upstream's code to replace argument lists with response files. I can look into it when I have the time.

@mvdan
Copy link
Member

mvdan commented Jun 13, 2023

Sorry, what do you mean? This is about go build -toolexec not supporting very long argument lists. This requires a bug fix in upstream Go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants
@mvdan @SaigyoujiYuyuko233 and others