Generate our CROSSTOOL

I want to add a second cortex-m4f one, which is mostly the same, and not
have to maintain two of them. Actually doing that is coming in a
separate change.

Change-Id: I6e985de31b7741a7aa27a1d221d28623192f0a08
diff --git a/tools/cpp/gen_crosstool.py b/tools/cpp/gen_crosstool.py
new file mode 100644
index 0000000..af28c56
--- /dev/null
+++ b/tools/cpp/gen_crosstool.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python3
+
+# Usage: gen_crosstool <base> <cortex_m4f> <output>
+# Example: bazel run //tools/cpp:gen_crosstool $(readlink -f tools/cpp/static_crosstool.pb) $(readlink -f tools/cpp/cortex_m4f_crosstool.pb) $(readlink -f tools/cpp/CROSSTOOL)
+
+import sys
+
+from third_party.bazel.protos import crosstool_config_pb2
+from google.protobuf import text_format
+from google.protobuf.descriptor import FieldDescriptor
+
+def process_string(string, substitutions):
+  for a, b in substitutions.items():
+    string = string.replace(a, b)
+  return string
+
+def rename_message_contents(proto, substitutions):
+  for descriptor, value in proto.ListFields():
+    if descriptor.type == FieldDescriptor.TYPE_STRING:
+      if descriptor.label == FieldDescriptor.LABEL_REPEATED:
+        new_value = []
+        for string in value:
+          new_value.append(process_string(string, substitutions))
+        value[:] = new_value
+      else:
+        setattr(proto, descriptor.name, process_string(value, substitutions))
+    if descriptor.type == FieldDescriptor.TYPE_MESSAGE:
+      if descriptor.label == FieldDescriptor.LABEL_REPEATED:
+        for sub_proto in value:
+          rename_message_contents(sub_proto, substitutions)
+      else:
+        rename_message_contents(value, substitutions)
+
+def add_m4f_toolchain(new_toolchain, m4f_proto, substitutions):
+  new_toolchain.CopyFrom(m4f_proto.toolchain[0])
+  rename_message_contents(new_toolchain, substitutions)
+
+def main(args):
+  crosstool_proto = crosstool_config_pb2.CrosstoolRelease()
+  with open(args[0], 'r') as f:
+    text_format.Merge(f.read(), crosstool_proto)
+
+  m4f_proto = crosstool_config_pb2.CrosstoolRelease()
+  with open(args[1], 'r') as f:
+    text_format.Merge(f.read(), m4f_proto)
+  add_m4f_toolchain(crosstool_proto.toolchain.add(), m4f_proto, {
+      '%NAME%': 'cortex-m4f',
+      '%CPU%': '__MK64FX512__',
+      '%F_CPU%': '120000000',
+      })
+
+  with open(args[2], 'w') as f:
+    f.write('# GENERATED FILE. DO NOT EDIT\n')
+    f.write('# Generated by tools/cpp/gen_crosstool.py\n')
+    f.write(text_format.MessageToString(crosstool_proto))
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv[1:]))