|
1 | 1 | #!/usr/bin/python
|
2 | 2 |
|
3 |
| -from os.path import dirname, join |
| 3 | +from os.path import dirname, join, isfile, realpath, relpath, split |
| 4 | +from zipfile import ZipFile |
4 | 5 | import sys
|
5 | 6 | sys.path.insert(0, 'buildlib/jinja2.egg')
|
6 | 7 | sys.path.insert(0, 'buildlib')
|
|
39 | 40 | '.swp',
|
40 | 41 | ]
|
41 | 42 |
|
| 43 | +python_files = [] |
| 44 | + |
| 45 | + |
42 | 46 | # Used by render.
|
43 | 47 | environment = jinja2.Environment(loader=jinja2.FileSystemLoader(
|
44 | 48 | join(curdir, 'templates')))
|
@@ -73,47 +77,97 @@ def is_blacklist(name):
|
73 | 77 | if fnmatch(name, pattern):
|
74 | 78 | return True
|
75 | 79 |
|
| 80 | +def listfiles(d): |
| 81 | + basedir = d |
| 82 | + subdirlist = [] |
| 83 | + for item in os.listdir(d): |
| 84 | + fn = join(d, item) |
| 85 | + if isfile(fn): |
| 86 | + yield fn |
| 87 | + else: |
| 88 | + subdirlist.append(os.path.join(basedir, item)) |
| 89 | + for subdir in subdirlist: |
| 90 | + for fn in listfiles(subdir): |
| 91 | + yield fn |
| 92 | + |
| 93 | +def make_pythonzip(): |
| 94 | + ''' |
| 95 | + Search for all the python related files, and construct the pythonXX.zip |
| 96 | + According to |
| 97 | + # http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html |
| 98 | + site-packages, config and lib-dynload will be not included. |
| 99 | + ''' |
| 100 | + global python_files |
| 101 | + d = realpath(join('private', 'lib', 'python2.7')) |
| 102 | + |
| 103 | + # selector function |
| 104 | + def select(fn): |
| 105 | + if is_blacklist(fn): |
| 106 | + return False |
| 107 | + fn = realpath(fn) |
| 108 | + assert(fn.startswith(d)) |
| 109 | + fn = fn[len(d):] |
| 110 | + if fn.startswith('/site-packages/') or \ |
| 111 | + fn.startswith('/config/') or \ |
| 112 | + fn.startswith('/lib-dynload/'): |
| 113 | + return False |
| 114 | + return fn |
| 115 | + |
| 116 | + # get a list of all python file |
| 117 | + python_files = [x for x in listfiles(d) if select(x)] |
| 118 | + |
| 119 | + # create the final zipfile |
| 120 | + zfn = join('private', 'lib', 'python27.zip') |
| 121 | + zf = ZipFile(zfn, 'w') |
| 122 | + |
| 123 | + # put all the python files in it |
| 124 | + for fn in python_files: |
| 125 | + afn = fn[len(d):] |
| 126 | + zf.write(fn, afn) |
| 127 | + zf.close() |
| 128 | + |
| 129 | + |
76 | 130 | def make_tar(fn, source_dirs, ignore_path=[]):
|
77 | 131 | '''
|
78 | 132 | Make a zip file `fn` from the contents of source_dis.
|
79 | 133 | '''
|
80 | 134 |
|
81 |
| - tf = tarfile.open(fn, 'w:gz') |
| 135 | + # selector function |
| 136 | + def select(fn): |
| 137 | + rfn = realpath(fn) |
| 138 | + if rfn in python_files: |
| 139 | + return False |
| 140 | + return not is_blacklist(fn) |
82 | 141 |
|
| 142 | + # get the files and relpath file of all the directory we asked for |
| 143 | + files = [] |
83 | 144 | for sd in source_dirs:
|
84 | 145 | compile_dir(sd)
|
| 146 | + files += [(x, relpath(realpath(x), sd)) for x in listfiles(sd) if select(x)] |
85 | 147 |
|
86 |
| - sd = os.path.abspath(sd) |
87 |
| - |
88 |
| - for dir, dirs, files in os.walk(sd): |
89 |
| - dirs = [d for d in dirs if not is_blacklist(d)] |
90 |
| - |
91 |
| - ignore = False |
92 |
| - for ip in ignore_path: |
93 |
| - if dir.startswith(ip): |
94 |
| - ignore = True |
95 |
| - if ignore: |
96 |
| - print 'ignored', fn |
97 |
| - continue |
98 |
| - |
99 |
| - for fn in dirs: |
100 |
| - fn = os.path.join(dir, fn) |
101 |
| - relfn = os.path.relpath(fn, sd) |
102 |
| - tf.add(fn, relfn, recursive=False) |
103 |
| - |
104 |
| - for fn in files: |
105 |
| - fn = os.path.join(dir, fn) |
106 |
| - relfn = os.path.relpath(fn, sd) |
107 |
| - if is_blacklist(relfn): |
| 148 | + # create tar.gz of thoses files |
| 149 | + tf = tarfile.open(fn, 'w:gz') |
| 150 | + dirs = [] |
| 151 | + for fn, afn in files: |
| 152 | + dn = dirname(afn) |
| 153 | + if dn not in dirs: |
| 154 | + # create every dirs first if not exist yet |
| 155 | + d = '' |
| 156 | + for component in split(dn): |
| 157 | + d = join(d, component) |
| 158 | + if d.startswith('/'): |
| 159 | + d = d[1:] |
| 160 | + if d == '' or d in dirs: |
108 | 161 | continue
|
109 |
| - tf.add(fn, relfn) |
110 |
| - print 'add', fn |
| 162 | + dirs.append(d) |
| 163 | + tinfo = tarfile.TarInfo(d) |
| 164 | + tinfo.type = tarfile.DIRTYPE |
| 165 | + tf.addfile(tinfo) |
111 | 166 |
|
112 |
| - # TODO: Fix me. |
113 |
| - # tf.writestr('.nomedia', '') |
| 167 | + # put the file |
| 168 | + tf.add(fn, afn) |
114 | 169 | tf.close()
|
115 | 170 |
|
116 |
| - |
117 | 171 | def make_package(args):
|
118 | 172 | version_code = 0
|
119 | 173 | manifest_extra = '<uses-feature android:glEsVersion="0x00020000" />'
|
@@ -181,6 +235,9 @@ def make_package(args):
|
181 | 235 | if os.path.exists('assets/private.mp3'):
|
182 | 236 | os.unlink('assets/private.mp3')
|
183 | 237 |
|
| 238 | + # In order to speedup import and initial depack, |
| 239 | + # construct a python27.zip |
| 240 | + make_pythonzip() |
184 | 241 |
|
185 | 242 | # Package up the private and public data.
|
186 | 243 | if args.private:
|
|
0 commit comments