cmd/link: use a .def file to mark exported symbols on Windows

Binutils defaults to exporting all symbols when building a Windows DLL.
To avoid that we were marking symbols with __declspec(dllexport) in
the cgo-generated headers, which instructs ld to export only those
symbols. However, that approach makes the headers hard to reuse when
importing the resulting DLL into other projects, as imported symbols
should be marked with __declspec(dllimport).

A better approach is to generate a .def file listing the symbols to
export, which gets the same effect without having to modify the headers.

Updates #30674
Fixes #56994

Change-Id: I22bd0aa079e2be4ae43b13d893f6b804eaeddabf
Reviewed-on: https://go-review.googlesource.com/c/go/+/705776
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Than McIntosh <thanm@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
qmuntal 2025-09-22 15:48:36 +02:00 committed by Quim Muntal
parent 4b77733565
commit eaf2345256
8 changed files with 118 additions and 65 deletions

View file

@ -16,6 +16,7 @@ import (
"fmt"
"internal/abi"
"io"
"iter"
"log"
"math/bits"
"os"
@ -1109,6 +1110,18 @@ func (l *Loader) SetAttrCgoExportStatic(i Sym, v bool) {
}
}
// ForAllCgoExportStatic returns an iterator over all symbols
// marked with the "cgo_export_static" compiler directive.
func (l *Loader) ForAllCgoExportStatic() iter.Seq[Sym] {
return func(yield func(Sym) bool) {
for s := range l.attrCgoExportStatic {
if !yield(s) {
break
}
}
}
}
// IsGeneratedSym returns true if a symbol's been previously marked as a
// generator symbol through the SetIsGeneratedSym. The functions for generator
// symbols are kept in the Link context.