config/expandlibs.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 # This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 # License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
michael@0 4
michael@0 5 '''Expandlibs is a system that allows to replace some libraries with a
michael@0 6 descriptor file containing some linking information about them.
michael@0 7
michael@0 8 The descriptor file format is as follows:
michael@0 9 ---8<-----
michael@0 10 OBJS = a.o b.o ...
michael@0 11 LIBS = libfoo.a libbar.a ...
michael@0 12 --->8-----
michael@0 13
michael@0 14 (In the example above, OBJ_SUFFIX is o and LIB_SUFFIX is a).
michael@0 15
michael@0 16 Expandlibs also canonicalizes how to pass libraries to the linker, such
michael@0 17 that only the ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} form needs to be used:
michael@0 18 given a list of files, expandlibs will replace items with the form
michael@0 19 ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} following these rules:
michael@0 20
michael@0 21 - If a ${DLL_PREFIX}${ROOT}.${DLL_SUFFIX} or
michael@0 22 ${DLL_PREFIX}${ROOT}.${IMPORT_LIB_SUFFIX} file exists, use that instead
michael@0 23 - If the ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} file exists, use it
michael@0 24 - If a ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX}.${LIB_DESC_SUFFIX} file exists,
michael@0 25 replace ${LIB_PREFIX}${ROOT}.${LIB_SUFFIX} with the OBJS and LIBS the
michael@0 26 descriptor contains. And for each of these LIBS, also apply the same
michael@0 27 rules.
michael@0 28 '''
michael@0 29 from __future__ import with_statement
michael@0 30 import sys, os, errno
michael@0 31 import expandlibs_config as conf
michael@0 32
michael@0 33 def ensureParentDir(file):
michael@0 34 '''Ensures the directory parent to the given file exists'''
michael@0 35 dir = os.path.dirname(file)
michael@0 36 if dir and not os.path.exists(dir):
michael@0 37 try:
michael@0 38 os.makedirs(dir)
michael@0 39 except OSError, error:
michael@0 40 if error.errno != errno.EEXIST:
michael@0 41 raise
michael@0 42
michael@0 43 def relativize(path):
michael@0 44 '''Returns a path relative to the current working directory, if it is
michael@0 45 shorter than the given path'''
michael@0 46 def splitpath(path):
michael@0 47 dir, file = os.path.split(path)
michael@0 48 if os.path.splitdrive(dir)[1] == os.sep:
michael@0 49 return [file]
michael@0 50 return splitpath(dir) + [file]
michael@0 51
michael@0 52 if not os.path.exists(path):
michael@0 53 return path
michael@0 54 curdir = splitpath(os.path.abspath(os.curdir))
michael@0 55 abspath = splitpath(os.path.abspath(path))
michael@0 56 while curdir and abspath and curdir[0] == abspath[0]:
michael@0 57 del curdir[0]
michael@0 58 del abspath[0]
michael@0 59 if not curdir and not abspath:
michael@0 60 return '.'
michael@0 61 relpath = os.path.join(*[os.pardir for i in curdir] + abspath)
michael@0 62 if len(path) > len(relpath):
michael@0 63 return relpath
michael@0 64 return path
michael@0 65
michael@0 66 def isObject(path):
michael@0 67 '''Returns whether the given path points to an object file, that is,
michael@0 68 ends with OBJ_SUFFIX or .i_o'''
michael@0 69 return os.path.splitext(path)[1] in [conf.OBJ_SUFFIX, '.i_o']
michael@0 70
michael@0 71 def isDynamicLib(path):
michael@0 72 '''Returns whether the given path points to a dynamic library, that is,
michael@0 73 ends with DLL_SUFFIX.'''
michael@0 74 # On mac, the xul library is named XUL, instead of libxul.dylib. Assume any
michael@0 75 # file by that name is a dynamic library.
michael@0 76 return os.path.splitext(path)[1] == conf.DLL_SUFFIX or os.path.basename(path) == 'XUL'
michael@0 77
michael@0 78 class LibDescriptor(dict):
michael@0 79 KEYS = ['OBJS', 'LIBS']
michael@0 80
michael@0 81 def __init__(self, content=None):
michael@0 82 '''Creates an instance of a lib descriptor, initialized with contents
michael@0 83 from a list of strings when given. This is intended for use with
michael@0 84 file.readlines()'''
michael@0 85 if isinstance(content, list) and all([isinstance(item, str) for item in content]):
michael@0 86 pass
michael@0 87 elif content is not None:
michael@0 88 raise TypeError("LibDescriptor() arg 1 must be None or a list of strings")
michael@0 89 super(LibDescriptor, self).__init__()
michael@0 90 for key in self.KEYS:
michael@0 91 self[key] = []
michael@0 92 if not content:
michael@0 93 return
michael@0 94 for key, value in [(s.strip() for s in item.split('=', 2)) for item in content if item.find('=') >= 0]:
michael@0 95 if key in self.KEYS:
michael@0 96 self[key] = value.split()
michael@0 97
michael@0 98 def __str__(self):
michael@0 99 '''Serializes the lib descriptor'''
michael@0 100 return '\n'.join('%s = %s' % (k, ' '.join(self[k])) for k in self.KEYS if len(self[k]))
michael@0 101
michael@0 102 class ExpandArgs(list):
michael@0 103 def __init__(self, args):
michael@0 104 '''Creates a clone of the |args| list and performs file expansion on
michael@0 105 each item it contains'''
michael@0 106 super(ExpandArgs, self).__init__()
michael@0 107 for arg in args:
michael@0 108 self += self._expand(arg)
michael@0 109
michael@0 110 def _expand(self, arg):
michael@0 111 '''Internal function doing the actual work'''
michael@0 112 (root, ext) = os.path.splitext(arg)
michael@0 113 if ext != conf.LIB_SUFFIX or not os.path.basename(root).startswith(conf.LIB_PREFIX):
michael@0 114 return [relativize(arg)]
michael@0 115 if len(conf.IMPORT_LIB_SUFFIX):
michael@0 116 dll = root + conf.IMPORT_LIB_SUFFIX
michael@0 117 else:
michael@0 118 dll = root.replace(conf.LIB_PREFIX, conf.DLL_PREFIX, 1) + conf.DLL_SUFFIX
michael@0 119 if os.path.exists(dll):
michael@0 120 return [relativize(dll)]
michael@0 121 if os.path.exists(arg):
michael@0 122 return [relativize(arg)]
michael@0 123 return self._expand_desc(arg)
michael@0 124
michael@0 125 def _expand_desc(self, arg):
michael@0 126 '''Internal function taking care of lib descriptor expansion only'''
michael@0 127 if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
michael@0 128 with open(arg + conf.LIBS_DESC_SUFFIX, 'r') as f:
michael@0 129 desc = LibDescriptor(f.readlines())
michael@0 130 objs = [relativize(o) for o in desc['OBJS']]
michael@0 131 for lib in desc['LIBS']:
michael@0 132 objs += self._expand(lib)
michael@0 133 return objs
michael@0 134 return [arg]
michael@0 135
michael@0 136 class ExpandLibsDeps(ExpandArgs):
michael@0 137 '''Same as ExpandArgs, but also adds the library descriptor to the list'''
michael@0 138 def _expand_desc(self, arg):
michael@0 139 objs = super(ExpandLibsDeps, self)._expand_desc(arg)
michael@0 140 if os.path.exists(arg + conf.LIBS_DESC_SUFFIX):
michael@0 141 objs += [relativize(arg + conf.LIBS_DESC_SUFFIX)]
michael@0 142 return objs
michael@0 143
michael@0 144 if __name__ == '__main__':
michael@0 145 print " ".join(ExpandArgs(sys.argv[1:]))

mercurial