@@ -1457,6 +1457,9 @@ func (ctxt *Link) hostlink() {
1457
1457
// Only macOS supports unmapped segments such as our __DWARF segment.
1458
1458
combineDwarf := ctxt .IsDarwin () && ! * FlagW && machoPlatform == PLATFORM_MACOS
1459
1459
1460
+ var isMSVC bool // used on Windows
1461
+ wlPrefix := "-Wl,--"
1462
+
1460
1463
switch ctxt .HeadType {
1461
1464
case objabi .Hdarwin :
1462
1465
if combineDwarf {
@@ -1501,22 +1504,34 @@ func (ctxt *Link) hostlink() {
1501
1504
argv = append (argv , "-Wl,--no-execute-only" )
1502
1505
}
1503
1506
case objabi .Hwindows :
1507
+ isMSVC = ctxt .isMSVC ()
1508
+ if isMSVC {
1509
+ // For various options, MSVC lld-link only accepts one dash.
1510
+ // TODO: It seems mingw clang supports one or two dashes,
1511
+ // maybe we can always use one dash, but I'm not sure about
1512
+ // legacy compilers that currently work.
1513
+ wlPrefix = "-Wl,-"
1514
+ }
1515
+
1504
1516
if windowsgui {
1505
1517
argv = append (argv , "-mwindows" )
1506
1518
} else {
1507
1519
argv = append (argv , "-mconsole" )
1508
1520
}
1509
1521
// Mark as having awareness of terminal services, to avoid
1510
1522
// ancient compatibility hacks.
1511
- argv = append (argv , "-Wl,--tsaware" )
1523
+
1524
+ argv = append (argv , wlPrefix + "tsaware" )
1512
1525
1513
1526
// Enable DEP
1514
- argv = append (argv , "-Wl,-- nxcompat" )
1527
+ argv = append (argv , wlPrefix + " nxcompat" )
1515
1528
1516
- argv = append (argv , fmt .Sprintf ("-Wl,--major-os-version=%d" , PeMinimumTargetMajorVersion ))
1517
- argv = append (argv , fmt .Sprintf ("-Wl,--minor-os-version=%d" , PeMinimumTargetMinorVersion ))
1518
- argv = append (argv , fmt .Sprintf ("-Wl,--major-subsystem-version=%d" , PeMinimumTargetMajorVersion ))
1519
- argv = append (argv , fmt .Sprintf ("-Wl,--minor-subsystem-version=%d" , PeMinimumTargetMinorVersion ))
1529
+ if ! isMSVC {
1530
+ argv = append (argv , fmt .Sprintf ("-Wl,--major-os-version=%d" , PeMinimumTargetMajorVersion ))
1531
+ argv = append (argv , fmt .Sprintf ("-Wl,--minor-os-version=%d" , PeMinimumTargetMinorVersion ))
1532
+ argv = append (argv , fmt .Sprintf ("-Wl,--major-subsystem-version=%d" , PeMinimumTargetMajorVersion ))
1533
+ argv = append (argv , fmt .Sprintf ("-Wl,--minor-subsystem-version=%d" , PeMinimumTargetMinorVersion ))
1534
+ }
1520
1535
case objabi .Haix :
1521
1536
argv = append (argv , "-pthread" )
1522
1537
// prevent ld to reorder .text functions to keep the same
@@ -1557,16 +1572,21 @@ func (ctxt *Link) hostlink() {
1557
1572
// an ancient compiler with ancient defaults.
1558
1573
var dbopt string
1559
1574
var heopt string
1560
- dbon := "--dynamicbase"
1561
- heon := "--high-entropy-va"
1562
- dboff := "--disable-dynamicbase"
1563
- heoff := "--disable-high-entropy-va"
1575
+ dbon := wlPrefix + "dynamicbase"
1576
+ heon := wlPrefix + "high-entropy-va"
1577
+ dboff := wlPrefix + "disable-dynamicbase"
1578
+ heoff := wlPrefix + "disable-high-entropy-va"
1579
+ if isMSVC {
1580
+ heon = wlPrefix + "highentropyva"
1581
+ heoff = wlPrefix + "highentropyva:no"
1582
+ dboff = wlPrefix + "dynamicbase:no"
1583
+ }
1564
1584
if val {
1565
1585
dbopt = dbon
1566
1586
heopt = heon
1567
1587
} else {
1568
1588
// Test to see whether "--disable-dynamicbase" works.
1569
- newer := linkerFlagSupported (ctxt .Arch , argv [0 ], "" , "-Wl," + dboff )
1589
+ newer := linkerFlagSupported (ctxt .Arch , argv [0 ], "" , dboff )
1570
1590
if newer {
1571
1591
// Newer compiler, which supports both on/off options.
1572
1592
dbopt = dboff
@@ -1579,11 +1599,11 @@ func (ctxt *Link) hostlink() {
1579
1599
}
1580
1600
}
1581
1601
if dbopt != "" {
1582
- argv = append (argv , "-Wl," + dbopt )
1602
+ argv = append (argv , dbopt )
1583
1603
}
1584
1604
// enable high-entropy ASLR on 64-bit.
1585
1605
if ctxt .Arch .PtrSize >= 8 && heopt != "" {
1586
- argv = append (argv , "-Wl," + heopt )
1606
+ argv = append (argv , heopt )
1587
1607
}
1588
1608
return argv
1589
1609
}
@@ -1927,9 +1947,11 @@ func (ctxt *Link) hostlink() {
1927
1947
argv = append (argv , "-lsynchronization" )
1928
1948
}
1929
1949
}
1930
- // libmingw32 and libmingwex have some inter-dependencies,
1931
- // so must use linker groups.
1932
- argv = append (argv , "-Wl,--start-group" , "-lmingwex" , "-lmingw32" , "-Wl,--end-group" )
1950
+ if ! isMSVC {
1951
+ // libmingw32 and libmingwex have some inter-dependencies,
1952
+ // so must use linker groups.
1953
+ argv = append (argv , "-Wl,--start-group" , "-lmingwex" , "-lmingw32" , "-Wl,--end-group" )
1954
+ }
1933
1955
argv = append (argv , peimporteddlls ()... )
1934
1956
}
1935
1957
@@ -2182,6 +2204,7 @@ func trimLinkerArgv(argv []string) []string {
2182
2204
"-isysroot" ,
2183
2205
"--sysroot" ,
2184
2206
"-target" ,
2207
+ "--target" ,
2185
2208
}
2186
2209
prefixesToKeep := []string {
2187
2210
"-f" ,
@@ -2192,6 +2215,7 @@ func trimLinkerArgv(argv []string) []string {
2192
2215
"-isysroot" ,
2193
2216
"--sysroot" ,
2194
2217
"-target" ,
2218
+ "--target" ,
2195
2219
}
2196
2220
2197
2221
var flags []string
@@ -3024,3 +3048,19 @@ func (ctxt *Link) findExtLinkTool(toolname string) string {
3024
3048
cmdpath := strings .TrimRight (string (out ), "\r \n " )
3025
3049
return cmdpath
3026
3050
}
3051
+
3052
+ // isMSVC reports whether the C toolchain is clang with a -msvc target,
3053
+ // e.g. the clang bundled in MSVC.
3054
+ func (ctxt * Link ) isMSVC () bool {
3055
+ extld := ctxt .extld ()
3056
+ name , args := extld [0 ], extld [1 :]
3057
+ args = append (args , trimLinkerArgv (flagExtldflags )... )
3058
+ args = append (args , "--version" )
3059
+ cmd := exec .Command (name , args ... )
3060
+ if out , err := cmd .CombinedOutput (); err == nil {
3061
+ if bytes .Contains (out , []byte ("-msvc\n " )) || bytes .Contains (out , []byte ("-msvc\r " )) {
3062
+ return true
3063
+ }
3064
+ }
3065
+ return false
3066
+ }
0 commit comments