mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/link: support MSVC clang
Currently on Windows, for cgo, we support MinGW-based C toolchain, that is, with a -windows-gnu target. This CL makes it work with clang with a -windows-msvc target. The LLVM toolchain bundled in MSVC (https://learn.microsoft.com/en-us/cpp/build/clang-support-msbuild) is such an example. Currently it is expecting lld-link as the C linker, which is also bundled in MSVC, can be requested with -fuse-ld=lld, but is not the default. This is the first step, which makes it generate a working cgo binary. There are still more work to do, e.g. there are some linker warnings, and the binary doesn't have symbol table. all.bat doesn't pass with this setting. Change-Id: I54d33f7dd5f5eeeafa0735cd52f4127fe4865636 Reviewed-on: https://go-review.googlesource.com/c/go/+/703055 Reviewed-by: Than McIntosh <thanm@golang.org> Reviewed-by: Florian Zenker <floriank@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
parent
9271bbbb80
commit
c70713da82
1 changed files with 56 additions and 16 deletions
|
|
@ -1457,6 +1457,9 @@ func (ctxt *Link) hostlink() {
|
||||||
// Only macOS supports unmapped segments such as our __DWARF segment.
|
// Only macOS supports unmapped segments such as our __DWARF segment.
|
||||||
combineDwarf := ctxt.IsDarwin() && !*FlagW && machoPlatform == PLATFORM_MACOS
|
combineDwarf := ctxt.IsDarwin() && !*FlagW && machoPlatform == PLATFORM_MACOS
|
||||||
|
|
||||||
|
var isMSVC bool // used on Windows
|
||||||
|
wlPrefix := "-Wl,--"
|
||||||
|
|
||||||
switch ctxt.HeadType {
|
switch ctxt.HeadType {
|
||||||
case objabi.Hdarwin:
|
case objabi.Hdarwin:
|
||||||
if combineDwarf {
|
if combineDwarf {
|
||||||
|
|
@ -1501,6 +1504,15 @@ func (ctxt *Link) hostlink() {
|
||||||
argv = append(argv, "-Wl,--no-execute-only")
|
argv = append(argv, "-Wl,--no-execute-only")
|
||||||
}
|
}
|
||||||
case objabi.Hwindows:
|
case objabi.Hwindows:
|
||||||
|
isMSVC = ctxt.isMSVC()
|
||||||
|
if isMSVC {
|
||||||
|
// For various options, MSVC lld-link only accepts one dash.
|
||||||
|
// TODO: It seems mingw clang supports one or two dashes,
|
||||||
|
// maybe we can always use one dash, but I'm not sure about
|
||||||
|
// legacy compilers that currently work.
|
||||||
|
wlPrefix = "-Wl,-"
|
||||||
|
}
|
||||||
|
|
||||||
if windowsgui {
|
if windowsgui {
|
||||||
argv = append(argv, "-mwindows")
|
argv = append(argv, "-mwindows")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1508,15 +1520,18 @@ func (ctxt *Link) hostlink() {
|
||||||
}
|
}
|
||||||
// Mark as having awareness of terminal services, to avoid
|
// Mark as having awareness of terminal services, to avoid
|
||||||
// ancient compatibility hacks.
|
// ancient compatibility hacks.
|
||||||
argv = append(argv, "-Wl,--tsaware")
|
|
||||||
|
argv = append(argv, wlPrefix+"tsaware")
|
||||||
|
|
||||||
// Enable DEP
|
// Enable DEP
|
||||||
argv = append(argv, "-Wl,--nxcompat")
|
argv = append(argv, wlPrefix+"nxcompat")
|
||||||
|
|
||||||
argv = append(argv, fmt.Sprintf("-Wl,--major-os-version=%d", PeMinimumTargetMajorVersion))
|
if !isMSVC {
|
||||||
argv = append(argv, fmt.Sprintf("-Wl,--minor-os-version=%d", PeMinimumTargetMinorVersion))
|
argv = append(argv, fmt.Sprintf("-Wl,--major-os-version=%d", PeMinimumTargetMajorVersion))
|
||||||
argv = append(argv, fmt.Sprintf("-Wl,--major-subsystem-version=%d", PeMinimumTargetMajorVersion))
|
argv = append(argv, fmt.Sprintf("-Wl,--minor-os-version=%d", PeMinimumTargetMinorVersion))
|
||||||
argv = append(argv, fmt.Sprintf("-Wl,--minor-subsystem-version=%d", PeMinimumTargetMinorVersion))
|
argv = append(argv, fmt.Sprintf("-Wl,--major-subsystem-version=%d", PeMinimumTargetMajorVersion))
|
||||||
|
argv = append(argv, fmt.Sprintf("-Wl,--minor-subsystem-version=%d", PeMinimumTargetMinorVersion))
|
||||||
|
}
|
||||||
case objabi.Haix:
|
case objabi.Haix:
|
||||||
argv = append(argv, "-pthread")
|
argv = append(argv, "-pthread")
|
||||||
// prevent ld to reorder .text functions to keep the same
|
// prevent ld to reorder .text functions to keep the same
|
||||||
|
|
@ -1557,16 +1572,21 @@ func (ctxt *Link) hostlink() {
|
||||||
// an ancient compiler with ancient defaults.
|
// an ancient compiler with ancient defaults.
|
||||||
var dbopt string
|
var dbopt string
|
||||||
var heopt string
|
var heopt string
|
||||||
dbon := "--dynamicbase"
|
dbon := wlPrefix + "dynamicbase"
|
||||||
heon := "--high-entropy-va"
|
heon := wlPrefix + "high-entropy-va"
|
||||||
dboff := "--disable-dynamicbase"
|
dboff := wlPrefix + "disable-dynamicbase"
|
||||||
heoff := "--disable-high-entropy-va"
|
heoff := wlPrefix + "disable-high-entropy-va"
|
||||||
|
if isMSVC {
|
||||||
|
heon = wlPrefix + "highentropyva"
|
||||||
|
heoff = wlPrefix + "highentropyva:no"
|
||||||
|
dboff = wlPrefix + "dynamicbase:no"
|
||||||
|
}
|
||||||
if val {
|
if val {
|
||||||
dbopt = dbon
|
dbopt = dbon
|
||||||
heopt = heon
|
heopt = heon
|
||||||
} else {
|
} else {
|
||||||
// Test to see whether "--disable-dynamicbase" works.
|
// Test to see whether "--disable-dynamicbase" works.
|
||||||
newer := linkerFlagSupported(ctxt.Arch, argv[0], "", "-Wl,"+dboff)
|
newer := linkerFlagSupported(ctxt.Arch, argv[0], "", dboff)
|
||||||
if newer {
|
if newer {
|
||||||
// Newer compiler, which supports both on/off options.
|
// Newer compiler, which supports both on/off options.
|
||||||
dbopt = dboff
|
dbopt = dboff
|
||||||
|
|
@ -1579,11 +1599,11 @@ func (ctxt *Link) hostlink() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if dbopt != "" {
|
if dbopt != "" {
|
||||||
argv = append(argv, "-Wl,"+dbopt)
|
argv = append(argv, dbopt)
|
||||||
}
|
}
|
||||||
// enable high-entropy ASLR on 64-bit.
|
// enable high-entropy ASLR on 64-bit.
|
||||||
if ctxt.Arch.PtrSize >= 8 && heopt != "" {
|
if ctxt.Arch.PtrSize >= 8 && heopt != "" {
|
||||||
argv = append(argv, "-Wl,"+heopt)
|
argv = append(argv, heopt)
|
||||||
}
|
}
|
||||||
return argv
|
return argv
|
||||||
}
|
}
|
||||||
|
|
@ -1927,9 +1947,11 @@ func (ctxt *Link) hostlink() {
|
||||||
argv = append(argv, "-lsynchronization")
|
argv = append(argv, "-lsynchronization")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// libmingw32 and libmingwex have some inter-dependencies,
|
if !isMSVC {
|
||||||
// so must use linker groups.
|
// libmingw32 and libmingwex have some inter-dependencies,
|
||||||
argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
|
// so must use linker groups.
|
||||||
|
argv = append(argv, "-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group")
|
||||||
|
}
|
||||||
argv = append(argv, peimporteddlls()...)
|
argv = append(argv, peimporteddlls()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2182,6 +2204,7 @@ func trimLinkerArgv(argv []string) []string {
|
||||||
"-isysroot",
|
"-isysroot",
|
||||||
"--sysroot",
|
"--sysroot",
|
||||||
"-target",
|
"-target",
|
||||||
|
"--target",
|
||||||
}
|
}
|
||||||
prefixesToKeep := []string{
|
prefixesToKeep := []string{
|
||||||
"-f",
|
"-f",
|
||||||
|
|
@ -2192,6 +2215,7 @@ func trimLinkerArgv(argv []string) []string {
|
||||||
"-isysroot",
|
"-isysroot",
|
||||||
"--sysroot",
|
"--sysroot",
|
||||||
"-target",
|
"-target",
|
||||||
|
"--target",
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags []string
|
var flags []string
|
||||||
|
|
@ -3024,3 +3048,19 @@ func (ctxt *Link) findExtLinkTool(toolname string) string {
|
||||||
cmdpath := strings.TrimRight(string(out), "\r\n")
|
cmdpath := strings.TrimRight(string(out), "\r\n")
|
||||||
return cmdpath
|
return cmdpath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isMSVC reports whether the C toolchain is clang with a -msvc target,
|
||||||
|
// e.g. the clang bundled in MSVC.
|
||||||
|
func (ctxt *Link) isMSVC() bool {
|
||||||
|
extld := ctxt.extld()
|
||||||
|
name, args := extld[0], extld[1:]
|
||||||
|
args = append(args, trimLinkerArgv(flagExtldflags)...)
|
||||||
|
args = append(args, "--version")
|
||||||
|
cmd := exec.Command(name, args...)
|
||||||
|
if out, err := cmd.CombinedOutput(); err == nil {
|
||||||
|
if bytes.Contains(out, []byte("-msvc\n")) || bytes.Contains(out, []byte("-msvc\r")) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue