summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/build/config/ios/write_framework_hmap.py
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/build/config/ios/write_framework_hmap.py')
-rw-r--r--third_party/libwebrtc/build/config/ios/write_framework_hmap.py103
1 files changed, 103 insertions, 0 deletions
diff --git a/third_party/libwebrtc/build/config/ios/write_framework_hmap.py b/third_party/libwebrtc/build/config/ios/write_framework_hmap.py
new file mode 100644
index 0000000000..ac467ee92a
--- /dev/null
+++ b/third_party/libwebrtc/build/config/ios/write_framework_hmap.py
@@ -0,0 +1,103 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+from __future__ import print_function
+
+import os
+import struct
+import sys
+
+def Main(args):
+ if len(args) < 4:
+ print(
+ "Usage: %s output.hmap Foo.framework header1.h..." % args[0],
+ file=sys.stderr)
+ return 1
+
+ (out, framework, all_headers) = args[1], args[2], args[3:]
+
+ framework_name = os.path.basename(framework).split('.')[0]
+ all_headers = map(os.path.abspath, all_headers)
+ filelist = {}
+ for header in all_headers:
+ filename = os.path.basename(header)
+ filelist[filename] = header
+ filelist[os.path.join(framework_name, filename)] = header
+ WriteHmap(out, filelist)
+ return 0
+
+
+def NextGreaterPowerOf2(x):
+ return 2**(x).bit_length()
+
+
+def WriteHmap(output_name, filelist):
+ """Generates a header map based on |filelist|.
+
+ Per Mark Mentovai:
+ A header map is structured essentially as a hash table, keyed by names used
+ in #includes, and providing pathnames to the actual files.
+
+ The implementation below and the comment above comes from inspecting:
+ http://www.opensource.apple.com/source/distcc/distcc-2503/distcc_dist/include_server/headermap.py?txt
+ while also looking at the implementation in clang in:
+ https://llvm.org/svn/llvm-project/cfe/trunk/lib/Lex/HeaderMap.cpp
+ """
+ magic = 1751998832
+ version = 1
+ _reserved = 0
+ count = len(filelist)
+ capacity = NextGreaterPowerOf2(count)
+ strings_offset = 24 + (12 * capacity)
+ max_value_length = len(max(filelist.values(), key=lambda v: len(v)))
+
+ out = open(output_name, 'wb')
+ out.write(struct.pack('<LHHLLLL', magic, version, _reserved, strings_offset,
+ count, capacity, max_value_length))
+
+ # Create empty hashmap buckets.
+ buckets = [None] * capacity
+ for file, path in filelist.items():
+ key = 0
+ for c in file:
+ key += ord(c.lower()) * 13
+
+ # Fill next empty bucket.
+ while buckets[key & capacity - 1] is not None:
+ key = key + 1
+ buckets[key & capacity - 1] = (file, path)
+
+ next_offset = 1
+ for bucket in buckets:
+ if bucket is None:
+ out.write(struct.pack('<LLL', 0, 0, 0))
+ else:
+ (file, path) = bucket
+ key_offset = next_offset
+ prefix_offset = key_offset + len(file) + 1
+ suffix_offset = prefix_offset + len(os.path.dirname(path) + os.sep) + 1
+ next_offset = suffix_offset + len(os.path.basename(path)) + 1
+ out.write(struct.pack('<LLL', key_offset, prefix_offset, suffix_offset))
+
+ # Pad byte since next offset starts at 1.
+ out.write(struct.pack('<x'))
+
+ for bucket in buckets:
+ if bucket is not None:
+ (file, path) = bucket
+ base = os.path.dirname(path) + os.sep
+ path = os.path.basename(path)
+ file = file.encode('UTF-8')
+ base = base.encode('UTF-8')
+ path = path.encode('UTF-8')
+ out.write(struct.pack('<%ds' % len(file), file))
+ out.write(struct.pack('<s', b'\0'))
+ out.write(struct.pack('<%ds' % len(base), base))
+ out.write(struct.pack('<s', b'\0'))
+ out.write(struct.pack('<%ds' % len(path), path))
+ out.write(struct.pack('<s', b'\0'))
+
+
+if __name__ == '__main__':
+ sys.exit(Main(sys.argv))