|
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