Skip to content

Unix toolchains will not try to use fat binaries. #19432

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

Closed
wants to merge 1 commit into from

Conversation

drodriguez
Copy link
Contributor

Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was trying to "lipo" several
architectures into one file even for those targets (only Windows
was exercising that part of the code, it seems).

This patch removes the copy for a bogus empty target, and modifies
the Unix toolchain to look into the architecture subdirectory,
instead of trying to use the platform directory. The Windows
toolchain already checked the architecture directory, and not the
platform one.

This should allow building two Linux or Android SDKs for different
architures side by side.

Some tests are modified to handle the new structure. The tests are
hardcoded to use x86_64 because their targets were originally
x86_64.

@drodriguez
Copy link
Contributor Author

Please review @compnerd, @gottesmm, @jrose-apple

@jrose-apple
Copy link
Contributor

I thought someone else was working on this too. @lanza, maybe?

@drodriguez
Copy link
Contributor Author

#14245 is a subset of this solution. #16194 seems like another similar solution. I will have a look at those comments (I didn’t check LLDB or SwiftPM, for example). And I will talk with them to figure out how to proceed.

@drodriguez
Copy link
Contributor Author

I talked offline with @lanza and he is OK with me taking over this.

From what I have talked with him, my solution is completely forgetting the installation phase and some other changes in the toolchains. I will try to include those improvements here as soon as I can.

drodriguez added a commit to drodriguez/swift-corelibs-libdispatch that referenced this pull request Sep 26, 2018
Depends on swiftlang/swift#19432

Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was placing the build results in the
platform/OS folder, instead of the per-architecture folder. Having two
architectures side by side was impossible.

After applying the above patch in the Swift compiler, non-Darwin
platforms will look into the per-architecture folders, so the sibling
projects need to leave the products in the right place.
drodriguez added a commit to drodriguez/swift-corelibs-xctest that referenced this pull request Sep 26, 2018
Depends on swiftlang/swift#19432

Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was placing the build results in the
platform/OS folder, instead of the per-architecture folder. Having two
architectures side by side was impossible.

After applying the above patch in the Swift compiler, non-Darwin
platforms will look into the per-architecture folders, so the sibling
projects need to leave the products in the right place.
drodriguez added a commit to drodriguez/swift-corelibs-foundation that referenced this pull request Sep 28, 2018
Depends on swiftlang/swift#19432

Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was placing the build results in the
platform/OS folder, instead of the per-architecture folder. Having two
architectures side by side was impossible.

After applying the above patch in the Swift compiler, non-Darwin
platforms will look into the per-architecture folders, so the sibling
projects need to leave the products in the right place.

The change is performed in the CMakeList.txt file (which as far as I
understand is not used to build Foundation at the moment), and the
Python script.
@drodriguez
Copy link
Contributor Author

The latest version of the commit includes the changes in Nathan’s version that I didn’t catch, it also includes slightly modified version to correctly generate the install scripts for non-Darwin platforms.

To build a full package, changes in other projects are necessary:

With all those changes a utils/build-toolchain invocation successfully completes.

@jrose-apple
Copy link
Contributor

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 27c78343fff76e4bd4bb10573e768ded0c1c33e7

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 27c78343fff76e4bd4bb10573e768ded0c1c33e7

@kevints
Copy link
Contributor

kevints commented Sep 28, 2018

What about adding a flag to emit this path and changing the corelibs buildsystems to use the result of this rather than duplicating this logic across all three buildsystems. For example (names bikesheddable):

$ swift-config --libdir
/usr/lib/swift/linux/x86_64
$ swift-config --swiftmoduledir
/usr/lib/swift/linux/x86_64
$ swift-config --includedir
/usr/lib/swift
$ swift-config --static-libdir
/usr/lib/swift_static/linux/x86_64
$ swift-config --static-swiftmoduledir
/usr/lib/swift_static/linux/x86_64

You could also do this as an installed CMake config file or a pkg-config file. The advantage is that other build systems that need this knowledge (swifpm, a hypothetical swift library installer) could ask this tool as well.

@drodriguez
Copy link
Contributor Author

Seems that the two builds failed because they tried to find the original commit from this PR, instead of the last version. Is there something I need to do for the CI to pick up the right one?

@kevints: sounds like a great idea, but I don’t see this swift-config tool anywhere. Will I need to introduce it? The tool will need to support the same target triples as the compiler (otherwise there’s no way to cross compile), and there will always be knowledge duplicated between the compiler and this tool. BTW, this solution was a intermediate solution that changed the least possible (and it is already quite large change, to be honest, but I don’t know how to break it further).

@jrose-apple
Copy link
Contributor

Ah, those get automatically retried by our CI system; they're not the real issue. The "Details" section of the actual checks shows the real failures: Apple platforms are failing to configure, and Linux build-script is trying to run a command that might not exist anymore.

@drodriguez
Copy link
Contributor Author

I see the problems now. I change that check to a precondition as one of the last things. I will try to find some time to check what’s happening on Darwin. The Linux one is stranger. I will see if I can reproduce and fix it. Thanks!

@kevints
Copy link
Contributor

kevints commented Oct 1, 2018

@drodriguez you'd have to introduce it. The advantage is that this tool would be built from this repository and so it would always have up-to-date information about these paths and downstream projects (like s-c-f and s-c-d) would just need to query this tool rather than duplicate its logic in the language of their own buildsystem). I suspect it would be less total code but I don't want to hold this change up if it proves more difficult than expected to implement.

@drodriguez
Copy link
Contributor Author

I tested with a Darwin machine again and find two small problems during configuration which should be fixed in the last commit. I will try to reproduce the Linux problem tomorrow (sadly the details are already gone from the CI server, and I didn’t save them anywhere).

@kevints: I don’t disagree that the tool is a good idea, but I wasn’t planning into creating a tool for this, since previously all the path calculation was already duplicated (but I agree that it was simpler). Anyway, I can try to create such tool as a follow up, because a new tool will add a lot more code to an already complicated diff.

@swift-ci

This comment has been minimized.

@swift-ci

This comment has been minimized.

@swift-ci
Copy link
Contributor

swift-ci commented Oct 5, 2018

Build failed
Swift Test Linux Platform
Git Sha - 30596b6a97e77fefff84ce448c2449c2e145833c

@compnerd
Copy link
Member

compnerd commented Oct 8, 2018

