You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
make.bash: clarify that CGO_ENABLED=0 sets default into resulting compiler #51305
Does this issue reproduce with the latest release?
Yes.
What did you do?
Ran CGO_ENABLED=0 ./make.bash.
What did you expect to see?
I expected it to produce a compiler (without using cgo) that abides by the documented behavior for cgo. Namely, host builds have cgo enabled by default.
What did you see instead?
The resulting compiler defaults to cgo disabled even for the host, as confirmed by go env.
@seankhliao This behavior is not at all implied by the current documentation for make.bash.
# CGO_ENABLED: Controls cgo usage during the build. Set it to 1
# to include all cgo related files, .c and .go file with "cgo"
# build directive, in the build. Set it to 0 to ignore them.
That does not make it clear that it is actually going to burn a default into the resulting compiler. Probably there need to be two different flags:
Should cgo be enabled while compiling?
What default value should be burned into the resulting compiler?
changed the title [-]make.bash: CGO_ENABLED=0 sets default into resulting compiler[/-][+]make.bash: clarify that CGO_ENABLED=0 sets default into resulting compiler[/+]on Feb 21, 2022
We aren't going to change how CGO_ENABLED works today.
@ianlancetaylor I'd like to request that you reconsider this. Today if I build a compiler targeting linux from an Alpine image (yes I know this isn't fully supported), then my options are either:
build with CGO_ENABLED=0, which has the unwanted side effect of producing a compiler that doesn't do cgo for the host by default
build without CGO_ENABLED=0 and produce an unusable compiler that is linked with musl
I think it would make more sense (and be more consistent) if there were CGO_ENABLED_FOR_$GOOS_$GOARCH environment variables, which set the defaults for the built compiler. This would accomplish two goals:
In my case, I would run with CGO_ENABLED=0 CGO_ENABLED_FOR_linux_amd64=1 and get the expected result.
People who are currently setting CC_FOR_$GOOS_$GOARCH can improve their experience by not having to explicitly set CGO_ENABLED=1 for a target for which they have pre-selected a C compiler.
I'm not opposed to adding CGO_ENABLED_FOR_${GOOS}_$(GOARCH} or perhaps more simply CGO_ENABLED_FOR_TARGET. What I'm opposed to is changing the current meaning of CGO_ENABLED.
We are planning some changes to the way cgo in std is handled, and it may be worth revisiting this behavior at that time. For now we should probably sit on this issue.
For anyone looking for a workaround for the original issue, on linux/amd64 you can explicitly set GOHOSTARCH=386 to fool make.bash into thinking it is doing a cross-compile, so it will produce a compiler without cgo that still has cgo enabled by default. Note that you will also need to install gcc-multilib, as the bootstrap compiler will still be compiled with cgo.
Since Go 1.21 via commit 8a27154, the Go toolchain is statically linked. One does not need to set CGO_ENABLED=0 during ./make.bash to force this.
The comment in make.bash has not changed however.
Although there is no mention of the toolchain CGO_ENABLED option, on https://pkg.go.dev/cmd/cgo we have:
The cgo tool is enabled by default for native builds on systems where it is expected to work. It is disabled by default when cross-compiling as well as when the CC environment variable is unset and the default C compiler (typically gcc or clang) cannot be found on the system PATH. You can override the default by setting the CGO_ENABLED environment variable when running the go tool: set it to 1 to enable the use of cgo, and to 0 to disable it.
Disabling cgo by default for cross-compilation is a unfortunate divergence from native builds.
I think it would make more sense (and be more consistent) if there were CGO_ENABLED_FOR_$GOOS_$GOARCH environment variables, which set the defaults for the built compiler. This would accomplish two goals:
1. In my case, I would run with `CGO_ENABLED=0 CGO_ENABLED_FOR_linux_amd64=1` and get the expected result.
2. People who are currently setting `CC_FOR_$GOOS_$GOARCH` can improve their experience by not having to explicitly set `CGO_ENABLED=1` for a target for which they have pre-selected a C compiler.
Perhaps we can address this by recognizing CC_FOR_$GOOS_$GOARCH as hint that cross-compilation with cgo actually works without introducing a new variable?
Activity
seankhliao commentedon Feb 21, 2022
This is working as intended, ref #12808
rittneje commentedon Feb 21, 2022
@seankhliao This behavior is not at all implied by the current documentation for make.bash.
That does not make it clear that it is actually going to burn a default into the resulting compiler. Probably there need to be two different flags:
Please re-open this issue.
ianlancetaylor commentedon Feb 21, 2022
The current behavior is working as intended. We aren't going to change how
CGO_ENABLEDworks today.Reopening to clarify the documentation.
[-]make.bash: CGO_ENABLED=0 sets default into resulting compiler[/-][+]make.bash: clarify that CGO_ENABLED=0 sets default into resulting compiler[/+]rittneje commentedon Feb 22, 2022
@ianlancetaylor I'd like to request that you reconsider this. Today if I build a compiler targeting linux from an Alpine image (yes I know this isn't fully supported), then my options are either:
CGO_ENABLED=0, which has the unwanted side effect of producing a compiler that doesn't do cgo for the host by defaultCGO_ENABLED=0and produce an unusable compiler that is linked with muslI think it would make more sense (and be more consistent) if there were
CGO_ENABLED_FOR_$GOOS_$GOARCHenvironment variables, which set the defaults for the built compiler. This would accomplish two goals:CGO_ENABLED=0 CGO_ENABLED_FOR_linux_amd64=1and get the expected result.CC_FOR_$GOOS_$GOARCHcan improve their experience by not having to explicitly setCGO_ENABLED=1for a target for which they have pre-selected a C compiler.ianlancetaylor commentedon Feb 22, 2022
I'm not opposed to adding
CGO_ENABLED_FOR_${GOOS}_$(GOARCH}or perhaps more simplyCGO_ENABLED_FOR_TARGET. What I'm opposed to is changing the current meaning ofCGO_ENABLED.rsc commentedon Feb 22, 2022
We are planning some changes to the way cgo in std is handled, and it may be worth revisiting this behavior at that time. For now we should probably sit on this issue.
rittneje commentedon Mar 12, 2022
For anyone looking for a workaround for the original issue, on linux/amd64 you can explicitly set
GOHOSTARCH=386to fool make.bash into thinking it is doing a cross-compile, so it will produce a compiler without cgo that still has cgo enabled by default. Note that you will also need to installgcc-multilib, as the bootstrap compiler will still be compiled with cgo.Lekensteyn commentedon Oct 2, 2025
Since Go 1.21 via commit 8a27154, the Go toolchain is statically linked. One does not need to set
CGO_ENABLED=0during./make.bashto force this.The comment in
make.bashhas not changed however.Although there is no mention of the toolchain
CGO_ENABLEDoption, on https://pkg.go.dev/cmd/cgo we have:Disabling cgo by default for cross-compilation is a unfortunate divergence from native builds.
Perhaps we can address this by recognizing
CC_FOR_$GOOS_$GOARCHas hint that cross-compilation with cgo actually works without introducing a new variable?make.bash, make.rc, make.bat: document that CGO_ENABLED sets the default
gopherbot commentedon Oct 27, 2026
Change https://go.dev/cl/854745 mentions this issue:
make.bash, make.rc, make.bat: document that CGO_ENABLED sets the default