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?
Consider using `CGO_ENABLED=1` for default macOS build
cmd/link: cross compile from MacOS to Windows with CGO_ENABLED=1 and -buildmode=c-archive not working
go - How to compile an amd64 binary that uses C on an M1 (arm64) Mac - Stack Overflow
Releaser build with CGO_ENABLED=0 doesn't run on Mac M1
In my case, I also needed to set CGO_ENABLED to true. The app now compiles fine for amd64 with GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build
(Thanks to this answer)
The answer to the wasm question (as you posted) talks about cgo. cgo invokes platform compiler with platform specific headers/libs (on Mac, with framework too). When you cross-compile with CC, you also need cross-compile compiler + headers/libs + frameworks. It is not easy: you may need tools like xgo. But still cross-compile may fail.
Go is different, Go re-implements a HAL in go or plan9 ASM on each OS/arch. So when you cross-compile cgo + go for am64 on arm64 together, go build will try to blend "cgo+arm64" with "go+amd64". Sadly, it is an empty set for the built-in go build tool.
Refer to the @fperson's own answer.
I guess I should have known this, but spent all day down wrong rabbit holes of compilers and deployment targets, trying to figure out why go build was skipping my files with import "C" in them when compiling to darwin/arm64 for new apple silicon.
I've done cross-compiling to wasm and bsd before, but never with cgo, so I never new CGO_ENABLED=1 had to be set to cross-compile with cgo.
Hope this can save someone else time too.
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/
hi,
I'm trying to cross build on Linux a project which uses https://github.com/shirou/gopsutil.
Everything fine except for MacOS: I get "not implement". Looking at https://github.com/shirou/gopsutil/tree/master/v3/cpu code it seems it's because I don't build with cgo and the MacOS (darwin) version only works with cgo.
How do I go build on Linux with cgo with MacOS as target ?
CGO_ENABLED=1 GOOS=darwin GOARCH=amd64 go build main.go
gives an error (gcc: error: unrecognized command-line option '-arch). I guess I'm missing a cross compile C tool chain ?
Complementary to this, is there any github actions (ci/cd) that can do that ? Ideally I'd like to have binaries for all platforms built and published when a tagged release is committed. Can Github do that (with cgo, I know it can without) ?
sample code : https://gist.github.com/kgersen/ca265719c76ed1a41e98c2801135b3b8 (cross building on Linux for darwin and running on darwin gives 'not implemented').
Hello,
I have a github actions runner running Linux and it needs time build a go binary using cgo for arm64 architecture. Any examples?