@@ -163,70 +163,77 @@ def add(mode, rootpathsrc, rootpathdst):
163163 dirnames .extend (new_dirnames )
164164
165165
166+ class Options :
167+ def __init__ (self ):
168+ self .export_name = 'Module'
169+ self .has_preloaded = False
170+ self .jsoutput = None
171+ self .from_emcc = False
172+ self .force = True
173+ # If set to True, IndexedDB (IDBFS in library_idbfs.js) is used to locally
174+ # cache VFS XHR so that subsequent page loads can read the data from the
175+ # offline cache instead.
176+ self .use_preload_cache = False
177+ self .indexeddb_name = 'EM_PRELOAD_CACHE'
178+ # If set to True, the package metadata is stored separately from js-output
179+ # file which makes js-output file immutable to the package content changes.
180+ # If set to False, the package metadata is stored inside the js-output file
181+ # which makes js-output file to mutate on each invocation of this packager tool.
182+ self .separate_metadata = False
183+ self .lz4 = False
184+ self .use_preload_plugins = False
185+ self .support_node = True
186+
187+
188+ options = Options ()
189+
190+
166191def main ():
167192 data_files = []
168- export_name = 'Module'
169- leading = ''
170- has_preloaded = False
171193 plugins = []
172- jsoutput = None
173- from_emcc = False
174- force = True
175- # If set to True, IndexedDB (IDBFS in library_idbfs.js) is used to locally
176- # cache VFS XHR so that subsequent page loads can read the data from the
177- # offline cache instead.
178- use_preload_cache = False
179- indexeddb_name = 'EM_PRELOAD_CACHE'
180- # If set to True, the package metadata is stored separately from js-output
181- # file which makes js-output file immutable to the package content changes.
182- # If set to False, the package metadata is stored inside the js-output file
183- # which makes js-output file to mutate on each invocation of this packager tool.
184- separate_metadata = False
185- lz4 = False
186- use_preload_plugins = False
187- support_node = True
194+ leading = ''
188195
189196 for arg in sys .argv [2 :]:
190197 if arg == '--preload' :
191- has_preloaded = True
198+ options . has_preloaded = True
192199 leading = 'preload'
193200 elif arg == '--embed' :
194201 leading = 'embed'
195202 elif arg == '--exclude' :
196203 leading = 'exclude'
197204 elif arg == '--no-force' :
198- force = False
205+ options . force = False
199206 leading = ''
200207 elif arg == '--use-preload-cache' :
201- use_preload_cache = True
208+ options . use_preload_cache = True
202209 leading = ''
203210 elif arg .startswith ('--indexedDB-name' ):
204- indexeddb_name = arg .split ('=' , 1 )[1 ] if '=' in arg else None
211+ options . indexeddb_name = arg .split ('=' , 1 )[1 ] if '=' in arg else None
205212 leading = ''
206213 elif arg == '--no-heap-copy' :
207214 print ('ignoring legacy flag --no-heap-copy (that is the only mode supported now)' )
208215 leading = ''
209216 elif arg == '--separate-metadata' :
210- separate_metadata = True
217+ options . separate_metadata = True
211218 leading = ''
212219 elif arg == '--lz4' :
213- lz4 = True
220+ options . lz4 = True
214221 leading = ''
215222 elif arg == '--use-preload-plugins' :
216- use_preload_plugins = True
223+ options . use_preload_plugins = True
217224 leading = ''
218225 elif arg == '--no-node' :
219- support_node = False
226+ options . support_node = False
220227 leading = ''
221228 elif arg .startswith ('--js-output' ):
222- jsoutput = arg .split ('=' , 1 )[1 ] if '=' in arg else None
229+ options . jsoutput = arg .split ('=' , 1 )[1 ] if '=' in arg else None
223230 leading = ''
224231 elif arg .startswith ('--export-name' ):
225232 if '=' in arg :
226- export_name = arg .split ('=' , 1 )[1 ]
233+ options . export_name = arg .split ('=' , 1 )[1 ]
227234 leading = ''
228235 elif arg .startswith ('--from-emcc' ):
229- from_emcc = True
236+ options . from_emcc = True
230237 leading = ''
231238 elif arg .startswith ('--plugin' ):
232239 with open (arg .split ('=' , 1 )[1 ]) as f :
@@ -260,46 +267,23 @@ def main():
260267 print ('Unknown parameter:' , arg , file = sys .stderr )
261268 return 1
262269
263- if (not force ) and not data_files :
264- has_preloaded = False
265- if not has_preloaded or jsoutput is None :
266- assert not separate_metadata , (
270+ if (not options . force ) and not data_files :
271+ options . has_preloaded = False
272+ if not options . has_preloaded or options . jsoutput is None :
273+ assert not options . separate_metadata , (
267274 'cannot separate-metadata without both --preloaded files '
268275 'and a specified --js-output' )
269276
270- if not from_emcc :
277+ if not options . from_emcc :
271278 print ('Remember to build the main file with -s FORCE_FILESYSTEM=1 '
272279 'so that it includes support for loading this file package' ,
273280 file = sys .stderr )
274281
275- if jsoutput and os .path .abspath (jsoutput ) == os .path .abspath (data_target ):
282+ if options . jsoutput and os .path .abspath (options . jsoutput ) == os .path .abspath (data_target ):
276283 print ('error: TARGET should not be the same value of --js-output' ,
277284 file = sys .stderr )
278285 return 1
279286
280- ret = ''
281- # emcc will add this to the output itself, so it is only needed for
282- # standalone calls
283- if not from_emcc :
284- ret = '''
285- var Module = typeof %(EXPORT_NAME)s !== 'undefined' ? %(EXPORT_NAME)s : {};\n ''' % {"EXPORT_NAME" : export_name }
286-
287- ret += '''
288- if (!Module.expectedDataFileDownloads) {
289- Module.expectedDataFileDownloads = 0;
290- }
291- Module.expectedDataFileDownloads++;
292- (function() {
293- // When running as a pthread, FS operations are proxied to the main thread, so we don't need to
294- // fetch the .data bundle on the worker
295- if (Module['ENVIRONMENT_IS_PTHREAD']) return;
296- var loadPackage = function(metadata) {\n '''
297-
298- code = '''
299- function assert(check, msg) {
300- if (!check) throw msg + new Error().stack;
301- }\n '''
302-
303287 for file_ in data_files :
304288 if not should_ignore (file_ ['srcpath' ]):
305289 if os .path .isdir (file_ ['srcpath' ]):
@@ -377,6 +361,56 @@ def was_seen(name):
377361
378362 metadata = {'files' : []}
379363
364+ ret = generate_js (data_files , metadata )
365+
366+ if options .force or len (data_files ):
367+ if options .jsoutput is None :
368+ print (ret )
369+ else :
370+ # Overwrite the old jsoutput file (if exists) only when its content
371+ # differs from the current generated one, otherwise leave the file
372+ # untouched preserving its old timestamp
373+ if os .path .isfile (options .jsoutput ):
374+ with open (options .jsoutput ) as f :
375+ old = f .read ()
376+ if old != ret :
377+ with open (options .jsoutput , 'w' ) as f :
378+ f .write (ret )
379+ else :
380+ with open (options .jsoutput , 'w' ) as f :
381+ f .write (ret )
382+ if options .separate_metadata :
383+ with open (options .jsoutput + '.metadata' , 'w' ) as f :
384+ json .dump (metadata , f , separators = (',' , ':' ))
385+
386+ return 0
387+
388+
389+ def generate_js (data_files , metadata ):
390+ # emcc will add this to the output itself, so it is only needed for
391+ # standalone calls
392+ if options .from_emcc :
393+ ret = ''
394+ else :
395+ ret = '''
396+ var Module = typeof %(EXPORT_NAME)s !== 'undefined' ? %(EXPORT_NAME)s : {};\n ''' % {"EXPORT_NAME" : options .export_name }
397+
398+ ret += '''
399+ if (!Module.expectedDataFileDownloads) {
400+ Module.expectedDataFileDownloads = 0;
401+ }
402+ Module.expectedDataFileDownloads++;
403+ (function() {
404+ // When running as a pthread, FS operations are proxied to the main thread, so we don't need to
405+ // fetch the .data bundle on the worker
406+ if (Module['ENVIRONMENT_IS_PTHREAD']) return;
407+ var loadPackage = function(metadata) {\n '''
408+
409+ code = '''
410+ function assert(check, msg) {
411+ if (!check) throw msg + new Error().stack;
412+ }\n '''
413+
380414 # Set up folders
381415 partial_dirs = []
382416 for file_ in data_files :
@@ -391,7 +425,7 @@ def was_seen(name):
391425 % (json .dumps ('/' + '/' .join (parts [:i ])), json .dumps (parts [i ])))
392426 partial_dirs .append (partial )
393427
394- if has_preloaded :
428+ if options . has_preloaded :
395429 # Bundle all datafiles into one archive. Avoids doing lots of simultaneous
396430 # XHRs which has overhead.
397431 start = 0
@@ -430,7 +464,7 @@ def was_seen(name):
430464 Module['removeRunDependency']('fp ' + that.name);
431465 '''
432466
433- if not lz4 :
467+ if not options . lz4 :
434468 # Data requests - for getting a block of data out of the big archive - have
435469 # a similar API to XHRs
436470 code += '''
@@ -462,7 +496,7 @@ def was_seen(name):
462496 var files = metadata['files'];
463497 for (var i = 0; i < files.length; ++i) {
464498 new DataRequest(files[i]['start'], files[i]['end'], files[i]['audio'] || 0).open('GET', files[i]['filename']);
465- }\n ''' % (create_preloaded if use_preload_plugins else create_data )
499+ }\n ''' % (create_preloaded if options . use_preload_plugins else create_data )
466500
467501 for (counter , file_ ) in enumerate (data_files ):
468502 filename = file_ ['dstpath' ]
@@ -488,8 +522,8 @@ def was_seen(name):
488522 else :
489523 assert 0
490524
491- if has_preloaded :
492- if not lz4 :
525+ if options . has_preloaded :
526+ if not options . lz4 :
493527 # Get the big archive and split it up
494528 use_data = '''
495529 // Reuse the bytearray from the XHR as the source for file reads.
@@ -516,7 +550,7 @@ def was_seen(name):
516550 assert(typeof Module['LZ4'] === 'object', 'LZ4 not present - was your app build with -s LZ4=1 ?');
517551 Module['LZ4'].loadPackage({ 'metadata': metadata, 'compressedData': compressedData }, %s);
518552 Module['removeRunDependency']('datafile_%s');
519- ''' % (meta , "true" if use_preload_plugins else "false" , js_manipulation .escape_for_js_string (data_target ))
553+ ''' % (meta , "true" if options . use_preload_plugins else "false" , js_manipulation .escape_for_js_string (data_target ))
520554
521555 package_uuid = uuid .uuid4 ()
522556 package_name = data_target
@@ -546,7 +580,7 @@ def was_seen(name):
546580 var PACKAGE_UUID = metadata['package_uuid'];
547581 '''
548582
549- if use_preload_cache :
583+ if options . use_preload_cache :
550584 code += r'''
551585 var indexedDB;
552586 if (typeof window === 'object') {
@@ -559,7 +593,7 @@ def was_seen(name):
559593 }
560594 var IDB_RO = "readonly";
561595 var IDB_RW = "readwrite";
562- var DB_NAME = "''' + indexeddb_name + '''";
596+ var DB_NAME = "''' + options . indexeddb_name + '''";
563597 var DB_VERSION = 1;
564598 var METADATA_STORE_NAME = 'METADATA';
565599 var PACKAGE_STORE_NAME = 'PACKAGES';
@@ -712,7 +746,7 @@ def was_seen(name):
712746
713747 # add Node.js support code, if necessary
714748 node_support_code = ''
715- if support_node :
749+ if options . support_node :
716750 node_support_code = '''
717751 if (typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node === 'string') {
718752 require('fs').readFile(packageName, function(err, contents) {
@@ -793,7 +827,7 @@ def was_seen(name):
793827 code += '''
794828 if (!Module.preloadResults) Module.preloadResults = {};\n '''
795829
796- if use_preload_cache :
830+ if options . use_preload_cache :
797831 code += '''
798832 function preloadFallback(error) {
799833 console.error(error);
@@ -864,7 +898,7 @@ def was_seen(name):
864898 Module["preRun"].push(runWithFS); // FS is not initialized yet, wait for it
865899 }\n '''
866900
867- if separate_metadata :
901+ if options . separate_metadata :
868902 _metadata_template = '''
869903 Module['removeRunDependency']('%(metadata_file)s');
870904 }
@@ -888,7 +922,7 @@ def was_seen(name):
888922 } else {
889923 if (!Module['preRun']) Module['preRun'] = [];
890924 Module["preRun"].push(runMetaWithFS);
891- }\n ''' % {'metadata_file' : os .path .basename (jsoutput + '.metadata' )}
925+ }\n ''' % {'metadata_file' : os .path .basename (options . jsoutput + '.metadata' )}
892926
893927 else :
894928 _metadata_template = '''
@@ -898,27 +932,7 @@ def was_seen(name):
898932 ret += '''%s
899933 })();\n ''' % _metadata_template
900934
901- if force or len (data_files ):
902- if jsoutput is None :
903- print (ret )
904- else :
905- # Overwrite the old jsoutput file (if exists) only when its content
906- # differs from the current generated one, otherwise leave the file
907- # untouched preserving its old timestamp
908- if os .path .isfile (jsoutput ):
909- with open (jsoutput ) as f :
910- old = f .read ()
911- if old != ret :
912- with open (jsoutput , 'w' ) as f :
913- f .write (ret )
914- else :
915- with open (jsoutput , 'w' ) as f :
916- f .write (ret )
917- if separate_metadata :
918- with open (jsoutput + '.metadata' , 'w' ) as f :
919- json .dump (metadata , f , separators = (',' , ':' ))
920-
921- return 0
935+ return ret
922936
923937
924938if __name__ == '__main__' :
0 commit comments