@@ -1138,6 +1138,13 @@ getSanitizerRuntimeLibNameForDarwin(StringRef Sanitizer,
1138
1138
+ (shared ? " _dynamic.dylib" : " .a" )).str ();
1139
1139
}
1140
1140
1141
+ static std::string
1142
+ getSanitizerRuntimeLibNameForWindows (StringRef Sanitizer,
1143
+ const llvm::Triple &Triple) {
1144
+ return (Twine (" clang_rt." ) + Sanitizer + " -" + Triple.getArchName () + " .lib" )
1145
+ .str ();
1146
+ }
1147
+
1141
1148
static std::string
1142
1149
getSanitizerRuntimeLibNameForLinux (StringRef Sanitizer, const llvm::Triple &Triple) {
1143
1150
return (Twine (" libclang_rt." ) + Sanitizer + " -" +
@@ -1154,6 +1161,17 @@ bool toolchains::Darwin::sanitizerRuntimeLibExists(
1154
1161
return llvm::sys::fs::exists (sanitizerLibPath.str ());
1155
1162
}
1156
1163
1164
+ bool toolchains::Windows::sanitizerRuntimeLibExists (const ArgList &args,
1165
+ StringRef sanitizer,
1166
+ bool shared) const {
1167
+ SmallString<128 > sanitizerLibPath;
1168
+ getClangLibraryPath (*this , args, sanitizerLibPath);
1169
+ llvm::sys::path::append (
1170
+ sanitizerLibPath,
1171
+ getSanitizerRuntimeLibNameForWindows (sanitizer, this ->getTriple ()));
1172
+ return llvm::sys::fs::exists (sanitizerLibPath.str ());
1173
+ }
1174
+
1157
1175
bool toolchains::GenericUnix::sanitizerRuntimeLibExists (
1158
1176
const ArgList &args, StringRef sanitizer, bool shared) const {
1159
1177
SmallString<128 > sanitizerLibPath;
@@ -1196,16 +1214,22 @@ addLinkRuntimeLibForDarwin(const ArgList &Args, ArgStringList &Arguments,
1196
1214
}
1197
1215
}
1198
1216
1217
+ static void addLinkRuntimeLibForWindows (const ArgList &Args,
1218
+ ArgStringList &Arguments,
1219
+ StringRef WindowsLibName,
1220
+ const ToolChain &TC) {
1221
+ SmallString<128 > P;
1222
+ getClangLibraryPath (TC, Args, P);
1223
+ llvm::sys::path::append (P, WindowsLibName);
1224
+ Arguments.push_back (Args.MakeArgString (P));
1225
+ }
1226
+
1199
1227
static void
1200
1228
addLinkRuntimeLibForLinux (const ArgList &Args, ArgStringList &Arguments,
1201
1229
StringRef LinuxLibName,
1202
1230
const ToolChain &TC) {
1203
- SmallString<128 > Dir;
1204
- getRuntimeLibraryPath (Dir, Args, TC, /* Shared=*/ true );
1205
- // Remove platform name.
1206
- llvm::sys::path::remove_filename (Dir);
1207
- llvm::sys::path::append (Dir, " clang" , " lib" , " linux" );
1208
- SmallString<128 > P (Dir);
1231
+ SmallString<128 > P;
1232
+ getClangLibraryPath (TC, Args, P);
1209
1233
llvm::sys::path::append (P, LinuxLibName);
1210
1234
Arguments.push_back (Args.MakeArgString (P));
1211
1235
}
@@ -1228,11 +1252,21 @@ addLinkSanitizerLibArgsForDarwin(const ArgList &Args,
1228
1252
/* AddRPath=*/ shared, TC);
1229
1253
}
1230
1254
1231
- static void
1232
- addLinkSanitizerLibArgsForLinux (const ArgList &Args,
1233
- ArgStringList &Arguments,
1234
- StringRef Sanitizer, const ToolChain &TC) {
1235
- addLinkRuntimeLibForLinux (Args, Arguments,
1255
+ static void addLinkSanitizerLibArgsForWindows (const ArgList &Args,
1256
+ ArgStringList &Arguments,
1257
+ StringRef Sanitizer,
1258
+ const ToolChain &TC) {
1259
+ addLinkRuntimeLibForWindows (
1260
+ Args, Arguments,
1261
+ getSanitizerRuntimeLibNameForWindows (Sanitizer, TC.getTriple ()), TC);
1262
+ }
1263
+
1264
+ static void addLinkSanitizerLibArgsForLinux (const ArgList &Args,
1265
+ ArgStringList &Arguments,
1266
+ StringRef Sanitizer,
1267
+ const ToolChain &TC) {
1268
+ addLinkRuntimeLibForLinux (
1269
+ Args, Arguments,
1236
1270
getSanitizerRuntimeLibNameForLinux (Sanitizer, TC.getTriple ()), TC);
1237
1271
1238
1272
// Code taken from
@@ -1510,24 +1544,148 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
1510
1544
return II;
1511
1545
}
1512
1546
1547
+ ToolChain::InvocationInfo
1548
+ toolchains::Windows::constructInvocation (const LinkJobAction &job,
1549
+ const JobContext &context) const {
1550
+ assert (context.Output .getPrimaryOutputType () == file_types::TY_Image &&
1551
+ " Invalid linker output type." );
1552
+
1553
+ ArgStringList Arguments;
1554
+
1555
+ switch (job.getKind ()) {
1556
+ case LinkKind::None:
1557
+ llvm_unreachable (" invalid link kind" );
1558
+ case LinkKind::Executable:
1559
+ // Default case, nothing extra needed.
1560
+ break ;
1561
+ case LinkKind::DynamicLibrary:
1562
+ Arguments.push_back (" -shared" );
1563
+ break ;
1564
+ }
1565
+
1566
+ // Select the linker to use.
1567
+ std::string Linker;
1568
+ if (const Arg *A = context.Args .getLastArg (options::OPT_use_ld)) {
1569
+ Linker = A->getValue ();
1570
+ }
1571
+ if (!Linker.empty ())
1572
+ Arguments.push_back (context.Args .MakeArgString (" -fuse-ld=" + Linker));
1573
+
1574
+ // Configure the toolchain.
1575
+ // By default, use the system clang++ to link.
1576
+ const char *Clang = nullptr ;
1577
+ if (const Arg *A = context.Args .getLastArg (options::OPT_tools_directory)) {
1578
+ StringRef toolchainPath (A->getValue ());
1579
+
1580
+ // If there is a clang in the toolchain folder, use that instead.
1581
+ if (auto toolchainClang =
1582
+ llvm::sys::findProgramByName (" clang++" , {toolchainPath}))
1583
+ Clang = context.Args .MakeArgString (toolchainClang.get ());
1584
+ }
1585
+ if (Clang == nullptr ) {
1586
+ if (auto pathClang = llvm::sys::findProgramByName (" clang++" , None))
1587
+ Clang = context.Args .MakeArgString (pathClang.get ());
1588
+ }
1589
+ assert (Clang &&
1590
+ " clang++ was not found in the toolchain directory or system path." );
1591
+
1592
+ std::string Target = getTriple ().str ();
1593
+ if (!Target.empty ()) {
1594
+ Arguments.push_back (" -target" );
1595
+ Arguments.push_back (context.Args .MakeArgString (Target));
1596
+ }
1597
+
1598
+ SmallString<128 > SharedRuntimeLibPath;
1599
+ getRuntimeLibraryPath (SharedRuntimeLibPath, context.Args , *this ,
1600
+ /* Shared=*/ true );
1601
+
1602
+ // Link the standard library.
1603
+ Arguments.push_back (" -L" );
1604
+ if (context.Args .hasFlag (options::OPT_static_stdlib,
1605
+ options::OPT_no_static_stdlib, false )) {
1606
+ SmallString<128 > StaticRuntimeLibPath;
1607
+ getRuntimeLibraryPath (StaticRuntimeLibPath, context.Args , *this ,
1608
+ /* Shared=*/ false );
1609
+
1610
+ // Since Windows has separate libraries per architecture, link against the
1611
+ // architecture specific version of the static library.
1612
+ Arguments.push_back (context.Args .MakeArgString (StaticRuntimeLibPath + " /" +
1613
+ getTriple ().getArchName ()));
1614
+ } else {
1615
+ Arguments.push_back (context.Args .MakeArgString (SharedRuntimeLibPath + " /" +
1616
+ getTriple ().getArchName ()));
1617
+ }
1618
+
1619
+ SmallString<128 > swiftrtPath = SharedRuntimeLibPath;
1620
+ llvm::sys::path::append (swiftrtPath,
1621
+ swift::getMajorArchitectureName (getTriple ()));
1622
+ llvm::sys::path::append (swiftrtPath, " swiftrt.o" );
1623
+ Arguments.push_back (context.Args .MakeArgString (swiftrtPath));
1624
+
1625
+ addPrimaryInputsOfType (Arguments, context.Inputs , context.Args ,
1626
+ file_types::TY_Object);
1627
+ addInputsOfType (Arguments, context.InputActions , file_types::TY_Object);
1628
+
1629
+ for (const Arg *arg :
1630
+ context.Args .filtered (options::OPT_F, options::OPT_Fsystem)) {
1631
+ if (arg->getOption ().matches (options::OPT_Fsystem))
1632
+ Arguments.push_back (" -iframework" );
1633
+ else
1634
+ Arguments.push_back (context.Args .MakeArgString (arg->getSpelling ()));
1635
+ Arguments.push_back (arg->getValue ());
1636
+ }
1637
+
1638
+ if (!context.OI .SDKPath .empty ()) {
1639
+ Arguments.push_back (" -I" );
1640
+ Arguments.push_back (context.Args .MakeArgString (context.OI .SDKPath ));
1641
+ }
1642
+
1643
+ if (job.getKind () == LinkKind::Executable) {
1644
+ if (context.OI .SelectedSanitizers & SanitizerKind::Address)
1645
+ addLinkSanitizerLibArgsForWindows (context.Args , Arguments, " asan" , *this );
1646
+ }
1647
+
1648
+ if (context.Args .hasArg (options::OPT_profile_generate)) {
1649
+ SmallString<128 > LibProfile (SharedRuntimeLibPath);
1650
+ llvm::sys::path::remove_filename (LibProfile); // remove platform name
1651
+ llvm::sys::path::append (LibProfile, " clang" , " lib" );
1652
+
1653
+ llvm::sys::path::append (LibProfile, getTriple ().getOSName (),
1654
+ Twine (" clang_rt.profile-" ) +
1655
+ getTriple ().getArchName () + " .lib" );
1656
+ Arguments.push_back (context.Args .MakeArgString (LibProfile));
1657
+ Arguments.push_back (context.Args .MakeArgString (
1658
+ Twine (" -u" , llvm::getInstrProfRuntimeHookVarName ())));
1659
+ }
1660
+
1661
+ context.Args .AddAllArgs (Arguments, options::OPT_Xlinker);
1662
+ context.Args .AddAllArgs (Arguments, options::OPT_linker_option_Group);
1663
+
1664
+ // This should be the last option, for convenience in checking output.
1665
+ Arguments.push_back (" -o" );
1666
+ Arguments.push_back (
1667
+ context.Args .MakeArgString (context.Output .getPrimaryOutputFilename ()));
1668
+
1669
+ return {Clang, Arguments};
1670
+ }
1671
+
1513
1672
ToolChain::InvocationInfo
1514
1673
toolchains::GenericUnix::constructInvocation (const InterpretJobAction &job,
1515
1674
const JobContext &context) const {
1516
1675
InvocationInfo II = ToolChain::constructInvocation (job, context);
1517
1676
1518
1677
SmallString<128 > runtimeLibraryPath;
1519
- getRuntimeLibraryPath (runtimeLibraryPath, context.Args , *this , /* Shared=*/ true );
1678
+ getRuntimeLibraryPath (runtimeLibraryPath, context.Args , *this ,
1679
+ /* Shared=*/ true );
1520
1680
1521
1681
addPathEnvironmentVariableIfNeeded (II.ExtraEnvironment , " LD_LIBRARY_PATH" ,
1522
1682
" :" , options::OPT_L, context.Args ,
1523
1683
runtimeLibraryPath);
1524
1684
return II;
1525
1685
}
1526
1686
1527
-
1528
- ToolChain::InvocationInfo
1529
- toolchains::GenericUnix::constructInvocation (const AutolinkExtractJobAction &job,
1530
- const JobContext &context) const {
1687
+ ToolChain::InvocationInfo toolchains::GenericUnix::constructInvocation (
1688
+ const AutolinkExtractJobAction &job, const JobContext &context) const {
1531
1689
assert (context.Output .getPrimaryOutputType () == file_types::TY_AutolinkFile);
1532
1690
1533
1691
ArgStringList Arguments;
@@ -1536,14 +1694,14 @@ toolchains::GenericUnix::constructInvocation(const AutolinkExtractJobAction &job
1536
1694
addInputsOfType (Arguments, context.InputActions , file_types::TY_Object);
1537
1695
1538
1696
Arguments.push_back (" -o" );
1539
- Arguments.push_back (context. Args . MakeArgString (
1540
- context.Output .getPrimaryOutputFilename ()));
1697
+ Arguments.push_back (
1698
+ context.Args . MakeArgString (context. Output .getPrimaryOutputFilename ()));
1541
1699
1542
1700
return {" swift-autolink-extract" , Arguments};
1543
1701
}
1544
1702
1545
1703
std::string toolchains::GenericUnix::getDefaultLinker () const {
1546
- switch (getTriple ().getArch ()) {
1704
+ switch (getTriple ().getArch ()) {
1547
1705
case llvm::Triple::arm:
1548
1706
case llvm::Triple::armeb:
1549
1707
case llvm::Triple::thumb:
0 commit comments