Skip to content

cmd/go: dev build produces invalid binaries on Windows when using cgo #75734

@djdv

Description

@djdv

Go version

go version go1.26-devel_eaf2345256 Mon Sep 29 12:24:13 2025 -0700 windows/amd64

Output of go env in your module/workspace:

set AR=ar
set CC=gcc
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_ENABLED=1
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set CXX=g++
set GCCGO=gccgo
set GO111MODULE=
set GOAMD64=v1
set GOARCH=amd64
set GOAUTH=netrc
set GOBIN=
set GOCACHE=C:\Users\Dominic Della Valle\AppData\Local\go-build
set GOCACHEPROG=
set GODEBUG=
set GOENV=C:\Users\Dominic Della Valle\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFIPS140=off
set GOFLAGS=
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\DOMINI~1\AppData\Local\Temp\go-build4131726389=/tmp/go-build -gno-record-gcc-switches
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMOD=C:\Users\Dominic Della Valle\Projects\Go\src\local\cgo-test\go.mod
set GOMODCACHE=C:\Users\Dominic Della Valle\Projects\Go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\Dominic Della Valle\Projects\Go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Users\Dominic Della Valle\Projects\Go\goroot
set GOSUMDB=sum.golang.org
set GOTELEMETRY=on
set GOTELEMETRYDIR=C:\Users\Dominic Della Valle\AppData\Roaming\go\telemetry
set GOTMPDIR=
set GOTOOLCHAIN=auto
set GOTOOLDIR=C:\Users\Dominic Della Valle\Projects\Go\goroot\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.26-devel_eaf2345256 Mon Sep 29 12:24:13 2025 -0700
set GOWORK=
set PKG_CONFIG=pkg-config

What did you do?

On and after commit eaf2345 (cc @qmuntal)
go run or go build on a package that utilizes cgo while CGO_ENABLED=1
Should be using gcc from Msys2, specifically package mingw64/mingw-w64-x86_64-gcc version gcc.exe (Rev8, Built by MSYS2 project) 15.2.0
Screencast showing this: https://www.youtube.com/watch?v=MWbzfYbeRe8

main.go

package main

func main() {
	someFunc()
}

main_cgo.go

//go:build cgo

package main

/*
#include <stdio.h>
#include <stdlib.h>

void hello(const char* name) {
	printf("Hello from the %s runtime!\n", name);
}
*/
import "C"

import "unsafe"

func someFunc() {
	const name = "C"
	cName := C.CString(name)
	C.hello(cName)
	C.free(unsafe.Pointer(cName))
}

main_nocgo.go

//go:build !cgo

package main

import (
	"fmt"
)

func hello(name string) {
	fmt.Printf("Hello from the %s runtime!\n", name)
}

func someFunc() {
	const name = "Go"
	hello(name)
}

What did you see happen?

Compiler outputs an unexecutable file.

What did you expect to see?

Valid executable produced.

Metadata

Metadata

Assignees

Labels

FixPendingIssues that have a fix which has not yet been reviewed or submitted.OS-Windows

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions