-
Notifications
You must be signed in to change notification settings - Fork 136
Fix cross-compiling ios targets with cmake 3.14 #88
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
e7b8828 to
e15260a
Compare
src/lib.rs
Outdated
| is_ninja = generator.to_string_lossy().contains("Ninja"); | ||
| } | ||
| if target.contains("windows-gnu") { | ||
| if target_triplet.contains("windows-gnu") { |
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.
If a Target type is being added here, perhaps these methods that all use contains could be moved to methods? Alternatively could the methods on Target just be used inline where they're used here? (it just seems weird to do half for some and half for others)
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.
I think that would be a good direction for this codebase to move towards. I don't have the bandwidth to refactor it though. My thinking is basically that by providing the base structure for organization of targets, it can slowly move in that direction. However, let me know if you'd prefer I get rid of Target and inline everything instead.
| if parts.len() < 3 { | ||
| fail(&format!( | ||
| "target triplet not in the form arch-vendor-platform: {}", | ||
| target_triplet | ||
| )); | ||
| } |
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.
I think this may want to be a bit less strict for platforms like wasm32-wasi which could show up here
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.
I've moved this check into an Apple-specific AppleTarget.
src/lib.rs
Outdated
| &self.rust_target_vendor == "apple" && &self.rust_target_platform == "darwin" | ||
| } | ||
|
|
||
| fn is_cross_compiling(&self) -> bool { |
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.
This seems not quite right perhaps? This is where I think it might be better to inline the definition here above because is_cross_compiling doesn't only take into account iOS
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.
I've removed the is_cross_compiling method.
src/lib.rs
Outdated
| self.is_ios_target() | ||
| } | ||
|
|
||
| fn cmake_system_name(&self) -> Option<String> { |
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.
similar to above, this sort of seems too general to only handle iOS, so it may be best to inline the definition above where it's called?
8609afc to
00a2381
Compare
|
I pushed a new revision. The biggest changes are:
|
|
It occurred to me that |
|
Thanks for this, and sorry for taking awhile to get back to this! This is getting to be a pretty significant PR, I would personally prefer to not pick up regex/lazy_static dependencies for example. If using cmake on iOS is so different from all other platforms should there perhaps be a separate crate for that? |
I've ran into this issue across a number of different projects I've attempted to compile to iOS. I admit that it's a never ending battle to make things work cross platform but I think that doing it here will save a lot of leg work for other crates using cmake that want to support multiple platforms. That being said, I'm also not big on picking up regex/lazy_static as a dependency for this project. I'd be up to help remove it. Anyway, it's been a while since this PR was commented on or updated. I just wanted to share my interest and offer to continue the work on it because it'll fix issues with rendy, shaderc and the examples in wgpu. I'm sure there are others but that's just what I was working on this evening. |
|
@simlay Thanks for offering to continue working on it. Feel free to make whatever changes you see fit. To the best of my knowledge, all the logic in the PR is correct, but it needs refactoring to address @alexcrichton's comments. |
|
The regular expressions seem simple enough that you could just parse it by hand. Adding regex as a dependency doesn't seem like a good idea. |
|
So, I'm not sure the best way to take over a PR via github but I've addressed the regex and lazy_static dependencies in simlay@7566053. I've got mixed feelings about it as the logic makes some assumptions on input. Anyway, I'd like to move forward and hopefully get this PR merged at some point. Is there anything I can do to unblock this? |
|
It's fine to send a new PR, and when that one's merged I can close this one. |
* Rename target variable to target_triple * Remove a bit of code duplication * Add GenericTarget with several override points * Add support for cross-compiling Apple targets with cmake 3.14 * Removed lazy_static and regex Co-authored-by: Kyle Fleming <[email protected]>
|
Now landed in #93 |
…st-lang#88 states (rust-lang#93)"" This reverts commit 9a53f43.
…st-lang#88 states (rust-lang#93)"" This reverts commit 9a53f43.
rust-lang#93) * Rename target variable to target_triple * Remove a bit of code duplication * Add GenericTarget with several override points * Add support for cross-compiling Apple targets with cmake 3.14 * Removed lazy_static and regex Co-authored-by: Kyle Fleming <[email protected]>
rust-lang#93) * Rename target variable to target_triple * Remove a bit of code duplication * Add GenericTarget with several override points * Add support for cross-compiling Apple targets with cmake 3.14 Co-authored-by: simlay <[email protected]> Co-authored-by: Kyle Fleming <[email protected]>
Summary
This PR fixes iOS cross-compilation support when using Cmake 3.14+. The issue is described in more detail here: #87
Implementation
This PR checks the target triplet (either the
targetmember variable if it's set, otherwise theTARGETenvironment variable) and looks for an ending of-apple-iosto determine if we're cross-compiling for iOS or not.If we are cross-compiling for iOS, it disables the default compiler flags for the cc-rs build config, and proceeds to set the required flags to allow cmake itself to set them:
CMAKE_SYSTEM_NAMEis not set, set it toiOS.CMAKE_OSX_ARCHITECTURESis not set, set it to the cmake equivalent of the target architecture pulled from thetargetvariable. (cmake equivalents are:arm64,armv7,armv7s,i386, orx86_64)CMAKE_OSX_DEPLOYMENT_TARGETis not set, we look for theIPHONEOS_DEPLOYMENT_TARGETenvironment variable (which is what cc-rs, llvm, rustc, etc use). If that doesn't exist, we default to7.0, which is what cc-rs defaults to (note that cmake defaults to 9.0, but in my opinion, it's better to have consistency across the whole project than to have vertical consistency within a particular tool).CMAKE_OSX_SYSROOTisn't set, set it to eitheriphoneosoriphonesimulatorto match the (canonical, version-less) sdk name xcode uses (xcodebuild -showsdks). This could also be set to a path to an SDK, but by setting it to the name of an SDK, cmake automatically selects the path to the most recent version it can find for that sdk.I set the variables up so that it only sets them if they weren't previously defined, which should allow users to override them however they want.
-fPICand-fembed-bitcodeare added, as those were previously added by cc-rs (which we disabled, as noted above) but are not currently added by cmake. (I couldn't find documentation stating whether-fPICis necessary, but I've left it in for continuity)(I only have minimal rust experience at the moment, so if there are any conventions you'd like me to follow that I might not know about, feel free to suggest.)
Questions
Cmake <3.14
One caveat is that I've only tested this with cmake 3.15. I'm assuming it works with cmake 3.14 since the code in question within cmake hasn't changed. However, I don't know how it handles cmake <3.14.
Prior to cmake 3.14, I believe the procedure was to set
CMAKE_OSX_SYSROOT(same as above) andCMAKE_OSX_SYSROOT(same as above).CMAKE_SYSTEM_NAMEwill be set toDarwinautomatically within cmake.I'm not sure 100% how cmake <3.14 handled
CMAKE_OSX_DEPLOYMENT_TARGET/IPHONEOS_DEPLOYMENT_TARGETso I can't speak to that.Do you want cmake-rs to support versions <3.14? If so we will need a way to determine which cmake version is installed. An easier middle option would be to have the above variables set only for 3.14+ and do nothing for versions <3.14, which in theory might facilitate backwards compatibility with existing projects using cmake-rs.
I don't currently have a good understanding of the needs of cmake-rs and the community using it, so I leave that up to your discretion. How do you want to handle introducing this feature?
Config variables
Do you want the
deploymentTargetto be aConfigvariable? Practically speaking, it can currently be set by defining the cmake variableCMAKE_OSX_DEPLOYMENT_TARGET. (Although, I imagine deployment target might be a configuration option that other targets might have, which is why I mentiondeploymentTargetinstead ofosxDeploymentTargetoriosDeploymentTarget.)This gets a bit hairy though because
CMAKE_OSX_DEPLOYMENT_TARGETis also the variable for setting the macOS deployment target when building for a macOS target. Cmake automatically setsCMAKE_OSX_DEPLOYMENT_TARGETfromMACOSX_DEPLOYMENT_TARGETwhenCMAKE_SYSTEM_NAMEis set toDarwinbut not when it's set toiOS.My point is mainly just that a) if environment variables for the deployment target are namespaced per platform, it could suggest that if a cmake-rs
Configparameter were to be added, it might want to do the same. And b) I could see a future where cmake adds support forCMAKE_OSX_DEPLOYMENT_TARGETdefaulting toIPHONEOS_DEPLOYMENT_TARGET, in which case using environment variables as the canonical way to set the deployment target might be the way to go anyways, rather than aConfigvariable (with the added benefit that it takes cmake-rs out of the loop).