cmd/go, cmd/link: use Windows response files for gcc/g++ to avoid arg length limits
#28,372 opened on Oct 24, 2018
Repository metrics
- Stars
- (133,883 stars)
- PR merge metrics
- (No merged PRs in 30d)
Description
What version of Go are you using (go version)?
1.11.1
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (go env)?
windows 386/amd64
What did you do?
Tried to compile a cgo program.
package main
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
)
func main() {
testCgo("c")
testCgo("cpp")
}
func testCgo(ending string) {
tmpdir, _ := ioutil.TempDir("", "cgo_resp_issue")
defer os.RemoveAll(tmpdir)
ioutil.WriteFile(filepath.Join(tmpdir, "gofile.go"), []byte(fmt.Sprint("package main\nimport \"C\"\nfunc main(){}")), 0644)
for i := 0; i < 1000; i++ {
ioutil.WriteFile(filepath.Join(tmpdir, fmt.Sprintf("cfile_%v."+ending, i)), []byte(fmt.Sprintf("void func_%v(){}", i)), 0644)
}
cmd := exec.Command("go", "build", "-v", "-x", "-ldflags=all=\"-extldflags=-v\"")
cmd.Dir = tmpdir
if out, err := cmd.CombinedOutput(); err != nil {
println("failed:", ending, err.Error(), string(out))
}
}
What did you expect to see?
a successful compilation
What did you see instead?
gcc: error: CreateProcess: No such file or directory
and/or
g++: error: CreateProcess: No such file or directory
Possible solution?
This patch works for my needs. It's mostly a copy of: https://go-review.googlesource.com/c/go/+/110395 But I also needed to escape the backslashes to make it work.
[patch omitted]
More info
The issue is related to: https://github.com/golang/go/issues/18468 and https://github.com/golang/go/blob/master/src/cmd/go/internal/work/exec.go#L2851
The problem is caused by the 32K character limit on windows https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessasuserw
The maximum length of this string is 32K characters.
Also, once there is support for msvc on windows (https://github.com/golang/go/issues/20982) it might be good idea to whitelist cl as well.