Skip to content
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

Android: add cross-compilation configuration file flag #3403

Merged
merged 1 commit into from Jun 28, 2021

Conversation

finagolfin
Copy link
Contributor

@finagolfin finagolfin commented Apr 14, 2021

Motivation:

This enables cross-compiling SPM for other hosts, such as Android.

Modifications:

In addition to --cross-compile-hosts, add a new bootstrap flag, --cross-compile-config, that will pass in a JSON file with the destination cross-compilation flags.

Result:

SPM can be cross-compiled for another OS, with Android as the first example.

@tomerd
Copy link
Member

tomerd commented Apr 14, 2021

cc @compnerd @weissi

@tomerd tomerd assigned compnerd and abertelrud and unassigned abertelrud Apr 14, 2021
@neonichu
Copy link
Member

Even though these two will be largely the same, both are needed because some PackageDescription libraries are not built by SPM itself, so the string is needed to build those with CMake.

I think this is actually a bug and I was planning to fix it. Any binaries we are installing should be built during the second stage, anything build by CMake should only be there temporarily.

@finagolfin
Copy link
Contributor Author

I think this is actually a bug and I was planning to fix it.

OK, I'm referring specifically to these libraries that are only built by CMake right now.

@neonichu
Copy link
Member

neonichu commented Apr 15, 2021

Yep, we're talking about the same thing. I realize that they are currently being built by CMake only. We found this issue independently of this PR and I am planning to fix it soon, that's why I wanted to bring it up here.

Potentially, it would make sense to wait with this PR until that issue is fixed because then we don't need the second flag, if I understand this correctly.

@finagolfin
Copy link
Contributor Author

Yes, if two of those libraries were generated by the SPM build also (one of the PD libraries is built by SPM, but not installed), then the first flag added by this pull isn't needed. It is only needed because the build currently installs those CMake-generated libs. I can wait if you want to fix the build first.

Copy link
Collaborator

@compnerd compnerd left a comment

Choose a reason for hiding this comment

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

Could you please also reflow the text that is being added? Some of the lines are pretty long.

I'm not a big fan of adding more infrastructure in the bootstrap script, my understanding is that we want to move away from that.

if args.cross_compile_hosts: # Use XCBuild target directory when building for multiple arches.
args.target_dir = os.path.join(args.build_dir, "apple/Products")
if args.cross_compile_hosts:
if "macosx-arm64" in args.cross_compile_hosts:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think that this is correct; there are a number of targets that may be used, can you just invert the condition here instead?

if args.cross_compile_hosts:
  if re.match('android-', args.cross_compile_hosts):
    args.target_dir = os.path.join(args.build_dir, get_build_targets(args, cross_compile=True))
  else:
    args.target_dir = os.path.join(args.build_dir, 'apple/Products')

Yes, it isn't great, but leaves the behaviour the same while adding support for your use case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, this is right, see the similar logic at the end of the script. Basically, Mishal only added support for cross-compiling SPM for macOS arm64 and he explicitly spelled that out below, but didn't bother here: I went ahead and made it explicit here too, now that I added Android also.

Copy link
Collaborator

Choose a reason for hiding this comment

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

WFM

@finagolfin
Copy link
Contributor Author

Could you please also reflow the text that is being added?

Done, although this script already has a bunch of long lines that I didn't add.

I'm not a big fan of adding more infrastructure in the bootstrap script

I'm not sure what "infrastructure" refers to in this context.

@compnerd
Copy link
Collaborator

@swift-ci please test

@finagolfin
Copy link
Contributor Author

CI failures in the lldb tests on linux and building the compiler on macOS are unrelated to this pull.

@tomerd
Copy link
Member

tomerd commented Apr 19, 2021

@swift-ci please smoke test

@tomerd
Copy link
Member

tomerd commented Apr 19, 2021

@neonichu have your concerns here been addressed and this is ready to be merged?

@tomerd
Copy link
Member

tomerd commented Apr 19, 2021

@buttaface please note we have branched 5.5 to release/5.5 so once this is merged we will need a corresponding PR if we need this to be included in 5.5

@finagolfin
Copy link
Contributor Author

Sigh, I made one last formatting change without testing and Python's complaining about that on the CI: I will never understand where line breaks are allowed in Python.

This pull works with the way the SPM build currently builds some release libraries with CMake and most everything else with the bootstrap SPM, but Boris wants to move the SPM build to a full SPM bootstrap. I'm fine with waiting for that change because it will allow me to simplify this pull and remove one of the bootstrap script flags I otherwise need, provided changing the build to SPM only doesn't take months or something.

I will submit a pull for the 5.5 branch once this is in.

@tomerd tomerd added the WIP Work in progress label Apr 22, 2021
@finagolfin
Copy link
Contributor Author

@abertelrud, I understand that you're looking to fix #3431 now by merging the two PD libraries, any plans to merge that back to the 5.5 branch? If not, I'd like to get this pull into trunk and 5.5 now and I will rework these changes, that cross-compile the two PD libraries with CMake, in another pull to adapt to when you get that PD merge pull into trunk.

If you plan to merge the two PD libraries in 5.5 too, then I will wait till you get that into trunk and rework this pull then.

@abertelrud
Copy link
Contributor

abertelrud commented Apr 30, 2021

I put up #3464 now, though it's still a WIP. I'm not sure whether it's in scope for 5.5 but I think it would be good if the question there can be cleared up (about unsafe compiler flags in the manifest). I will wrap up the bootstrap script changes there today or tomorrow and then there should be a discussion about whether that change can go into 5.5. Which will then affect this PR.

@abertelrud
Copy link
Contributor

I don't have an opinion about whether this is merged first though — I think that the bootstrap script will need to be modified either way, and if this is merged first, I can easily adapt #3464.

@finagolfin
Copy link
Contributor Author

Alright, I will wait till a decision is made on whether #3464 should go into 5.5 and then modify this as needed.

@abertelrud
Copy link
Contributor

Looks good to me given the current somewhat unfortunate implementation of universal binaries for the macOS toolchain. I have requested that the compiler scripts change to using --build-all-architectures to convey the intent of building for all supported architectures on platforms where that is relevant, and that the --cross flags be used for building for other platforms, as is done here.

@tomerd @neonichu any concerns with this change to unblock Android?

@abertelrud
Copy link
Contributor

Actually: @buttaface what is the semantic distinction here between cross-compile-hosts and cross-compile-target-triple? It sounds as if the latter is essentially the way the former was intended to work, except that it only supports a single target. Is the reason for keeping cross-compile-hosts here because there are existing scripts that call it?

@finagolfin
Copy link
Contributor Author

Ideally, nothing different. --cross-compile-hosts uses the build-script format of android-aarch64, while --cross-compile-target-triple is the LLVM/Swift target triple, ie aarch64-unknown-linux-android. We could combine the two to only use the latter, but since the former is already being used as you noted, I just added the triple as another flag.

@abertelrud
Copy link
Contributor

Ideally, nothing different. --cross-compile-hosts uses the build-script format of android-aarch64, while --cross-compile-target-triple is the LLVM/Swift target triple, ie aarch64-unknown-linux-android. We could combine the two to only use the latter, but since the former is already being used as you noted, I just added the triple as another flag.

Thanks for clarifying. I think it makes sense to merge this to unblock Android, but over time it seems that the script can be cleaned up. I think that can be done in separate PRs. Would it make sense to make --cross-compile-target-triple be able to support a list so that it completely subsume --cross-compile-hosts, or am I missing the point of that new flag? i.e. if it were a list (which AFAICT should be a simple change), could we get the toolchain build scripts to use it and then get rid of --cross-compile-hosts?

@finagolfin
Copy link
Contributor Author

I actually don't think --cross-compile-hosts should be a list, but yes, we could probably merge these two flags at some point. I have opened a pull in the main Swift repo to pass these cross-compilation flags into SPM, apple/swift#36917, I will raise the possibility with Mishal there.

@finagolfin
Copy link
Contributor Author

Hold on, I just thought of a way to do this without that additional flag, will try it and update this pull if it works.

@abertelrud
Copy link
Contributor

Hold on, I just thought of a way to do this without that additional flag, will try it and update this pull if it works.

That would be great! I don't want to hold this up any longer, but any simplification to what's already a complicated situation would be great.

@abertelrud
Copy link
Contributor

I actually don't think --cross-compile-hosts should be a list, . . .

