summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiago.sousa.santos@collabora.com>2013-03-07 12:36:32 -0300
committerThiago Santos <thiago.sousa.santos@collabora.com>2013-03-07 16:02:43 -0300
commit609202624cdfa04957afa12eaa298249ebce4788 (patch)
tree92f7c395b620dc4b8e2e1551a64801a2c95ac56b
parentf24cd6c2b32f0e5b1493ddd4539daf684eb06e5e (diff)
xcode: fwlib: make static framework generator handle both thin and fat libs
Static library frameworks can be generated with both a fat and a thin binary, depends on the arch selected for the build. In case it is a fat library, extra work is required to split the fat small libraries into its thin parts, merge their objects together separately and then create a new fat library from the merged thing versions
-rw-r--r--cerbero/ide/xcode/fwlib.py65
1 files changed, 54 insertions, 11 deletions
diff --git a/cerbero/ide/xcode/fwlib.py b/cerbero/ide/xcode/fwlib.py
index a81c535..aa0682e 100644
--- a/cerbero/ide/xcode/fwlib.py
+++ b/cerbero/ide/xcode/fwlib.py
@@ -77,20 +77,63 @@ class StaticFrameworkLibrary(FrameworkLibrary):
def _get_lib_file_name(self, lib):
return 'lib%s.a' % lib
+ def _split_static_lib(self, lib, thin_arch=None):
+ '''Splits the static lib @lib into its object files
+
+ Splits the static lib @lib into its object files and returns
+ a new temporary directory where the .o files should be found.
+
+ if @thin_arch was provided, it considers the @lib to be a fat
+ binary and takes its thin version for the @thin_arch specified
+ before retrieving the object files.
+ '''
+ lib_tmpdir = tempfile.mkdtemp()
+ shutil.copy(lib, lib_tmpdir)
+ tmplib = os.path.join(lib_tmpdir, os.path.basename(lib))
+
+ if thin_arch: #should be a fat file, split only to the arch we want
+ newname = '%s_%s' % (thin_arch, os.path.basename(lib))
+ shell.call('lipo %s -thin %s -output %s' % (tmplib,
+ thin_arch, newname), lib_tmpdir)
+ tmplib = os.path.join (lib_tmpdir, newname)
+
+ shell.call('ar -x %s' % tmplib, lib_tmpdir)
+ return lib_tmpdir
+
def _create_framework_library(self, libname, install_name, libraries, arch):
tmpdir = tempfile.mkdtemp()
- for lib in libraries:
- libprefix = os.path.split(lib)[-1].replace('.', '_')
- lib_tmpdir = tempfile.mkdtemp()
- shutil.copy(lib, lib_tmpdir)
+ libname = os.path.basename (libname) # just to make sure
+
+ if arch == Architecture.UNIVERSAL:
+ archs = [Architecture.X86, Architecture.ARMv7] #TODO
+ else:
+ archs = [arch]
+
+ archs = [a if a != Architecture.X86 else 'i386' for a in archs]
+
+ for thin_arch in archs:
+ shell.call ('mkdir -p %s' % thin_arch, tmpdir)
+ tmpdir_thinarch = os.path.join(tmpdir, thin_arch)
+
+ for lib in libraries:
+ libprefix = os.path.split(lib)[-1].replace('.', '_')
+
+ if len(archs) > 1: #should be a fat file, split only to the arch we want
+ libprefix += '_%s_' % thin_arch
+ lib_tmpdir = self._split_static_lib(lib, thin_arch)
+ else:
+ lib_tmpdir = self._split_static_lib(lib)
- tmplib = os.path.join(lib_tmpdir, os.path.basename(lib))
- shell.call('ar -x %s' % tmplib, lib_tmpdir)
+ obj_files = shell.ls_files(['*.o'], lib_tmpdir)
+ for obj_f in obj_files:
+ shell.call('cp %s %s' % (os.path.join(lib_tmpdir, obj_f), '%s-%s' % (libprefix, obj_f)), tmpdir_thinarch)
+ shell.call('ar -cqS %s %s-%s' % (libname, libprefix, obj_f), tmpdir_thinarch)
+ shell.call('ar -s %s' % (libname), tmpdir_thinarch)
- obj_files = shell.ls_files(['*.o'], lib_tmpdir)
- for obj_f in obj_files:
- shell.call('cp %s %s' % (os.path.join(lib_tmpdir, obj_f), '%s-%s' % (libprefix, obj_f)), tmpdir)
- shell.call('ar -cqS %s %s-%s' % (libname, libprefix, obj_f), tmpdir)
- shell.call('ar -s %s' % (libname), tmpdir)
+ if len(archs) > 1:
+ #merge the final libs into a fat file again
+ shell.call('lipo %s -create -output %s' % (' '.join([os.path.join(tmpdir, arch, libname) for arch in archs]), install_name), tmpdir)
+ else:
+ shell.call('cp %s %s' % (os.path.join(tmpdir, arch, libname), install_name), tmpdir)