-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[driver] Implement a Windows toolchain for cross-compiling #13236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that we should split out the implementation into a new .cpp
.
lib/Driver/ToolChains.cpp
Outdated
return (Twine("clang_rt.") | ||
+ Sanitizer + "-" | ||
+ Triple.getArchName() | ||
+ (shared ? ".dll" : ".lib")).str(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that this is right. You never link against the .dll
but rather the .lib
.
lib/Driver/ToolChains.cpp
Outdated
getRuntimeLibraryPath(Dir, Args, TC); | ||
// Remove platform name. | ||
llvm::sys::path::remove_filename(Dir); | ||
llvm::sys::path::append(Dir, "clang", "lib", "windows"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this effectively getClangLibraryPathOnWindows
?
lib/Driver/ToolChains.cpp
Outdated
Arguments.push_back("-lc++"); | ||
// Add explicit dependency on -lc++abi, as -lc++ doesn't re-export | ||
// all RTTI-related symbols that are used. | ||
Arguments.push_back("-lc++abi"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the assumption on the library names here and the spelling for the argument? Furthermore, Windows doesn't use libc++abi
ever but rather vcruntime.
lib/Driver/ToolChains.cpp
Outdated
|
||
addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "PATH", | ||
":", options::OPT_L, context.Args, | ||
runtimeLibraryPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't do this, this way (via the environment). We use use -libpath
or -L
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That doesn't work for the interpreter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixing this is probably out of scope for the PR as I'm only able to test cross-compiling at the moment, so testing the interpreter isn't an option.
lib/Driver/ToolChains.cpp
Outdated
Arguments.push_back( | ||
context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); | ||
|
||
return {"swift-autolink-extract", Arguments}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels wrong. We shouldn't be using swift-autolink-extract
on Windows at all. We have auto-linking support, and we should make that work instead.
lib/Driver/ToolChains.cpp
Outdated
if (!VCToolsDir.empty()) { | ||
Arguments.push_back("-Xlinker"); | ||
Arguments.push_back(context.Args.MakeArgString("/LIBPATH:" + llvm::Twine(VCToolsInstallDir) | ||
+ "/Lib/" + tripleWinArchName)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See previous point of -L
.
lib/Driver/ToolChains.cpp
Outdated
+ "/Lib/" + llvm::Twine(UCRTVer) + "/ucrt/" + tripleWinArchName)); | ||
Arguments.push_back("-Xlinker"); | ||
Arguments.push_back(context.Args.MakeArgString("/LIBPATH:" + llvm::Twine(UCRTDir) | ||
+ "/Lib/" + llvm::Twine(UCRTVer) + "/um/" + tripleWinArchName)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And again
lib/Driver/ToolChains.cpp
Outdated
Arguments.push_back(context.Args.MakeArgString(context.OI.SDKPath)); | ||
} | ||
|
||
// Add any autolinking scripts to the arguments |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See previous point about auto-linking.
lib/Driver/ToolChains.cpp
Outdated
} | ||
else { | ||
Arguments.push_back(context.Args.MakeArgString(SharedRuntimeLibPath)); | ||
Arguments.push_back("-lswiftCore"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be the absolute path to the swiftCore.lib
as that is in a well defined location I believe.
lib/Driver/ToolChains.cpp
Outdated
Arguments.push_back("-lswiftCore"); | ||
} | ||
|
||
// Explicitly pass the target to the linker |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be to the driver, the linker does not read the target.
@compnerd Okay, I'll start making those adjustments. Just a note that whenever there's a 'why have you done this' it's because I started with the GenericUnix toolchain and just tweaked until it worked; this was just a starting point and I was fulling expecting further changes. |
@jrose-apple Would you want this split out into a separate CPP file, and, if so, should the GenericUnix and Darwin toolchains also have their own CPP files? |
lib/Driver/ToolChains.cpp
Outdated
for (const Arg *arg : context.Args.filtered(options::OPT_F, | ||
options::OPT_Fsystem)) { | ||
if (arg->getOption().matches(options::OPT_Fsystem)) | ||
Arguments.push_back("-iframework"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we ever get frameworks being passed to the linker in a Windows context?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only thing that is interesting about a framework is the fact that they have a particular layout. I don't see a strong reason to not forward those along to clang and have clang just transliterate them into the appropriate -I
and -L
options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It probably does make sense to split up ToolChains.cpp at this point. That should happen in a no-functionality-change commit, though, and that can be after this PR.
lib/Driver/ToolChains.cpp
Outdated
ArgStringList &Arguments, | ||
StringRef Sanitizer, | ||
const ToolChain &TC, | ||
bool shared = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: misaligned arguments here, and the close paren should follow the last argument instead of going on the next line.
lib/Driver/ToolChains.cpp
Outdated
ToolChain::InvocationInfo | ||
toolchains::Windows::constructInvocation(const InterpretJobAction &job, | ||
const JobContext &context) const { | ||
InvocationInfo II = ToolChain::constructInvocation(job, context); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for this now that you're inheriting directly from ToolChain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see this is vestigial because @compnerd had you remove the LD_LIBRARY_PATH trick. Unfortunately we'll need to come up with something similar for Windows if we want the interpreter to work with -L. We're probably not doing the right thing on Windows anyway, though (dlopen
).
lib/Driver/ToolChains.cpp
Outdated
|
||
// Configure the toolchain. | ||
// By default, use the system clang++ to link. | ||
const char * Clang = "clang++"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has there been any discussion about using cl
directly? Do we get any benefit from using Clang?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there are tradeoffs to each approach. With cl
, the user doesn't need Clang installed, but Clang does provide things like ASAN that MSVC is missing. If we also might end up with a dependency on Compiler-RT (see #13234) then it'd probably be worth sticking with Clang.
As for using the clang-cl
vs. clang
driver: I don't have any strong opinions there. I suppose there'd be some benefit in consistency with other platforms, but if the consensus is that clang-cl
is preferred I can easily switch over the commands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose one option would be to use clang-cl
by default and fallback to cl
if Clang isn't installed.
lib/Driver/ToolChains.cpp
Outdated
|
||
StringRef tripleWinArchName; | ||
switch (getTriple().getArch()) { | ||
case llvm::Triple::x86: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: case
labels are not indented in LLVM style.
lib/Driver/ToolChains.cpp
Outdated
StringRef UCRTVer(UCRTVersion); | ||
|
||
if (!UCRTDir.empty() && !UCRTVer.empty()) { | ||
Arguments.push_back("-L"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: accidental double-indent here.
lib/Driver/ToolChains.cpp
Outdated
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath)); | ||
|
||
SmallString<128> linkFilePath = StaticRuntimeLibPath; | ||
llvm::sys::path::append(linkFilePath, "static-executable-args.lnk"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work on Windows?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The static stdlib isn't currently building on Windows, but thinking about it more I think we'd end up passing the same arguments here whether we're building static or shared, so this section should be removed. @compnerd, thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant linker scripts in general, but that's also a reasonable question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think I made a similar point when I looked through this, that the invocation should be similar.
@jrose-apple linker scripts are not supported on Windows, but this isn't a linker script, it is a response file, which is supported (link and lld both support it, and those are the only viable linkers atm).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, of course. Thanks, Saleem.
lib/Driver/ToolChains.cpp
Outdated
} | ||
|
||
// Explicitly pass the target to the driver | ||
Arguments.push_back(context.Args.MakeArgString("--target=" + getTriple().str())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You already have this above.
lib/Driver/ToolChains.cpp
Outdated
Arguments.push_back(context.Args.MakeArgString(LibProfile)); | ||
Arguments.push_back(context.Args.MakeArgString( | ||
Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do all of these things work on Windows?
lib/Driver/ToolChains.cpp
Outdated
@@ -1690,7 +1954,7 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job, | |||
Arguments.push_back("-lswiftCore"); | |||
} | |||
|
|||
// Explicitly pass the target to the linker | |||
// Explicitly pass the target to the driver |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"the driver" means "the Swift driver" in this context. If you don't like "the linker", please just say "Clang" here.
lib/Driver/ToolChains.cpp
Outdated
bool shared = true | ||
) { | ||
// Sanitizer runtime libraries requires C++. | ||
Arguments.push_back("-lc++"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't everything need C++, not just the sanitizers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is copied across from the Darwin implementation. I haven't had a chance (yet) to test the sanitisers, but everything else works fine without the -lc++
flag – it might not even be necessary with the sanitisers.
In general, do we want to err on the side of 'untested but might work', or 'only present if it's guaranteed to work,' considering there's a lot on Windows that won't be able to be tested properly for a while?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thoughts are that no one will ever remove something unnecessary, but they will add what's necessary. Therefore I'd rather err on the minimal side.
I've just run |
lib/Driver/ToolChains.cpp
Outdated
@@ -1104,6 +1113,12 @@ getSanitizerRuntimeLibNameForDarwin(StringRef Sanitizer, | |||
+ (shared ? "_dynamic.dylib" : ".a")).str(); | |||
} | |||
|
|||
static std::string getSanitizerRuntimeLibNameForWindows( | |||
StringRef Sanitizer, const llvm::Triple &Triple, bool shared = true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shared is an unused parameter.
lib/Driver/Driver.cpp
Outdated
return llvm::make_unique<toolchains::Cygwin>(driver, target); | ||
} else { | ||
return llvm::make_unique<toolchains::Windows>(driver, target); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary braces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This matches the target.isAndroid
conditional above. What's the Swift project style on this? Should I change both of them to remove the braces?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're based on LLVM style, which says no braces for single-line if-statements. We swing pretty heavily on the side of having them whenever it's a grey area, though:
- If you have comments inside the body, provide the braces.
- If the line wraps, people usually provide the braces.
- If another branch of the
if
has braces, people usually add braces to all of them. - If the condition wraps, sometimes people provide braces.
lib/Driver/ToolChains.cpp
Outdated
const ToolChain &TC, | ||
bool shared = true) { | ||
// Sanitizer runtime libraries requires C++. | ||
Arguments.push_back("-lc++"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This naming is still wrong. Plus, what if Im using msvcprt
for the C++ runtime?
lib/Driver/ToolChains.cpp
Outdated
if (auto toolchainClang = | ||
llvm::sys::findProgramByName("clang++", {toolchainPath})) { | ||
Clang = context.Args.MakeArgString(toolchainClang.get()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use clang++
, we shouldn't be adding the C++ runtime link.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that we should always do a findProgramByName
for clang++. That way when you do -v
you can see which clang is being used.
lib/Driver/ToolChains.cpp
Outdated
} else if (context.Args.hasFlag(options::OPT_static_stdlib, | ||
options::OPT_no_static_stdlib, false)) { | ||
staticStdlib = true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialize the variables at declaration time rather than the separate conditional?
lib/Driver/ToolChains.cpp
Outdated
bool staticExecutable = context.Args.hasFlag( | ||
options::OPT_static_executable, options::OPT_no_static_executable, false); | ||
bool staticStdlib = context.Args.hasFlag( | ||
options::OPT_static_stdlib, options::OPT_no_static_stdlib, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't exactly equivalent: previously staticExecutable
implied !staticStdlib
. But that doesn't actually make sense to me; shouldn't it be the other way around?
I was playing around with the different options and seeing if I could test the different With regards to the I believe I've addressed the other concerns. Whether we should be using |
Can you please add some tests to ensure that the various codepaths generate the proper tool invocations? |
Sure. I've briefly looked through test/Driver and there's quite a lot in there – this is the first functionality I've added to Swift so I'm not familiar with the all the testing commands and output check tools. Is there anywhere in particular you could point me to for other platforms that would be a good starting point? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some tests to add to / steal from:
- Driver/linker.swift has a bunch of simple link lines just to test that we get to linking at all
- Driver/linker-autolink-extract.swift probably works unmodified with a Windows triple
- Driver/sdk.swift could be relevant
- Driver/sanitizers.swift is probably worth adding to, since you included sanitizer logic here
lib/Driver/ToolChains.cpp
Outdated
const JobContext &context) const { | ||
InvocationInfo II = ToolChain::constructInvocation(job, context); | ||
|
||
return II; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just take this out if we're not going to be doing anything with it right now.
I've added tests in those files and fixed a couple of other small issues I've found. All of the tests pass locally. Is there anywhere I've missed coverage? |
Checking back on this PR - are we okay to merge this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good from my end. Saleem?
lib/Option/SanitizerOptions.cpp
Outdated
@@ -139,7 +139,7 @@ OptionSet<SanitizerKind> swift::parseSanitizerArgValues( | |||
} | |||
|
|||
// Sanitizers are only supported on Linux or Darwin. | |||
if (!(Triple.isOSDarwin() || Triple.isOSLinux())) { | |||
if (!(Triple.isOSDarwin() || Triple.isOSLinux() || Triple.isOSWindows())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment here is no longer valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now changed this to "Check that we're one of the known supported targets for sanitizers."
lib/Driver/ToolChains.cpp
Outdated
@@ -1025,6 +1025,15 @@ static void getClangLibraryPathOnDarwin(SmallVectorImpl<char> &libPath, | |||
llvm::sys::path::append(libPath, "clang", "lib", "darwin"); | |||
} | |||
|
|||
static void getClangLibraryPathOnWindows(SmallVectorImpl<char> &libPath, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm starting to think this needs refactoring, but I won't make you do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be happy to take a look at splitting up this file and refactoring some of the common functionality in an NFC follow-up PR – I think there's some fairly straightforward things that would help.
e2e36aa
to
5cbc83c
Compare
I've updated this PR to include static linking support, since I now have that working locally on Windows. I also added Note that it's not possible to directly test the static linking (as per test/Driver/static-stdlib) yet since there are still some changes to be made before building the static libraries actually works. I've tested the invocations locally with some workarounds, though. I can squash these commits before it's merged if that's helpful. |
ac026e1
to
3ec1f9e
Compare
@compnerd Does this look okay to you now? |
@jrose-apple If @compnerd doesn't have any complaints, are we okay to merge this? There've been a couple of small changes (static linking support and adding the COFF registration object) since you likely last looked at it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't see anything that raises any flags for me. Yes, if Saleem's good I'm good. Thanks, Thomas.
lib/Driver/ToolChains.cpp
Outdated
getRuntimeStaticLibraryPath(StaticRuntimeLibPath, context.Args, *this); | ||
|
||
// Since Windows has separate libraries per architecture, link against the | ||
// architecture specific version of the static library. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should getRuntimeStaticLibraryPath
just do this? Are there places where we call it and need it to not do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Windows is the only place we currently add the arch that I can see. I think on Darwin universal binaries are produced and copied to the lib/swift_static/platform folder; on Linux, I think the current assumption is that only one architecture will ever be present per platform, and so just using the copied libraries is fine (although probably not technically correct).
On Windows, the files in that folder are (currently) just the static libraries for whichever arch was built last, so linking against that is definitely incorrect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks right. Once that's merged we can remove the extra code here and just use getRuntimeStaticLibraryPathWithArch
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, sorry. I've been busying in a bit of freeze with all the code I posted in all the PRs in December to take them and try and cut and stabilize a usable toolchain to ship in Fuchsia. Everything is getting to a good place with that toolchain so I should have more time to switch back and rebase all my PRs to get them ready to land upstream easier (and so I can get a new toolchain going with changes since the 4.1 branch).
lib/Driver/ToolChains.cpp
Outdated
+ getTriple().getArchName())); | ||
|
||
Arguments.push_back("-Xlinker"); | ||
Arguments.push_back("/NODEFAULTLIB:libcmt"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you leave a comment for why this is necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done; I've been specific to the degree I understand the problem, which I admit is not fully.
I'm not actually certain it'll be necessary in the future (it may just be an artefact of how static libraries are currently produced for Windows), but for now adding that flag avoids the mentioned issues. @compnerd would probably have a better idea as to why it's needed.
As an example, some of the errors it avoids are:
/usr/bin/lld-link: error: swiftCore.lib(Exclusivity.cpp.o): undefined symbol: __imp__wassert
/usr/bin/lld-link: warning: swiftCore.lib(Metadata.cpp.o): locally defined symbol imported: free (defined in libucrt.lib(free.obj))
@troughton - any chance you can rebase/squash the patches into a coherent patch? |
@compnerd I'll take a look – I should have some time to do that today. While you're around, can you quickly look at the |
814501a
to
23308c8
Compare
@compnerd Provided this all looks okay to you, we should be ready to test and merge. |
23308c8
to
7ff63b9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please clang-format
the diff
lib/Driver/ToolChains.cpp
Outdated
} | ||
if (!Linker.empty()) { | ||
Arguments.push_back(context.Args.MakeArgString("-fuse-ld=" + Linker)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The braces are unnecessary.
lib/Driver/ToolChains.cpp
Outdated
if (auto toolchainClang = | ||
llvm::sys::findProgramByName("clang++", {toolchainPath})) { | ||
Clang = context.Args.MakeArgString(toolchainClang.get()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that we should always do a findProgramByName
for clang++. That way when you do -v
you can see which clang is being used.
lib/Driver/ToolChains.cpp
Outdated
// | ||
// To avoid this, we specify that libcmt should not be linked against. | ||
Arguments.push_back("-Xlinker"); | ||
Arguments.push_back("/NODEFAULTLIB:libcmt"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems wrong. We should be building with -MT
or -MD
appropriately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed this for now. Removing it will break building apps (in my case), but I think its presence is symptomatic of a bigger issue: how do we decide which library is appropriate?
Currently, it's whatever the standard library is linked against, but I don't think that's right; rather, it should be determined based on the product we're building. Is the right solution to build the standard library with undefined symbols that are resolved once it's linked with the final Swift executable/library?
lib/Driver/ToolChains.cpp
Outdated
} | ||
|
||
if (!context.OI.SDKPath.empty()) { | ||
Arguments.push_back("--sysroot"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like it won't work. The toolchain for x86_64-unknown-windows-msvc
does not support --sysroot
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've replaced --sysroot
with -I
.
Pretty excited about this, I think that this will help with getting the IRGen tests passing, and I can look into fixing the rest of the Driver tests as well. |
7ff63b9
to
d99bb5d
Compare
Let's go ahead and merge this and then we can improve it from there. @swift-ci please test |
Build failed |
Build failed |
d99bb5d
to
509b1ff
Compare
The build failure above appears to be unrelated, but I'd missed a test when I changed |
@swift-ci Please test |
Build failed |
Build failed |
509b1ff
to
d0be952
Compare
d0be952
to
5bb6ac2
Compare
The I've removed the changes to the |
|
Build failed |
@swift-ci please test |
In this PR, I've implemented an initial Windows toolchain that has been tested to work in cross-compiling from Linux to Windows.
When combined with #13140, this enables an invocation like:
to produce a Windows executable (note that the executable itself will still run into separate issues).
I've followed the pattern of the
GenericUnix
toolchain here, which does mean there's currently a fair amount of code duplication. I don't know how much will need to change for native builds, and nor do I know how many of the extra arguments (such as ASAN or producing a static executable) will work as-is. However, I thought that Windows is sufficiently different enough from the existing OSes to justify its own toolchain and expect it to diverge further as it is expanded, making this a good starting point.