@drodriguez seems that the failures are related to the integration tests failing during s-p-m tests due to not linking Foundation and dispatch (can't find it is my guess).

@drodriguez
Copy link
Contributor Author

@compnerd: I think you are missing the related PRs in your CI command. Like:

swiftlang/swift-corelibs-libdispatch#392
swiftlang/swift-corelibs-xctest#225
swiftlang/swift-corelibs-foundation#1710
@swift-ci Please test

The missing symbols are XCTest, which currently leaves the products in the root directory, but the compiler is looking into the per-arch directory (to support multiple architectures without fat libraries support).

@compnerd
Copy link
Member

compnerd commented Oct 8, 2018

@swift-ci
Copy link
Contributor

swift-ci commented Oct 8, 2018

Build failed
Swift Test OS X Platform
Git Sha - 45301579081b17d18d72da89f60419c806d183ce

@swift-ci
Copy link
Contributor

swift-ci commented Oct 8, 2018

Build failed
Swift Test Linux Platform
Git Sha - 45301579081b17d18d72da89f60419c806d183ce

@drodriguez
Copy link
Contributor Author

Seems that I can reproduce the errors in CI, but I don’t know where to start. The problems disappear if I compile without my code.

For missing_imports_repl:

build/Ninja-ReleaseAssert/swift-macosx-x86_64/bin/swiftc -frontend -target x86_64-apple-macosx10.9  -module-cache-path 'build/Ninja-ReleaseAssert/swift-macosx-x86_64/swift-test-results/x86_64-apple-macosx10.9/clang-module-cache' -sdk '/Applications/xcode_10.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk' -swift-version 4  -repl  < swift/test/Interpreter/SDK/missing_imports_repl.swift 2>&1 -I build/Ninja-ReleaseAssert/swift-macosx-x86_64/test-macosx-x86_64/Interpreter/SDK/Output/missing_imports_repl.swift.tmp
<unknown>:0: error: fatal error encountered during compilation; please file a bug report with your project and the crash log
<unknown>:0: note: Symbol not found: __swift_FORCE_LOAD_$_swiftAppKit
…
0  swiftc                   0x000000010f3e5dd8 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 40
1  swiftc                   0x000000010f3e4da8 llvm::sys::RunSignalHandlers() + 248
2  swiftc                   0x000000010f3e63f2 SignalHandler(int) + 258
3  libsystem_platform.dylib 0x00007fff52128f5a _sigtramp + 26
4  libsystem_platform.dylib 0x00007ffee46e5ef0 _sigtramp + 2455490480
5  libsystem_c.dylib        0x00007fff51ec61ae abort + 127
6  swiftc                   0x000000010b567ff1 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*)::$_1::__invoke(void*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) + 529
7  swiftc                   0x000000010f378a9b llvm::report_fatal_error(llvm::Twine const&, bool) + 251
8  swiftc                   0x000000010f378b99 llvm::report_fatal_error(llvm::StringRef, bool) + 41
9  swiftc                   0x000000010c1c818b llvm::MCJIT::generateCodeForModule(llvm::Module*) + 2715
10 swiftc                   0x000000010c1c85ad llvm::MCJIT::finalizeObject() + 413
11 swiftc                   0x000000010b5beb6b REPLEnvironment::executeSwiftSource(llvm::StringRef, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) + 1403
12 swiftc                   0x000000010b5b9c03 swift::runREPL(swift::CompilerInstance&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, bool) + 1379
13 swiftc                   0x000000010b564d30 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 2976
14 swiftc                   0x000000010b5630fd swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3021
15 swiftc                   0x000000010b51549e main + 686
16 libdyld.dylib            0x00007fff51e1a015 start + 1

The problem is the line import MapKit. If I change to AppKit, it crashes in the same way. If I change it to Foundation, it works.

In the case of GLKit_jit.swift, the stack trace is not the same, but seems that the import triggers the crash.

$ build/Ninja-ReleaseAssert/swift-macosx-x86_64/bin/swiftc -frontend -target x86_64-apple-macosx10.9  -module-cache-path 'build/Ninja-ReleaseAssert/swift-macosx-x86_64/swift-test-results/x86_64-apple-macosx10.9/clang-module-cache' -sdk '/Applications/xcode_10.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk' -swift-version 4  -interpret  -module-name=main swift/test/Interpreter/SDK/GLKit.swift
Stack dump:
0.	Program arguments: build/Ninja-ReleaseAssert/swift-macosx-x86_64/bin/swiftc -frontend -target x86_64-apple-macosx10.9 -module-cache-path build/Ninja-ReleaseAssert/swift-macosx-x86_64/swift-test-results/x86_64-apple-macosx10.9/clang-module-cache -sdk /Applications/xcode_10.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -swift-version 4 -interpret -module-name=main swift/test/Interpreter/SDK/GLKit.swift
0  swiftc                   0x0000000103f28dd8 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 40
1  swiftc                   0x0000000103f27da8 llvm::sys::RunSignalHandlers() + 248
2  swiftc                   0x0000000103f293f2 SignalHandler(int) + 258
3  libsystem_platform.dylib 0x00007fff52128f5a _sigtramp + 26
4  libsystem_platform.dylib 0x00000000000006e0 _sigtramp + 2918021024
5  libsystem_platform.dylib 0x0000000107e752e2 _sigtramp + 3050619810
6  swiftc                   0x0000000100d0dc4d llvm::MCJIT::runFunction(llvm::Function*, llvm::ArrayRef<llvm::GenericValue>) + 461
7  swiftc                   0x0000000100d117f1 llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, char const* const*) + 1329
8  swiftc                   0x00000001000fbfbb swift::RunImmediately(swift::CompilerInstance&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, swift::IRGenOptions&, swift::SILOptions const&) + 3547
9  swiftc                   0x00000001000aa580 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 13296
10 swiftc                   0x00000001000a60fd swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3021
11 swiftc                   0x000000010005849e main + 686
12 libdyld.dylib            0x00007fff51e1a015 start + 1
Segmentation fault: 11

And finally Cocoa_repl.swift seems to be the same as the one with MapKit:

$ build/Ninja-ReleaseAssert/swift-macosx-x86_64/bin/swiftc -frontend -target x86_64-apple-macosx10.9  -module-cache-path 'build/Ninja-ReleaseAssert/swift-macosx-x86_64/swift-test-results/x86_64-apple-macosx10.9/clang-module-cache' -sdk '/Applications/xcode_10.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk' -swift-version 4  -repl  < swift/test/Interpreter/SDK/Cocoa_repl.swift 2>&1
<unknown>:0: error: fatal error encountered during compilation; please file a bug report with your project and the crash log
<unknown>:0: note: Symbol not found: __swift_FORCE_LOAD_$_swiftAppKit
Stack dump:
0.	Program arguments: build/Ninja-ReleaseAssert/swift-macosx-x86_64/bin/swiftc -frontend -target x86_64-apple-macosx10.9 -module-cache-path build/Ninja-ReleaseAssert/swift-macosx-x86_64/swift-test-results/x86_64-apple-macosx10.9/clang-module-cache -sdk /Applications/xcode_10.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -swift-version 4 -repl
1.	while processing REPL source:
// RUN: %target-repl-run-simple-swift | %FileCheck %s
// REQUIRES: objc_interop
// REQUIRES: swift_repl
import Cocoa
// CHECK: 0{{$}}
0  swiftc                   0x0000000105b9cdd8 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 40
1  swiftc                   0x0000000105b9bda8 llvm::sys::RunSignalHandlers() + 248
2  swiftc                   0x0000000105b9d3f2 SignalHandler(int) + 258
3  libsystem_platform.dylib 0x00007fff52128f5a _sigtramp + 26
4  libsystem_platform.dylib 0x00007ffeedf2efb0 _sigtramp + 2615173232
5  libsystem_c.dylib        0x00007fff51ec61ae abort + 127
6  swiftc                   0x0000000101d1eff1 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*)::$_1::__invoke(void*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) + 529
7  swiftc                   0x0000000105b2fa9b llvm::report_fatal_error(llvm::Twine const&, bool) + 251
8  swiftc                   0x0000000105b2fb99 llvm::report_fatal_error(llvm::StringRef, bool) + 41
9  swiftc                   0x000000010297f18b llvm::MCJIT::generateCodeForModule(llvm::Module*) + 2715
10 swiftc                   0x000000010297f5ad llvm::MCJIT::finalizeObject() + 413
11 swiftc                   0x0000000101d75b6b REPLEnvironment::executeSwiftSource(llvm::StringRef, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) + 1403
12 swiftc                   0x0000000101d70c03 swift::runREPL(swift::CompilerInstance&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&, bool) + 1379
13 swiftc                   0x0000000101d1bd30 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 2976
14 swiftc                   0x0000000101d1a0fd swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3021
15 swiftc                   0x0000000101ccc49e main + 686
16 libdyld.dylib            0x00007fff51e1a015 start + 1
Abort trap: 6

@drodriguez
Copy link
Contributor Author

With one the last changes in the CMake module I forgot to change one usage of IS_DARWIN, which ended up making the swiftc binary not having the right RPATH, so when it was used in the repl mode it couldn’t load libraries which depend on other libraries. It took me a long time to realize what was happening.

@compnerd
Copy link
Member

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 4f8ab602fe66b3db081d90a23aa971de6261c071

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 4f8ab602fe66b3db081d90a23aa971de6261c071

drodriguez added a commit to drodriguez/swift-corelibs-foundation that referenced this pull request Oct 10, 2018
Depends on swiftlang/swift#19432

Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was placing the build results in the
platform/OS folder, instead of the per-architecture folder. Having two
architectures side by side was impossible.

