-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Added -toolchain option to swiftc #2912
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
Looks reasonable to me. The change needs tests though. CC @jrose-apple.
With this change, we are still going through the system Clang, right? This does not sound right to me because the system Clang might not even know about our target. (For example, if the toolchain for the target uses a fork of Clang.) |
We're still going through system Clang, just passing the Without this change, this is what happens when trying to cross-compile any executable:
Note the call to |
I understand. What I am saying is that the system Clang might not even know about the target, so we should prefer the Clang from the toolchain, if it exists. |
You mean like this? (needs tests of course) |
427b49c
to
3bfa8d8
Compare
@karwa Yes, exactly! Thank you! |
// BINUTILS-DAG: [[OBJECTFILE]] | ||
// BINUTILS-DAG: @[[AUTOLINKFILE]] | ||
// BINUTILS-DAG: -B {{[^ ]+}}/Inputs/fake-toolchain | ||
// BINUTILS: -o 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.
Could you add a newline here?
@swift-ci Please test |
Haven't had a chance to look at the code yet, but I'm concerned about overloading the term "toolchain". There's the classic compiler tools meaning, and then there's the Xcode meaning, which we've adopted on swift.org. They're related but refer to very different levels in the directory structure. |
@@ -87,12 +87,12 @@ class ToolChain { | |||
|
|||
/// Packs together information chosen by toolchains to create jobs. | |||
struct InvocationInfo { | |||
const char *ExecutableName; | |||
StringRef ExecutableName; |
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 was deliberately a char *
to show that it was null-terminated. If you're removing that guarantee, you need to update the uses of 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.
@jrose-apple If I'm not removing that guarantee, would a comment and some assertions suffice?
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, we've gotten into trouble here before. No StringRef should ever be assumed null-terminated. What's wrong with char *
?
I know it's not a good long-term solution, but is there anything wrong with setting PATH for now? |
Fixed test. We can rename it from |
Sorry, I meant "I know setting PATH is not a good long-term solution". I just wanted to know how blocking this is. |
Well, I only really only need it for LLDB (maybe swiftpm, too), and I'm only cross-compiling for Since the only bit of binutils we need is the linker, and LLD seems to be making such great progress that we can imagine a day when we won't even need that, the clang lookup is probably the most long-term useful part. If even that isn't all that useful, I can drop it and keep the |
I'm wondering about other binutils. |
Speaking of dsymutil on Linux: dsymutil was recently (10 months ago, http://llvm.org/viewvc/llvm-project?view=revision&revision=244270) added to LLVM, but it's called EDIT: Oh no, Sure, we could add lookup support for |
I guess my point is that if this is really just about the linker and it doesn't affect any other tools, maybe we should name it as such. Do we expect it to stay just the linker, or potentially grow to other tools in the future? (BTW, the code comment about |
e062bbd
to
99a4f72
Compare
Random question, but did you consider having -toolchain point to a JSON file that describes the toolchain, rather than a path? That seems like a more generally extensible and customizable design. |
For example, I think it could be cool to be able to use something like: and have the compiler look for "beagleboard.toolchain" in a directory next to the swift executable (or some system location), then in your home directory, etc. Of course an absolute path to a toolchain file should also work. The toolchain file could have paths to all of the components that make up the toolchain as well as specify configuration options to specify the "kind" of component each is.
|
I think that's a bit overengineering. In the common case, people do organize their toolchains by directory; in the uncommon case, you can fake it with symlinks. |
I agree... if it turns out we need more metadata about a toolchain to do nice things automatically, I think it would make more sense to establish a convention for embedding the metadata in a file inside the toolchain, so users can still refer to the toolchain by path. This is essentially what we already do on Darwin platforms (and then that metadata has identifiers we have convenient access to), and I could imagine Swift defining a convention for that for Linux along with associated tools to use them. I agree with @lattner that the general features this enables are useful in the long run. For example, a current desired feature for SwiftPM that our users want/need is easy access to "cross compiling" to other toolchains, so they can use a newer |
@lattner @ddunbar This was always a kind of expert feature in the past, but the proliferation of computing and rich, embedded, accessible devices makes it something the average user might desire to do. Cross-compiling for a Raspberry Pi (linux-armv7) is no more an "advanced" feature than cross-compiling for iOS; it's just easier because of Apple's well-structured toolchain and the fact you can only do it from OSX. When it comes to "toolchain bundles" specifically, it is something we really should move to. I have actually been planning to introduce something like that for the build system, but of course the same challenge could be met with the same solution for cross-compiling other Swift code besides the standard library. Currently we have some... Undesirable things in CMake as a result - for example, we have include paths for Android hardcoded in
The biggest challenges we have for cross-compiling right now:
|
c02a6a0
to
95a454b
Compare
@@ -951,7 +951,21 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job, | |||
const Driver &D = getDriver(); | |||
const llvm::Triple &Triple = getTriple(); | |||
|
|||
InvocationInfo II{"ld"}; | |||
// Configure the 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.
Style nitpick: please end sentences in comments with periods.
Okay, looking good! I have a few last comments (mostly about the tests) but I think we're ready to merge. @modocache, @compnerd, @ddunbar? |
@@ -133,6 +133,10 @@ def j : JoinedOrSeparate<["-"], "j">, Flags<[DoesNotAffectIncrementalBuild]>, | |||
def sdk : Separate<["-"], "sdk">, Flags<[FrontendOption]>, | |||
HelpText<"Compile against <sdk>">, MetaVarName<"<sdk>">; | |||
|
|||
def tools_directory : Separate<["-"], "tools-directory">, | |||
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>, | |||
HelpText<"Look for external executables (ld, clang, binutils) in <toolchain>">, MetaVarName<"<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.
Would be nice to change the MetaVarName
to directory
.
And for the heck of it: @swift-ci Please test |
d6481a5
to
7f6fa34
Compare
…d (Darwin), or clang/binutils (Unix)
7f6fa34
to
0e32d15
Compare
@jrose-apple Feedback addressed. |
@swift-ci Please smoke test |
@swift-ci Please Python lint |
@jrose-apple tests seem good (but swiftci didn't report back here for some reason). We all clear, then? |
The Linux tests failed, even though it's probably not related. Let's just run again. @swift-ci Please smoke test |
Merged. Thanks for sticking with this one, @karwa! |
Provides a path to look for ld (Darwin), or clang/binutils (Unix).
[swift-3.0] Added -tools-directory option. (#2912)
What's in this pull request?
Added a
-toolchain
swiftc option. This works like clang/gcc's-B
flag (which allows specifying an alternate toolchain location). We need to be able to cross-compile executables in order to cross-compile the LLDB swift REPL. Since I believe it's only relevant for cross-compilers, I've made it aswiftc
-only option (are there any use-cases for running the interpreter with an alternate toolchain?)Currently, you can cross-compile with swift (assuming you've got a copy of the standard library compiled for the target), like so:
However, this only works for modules (swiftmodules), not for executables. The host swift generates a link command to the system clang++ with
-fuse-ld=gold
(or whatever is the correct linker for the target platform), but there is currently no way to tell it where to find the cross-linker. Normally, you would put this information behind the-B
switch, so we provide the same kind of functionality here.Adding
-toolchain ${gcc-toolchain-path}
to the above command allows swift to cross-compile an executable.This was previously suggested as
-Blinker
(#2483) and I thought it was resolved by the update to clang accepting absolute linker paths, however there are two reasons why that isn't true:So in short a
toolchain
flag is more flexible, and more compatible.Resolved bug number: (SR-)
Before merging this pull request to apple/swift repository:
Triggering Swift CI
The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:
Smoke Testing
Validation Testing
Lint Testing
Note: Only members of the Apple organization can trigger swift-ci.