Add nice skylark wrappers to abstract changing based on compiler etc

Change-Id: I1210ee698e13cab273a9d68d7669f1b0e5c9b7f7
diff --git a/tools/BUILD b/tools/BUILD
new file mode 100644
index 0000000..9e25adc
--- /dev/null
+++ b/tools/BUILD
@@ -0,0 +1,19 @@
+package(default_visibility = ['//visibility:public'])
+
+# Don't use these directly! Use //tools/build_rules/select.bzl instead.
+config_setting(
+  name = 'compiler_clang',
+  values = {'compiler': 'clang'}
+)
+config_setting(
+  name = 'compiler_gcc',
+  values = {'compiler': 'gcc'}
+)
+config_setting(
+  name = 'cpu_k8',
+  values = {'cpu': 'k8'},
+)
+config_setting(
+  name = 'cpu_roborio',
+  values = {'cpu': 'roborio'},
+)
diff --git a/tools/build_rules/select.bzl b/tools/build_rules/select.bzl
new file mode 100644
index 0000000..18701ef
--- /dev/null
+++ b/tools/build_rules/select.bzl
@@ -0,0 +1,63 @@
+# This file contains replacements for select where the keys have more abstract
+# meanings so we can map multiple conditions to the same value easily and
+# quickly find issues where something new isn't handled.
+# It will also make adding ORs when it makes sense easy to do nicely.
+
+all_cpus = ['amd64', 'roborio']
+'''All of the CPUs we know about.'''
+
+'''A select wrapper for CPU architectures.
+
+Args:
+  values: A mapping from architecture names (as strings) to other things.
+          Currently amd64 and roborio are recognized.
+          'else' is also allowed as a default.
+Returns a select which evaluates to the correct element of values.
+'''
+def cpu_select(values):
+  for cpu in all_cpus:
+    if cpu not in values:
+      if 'else' in values:
+        values[cpu] = values['else']
+      else:
+        fail('Need to handle %s CPUs!' % cpu, 'values')
+  for key in values:
+    if key not in all_cpus and key != 'else':
+      fail('Not sure what a %s CPU is!' % key, 'values')
+  return select({
+    '//tools:cpu_k8': values['amd64'],
+    '//tools:cpu_roborio': values['roborio'],
+  })
+
+'''A select wrapper for address space sizes.
+
+Args:
+  values: A mapping from address space sizes (as strings) to other things.
+Returns a select which evaluates to the correct element of values.
+'''
+def address_size_select(values):
+  if '32' not in values:
+    fail('Need to handle 32 bit addresses!', 'values')
+  if '64' not in values:
+    fail('Need to handle 64 bit addresses!', 'values')
+  return select({
+    '//tools:cpu_k8': values['64'],
+    '//tools:cpu_roborio': values['32'],
+  })
+
+'''A select wrapper for compilers.
+
+Args:
+  values: A mapping from compiler names (as strings) to other things.
+          Currently 'gcc' and 'clang' are recognized.
+Returns a select which evaluates to the correct element of values.
+'''
+def compiler_select(values):
+  if 'gcc' not in values:
+    fail('Need to handle gcc!', 'values')
+  if 'clang' not in values:
+    fail('Need to handle clang!', 'values')
+  return select({
+    '//tools:compiler_gcc': values['gcc'],
+    '//tools:compiler_clang': values['clang'],
+  })
diff --git a/tools/cpp/CROSSTOOL b/tools/cpp/CROSSTOOL
index 2390000..baa91b7 100644
--- a/tools/cpp/CROSSTOOL
+++ b/tools/cpp/CROSSTOOL
@@ -164,7 +164,6 @@
       action: "c++-header-parsing"
       action: "c++-header-preprocessing"
       action: "c++-module-compile"
-      flag_group {
 	  flag_group {
         # We always want to compile with -pthread semantics.
 	    flag: "-pthread"