Beginning support for ARMv7 hosts (RasPi, etc.) #439
Conversation
set(SWIFT_PRIMARY_VARIANT_SDK_default "LINUX") | ||
set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64") | ||
|
||
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64") |
gribozavr
Dec 11, 2015
Collaborator
Please leave a comment here that this only works for building a host compiler, and won't work for building cross-compilers.
Please leave a comment here that this only works for building a host compiler, and won't work for building cross-compilers.
@@ -216,7 +216,7 @@ extern "C" long double _swift_fmodl(long double lhs, long double rhs) { | |||
// This implementation is copied here to avoid a new dependency | |||
// on compiler-rt on Linux. | |||
// FIXME: rdar://14883575 Libcompiler_rt omits muloti4 | |||
#if __arm64__ || !defined(__APPLE__) | |||
#if (__arm64__ || !defined(__APPLE__)) && !defined(__arm__) |
gribozavr
Dec 11, 2015
Collaborator
Let's be more explicit in this list:
#if (defined(__APPLE__) && defined(__arm64__)) || \
(defined(__linux__) && defined(__x86_64__))
Let's be more explicit in this list:
#if (defined(__APPLE__) && defined(__arm64__)) || \
(defined(__linux__) && defined(__x86_64__))
@@ -12,16 +12,18 @@ | |||
// RUN: FileCheck -check-prefix watchOS_SIMPLE %s < %t.simple.txt | |||
|
|||
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-unknown-linux-gnu -Ffoo -framework bar -Lbaz -lboo -Xlinker -undefined %s 2>&1 > %t.linux.txt | |||
// RUN: FileCheck -check-prefix LINUX %s < %t.linux.txt | |||
// RUN: FileCheck -check-prefix LINUXx86 %s < %t.linux.txt |
gribozavr
Dec 11, 2015
Collaborator
Could you name this prefix LINUX-x86_86
?
Could you name this prefix LINUX-x86_86
?
// RUN: FileCheck -check-prefix LINUXx86 %s < %t.linux.txt | ||
|
||
// RUN: %swiftc_driver -driver-print-jobs -target armv7-unknown-linux-gnueabihf -Ffoo -framework bar -Lbaz -lboo -Xlinker -undefined %s 2>&1 > %t.linux.txt | ||
// RUN: FileCheck -check-prefix LINUXarm %s < %t.linux.txt |
gribozavr
Dec 11, 2015
Collaborator
Ditto, LINUX-arm
?
Ditto, LINUX-arm
?
@@ -657,6 +657,56 @@ elif run_os == 'linux-gnu': | |||
"ld -L%s" % | |||
(os.path.join(test_resource_dir, config.target_sdk_name))) | |||
|
|||
elif run_os == 'linux-gnueabihf': |
gribozavr
Dec 11, 2015
Collaborator
What is the difference between this block and the previous block? Can it be factored with 'if' statements instead of code duplication?
What is the difference between this block and the previous block? Can it be factored with 'if' statements instead of code duplication?
@@ -227,6 +227,9 @@ function set_deployment_target_based_options() { | |||
linux-x86_64) | |||
SWIFT_HOST_VARIANT_ARCH="x86_64" | |||
;; | |||
linux-armv7) | |||
SWIFT_HOST_VARIANT_ARCH="ARM" |
gribozavr
Dec 11, 2015
Collaborator
It should be armv7
.
It should be armv7
.
gribozavr
Dec 11, 2015
Collaborator
armv7-gnueabihf
eventually.
armv7-gnueabihf
eventually.
There are soft float and hard float variants of armv7 ABI (and even multiple variants of those, IIRC). To ensure that the arm port is future-proof, the architecture name here needs to be something like |
@@ -1115,8 +1115,13 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job, | |||
// Add the linker script that coalesces protocol conformance sections. | |||
Arguments.push_back("-Xlinker"); | |||
Arguments.push_back("-T"); | |||
Arguments.push_back( | |||
context.Args.MakeArgString(Twine(RuntimeLibPath) + "/x86_64/swift.ld")); | |||
#if defined(__arm__) |
gribozavr
Dec 11, 2015
Collaborator
Swift is a cross-compiler, we don't do #if
s in the C++ sources. Please query the target and use the correct path. getTriple().getArchName()
, I think, but it should also include the gnueabihf
suffix, so please leave a fixme for that.
Swift is a cross-compiler, we don't do #if
s in the C++ sources. Please query the target and use the correct path. getTriple().getArchName()
, I think, but it should also include the gnueabihf
suffix, so please leave a fixme for that.
In general this looks good to me, please fix those issues and I'll merge. |
With this comment: "There are soft float and hard float variants of armv7 ABI (and even multiple variants of those, IIRC). To ensure that the arm port is future-proof, the architecture name here needs to be something like armv7-gnueabihf to allow other variants. This is not necessarily something you need to worry about right now, but could you file an issue about taking care of that in future, when the port is in a better shape?" It's not clear with block of code you're referring to. You're absolutely correct that I have made no attempt to correctly handle soft-float versions, or any other abis, for that matter. I'd like to learn more about how the target triples are passed through the build scripts so that these are correctly handled, as well as eventual hope for cross-compiling. I've implemented all of your suggestions (thank you for them!), and I'll let you know when I finish testing it all again. |
I'm referring to the code in general, where it uses
Currently we don't have anything like hard/soft variants for any of the supported architectures, so there isn't anything you can look at. The first approximation would be to just use |
// FIXME: This should also query the abi type (i.e. gnueabihf) | ||
if (getTriple().getArch() == llvm::Triple::arm) { | ||
Arguments.push_back( | ||
context.Args.MakeArgString(Twine(RuntimeLibPath) + "/armv7/swift.ld")); |
gribozavr
Dec 12, 2015
Collaborator
Why not just concatenate in getTriple().getArchName()
? Or does it return something strange? If that's the case, convert the if
chain to switch.
Why not just concatenate in getTriple().getArchName()
? Or does it return something strange? If that's the case, convert the if
chain to switch.
context.Args.MakeArgString(Twine(RuntimeLibPath) + "/x86_64/swift.ld")); | ||
|
||
// FIXME: This should also query the abi type (i.e. gnueabihf) | ||
Arguments.push_back(context.Args.MakeArgString( |
gribozavr
Dec 12, 2015
Collaborator
Indentation on this line is off.
Indentation on this line is off.
set(SWIFT_PRIMARY_VARIANT_SDK_default "LINUX") | ||
set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64") | ||
|
||
# FIXME: This will not work while trying to cross-compile |
gribozavr
Dec 12, 2015
Collaborator
Indentation of the comment is off.
Indentation of the comment is off.
// LINUX-armv7-DAG: -lswiftCore | ||
// LINUX-armv7-DAG: -L [[STDLIB_PATH:[^ ]+/lib/swift]] | ||
// LINUX-armv7-DAG: -Xlinker -rpath -Xlinker [[STDLIB_PATH]] | ||
// LINUX-armv7-DAG: -Xlinker -T /{{[^ ]+}}/linux/arm/swift.ld |
gribozavr
Dec 12, 2015
Collaborator
This line needs to say .../armv7/swift.ld
This line needs to say .../armv7/swift.ld
gribozavr
Dec 12, 2015
Collaborator
Hm, interesting. On OS X that test fails with that symptom, but on Linux x86-64 it passes.
Hm, interesting. On OS X that test fails with that symptom, but on Linux x86-64 it passes.
gribozavr
Dec 12, 2015
Collaborator
Ah, no, it does not pass because the whole file is // XFAIL: linux
.
Feel free to factor out Linux-specific or Apple-specific parts into a separate file to increase test coverage.
Ah, no, it does not pass because the whole file is // XFAIL: linux
.
Feel free to factor out Linux-specific or Apple-specific parts into a separate file to increase test coverage.
The patch LGTM with those few issues fixed. May I also ask you to squash the commits? |
configure_sdk_unix(LINUX "Linux" "linux" "linux" "x86_64" "x86_64-unknown-linux-gnu") | ||
set(SWIFT_HOST_VARIANT_ARCH "x86_64") | ||
set(SWIFT_PRIMARY_VARIANT_ARCH_default "x86_64") | ||
else() |
gribozavr
Dec 12, 2015
Collaborator
Could you make an explicit branch based on the CMAKE_SYSTEM_PROCESSOR
value? This will simplify adding further ports.
Could you make an explicit branch based on the CMAKE_SYSTEM_PROCESSOR
value? This will simplify adding further ports.
hpux735
Dec 12, 2015
Author
Contributor
I believe that I've done this, but it's not clear from the pull request (apple:master hpux735:master) that it has been completed. Let me know if I need to try again.
I believe that I've done this, but it's not clear from the pull request (apple:master hpux735:master) that it has been completed. Let me know if I need to try again.
gribozavr
Dec 12, 2015
Collaborator
Sorry for being unclear, I meant instead of else()
assuming armv7
using an explicit value here.
Sorry for being unclear, I meant instead of else()
assuming armv7
using an explicit value here.
case "$(uname -s)" in | ||
Linux) | ||
# FIXME: This will not work while trying to cross-compile | ||
# It gets the architecture from the system processor arch. |
timbodeit
Dec 12, 2015
Contributor
Can you elaborate on what you mean by this?
The way I understand it, the processor architecture of the build machine is exactly what we'd want here.
Or what exactly is the issue while cross compiling?
Can you elaborate on what you mean by this?
The way I understand it, the processor architecture of the build machine is exactly what we'd want here.
Or what exactly is the issue while cross compiling?
hpux735
Dec 12, 2015
Author
Contributor
Excellent point, you're right. I've removed the comment. It's not collapsing this change in the pull request view, because I moved this development into the armv7 branch, and it's unclear to me how PRs work with branches that only exist on one fork.
Excellent point, you're right. I've removed the comment. It's not collapsing this change in the pull request view, because I moved this development into the armv7 branch, and it's unclear to me how PRs work with branches that only exist on one fork.
timbodeit
Dec 12, 2015
Contributor
You can choose a head branch when opening the pull request. The changes on this head branch (in your case master) will be tracked in the pull request.
Normally, I create a separate branch for each pull-request before opening it.
So, you'd either have to continue working on your master or close and resubmit the pull request with your armv7
branch selected as the HEAD. I don't think it's possible to change the head branch once a pull request has been created.
You can choose a head branch when opening the pull request. The changes on this head branch (in your case master) will be tracked in the pull request.
Normally, I create a separate branch for each pull-request before opening it.
So, you'd either have to continue working on your master or close and resubmit the pull request with your armv7
branch selected as the HEAD. I don't think it's possible to change the head branch once a pull request has been created.
gribozavr
Dec 12, 2015
Collaborator
Yes, I think this comment can be removed.
Yes, I think this comment can be removed.
case "$(uname -s)" in | ||
Linux) | ||
# FIXME: This will not work while trying to cross-compile | ||
# It gets the architecture from the system processor arch. |
timbodeit
Dec 12, 2015
Contributor
I think this one can be removed as well.
I hope I am understanding this correctly. Would be good if someone else could confirm my logic:
STDLIB_DEPLOYMENT_TARGETS
specifies all targets that the native build machine is capable of building.
See how Darwin \x86_64
contains the iphoneos-arm
targets?
This means, that a Darwin\ x86_64
build machine is able to (cross-)compile for all of the listed targets.
I think this one can be removed as well.
I hope I am understanding this correctly. Would be good if someone else could confirm my logic:
STDLIB_DEPLOYMENT_TARGETS
specifies all targets that the native build machine is capable of building.
See how Darwin \x86_64
contains the iphoneos-arm
targets?
This means, that a Darwin\ x86_64
build machine is able to (cross-)compile for all of the listed targets.
gribozavr
Dec 12, 2015
Collaborator
Right.
Right.
Thank you, merging! |
Beginning support for ARMv7 hosts (RasPi, etc.)
Does this mean that now, we will be able to program in Swift on Raspberry Pi? |
Thanks Dmitri! I appreciate all of your comments! We're getting close, Trevor. Swiftc can make executable files, but there is a remaining problem in the linker part of the process, so they can't run just yet. |
This comment has been minimized.
This comment has been minimized.
Is there a binary build somewhere to try out? |
This comment has been minimized.
This comment has been minimized.
I'm not sure how to package it up yet, but I'll look into it. The executables that swiftc makes don't run yet, so a binary build isn't all that useful. This is more of a starting point to fixing that last problem. |
This comment has been minimized.
This comment has been minimized.
Great, thx; a tarball similar to what rust offers (unofficially) should be enough to play with. |
Arguments.push_back( | ||
context.Args.MakeArgString(Twine(RuntimeLibPath) + "/x86_64/swift.ld")); | ||
|
||
// FIXME: This should also query the abi type (i.e. gnueabihf) |
modocache
Dec 14, 2015
Collaborator
@hpux735 @gribozavr Sorry if I'm missing something, but would something like the following work?
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 712ea65..872843a 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -1115,10 +1115,11 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
// Add the linker script that coalesces protocol conformance sections.
Arguments.push_back("-Xlinker");
Arguments.push_back("-T");
-
- // FIXME: This should also query the abi type (i.e. gnueabihf)
+
Arguments.push_back(context.Args.MakeArgString(
- Twine(RuntimeLibPath) + "/" + getTriple().getArchName() + "/swift.ld"));
+ Twine(RuntimeLibPath) + "/" + getTriple().getArchName() + \
+ llvm::Triple::getEnvironmentTypeName(getTriple().getEnvironment()) + \
+ "/swift.ld"));
// This should be the last option, for convenience in checking output.
Arguments.push_back("-o");
@hpux735 @gribozavr Sorry if I'm missing something, but would something like the following work?
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 712ea65..872843a 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -1115,10 +1115,11 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
// Add the linker script that coalesces protocol conformance sections.
Arguments.push_back("-Xlinker");
Arguments.push_back("-T");
-
- // FIXME: This should also query the abi type (i.e. gnueabihf)
+
Arguments.push_back(context.Args.MakeArgString(
- Twine(RuntimeLibPath) + "/" + getTriple().getArchName() + "/swift.ld"));
+ Twine(RuntimeLibPath) + "/" + getTriple().getArchName() + \
+ llvm::Triple::getEnvironmentTypeName(getTriple().getEnvironment()) + \
+ "/swift.ld"));
// This should be the last option, for convenience in checking output.
Arguments.push_back("-o");
gribozavr
Dec 14, 2015
Collaborator
I think so, with a dash in between.
I think so, with a dash in between.
modocache
Dec 14, 2015
Collaborator
Awesome. I'll send a pull request; there's also a test that needs updating.
Awesome. I'll send a pull request; there's also a test that needs updating.
hpux735
Dec 14, 2015
Author
Contributor
I think you’ll need to update the location where the stdlib is built into, otherwise the paths won’t match. I tried this last night.
On Dec 14, 2015, at 7:25 AM, Brian Gesiak notifications@github.com wrote:
In lib/Driver/ToolChains.cpp #439 (comment):
@@ -1115,8 +1115,10 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
// Add the linker script that coalesces protocol conformance sections.
Arguments.push_back("-Xlinker");
Arguments.push_back("-T");
- Arguments.push_back(
-
context.Args.MakeArgString(Twine(RuntimeLibPath) + "/x86_64/swift.ld"));
- // FIXME: This should also query the abi type (i.e. gnueabihf)
Awesome. I'll send a pull request; there's also a test that needs updating.
—
Reply to this email directly or view it on GitHub https://github.com/apple/swift/pull/439/files#r47509595.
I think you’ll need to update the location where the stdlib is built into, otherwise the paths won’t match. I tried this last night.
On Dec 14, 2015, at 7:25 AM, Brian Gesiak notifications@github.com wrote:
In lib/Driver/ToolChains.cpp #439 (comment):
@@ -1115,8 +1115,10 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
// Add the linker script that coalesces protocol conformance sections.
Arguments.push_back("-Xlinker");
Arguments.push_back("-T");
- Arguments.push_back(
context.Args.MakeArgString(Twine(RuntimeLibPath) + "/x86_64/swift.ld"));
- // FIXME: This should also query the abi type (i.e. gnueabihf)
Awesome. I'll send a pull request; there's also a test that needs updating.—
Reply to this email directly or view it on GitHub https://github.com/apple/swift/pull/439/files#r47509595.
hpux735
Dec 14, 2015
Author
Contributor
I think it's a good idea, but there's just one more piece to the puzzle. :)
I think it's a good idea, but there's just one more piece to the puzzle. :)
@petevine I've finally finished a downloadable package for a working (but still very alpha) swift compiler and Foundation for ARM: http://www.housedillon.com/?p=2287 |
Thanks, I'll give it a try on my Odroid. EDIT:
What variables can be set to provide (presumably) the correct search paths? |
I didn't get the exact same error message, but it doesn't work for me, either. |
No problem if it's a bug and not user error. Depending on the absence/presence of
after unpacking your distro in /tmp |
I think it’s just as likely that I don’t know how to make the distribution package correctly. Joe Bell is looking into making a debian repository for publishing this. Hopefully he’s able to make that work a little better. I definitely like having things in the issue tracker. Even if it ends up being user error, no worries, it can just be closed. Otherwise, I’m very likely to forget all the different little issues that people mention to me. The latter is a much worse outcome! :)
|
@petevine Try out the package just posted at http://dev.iachieved.it/iachievedit/debian-packages-for-swift-on-arm/, both snippets of Swift code at the bottom of the post work on BeagleBone Black and BeagleBoard X15. I need to run out and get me a RaspPi 2, oddly enough I don't own one yet. |
I'll need a direct link as I'm not interested in installing system-wide. Thx. |
You can use
|
Thx, that's exactly what I had in mind. I'll let you know as soon as I've tried it out. EDIT: |
Yah, I’m very confused. I can’t reproduce this bug. On my fresh install (are you using Ubuntu or Debian?), it works fine when I install at /opt/apple. The file you’re seeing in /tmp is generated by the build process. A huge part of the swift build process is clang. Can you paste in your source code, just in case?
|
It's Ubuntu 14.04 so that probably means clang is not getting installed correctly. Code is just one line: Could you paste your Mine looks like this:
|
@petevine I am on Ubuntu 14.04 as well, here is my version of Clang and
Of course I can't reproduce your issue either, and I've installed the package on 3 different ARM systems, all armv7l based. |
The only apparent difference is gcc 4.9 on my system. Could you attach a strace from a successful compilation? |
Yep, sure thing: http://ramone.coas.oregonstate.edu/hello.trace |
I'm fairly certain that this is a duplicate of this bug: https://bugs.swift.org/browse/SR-23 and is not an Arm specific thing. |
@hpux735 That's definitely not a successful compilation! (source file didn't exist) If the issue is not ARM-specific, never mind - I'll have a go at swift when it's ready. |
Oops. I updated it. Also note that I don’t think that it’s tracing the clang invocation. That’s likely where the issue really is.
|
I'm almost finished with enabling native compilation on ARMv7 hosts such as the Raspberry Pi, BeagleBone, Nvidia Tegras, etc...
The build of the swift compiler and standard library complete. The compiler is also capable of generating executables, though there is a remaining linker problem. I'm not sure where to move from here, so I'm hoping that this work can be a starting point for some. The error is: unexpected reloc type 0x03
I've tested this patch in attempt to determine whether it negatively effects building on MacOS or Ubuntu 15.10 on x68_64. In MacOS, the test suite completes with 2 unexpected failures, 2350 expected passes, 5 expected failures, and 33 unsupported tests. The x86_64 linux build completes with 1682 expected passes, 92 expected failures, 575 unsupported failures (apparently no unexpected failures). Finally, the linux arm port completes the testing suite with 1456 expected passes, 81 expected failures, 639 unsupported tests, and 155 unexpected failures.
I'm happy to make any changes to requested, and I'd be overjoyed if anyone had a crumb trail I could follow to address the linking issued.
Any comments are very appreciated!