@@ -1138,6 +1138,13 @@ getSanitizerRuntimeLibNameForDarwin(StringRef Sanitizer,
11381138 + (shared ? " _dynamic.dylib" : " .a" )).str ();
11391139}
11401140
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+
11411148static std::string
11421149getSanitizerRuntimeLibNameForLinux (StringRef Sanitizer, const llvm::Triple &Triple) {
11431150 return (Twine (" libclang_rt." ) + Sanitizer + " -" +
@@ -1154,6 +1161,17 @@ bool toolchains::Darwin::sanitizerRuntimeLibExists(
11541161 return llvm::sys::fs::exists (sanitizerLibPath.str ());
11551162}
11561163
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+
11571175bool toolchains::GenericUnix::sanitizerRuntimeLibExists (
11581176 const ArgList &args, StringRef sanitizer, bool shared) const {
11591177 SmallString<128 > sanitizerLibPath;
@@ -1196,16 +1214,22 @@ addLinkRuntimeLibForDarwin(const ArgList &Args, ArgStringList &Arguments,
11961214 }
11971215}
11981216
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+
11991227static void
12001228addLinkRuntimeLibForLinux (const ArgList &Args, ArgStringList &Arguments,
12011229 StringRef LinuxLibName,
12021230 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);
12091233 llvm::sys::path::append (P, LinuxLibName);
12101234 Arguments.push_back (Args.MakeArgString (P));
12111235}
@@ -1228,11 +1252,21 @@ addLinkSanitizerLibArgsForDarwin(const ArgList &Args,
12281252 /* AddRPath=*/ shared, TC);
12291253}
12301254
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,
12361270 getSanitizerRuntimeLibNameForLinux (Sanitizer, TC.getTriple ()), TC);
12371271
12381272 // Code taken from
@@ -1510,24 +1544,148 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
15101544 return II;
15111545}
15121546
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+
15131672ToolChain::InvocationInfo
15141673toolchains::GenericUnix::constructInvocation (const InterpretJobAction &job,
15151674 const JobContext &context) const {
15161675 InvocationInfo II = ToolChain::constructInvocation (job, context);
15171676
15181677 SmallString<128 > runtimeLibraryPath;
1519- getRuntimeLibraryPath (runtimeLibraryPath, context.Args , *this , /* Shared=*/ true );
1678+ getRuntimeLibraryPath (runtimeLibraryPath, context.Args , *this ,
1679+ /* Shared=*/ true );
15201680
15211681 addPathEnvironmentVariableIfNeeded (II.ExtraEnvironment , " LD_LIBRARY_PATH" ,
15221682 " :" , options::OPT_L, context.Args ,
15231683 runtimeLibraryPath);
15241684 return II;
15251685}
15261686
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 {
15311689 assert (context.Output .getPrimaryOutputType () == file_types::TY_AutolinkFile);
15321690
15331691 ArgStringList Arguments;
@@ -1536,14 +1694,14 @@ toolchains::GenericUnix::constructInvocation(const AutolinkExtractJobAction &job
15361694 addInputsOfType (Arguments, context.InputActions , file_types::TY_Object);
15371695
15381696 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 ()));
15411699
15421700 return {" swift-autolink-extract" , Arguments};
15431701}
15441702
15451703std::string toolchains::GenericUnix::getDefaultLinker () const {
1546- switch (getTriple ().getArch ()) {
1704+ switch (getTriple ().getArch ()) {
15471705 case llvm::Triple::arm:
15481706 case llvm::Triple::armeb:
15491707 case llvm::Triple::thumb:
0 commit comments