-
Notifications
You must be signed in to change notification settings - Fork 34
Description
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:
- 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
- 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?