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

Add iOS Cross-Compilation Support #461

Merged
merged 5 commits into from
Jan 18, 2025

Conversation

Treata11
Copy link
Contributor

Greetings,

Cross-compilation for a macOS target was already supported within this framework. To enable iOS compilations, I've introduced a new flag, IMATH_BUILD_APPLE_FRAMEWORKS, which is set to FALSE by default.

This implementation relies on the iOS-CMake toolchain for building.

Specifically, the following command can be used to build the project for iOS:

cmake -B build -G Xcode -DCMAKE_TOOLCHAIN_FILE=<path to ios.toolchain.cmake> -DPLATFORM=OS64 -DIMATH_BUILD_APPLE_FRAMEWORKS=ON 

Once built, the project can be installed using:

sudo cmake --build build --target install --config Release

The resulting iOS binaries can then be found in: build/src/Imath/Release-iphoneos/Imath-3_2.framework.

Copy link

linux-foundation-easycla bot commented Dec 24, 2024

CLA Signed

The committers listed above are authorized under a signed CLA.

@meshula
Copy link
Contributor

meshula commented Dec 24, 2024

Thanks for thinking of this. I think it would be great to support create an ios framework as you propose, but I'm thinking it would be preferable to base it on the native cmake facilities for ios. As far as I understand it the leetal toolchain files are meant to support old cmake versions. We specify cmake 3.14, which I think is new enough to natively support iOS.

https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_ARCHITECTURES.html
https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-ios-tvos-visionos-or-watchos

Replaced `TBB_USE_APPLE_FRAMEWORKS` with `IMATH_BUILD_APPLE_FRAMEWORKS`.

Signed-off-by: Treata <[email protected]>
@Treata11
Copy link
Contributor Author

Treata11 commented Dec 24, 2024

Thanks for the tips @meshula !

As far as I understand it the leetal toolchain files are meant to support old cmake versions. We specify cmake 3.14, which I think is new enough to natively support iOS.

I wasn't able to produce iOS frameworks with the native CMake 3.14 flags... Are any adjustments in project's settings required for that?

@meshula
Copy link
Contributor

meshula commented Dec 26, 2024

I'd really prefer not to have to ask people to use a toolchain file as it really complicates builds of systems with many components, so hopefully it's possible with CMake. I'm unclear if we need to bump to a later CMake version, or if there's a deeper problem. Adding @dgovil for advice, as he's been deep into producing cmake based framework builds for other projects recently.

@dgovil
Copy link

dgovil commented Dec 26, 2024

You shouldn't need toolchains if using recent CMake versions like 3.19 for iOS I believe and 3.28 for visionOS.

You can just set the CMAKE_SYSTEM_NAME to the appropriate platform version, and it'll find the correct SDK toolchain for you automatically.

@meshula
Copy link
Contributor

meshula commented Dec 26, 2024

Thanks! If 3.19 works, we could bump the min version.

@Treata11
Copy link
Contributor Author

Treata11 commented Jan 2, 2025

@meshula

I double checked it. V3.14 is sufficient to support Apple Frameworks builds (except for xrOS).
I'll depend on CMake's official terms & open the PR once it's done.

@Treata11 Treata11 closed this Jan 2, 2025
@Treata11
Copy link
Contributor Author

Treata11 commented Jan 2, 2025

@meshula It actually worked right out of the box! No further changes were required.

Configure:

cmake -S. -B _build -DIMATH_BUILD_APPLE_FRAMEWORKS=TRUE -DCMAKE_SYSTEM_NAME=iOS 

build:

sudo cmake --build _build --config Release --target install

and the frameworks would be located at: src/Imath/Imath-3_2.framework.

There are two warnings, though:

CMake Warning (dev) at config/LibraryDefine.cmake:88 (install):
  Target 'Imath' was changed to a FRAMEWORK sometime after install().  This
  may result in the wrong install DESTINATION.  Set the FRAMEWORK property
  earlier.
Call Stack (most recent call first):
  src/Imath/CMakeLists.txt:4 (imath_define_library)
This warning is for project developers.  Use -Wno-dev to suppress it.

@Treata11 Treata11 reopened this Jan 2, 2025
@meshula
Copy link
Contributor

meshula commented Jan 3, 2025

Great progress!

CMake Warning (dev) at config/LibraryDefine.cmake:88 (install):
  Target 'Imath' was changed to a FRAMEWORK sometime after install().  This
  may result in the wrong install DESTINATION.  Set the FRAMEWORK property
  earlier.

Did you experiment with "setting the FRAMEWORK property earlier"? It'd be nice to resolve that if possible.

@Treata11
Copy link
Contributor Author

Treata11 commented Jan 3, 2025

Silenced the warning.

@Vertexwahn
Copy link
Contributor

BTW: I do not know if this is an option for you but Bazel support on Apple is quite good (e.g. https://github.com/bazelbuild/rules_apple) and there is also a Bazelized version of OpenEXR...

@Treata11
Copy link
Contributor Author

Treata11 commented Jan 9, 2025

@Vertexwahn

BTW: I do not know if this is an option for you but Bazel support on Apple is quite good (e.g. https://github.com/bazelbuild/rules_apple) and there is also a Bazelized version of OpenEXR...

Never heard of them...
Does this Bazelized version of OpenEXR come with support for iOS-derived builds?

@Treata11
Copy link
Contributor Author

Treata11 commented Jan 9, 2025

@meshula
Is there anything else that has be handled in this PR?
Any updates in the readme or Github's CI?

@Vertexwahn
Copy link
Contributor

@Treata11 No - but I think this is something one could get working. Depends a bit what you want to achive - do you need a objc_library - do you want to consume it in a Swift App? Some hints -> https://baracoda.com/blog/ios-framework-bazel - was just a quick idea, since I would personally go this way when I have to ship an iOS app. For instance, there is https://github.com/MobileNativeFoundation/rules_xcodeproj that allows you to work in Xcode... etc. - was just an idea in the case you would already on the Bazel train for your iOS developments - for Android this would work similar https://github.com/bazelbuild/rules_android

@meshula
Copy link
Contributor

meshula commented Jan 10, 2025

@Treata11 I'm traveling this week, so won't be able to pull and test until next week. AFAIK, your PR is complete as is!

@meshula
Copy link
Contributor

meshula commented Jan 16, 2025

LGTM!

@cary-ilm
Copy link
Member

Catching up on this after being away. Thanks for the contribution! It would be good to validate this in the CI, especially to confirm the proper files get installed. I'll submit a separate PR for that, since I recently made it a complicated and haven't yet properly documented the process.

@cary-ilm cary-ilm merged commit e4fe355 into AcademySoftwareFoundation:main Jan 18, 2025
25 checks passed
@cary-ilm
Copy link
Member

@Treata11, I noticed that the iOS cross compilation installs libImath.dylib as a binary itself, whereas the regular build installs it as a symlink to a shared object versioned with the soname. For historical reasons, we include the software release number as file suffixes (-3_2), but the .dylib is also previxed by the soname, i.e.:

libImath-3_2.30.3.2.0.dylib - the shared library
libImath-3_2.30.dylib -> libImath-3_2.30.3.2.0.dylib
libImath-3_2.dylib -> libImath-3_2.30.dylib
libImath.dylib -> libImath-3_2.dylib

I have no experience with iOS dev and minimal experience with macOS in general, so I'm not sure of the best practices here, just wondering if the symlink to the soname-versioned .dylib is something we should support for iOS.

I submitted #465 to extend the CI to validate the iOS build.

@Treata11
Copy link
Contributor Author

@cary-ilm,

For historical reasons, we include the software release number as file suffixes (-3_2), but the .dylib is also previxed by the soname, i.e.:

I actually wanted to ask about this... The generated frameworks & the binary inside were both having the version number as their suffix.
Isn't that intended?

OUTPUT_NAME "${libname}${IMATH_LIB_SUFFIX}"

The name of the dylibs & the framework bundles can be overwritten with a simple framework-property OUTPUT_NAME. I think I fixed the issue & I'll open a new PR for it.

FRAMEWORK TRUE
FRAMEWORK_VERSION IMATH_LIB_VERSION
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER github.com/AcademySoftwareFoundation/Imath
OUTPUT_NAME "imath"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cary-ilm
This overwrote the binary's name with version suffix.

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