This should work:
Copygo env -w CGO_ENABLED=1
But if you don't have a C compiler installed on your machine, you will get another error message after setting this variable and trying to use go run -race .:
cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in %PATH%
If so, here are VS Code's instructions on how to install it
- Windows: https://code.visualstudio.com/docs/cpp/config-mingw
- Linux: https://code.visualstudio.com/docs/cpp/config-linux
This should work:
Copygo env -w CGO_ENABLED=1
But if you don't have a C compiler installed on your machine, you will get another error message after setting this variable and trying to use go run -race .:
cgo: C compiler "gcc" not found: exec: "gcc": executable file not found in %PATH%
If so, here are VS Code's instructions on how to install it
- Windows: https://code.visualstudio.com/docs/cpp/config-mingw
- Linux: https://code.visualstudio.com/docs/cpp/config-linux
You can write a batch script run.bat to run your code:
Copyset CGO_ENABLED=1
go run -race .
To accomplish this in Visual Studio Code, you can modify the environment variables via a launch script, see this question:
Is there any way to set environment variables in Visual Studio Code?
Getting CGO_ENABLED=0 when running a go project that uses github.com/mattn/go-sqlite3 library?
`CGO_ENABLED` cannot be set to `1`
What is the consequence of using CGO_ENABLED=0?
With CGO_ENABLED=0 you got a staticaly-linked binary (see: https://en.wikipedia.org/wiki/Static_build) so it will run without any external dependencies (you can buld your dockers from 'scratch' image) Like that: https://github.com/s0rg/microapp/blob/master/Dockerfile
More on reddit.comcmd/build: cgo cross build need to explictly set `CGO_ENABLED=1`
Videos
Many things are only available as C libraries, and re-implementing that all in Go would be costly. cgo has its downsides, but it can be a good trade-off. Even the standard library uses it (net for DNS lookups, os/user for user lookups) because it doesn't re-implement 100% of the behaviour in Go.
Cross-compiling C code is still rather hard; you'll need the target architecture's C compiler and toolchain (e.g. CC=aarch64-linux-musl-gccgo build to build an arm64 binary). None of that is installed by default so for most people cgo simply won't work when cross-compiling; they need to take manual steps to set it up first.
cgo often isn't strictly required (like in the net and os/user packages), so disabling it by default seems the most user-friendly option.
But there are no such constraints on the native platform, and it's expected to work by default without any user setup; so why not enable it by default?
If you're running on an Alpine image, it is impossible to compile and run Go programs in Alpine images right away. You must disable CGO by setting the environment variable CGO_ENABLED to false (the default value is true).
You can do this either by:
- Adding
go env -w CGO_ENABLED=0like Robert mentions in his comment or, - Setting the env value prefixing it in the
gocommand, e.g.:CGO_ENABLED=0 GOARCH=amd64 GOOS=linux go build -ldflags '-s -w' -tags lambda.norpc -o bin/<YOUR_FUNC>/bootstrap <YOUR_PATH>/main.go
See: https://megamorf.gitlab.io/2019/09/08/alpine-go-builds-with-cgo-enabled/
Is it a bad idea to set this environment variable to 0? From what I read, setting it to 1 means there should be a gcc compiler installed in the working system. Is this a correct interpretation? Why is it 1 by default?
I was trying to containerise my go application using the below docker file:
FROM golang:latest as builder
ENV GOOS=linux
COPY ./ /go/src/hello_world
WORKDIR /go/src/hello_world
RUN go build .
FROM alpine:latest
WORKDIR /usr/home
COPY --from=builder /go/src/hello_world/hello_world /usr/home
ENTRYPOINT ["./hello_world"]
This was giving me error but based on my findings I put ENV CGO_ENABLED=0 during build and it started working fine.
When is it required to be set to 1 and why did I have to explicitly set to 0 in my case?
P.S. I am very new to go so any resources on this would be appreciated.
With CGO_ENABLED=0 you got a staticaly-linked binary (see: https://en.wikipedia.org/wiki/Static_build) so it will run without any external dependencies (you can buld your dockers from 'scratch' image) Like that: https://github.com/s0rg/microapp/blob/master/Dockerfile
From what I read, setting it to 1 means there should be a gcc compiler installed in the working system. Is this a correct interpretation? Why is it 1 by default?
It doesn't actually mean you must have a gcc compiler available. It means a couple things. Some parts of the runtime like the dns resolver and user lookups use glibc so it will link against those if you use certain stdlib packages. There are some pure Go replacements that swap in if you disable cgo. But if you use any other 3rd party packages that do have cgo bindings to C then it would be expected that you have a compiler when you build. But you would find that out pretty quick if you disabled cgo and your project could no longer build those dependencies .
Hello,
I have a github actions runner running Linux and it needs time build a go binary using cgo for arm64 architecture. Any examples?