question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

iOS/OSX universal binaries handling

See original GitHub issue

universal (fat) binaries are pretty common for Apple platforms - that’s just binaries for several architectures combined together.

sorry for the long text - but I am trying to describe my use case as detailed as possible 😃 e.g. for OSX it’s common to have x86 + x64 universal binaries, while for iOS it’s usually armv7 + armv7s + arm64/armv8 combined together, plus optionally x86 and x64, if iOS simulator is requied (so from 3 to 5 architectues). same story for other Apple platforms, such as watchOS and tvOS. usually, universal binaries are produced by running multiple builds and then running lipo utility on resulting shared/static libraries. there is alternate approach to run single universal build, but it tends to be complicated and error-prone with configure (autotools) style projects - e.g. such configure scripts need to detect size of pointer, which is ambiguous in case of universal binaries (sizeof(void*) - 4 or 8?).

I need some advice on how to proceed with universal binaries in conan. there are several approaches how it could be done:

  1. conan receipt invokes N builds for N architectures and runs lipo to combine as postprocessing. this is the way I am currently using. typical conan file may look like:
if self.settings.os == "Windows":
   self.build_with_msvc()
else:
   self.build_with_configure()

and then for OSX/iOS it will become much more complicated, like:

if self.settings.os == "Windows":
   self.build_with_msvc()
elif self.settings.os == "iOS":
   arches = ["armv7", "armv7s", "arm64", "i386", "x86_64"]
   for arch in arches :
        self.build_with_configure(arch, "iphoneos")
    self.lipo(arches)
elif self.settings.os == "Macos":
   arches = ["i386", "x86_64"]
   for arch in arches :
        self.build_with_configure(arch, "macos")
    self.lipo(arches)
else:
   self.build_with_configure()

there are few disadvantages of such approach:

  • conanfile has very special path for iOS and Macos, although build process is same as for other NIX* platforms
  • lots of code copy-pasted from package to package for universal binaries handling
  • package “arch” setting is no longer showing the truth, moreover, it’s confusing field in case of universal binaries
  1. build N conan packages for each architecture and then combine them somehow the idea is to build conan packages for each architecture (armv7, arm64, etc) as usual and then somehow combine them into aggregated multi-architecture conan package. I am not sure if it’s even possible now to have some approach for conan package to support multiple settings at the same time, but probably there are more use cases for such combined packages (e.g. Windows tools which may run on both x86 and x64, but not on ARM might have combined x86+x64 indication). probably this approach ends up in some new conan command line, like “conan combine” or “conan lipo” which will run lipo for all libraries from packages to be combined.

some unclear points about this approach:

  • while binaries are in general easy to handle, headers might be tricky part if they are different for different arches (in my practice I just copy headers from sources, but some headers might be generated from the build process and contain definitions like SIZE_OF_VOIDP)
  • anyway, conan somehow needs to know which binaries to process and where are they located (but in worst case, conan still can wildcard *so *a *dylib)
  • some convention on how to identify and describe combined packages shall be developed
  • new conan command will be too OS-specific which might be not good (or useless for other arches?)
  • probably issues with conflict resolution may appear - e.g. if asked for x86 arch, what to install, x86 or x86+x64 package?

Issue Analytics

  • State:open
  • Created 7 years ago
  • Reactions:19
  • Comments:29 (25 by maintainers)

github_iconTop GitHub Comments

8reactions
anton-matosovcommented, Mar 10, 2019

Looks like CMake has direct support for fat binaries now https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_ARCHITECTURES.html I have not tried it yet, but looks promising. If Conan would allow array of target architectures instead of single value it would match cmake (and Xcode) approach and make it easy to integrate

2reactions
canatellacommented, Aug 22, 2019

This kind of many to one flow is still needed on Android when building with the ndk provided cmake toolchain (which is required if you want to build for a recent NDK).

Another approach would be to allow requirements to specify settings. So I could create a parent package that would require a child with android abi armeabi-v7a and the same child with arm64-v8a. Then assemble them in an aar file for Android distribution.

so I could do a

self.build_requires('mypackage/1.0@repo/stable', settings={ 'os.abi': ['armeabi-v7a', 'arm64-v8a']})
Read more comments on GitHub >

github_iconTop Results From Across the Web

Building a Universal macOS Binary - Apple Developer
A universal binary runs natively on both Apple silicon and Intel-based Mac computers, because it contains executable code for both architectures.
Read more >
A deep dive on macOS universal binaries - Juan Cruz Viotti
In both cases, universal binaries played a key role on enabling a smooth CPU architecture transition for both developers and end-users.
Read more >
Creating a universal binary using Intel compiler - Stack Overflow
and creates a universal binary by compiling and linking for both archs and running lipo for gluing them together. However using this command ......
Read more >
TinyClock: a tiny true 5-arch universal Mac OS X single-binary ...
To be fair to Microsoft, they've handled backwards compatibility for ... Because OSX has had the concept of universal binaries for ever,.
Read more >
Compiling for macOS - Godot Docs
scons platform=osx arch=arm64 --jobs=$(sysctl -n hw.logicalcpu). To support both architectures in a single "Universal 2" binary, run the above two commands ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found