-
Notifications
You must be signed in to change notification settings - Fork 10.5k
SR-648: Allow swiftpm to statically link binaries on Linux #9958
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
@jrose-apple can you review this? We would like to get static-stdlib support into SwiftPM for 4 if possible. The build-script changes LGTM, but the driver part I think needs you review (and @spevans it would be good to have a test encoding why this reordering is important, IMHO) |
The re-ordering of the auto link files is because when linking in static libraries and object files the ordering of arguments is important and the dependant libraries need to come after the objects/libs that require them. This is also the reason that the My testing so far has not shown the changes to affect normal dynamic linking either. As for a test case I have a change for swift-corelibs-foundation that adds a static_test target that links the TestFoundation binary with the static swift libs which can be run manually on linux although I am still running some tests on it and it is not fully finished. |
I meant just a |
Oh I see, yes I should be able to add one for that. |
I think if you're going to change it at all you should put the -Xlinker options all the way at the end. Anything else would run into some other ordering problem later. |
I moved the -Xlinker options as far to the end as was possible without causing the tests to break. This meant they ended up just before the I added a test to check the autolink and linker options are in the correct order. |
Why do they need to be before swift_end.o? We don't expect (Also, why |
I dont know the exact reason they need to be before the
Then it can be invoked as follows: The The |
Ah, my bad on misreading the |
- If --build-swift-static-stdlib option is used then also produce static versions of libXCTest.a and libdispatch.a and put them into the lib/swift_static/linux/ toolchain directory. libFoundation.a is already being built and deployed there. - Binaries with the swift libs statically linked in can then be built with using the command: swift build -Xswiftc -static-stdlib -Xlinker -lcurl -Xlinker -l:libxml2.a -Xlinker -llzma -Xlinker /lib/x86_64-linux-gnu/libz.so.1 -Xlinker -lbsd -Xlinker --allow-multiple-definition Note: This is a dynamic binary with the libswiftCore, libFoundation and libdispatch libraries statically linked in. - Further fixes should reduce the complexity of the above command.
- Reordering the auto link files when linking in static libraries and object files is required because the ordering of arguments is important, and the dependant libraries need to come after the objects/libs that require them. This is not a problem for libswiftCore.a but can be an issue with libs that sit on top of it, e.g. libFoundation.a - Dont add an -rpath to the Swift dynamic libraries if using -static-stdlib
- Move the -Xlinker and -l options to just before swift_end.o - Add testcase to check linker option ordering.
I just realised that I didn't update the build command, it should be:
This is because in this case The You are also correct about being able to use The underlying problem is that Using these link options was only really a halfway stage to show the current progress. If moving the options to the end is an issue I can always revert that one change and use a different method such as extending the |
The |
@swift-ci please smoke test |
@alblue could you rerun the linux one please, from the logs it looks like it might have been a temporary network issue |
@swift-ci please smoke test linux |
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.
All right, I guess I'm okay with this. Thanks for sticking with it, Simon!
// REQUIRES: static_stdlib | ||
print("hello world!") | ||
// RUN: %empty-directory(%t) | ||
// RUN: %target-swiftc_driver -v -static-stdlib -o %t/static-stdlib %s -Xlinker --no-allow-multiple-definition 2>&1| %FileCheck %s |
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 shouldn't need to actually run the linker here. Instead, you can use -###
(or -driver-print-jobs
) to show what would be run. That way we can run the test on other platforms.
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 you want me to update the test? The argument reordering change is only for Linux (actually GenericUnix) so I don't think it will make any difference on other platforms.
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.
Yes, please. GenericUnix is still used in other places, and it's useful to be able to run the test even on Darwin. (Also, not actually compiling and linking would run faster.)
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 Ive added the -driver-print-jobs and removed the linux requirement. It tested ok on Linux and macOS. If the commit looks ok could you rerun the tests please.
- Use -driver-print-jobs to avoid actually building the test file.
// RUN: %target-swiftc_driver -v -static-stdlib -o %t/static-stdlib %s -Xlinker --no-allow-multiple-definition 2>&1| %FileCheck %s | ||
// CHECK: Swift version | ||
// CHECK: Target: x86_64-unknown-linux-gnu | ||
// RUN: %target-swiftc_driver -driver-print-jobs -static-stdlib -o %t/static-stdlib %s -Xlinker --no-allow-multiple-definition 2>&1| %FileCheck %s |
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.
Thanks!
Could someone please run a test on this latest change please |
@swift-ci please smoke test |
@jrose-apple can this be merged now? |
Ah, yes, looks good! Thanks, Simon. |
If you want to bring this into Swift 4.0 branch, please follow the process at https://swift.org/blog/swift-4-0-release-process/. You can mention that this was reviewed by me. |
+1 on getting this into 4. Thanks for your perseverance on this @spevans! |
Turns out the order of the linker flags matters on Linux; see swiftlang#9958. I don’t know if the change I previously made would break something, but it’s not worth risking it.
This PR requires swiftlang/swift-corelibs-foundation#1011 and
swiftlang/swift-corelibs-xctest#190 to be merged beforehand.
If --build-swift-static-stdlib option is used then also produce
static versions of libXCTest.a and libdispatch.a and put them
into the lib/swift_static/linux/ toolchain directory.
libFoundation.a is already being built and deployed there.
Binaries with the swift libs statically linked in can then be
built with using the command:
swift build -Xswiftc -static-stdlib -Xlinker -lcurl -Xlinker -lxml2 -Xlinker -lbsd -Xlinker --allow-multiple-definition
Note: This is a dynamic binary with the libswiftCore, libFoundation and libdispatch libraries statically linked in.
Further fixes should reduce the complexity of the above command.
There arent any unit tests in this PR, however I will add a followup one which builds a static version of TestFoundation to test xctest, libdispatch and libfoundation together.