Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[feature] Build variants to manage iOS/OSX universal binaries #9903

@gmeeker

Description

@gmeeker

Although using CMake with Xcode supports universal binaries, many libraries are using other build systems. This has been discussed in conan-io/conan-extensions#59 but it's complicated and specific to Apple. It's also apparently an issue for Android as discussed in #6384 (I'm not familiar with Android.)

This proposal, however, is to create a general purpose framework for calling the build tools multiple times, and then combining them (e.g. with 'lipo' on iOS/OSX). Using pyreq it could look like this:

from conans import ConanFile, Variants

class ExampleVariants(Variants):
    name = "variants_pyreq"
    version = "1.0"

    def conanfile(self):
        return super(ExampleVariants, self)

    def package(self):
        self.package_variants()
        print("package: running lipo")
        # self.run("lipo ...")

class ExampleVariantsConanFile(ConanFile):
    name = "variants_pyreq"
    version = "1.0"
from conans import ConanFile, Variants

# using pyreq makes the class hierarchy like this:
# class LipoConan(Variants, ConanFile):

class ExampleConan(ConanFile):
    name = "variants_example"
    version = "1.0"
    settings = "arch", "os"
    python_requires = "variants_pyreq/1.0@user/testing"
    python_requires_extend = "variants_pyreq.ExampleVariants"

    def configure(self):
        """ usual configure here """
        # self.set_variants("x86_64 armv8")
        # self.set_variants(self.settings.multiarch)
        self.set_variants([
            {"arch": "x86_64", "os.version": "10.13", "display_name": "Intel", "folder": "x86_64"},
            {"arch": "armv8", "os.version": "11.0", "display_name": "M1", "folder": "armv8"},
        ])

    def build_variant(self):
        print("build", self.settings.arch)

    def package_variant(self):
        print("package", self.settings.arch)

Note that Variants is a separate mix-in class, not a subclass of ConanFile. This works better for pyreq and also middleware (see below). Variants is only responsible for cloning the ConanFile instance for each variant and run build(), package() and test() in a subfolder (currently "variants/x86_64", etc.) It also handles settings for each variant, including adapting package_id(). Options are not handled per variant, although maybe we should consider this? Some libraries have processor specific options for SSE, etc. See the docstrings for Variants for more details, and how super() and MRO affect this.

My current implementation contains few changes outside of the new Variants flag, no new settings, and nothing OS specific. Perhaps lipo support could be included in conan eventually, but that's beyond the scope of this feature request. A more complete example using lipo for Apple is here:
https://github.com/gmeeker/conan-lipo-middleware/pyreq

Note, however, that each recipe must be customized to support variants. #9636 will address this with middleware to adapt existing recipes (like CCI) and can work with variants. It turned out to be the more complicated of the two, and variants is likely to get more attention.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions