Last active
February 13, 2024 10:09
-
-
Save ovaar/2106071841f1e917f89d10f6d3095638 to your computer and use it in GitHub Desktop.
Conan Macos Universal Binaries recipe
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from conan import ConanFile | |
from conan.tools.apple import is_apple_os | |
from conans import tools | |
from conan.errors import ConanException | |
from pathlib import Path | |
import os | |
import glob | |
import shutil | |
import json | |
class OsxUniversalConan(ConanFile): | |
name = "{PACKAGE_NAME}" | |
version = "{PACKAGE_VERSION}" | |
url = "None" | |
license = "None" | |
settings = "os", "arch", "compiler", "build_type" | |
no_copy_source = True | |
_config_cache=None | |
@property | |
def osx_multi_archs(self): | |
if self._config_cache is None: | |
path = self.lipo_folder / "config.json" | |
_config_cache = json.loads(path.read_text()) | |
return _config_cache | |
@property | |
def osx_archs(self): | |
return list(self.osx_multi_archs.keys()) | |
@property | |
def osx_revisions(self): | |
return list(self.osx_multi_archs.values()) | |
@property | |
def universal_folder(self): | |
return os.path.join(self.package_folder, "universal") | |
def lipo(self, filepath): | |
lipo_args = [] | |
# lipo -create -arch arm64 $dylib -arch x86_64 x86_64/$(basename $dylib) -output package_folder/$(basename $dylib); | |
for arch, rev in self.osx_multi_archs.items(): | |
abs_path:Path = Path(self.lipo_folder) / rev / filepath | |
abs_path.resolve() | |
lipo_args.append(f"-arch {tools.to_apple_arch(arch)} {str(abs_path.resolve())}") | |
output_file:Path = Path(self.package_folder) / filepath | |
if output_file.exists(): | |
output_file.unlink() | |
cmd = f"lipo -create {' '.join(lipo_args)} -output {str(output_file.resolve())}" | |
self.output.info(cmd) | |
self.run(cmd) | |
def package(self): | |
if not is_apple_os(self): | |
raise ConanException("Universal OSX binaries can only be built on macos!") | |
# pkgName/package/.lipo/ | |
self.lipo_folder=Path(self.package_folder) / ".." / ".lipo" | |
if not self.lipo_folder.exists(): | |
raise ConanException("Failed to create Universal Binary package, '.lipo' temporary folder does not exist!") | |
src:Path = self.lipo_folder / self.info.package_id() | |
# Conan clears the package_folder, so copy the .lipo temporary directory | |
shutil.copytree(src=str(src), dst=self.package_folder, dirs_exist_ok=True) | |
self._lib_files=glob.glob(f"{str(src)}/lib/**/*.a", recursive=True) | |
self._lib_files.extend(glob.glob(f"{str(src)}/lib/**/*.dylib", recursive=True)) | |
for i, f in enumerate(self._lib_files): | |
self._lib_files[i] = os.path.relpath(f, str(src)) | |
# Run lipo to combine packages | |
for filename in self._lib_files: | |
self.lipo(filename) | |
def package_info(self): | |
self.cpp_info.includedirs = ["include"] | |
self.cpp_info.libs = tools.collect_libs(self) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment