Skip to content

[CMake] Replace SWIFT_SDKS with SWIFT_CROSS_COMPILE_DEPLOYMENT_TARGETS #2835

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

karwa
Copy link
Contributor

@karwa karwa commented Jun 2, 2016

What's in this pull request?

Change build-script(-impl) -> CMake configuration arguments to use "deployment targets" instead of SDK names.

Deployment targets are made up of hyphen-separated lists; in the format {sdk name}-{architecture}, so they're the same things the build-script uses internally, save for the Apple platforms having slightly different SDK names.

Since we extract the components, I'm implicitly leaving it open for us to add options to the deployment target specifier (e.g. Soft/hard float ABI) by appending them. So you might see a linux-arm-hardfloat deployment target in the future.

We extract the SDK name 'blindly', it's validated in the big configuration if()...else() on SWIFT_HOST_VARIANT_SDK.

Architecture is also extracted 'blindly' (sometimes there are small variations, e.g. ppc64le or powerpc64le, but the build-script handles this and always gives us valid architectures). Validation happens in get_triple() for all SDKs except the Apple ones, because configure_sdk_darwin takes a list of architectures and calculates the triples itself.

This is part 1/2 when it comes to replacing SDKs with more specific deployment targets (to allow cross-compiling linux on linux, for example). One small win already with this change is that you can configure and build single slices of the standard library for Apple platforms (since the configured architecture list is no longer hardcoded to include them all).

Resolved bug number: (SR-)


Before merging this pull request to apple/swift repository:

  • Test pull request on Swift continuous integration.

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

Platform Comment
All supported platforms @swift-ci Please smoke test
All supported platforms @swift-ci Please smoke test and merge
OS X platform @swift-ci Please smoke test OS X platform
Linux platform @swift-ci Please smoke test Linux platform

Validation Testing

Platform Comment
All supported platforms @swift-ci Please test
All supported platforms @swift-ci Please test and merge
OS X platform @swift-ci Please test OS X platform
OS X platform @swift-ci Please benchmark
Linux platform @swift-ci Please test Linux platform

Lint Testing

Language Comment
Python @swift-ci Please Python lint

Note: Only members of the Apple organization can trigger swift-ci.

@karwa karwa force-pushed the host-triple branch 3 times, most recently from f0d4474 to 3ab8c22 Compare June 2, 2016 06:26
# FreeBSD
freebsd-x86_64)
#FIXME: Set a meaningful FreeBSD deployment version
FREEBSD_DEPLOYMENT_VERSION="10.3"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This replaces the FIXME in CMake, about FreeBSD using the local CMAKE_SYSTEM_VERSION to derive a deployment target. It should have its own parameter, like Darwin targets do, and that would solve the cross-compiling issue.

@gribozavr
Copy link
Contributor

Sorry, could you explain where you are hoping to arrive with this? Why do we need to make triples the primary identifier of the platform?

You are saying that we don't need to understand them, but even trying to tell apart iOS device from iOS simulator turns into a mess (get_sdk_from_triple).

@karwa
Copy link
Contributor Author

karwa commented Jun 2, 2016

Triples are only the identifier for configuration purposes. The reason is:

  • We need the triple for every SDK we configure. It's one of the parameters to configure_sdk_unix (configure_sdk_darwin calculates it on its own, but it's the same).
  • The current mechanism of configuring by SDK is not specific enough. It's fine to just say SWIFT_SDKS=IOS and configure to build all iOS architectures, but we don't want SWIFT_SDKS=LINUX to configure all of the supported Linux architectures, for example.
  • Since we need the triple anyway, and it contains all of the information we need, and it is vital that the other information (such as SWIFT_HOST_VARIANT_ARCH) is exactly the same as the what is in the triple (because that's what the swift compiler will use at runtime), it just makes sense to specify which targets to configure using triples.

You'll notice that those triples only exist once now (in the build script) where before they were calculated twice. That's another benefit.

This only affects configuration at the CMake level. There is no change to the outward parameters of the build script (that's still tuples, and it can stay like that. Nobody likes triples).

The reason the IOS/IOS_SIMULATOR distinction is a mess is because they have the same triple. The iOS Simulator is just x86 iOS - x86_64-apple-ios8.0. We separate that particular architecture out and call it the 'simulator' SDK, but it's a completely artificial distinction. IIUC, you should be able to take the iPhone simulator stdlib and use it directly on a theoretical Core i7 iPad.

@gribozavr
Copy link
Contributor

gribozavr commented Jun 2, 2016

Triples are only the identifier for configuration purposes.

Sorry, I don't think this is entirely true. We pass triples to the compiler from _add_variant_c_compile_link_flags.

We need the triple for every SDK we configure. It's one of the parameters to configure_sdk_unix (configure_sdk_darwin calculates it on its own, but it's the same).

Sure, but I'd rather translate an SDK/arch representation into triples, than trying to derive something from triples -- even from a fixed set of them; you never know when the set will grow.

The current mechanism of configuring by SDK is not specific enough. It's fine to just say SWIFT_SDKS=IOS and configure to build all iOS architectures, but we don't want SWIFT_SDKS=LINUX to configure all of the supported Linux architectures, for example.

Absolutely agreed. But we can do that using SDK/arch pairs just as well. Please feel free to choose your own mangling for this internal interface between build-script and CMake -- I'd prefer one that people don't already have expectations about.

Since we need the triple anyway [...] it just makes sense to specify which targets to configure using triples.

Sorry, this does not follow for me. If using triples requires having regexes in CMake (which I don't see how we would move into testable Python code), then in my opinion it is better to have a little duplication, but keep things more maintainable.

@karwa karwa changed the title Derive SWIFT_HOST_VARIANT_{SDK/ARCH} from SWIFT_HOST_TRIPLE [WIP] Replace SWIFT_SDKS Jun 8, 2016
@karwa
Copy link
Contributor Author

karwa commented Jun 8, 2016

Doesn't configure just yet - I think I've forgotten to quote a CMake variable somewhere. Looking for general feedback/help with the CMake issue (OSX).

To explain the rationale: is_sdk_requested hardcoded that the stdlib was always built for the host, even if it was never in SWIFT_SDKS. So SWIFT_SDKS was always basically the cross-compile list.

The next step to fully allowing targets to be cross-compiled would be to amend the prefix, so that the places which iterated over SWIFT_SDKS now iterate over all architectures (except for Darwin targets, where the architectures are a property of the SDK. That's an exceptional case - for most platforms, a different architecture will need a different SDK_PATH, toolchain, and other specific configuration).

@karwa karwa force-pushed the host-triple branch 6 times, most recently from 66bf784 to 9805740 Compare June 8, 2016 21:55
@karwa
Copy link
Contributor Author

karwa commented Jun 8, 2016

@gribozavr Okay I've tested this on OSX and the configuration seems to work. Can you please trigger a test to check the functionality?

EDIT: Oh, just noticed an issue with the buildbot

@karwa karwa force-pushed the host-triple branch 7 times, most recently from 15d1f7e to 72784d7 Compare June 9, 2016 00:01
@karwa
Copy link
Contributor Author

karwa commented Jun 9, 2016

@gribozavr OK, I'm happy with it now. I changed the external --stdlib-deployment-targets parameter to --cross-compile-stdlib-deployment-targets (yeah, it's a mouthful, but I think we should move to configuring in stages of verbs anyway). It's empty for all hosts except OSX, and if you want to explicitly remove them and only configure OSX, you can pass --cross-compile-stdlib-deployment-targets=" " or --cross-compile-stdlib-deployment-targets="none" (but not "", due to some python argument parsing weirdness). You shouldn't include the host itself in this list.

@karwa karwa changed the title [WIP] Replace SWIFT_SDKS [CMake] Replace SWIFT_SDKS with SWIFT_CROSS_COMPILE_DEPLOYMENT_TARGETS Jun 9, 2016
@karwa
Copy link
Contributor Author

karwa commented Jun 9, 2016

Rebased with the recent build-script changes, which needs to be amended itself. @ddunbar, you might want to check it over.

I'd like to get this in as part of a bigger change to use architecture-specific prefixes for CMake SDKs (which would allow, for example, a Linux host to cross-compile a Linux stdlib, something not possible today). It's now also possible to configure and build specific iOS slices from the command line, because they're not hardcoded:

./utils/build-script -r --ios --cross-compile-stdlib-deployment-targets="iphoneos-arm64" --build-stdlib-deployment-targets="iphoneos-arm64"

Will now configure for the iOS SDK only for iphoneos-arm64 and only build that slice. Unfortunately building a different slice requires a reconfiguration, due to the way universal libraries are handled (I think it's possible to change that, but it might be better to just optionally disable universal libraries -- do you really want different versions of the same libraries being merged together?)

"A list of deployment-targets to cross-compile the standard-library for (by default, the standard library is always compiled for the host)")

set(SWIFT_SKIP_HOST_STDLIB "" CACHE STRING
"If True, will not build the standard library for the host")
Copy link
Contributor Author

@karwa karwa Jun 10, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't actually work right now (due to other failures in other parts of the project; assuming SWIFT_HOST_VARIANT_SDK exists or whatnot), but a couple of parts of the old CMakeLists (which was hardcoded so this would never happen) indicated that it was supported at some point, or would at least be desirable in the future.

Specifically, SWIFT_PRIMARY_VARIANT gets set to Android when not building the stdlib for the Linux host, and swift-reflection-dump is gated by checking if we're building for the host's stdlib.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this note still true? There's not much harm in adding a CMake option that doesn't quite work right now, but I think a better approach would be to only add ones that already work as intended.

Would it be possible to either:

  1. Fix the issues you describe first, before merging this pull request?
  2. Or add this flag in a later pull request? It seems to be used in five locations, so maybe it's too much trouble.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I didn't describe it well, but what I meant to say is that (currently, before merging this PR) we always build for the host even if you don't include it in SWIFT_SDKS. So it doesn't actually work today (SWIFT_PRIMARY_VARIANT will never be Android).

While doing this patch, I removed the part that always builds for the host and found that there were other places which do assume the host is always being built. Maybe there are some other combination of settings which make it work (not building those failing parts)? I don't know; so I added the flag. It's not necessary though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I misunderstood. But yes, I think I encountered failures similar to the ones you mention here when I was working on #3027 -- and those were just the assumptions that the host stdlib was being built.

In any case, sounds good to me! Sorry for the noise.

@karwa karwa force-pushed the host-triple branch 2 times, most recently from 01fc571 to 0957e47 Compare June 11, 2016 03:01
get_sdk_from_stdlib_target("${stdlib_target}" target_sdk)
get_arch_from_stdlib_target("${stdlib_target}" target_arch)

if(NOT "${target_arch}" IN_LIST ${target_sdk}_VALID_ARCHITECTURES)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like IN_LIST is new in CMake 3.3. (https://cmake.org/cmake/help/v3.3/policy/CMP0057.html)

We support Ubuntu 14.04, which has CMake 2.8.12.

@karwa
Copy link
Contributor Author

karwa commented Jun 18, 2016

@gribozavr Replaced use of IN_LIST with new function list_contains in SwiftList.cmake

@karwa
Copy link
Contributor Author

karwa commented Jun 20, 2016

CC @gribozavr @modocache

I have part 2 of this done (i.e. cross-compiling linux on linux), going stale somewhere and I'd like to get them merged.

@karwa karwa mentioned this pull request Jun 21, 2016
1 task
else()
set("${result_var_name}" 1 PARENT_SCOPE)
endif()
endfunction()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit-pick: This could use a new line at the end of the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've raised our minimum-supported CMake since I pushed this, so I think it can be replaced with a built-in function now anyway

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nifty. For my own education, whats the builtin in newer cmake that does this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@modocache
Copy link
Contributor

This looks awesome. @gribozavr, @compnerd, do either of you have any thoughts?

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - 73c1ba2
Test requested by - @modocache

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - 73c1ba2
Test requested by - @modocache

@modocache
Copy link
Contributor

Yikes. CI must not like me. Those failures don't look normal. @shahmishal, are those interesting to you?

@karwa
Copy link
Contributor Author

karwa commented Aug 24, 2016

I'll update this patch soon. I'm hoping there's going to be a window after Swift 3 lands that we can make more significant progress on cross-compiling (defining a format for a toolchain "bundle" which includes the sysroot, native tools and build flags, which would be understood by both the build-script so you can build a compiler with it, and by the compiler itself so you can use it for cross-compiling swift applications).

This is a prereq for those changes. We need to be able to build for an arbitrary target not just an entire platform.

set(triple "${arch}-unknown-linux-gnu")
elseif("${arch}" MATCHES "(armv6|armv7)")
set(triple "${arch}-unknown-linux-gnueabihf")
endif()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if you want to use a compiler from a specific vendor? Lets take a concrete example: armv7-linaro-linux-gnueabihf? I don't see why we couldn't support that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure - I think we actually have a vendor flag in the build-script, so we can pass that along and substitute it in.

IIRC, it's important that this exactly matches the LLVM_HOST_TRIPLE from the build-script. It's been a long time since I tested it, but I think that even vendor mismatches cause the tools to not want to co-operate.

@slavapestov
Copy link
Contributor

Ping? Let's get this rebased and merge it in if there are no further comments.

@slavapestov slavapestov self-assigned this Jan 13, 2017
@jrose-apple
Copy link
Contributor

I definitely want @erg to pick up where @gribozavr left off, and make sure he understands and approves of the changes here. It's possible this will affect our internal process, and if so we need to know how to update that.

@jrose-apple jrose-apple requested a review from erg January 13, 2017 17:12
@karwa
Copy link
Contributor Author

karwa commented Jan 13, 2017

OK, I'll have a go at rebasing this.

@dcartman
Copy link

@karwa is this PR also included in your karwa/swift branch?

This weekend I want to have a run a cross-compiling for raspberry pi and beagle bone. It seems like your branch is currently the best place to start until this PR and #1398 are fully landed.

@CodaFi
Copy link
Contributor

CodaFi commented Jun 17, 2017

It's been a year and this patch has fallen behind and been split and spread across multiple other patches. I'm going to close this since priorities for smaller patches that come out of this seem clear. If that feeling is incorrect, please feel free to rebase this and reopen it.

@CodaFi CodaFi closed this Jun 17, 2017
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.