diff options
author | Lars Schneider <lars.schneider@autodesk.com> | 2012-09-25 14:44:54 +0200 |
---|---|---|
committer | Lars Schneider <lars.schneider@autodesk.com> | 2012-09-26 19:30:19 +0200 |
commit | 0c33345f226af403d15f5f83811488aead85b71b (patch) | |
tree | cc1787e201bb3184fb901500e94175f22d322c6a /tools/split.py | |
parent | c74da50989604747e3174429d0538f668b4ff7e7 (diff) |
Add emcc option "--split <size>" to split javascript file.
Splits the resulting javascript file into pieces to ease debugging.
This option only works if Javascript is generated (target -o <name>.js).
Files with function declarations must be loaded before main file upon execution.
Without "-g" option:
Creates files with function declarations up to the given size with the suffix "_functions.partxxx.js" and a main file with the suffix ".js".
With "-g" option:
Recreates the directory structure of the C source files and stores function declarations in their respective C files with the suffix ".js". If such a file exceeds the given size, files with the suffix ".partxxx.js" are created. The main file resides in the base directory and has the suffix ".js".
Diffstat (limited to 'tools/split.py')
-rwxr-xr-x | tools/split.py | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/tools/split.py b/tools/split.py new file mode 100755 index 00000000..ab1e97ca --- /dev/null +++ b/tools/split.py @@ -0,0 +1,94 @@ +import sys +import os + +def split_javascript_file(input_filename, output_filename_prefix, max_part_size_in_bytes): + + try: + # Contains the entire Emscripten generated Javascript code + input_file = open(input_filename,'r') + + # Javascript main file. On execution, this file needs to be loaded at last (!) + output_main_filename = output_filename_prefix + ".js" + output_main_file = open(output_main_filename,'w') + + # File with HTML script tags to load the Javascript files in HTML later on + output_html_include_file = open(output_filename_prefix + ".include.html",'w') + + # Variable will contain the source of a Javascript function if we find one during parsing + js_function = None + + # Dictionary with source file as key and an array of functions associated to that source file as value + function_buckets = {}; + + output_part_file = None + + # Iterate over Javascript source; write main file; parse function declarations. + for line in input_file: + if line == "//FUNCTION_BEGIN_MARKER\n": + js_function = "//Func\n" + elif line.startswith("//FUNCTION_END_MARKER_OF_SOURCE_FILE_"): + # At the end of the function marker we get the source file that is associated to that function. + associated_source_file_base = line[len("//FUNCTION_END_MARKER_OF_SOURCE_FILE_"):len(line)-1] + + if associated_source_file_base == "NO_SOURCE": + # Functions without associated source file are stored in a file in the base directory + associated_source_file_base = output_filename_prefix + "_functions"; + else: + # Functions with a known associated source file are stored in a file in the directory `output_filename_prefix` + associated_source_file_base = output_filename_prefix + os.path.realpath(associated_source_file_base) + + # Add the function to its respective file + if associated_source_file_base not in function_buckets: + function_buckets[associated_source_file_base] = [] + function_buckets[associated_source_file_base] += [js_function] + + # Clear the function read cache + js_function = None + else: + if js_function is None: + output_main_file.write(line) + else: + js_function += line + + # Iterate over all function buckets and write their functions to the associated files + # An associated file is split into chunks of `max_part_size_in_bytes` + for associated_source_file_base in function_buckets: + # At first we try to name the Javascript source file to match the assoicated source file + `.js` + js_source_file = associated_source_file_base + ".js" + + # Check if the directory of the Javascript source file exists + js_source_dir = os.path.dirname(js_source_file) + if len(js_source_dir) > 0 and not os.path.exists(js_source_dir): + os.makedirs(js_source_dir) + + output_part_file_counter = 0 + output_part_file = None + for js_function in function_buckets[associated_source_file_base]: + if output_part_file is None: + output_html_include_file.write("<script type=\"text/javascript\" src=\"" + js_source_file + "\"></script>") + output_part_file = open(js_source_file,'w') + + output_part_file.write(js_function) + + if output_part_file is not None and output_part_file.tell() > max_part_size_in_bytes: + output_part_file.close() + output_part_file = None + output_part_file_counter += 1 + js_source_file = associated_source_file_base + ".part" + str(output_part_file_counter) + ".js" + + if output_part_file is not None: + output_part_file.close() + output_part_file = None + + # Write the main Javascript file at last to the HTML includes because this file contains the code to start + # the execution of the generated Emscripten application and requires all the extracted functions. + output_html_include_file.write("<script type=\"text/javascript\" src=\"" + output_main_filename + "\"></script>") + + except Exception, e: + print >> sys.stderr, 'error: Splitting of Emscripten generated Javascript failed: %s' % str(e) + + finally: + if input_file is not None: input_file.close() + if output_main_file is not None: output_main_file.close() + if output_part_file is not None: output_part_file.close() + if output_html_include_file is not None: output_html_include_file.close()
\ No newline at end of file |