After applying the above patch in the Swift compiler, non-Darwin
platforms will look into the per-architecture folders, so the sibling
projects need to leave the products in the right place.
drodriguez added a commit to drodriguez/swift-corelibs-libdispatch that referenced this pull request Oct 10, 2018
Depends on swiftlang/swift#19432

Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was placing the build results in the
platform/OS folder, instead of the per-architecture folder. Having two
architectures side by side was impossible.

After applying the above patch in the Swift compiler, non-Darwin
platforms will look into the per-architecture folders, so the sibling
projects need to leave the products in the right place.
drodriguez added a commit to drodriguez/swift-corelibs-xctest that referenced this pull request Oct 10, 2018
Depends on swiftlang/swift#19432

Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was placing the build results in the
platform/OS folder, instead of the per-architecture folder. Having two
architectures side by side was impossible.

After applying the above patch in the Swift compiler, non-Darwin
platforms will look into the per-architecture folders, so the sibling
projects need to leave the products in the right place.
drodriguez added a commit to drodriguez/swift that referenced this pull request Oct 26, 2018
Support for Android aarch64 in many parts of the build-script. Most of
the changes are reuse variables/parameters that already existed for
Android ARMv7. There is also a new parameter to specify the ICU
data library, which is used by swiftlang#19503.

With this one can build either armv7 or aarch64, since building both
at the same time requires more changes like swiftlang#19432 (and probably
more work to support two set of paths).
@drodriguez drodriguez force-pushed the thin-platforms branch 2 times, most recently from f44e551 to e330c8a Compare October 31, 2018 18:50
drodriguez added a commit to drodriguez/swift-corelibs-libdispatch that referenced this pull request Oct 31, 2018
Depends on swiftlang/swift#19432

Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was placing the build results in the
platform/OS folder, instead of the per-architecture folder. Having two
architectures side by side was impossible.

After applying the above patch in the Swift compiler, non-Darwin
platforms will look into the per-architecture folders, so the sibling
projects need to leave the products in the right place.
drodriguez added a commit to drodriguez/swift-corelibs-xctest that referenced this pull request Oct 31, 2018
Depends on swiftlang/swift#19432

Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was placing the build results in the
platform/OS folder, instead of the per-architecture folder. Having two
architectures side by side was impossible.

After applying the above patch in the Swift compiler, non-Darwin
platforms will look into the per-architecture folders, so the sibling
projects need to leave the products in the right place.
drodriguez added a commit to drodriguez/swift-corelibs-libdispatch that referenced this pull request Nov 5, 2018
Depends on swiftlang/swift#19432

Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was placing the build results in the
platform/OS folder, instead of the per-architecture folder. Having two
architectures side by side was impossible.

After applying the above patch in the Swift compiler, non-Darwin
platforms will look into the per-architecture folders, so the sibling
projects need to leave the products in the right place.
Unix (other than Darwin) and Windows do not support fat binaries.
However, the build system was trying to "lipo" several
architectures into one file even for those targets (only Windows
was exercising that part of the code, it seems).

This patch removes the copy for a bogus empty target, and modifies
the Unix toolchain to look into the architecture subdirectory,
instead of trying to use the platform directory. The Windows
toolchain already checked the architecture directory, and not the
platform one.

This should allow building two Linux or Android SDKs for different
architures side by side.

Some tests are modified to handle the new structure. The tests are
hardcoded to use x86_64 because their targets were originally
x86_64.
zayass pushed a commit to readdle/swift that referenced this pull request May 31, 2019
Support for Android aarch64 in many parts of the build-script. Most of
the changes are reuse variables/parameters that already existed for
Android ARMv7. There is also a new parameter to specify the ICU
data library, which is used by swiftlang#19503.

With this one can build either armv7 or aarch64, since building both
at the same time requires more changes like swiftlang#19432 (and probably
more work to support two set of paths).
@drodriguez drodriguez closed this Oct 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants