-
Notifications
You must be signed in to change notification settings - Fork 131
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
@@ -383,7 +385,7 @@ impl Config { | |||
if let Some(ref generator) = self.generator { | |||
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.
src/lib.rs
Outdated
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 <kyle@kylefleming.net>
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 <kyle@kylefleming.net>
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 <simlay@users.noreply.github.com> Co-authored-by: Kyle Fleming <kyle@kylefleming.net>
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
target
member variable if it's set, otherwise theTARGET
environment variable) and looks for an ending of-apple-ios
to 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_NAME
is not set, set it toiOS
.CMAKE_OSX_ARCHITECTURES
is not set, set it to the cmake equivalent of the target architecture pulled from thetarget
variable. (cmake equivalents are:arm64
,armv7
,armv7s
,i386
, orx86_64
)CMAKE_OSX_DEPLOYMENT_TARGET
is not set, we look for theIPHONEOS_DEPLOYMENT_TARGET
environment 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_SYSROOT
isn't set, set it to eitheriphoneos
oriphonesimulator
to 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.
-fPIC
and-fembed-bitcode
are 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-fPIC
is 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_NAME
will be set toDarwin
automatically within cmake.I'm not sure 100% how cmake <3.14 handled
CMAKE_OSX_DEPLOYMENT_TARGET
/IPHONEOS_DEPLOYMENT_TARGET
so 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
deploymentTarget
to be aConfig
variable? 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 mentiondeploymentTarget
instead ofosxDeploymentTarget
oriosDeploymentTarget
.)This gets a bit hairy though because
CMAKE_OSX_DEPLOYMENT_TARGET
is also the variable for setting the macOS deployment target when building for a macOS target. Cmake automatically setsCMAKE_OSX_DEPLOYMENT_TARGET
fromMACOSX_DEPLOYMENT_TARGET
whenCMAKE_SYSTEM_NAME
is set toDarwin
but 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
Config
parameter 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_TARGET
defaulting 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 aConfig
variable (with the added benefit that it takes cmake-rs out of the loop).