Thanks for the reference to that discussion. I think this gets to a concern I have with the terminology here, and the conflation of platform and architecture when speaking of cross-compilation. In my view it doesn't make sense to cross-compile for, say, Windows and Darwin or Android and Linux in a single invocation of the bootstrap script, so really, only one target platform makes sense.

But within that platform, it makes sense to either choose the architectures for which to compile or have a "default vs all" switch. While the target triples are currently presented as a flat list, it's really only a single platform with one or more architectures that makes any sense for a single given build.

I think ideally it should be possible to specify a target platform and then either a set of target architectures for that platform, or perhaps simpler, a single flag that says "build all architectures for the platform" as opposed to building just a single default architecture (which would, for example, be the architecture of the host). Perhaps that won't suffice for some platforms, where it isn't the host, and there are also multiple architectures to choose from.

try:
command = [args.swiftc_path, '-print-target-info']
if cross_compile:
command += ['-target', args.cross_compile_target_triple]
cross_compile_json = json.load(open(args.cross_compile_config))
command += ['-target', cross_compile_json["target"]]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, this works and allows me to remove the extra triple flag. I just realized that the destination.json is just a JSON file, so we can parse it to get the target triple.

@abertelrud, if you agree with this change, just let me know and I will squash it into the first commit and update the commit message and we can get this in.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @buttaface, simplifying this down to get the information from the JSON instead of the having to pass another flag is a good improvement. I still want to hear what @neonichu and @tomerd think but this looks good given how things currently work. I will still want to work with @shahmishal to see if we can simplify the conceptual model around building for various platforms and architectures.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alright, will squash this commit and update the message.

@finagolfin
Copy link
Contributor Author

I think ideally it should be possible to specify a target platform and then either a set of target architectures for that platform

Yeah, we could reorganize it that way. As I mentioned before, I think --cross-compile-hosts was a quick hack by Boris to get the toolchain building for Apple Silicon, we can upgrade it with time.

@abertelrud
Copy link
Contributor

I think ideally it should be possible to specify a target platform and then either a set of target architectures for that platform

Yeah, we could reorganize it that way. As I mentioned before, I think --cross-compile-hosts was a quick hack by Boris to get the toolchain building for Apple Silicon, we can upgrade it with time.

Absolutely, it was all very understandable at the time. Just thoughts about how to improve on this step-by-step.

@finagolfin
Copy link
Contributor Author

Ready to go.

In addition to '--cross-compile-hosts', add a new bootstrap flag,
'--cross-compile-config', that will pass in a JSON file with the destination
cross-compilation flags.
@finagolfin finagolfin changed the title Android: add cross-compilation flags Android: add cross-compilation configuration file flag Jun 22, 2021
@finagolfin
Copy link
Contributor Author

@neonichu, I think you just need to sign off on this? I have updated my build-script pull, apple/swift#36917, that shows how this new bootstrap flag will be invoked.

@neonichu
Copy link
Member

@swift-ci please smoke test

@abertelrud
Copy link
Contributor

abertelrud commented Jun 28, 2021

@neonichu @buttaface This is currently marked with the wip (work-in-progress) tag. Is it ready to merge? Sounds like it is, based on comments, but that's at odds with the tag.

@finagolfin
Copy link
Contributor Author

Yeah, that tag was added two months ago, when this pull wasn't building. Several changes were made since then, please remove the tag and merge.

@neonichu neonichu removed the WIP Work in progress label Jun 28, 2021
@neonichu neonichu merged commit 38df7c3 into apple:main Jun 28, 2021
@neonichu
Copy link
Member

Thanks for the PR @buttaface!

@finagolfin
Copy link
Contributor Author

Thanks for finally getting this in, I will submit for the 5.5 branch.

finagolfin added a commit to finagolfin/swift-package-manager that referenced this pull request Jun 28, 2021
In addition to '--cross-compile-hosts', add a new bootstrap flag,
'--cross-compile-config', that will pass in a JSON file with the destination
cross-compilation flags.
tomerd pushed a commit that referenced this pull request Jul 1, 2021
In addition to '--cross-compile-hosts', add a new bootstrap flag,
'--cross-compile-config', that will pass in a JSON file with the destination
cross-compilation flags.
@finagolfin finagolfin deleted the cross branch July 2, 2021 04:58
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.

None yet

6 participants