aboutsummaryrefslogtreecommitdiff
path: root/tools/split.py
diff options
context:
space:
mode:
authorLars Schneider <lars.schneider@autodesk.com>2012-09-25 14:44:54 +0200
committerLars Schneider <lars.schneider@autodesk.com>2012-09-26 19:30:19 +0200
commit0c33345f226af403d15f5f83811488aead85b71b (patch)
treecc1787e201bb3184fb901500e94175f22d322c6a /tools/split.py
parentc74da50989604747e3174429d0538f668b4ff7e7 (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-xtools/split.py94
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