Merge "Add UUIDs for both the logger and parts"
diff --git a/README.md b/README.md
index e588d5c..af5ae6e 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,42 @@
 ```
   2. Allow Bazel's sandboxing to work:
      Follow the direction in `doc/frc971.conf`.
+### Setting up access to a workspace on the build server
+  1. Use ssh-keygen to create a public and private key.
+```console
+# IMPORTANT These are the windows instructions.
+cd ~
+ssh-keygen -f .\.ssh\id_971_rsa
+```
+  2. Send the contents of id_971_rsa.pub to Stephan along with the password that you want to use. WAIT for feedback, as he needs to setup the account.
+```console
+cat .\.ssh\id_971_rsa.pub
+# Then send the stuff that gets printed to Stephan via slack.
+```
+  3. Once you hear back from Stephan, test SSH.
+```console
+ssh [user]@build.frc971.org -p 2222 -i ./ssh/id_971_rsa -L 9971:127.0.0.1:3389
+```
+  4. If that doesnt work, then send the error msg to #coding However, if it does then use the `exit` command and then SSH tunnel.
+```console
+ssh [user]@build.frc971.org -p 2222 -i ./ssh/id_971_rsa -L 971:127.0.0.1:3389
+```
+  5. So at this point you run the Remote Desktop app in windows.
+Once you get there, all you need to do is put `127.0.0.1:9971` for the computer name, and use your SVN usrname.
+Once you get connected accept the server certificate, and then enter your password that you gave Stephan. (Its either something unique or your SVN pwd)
+Then select the Default panel config.
+You can exit the Remote Desktop if you are good w/ the raw cmd line interface.
+And for future logins all you have to do is tunnel and then login using the app.
+Now if you have a graphical application that you are developing (ie spline UI), then you have to run the build command in the Remote Desktop application.
+ 
+# ONE VERY IMPORTANT LAST STEP
+In order for you to be able to commit, you need to run this command, replacing <YOUR EMAIL> w/ your email that is in gerrit.
+```console
+git config --global user.email "<YOUR EMAIL>"
+```
+One thing that also needs to be said is that you DO NOT need to do any of the installation steps, or the step w/ `frc971.conf`.
+If there are any questions, use #coding so that other people who may reach the same issue can refer back to that.
+Some people that you can @ would be Het <--Insert your name here if you are pingable-->
 
 ### Some useful Bazel commands:
   * Build and test everything (on the host system):
diff --git a/aos/BUILD b/aos/BUILD
index a7d691b..286882f 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -466,7 +466,7 @@
         "configuration_test.cc",
     ],
     data = [
-        "//aos/events:pingpong_config.json",
+        "//aos/events:pingpong_config",
         "//aos/events:pong.bfbs",
         "//aos/testdata:test_configs",
     ],
diff --git a/aos/actions/BUILD b/aos/actions/BUILD
index 6276105..14592cf 100644
--- a/aos/actions/BUILD
+++ b/aos/actions/BUILD
@@ -58,7 +58,7 @@
     srcs = [
         "action_test.cc",
     ],
-    data = ["action_test_config.json"],
+    data = [":action_test_config"],
     deps = [
         ":action_lib",
         ":actions_fbs",
diff --git a/aos/aos_dump.cc b/aos/aos_dump.cc
index ac82b95..ef61f6b 100644
--- a/aos/aos_dump.cc
+++ b/aos/aos_dump.cc
@@ -14,6 +14,9 @@
             "If true, fetch the current message on the channel first");
 DEFINE_bool(pretty, false,
             "If true, pretty print the messages on multiple lines");
+DEFINE_bool(print_timestamps, true, "If true, timestamps are printed.");
+DEFINE_uint64(count, 0,
+              "If >0, aos_dump will exit after printing this many messages.");
 
 namespace {
 
@@ -29,14 +32,18 @@
       builder, channel->schema(), static_cast<const uint8_t *>(context.data),
       {FLAGS_pretty, static_cast<size_t>(FLAGS_max_vector_size)});
 
-  if (context.monotonic_remote_time != context.monotonic_event_time) {
-    std::cout << context.realtime_remote_time << " ("
-              << context.monotonic_remote_time << ") delivered "
-              << context.realtime_event_time << " ("
-              << context.monotonic_event_time << "): " << *builder << '\n';
+  if (FLAGS_print_timestamps) {
+    if (context.monotonic_remote_time != context.monotonic_event_time) {
+      std::cout << context.realtime_remote_time << " ("
+                << context.monotonic_remote_time << ") delivered "
+                << context.realtime_event_time << " ("
+                << context.monotonic_event_time << "): " << *builder << '\n';
+    } else {
+      std::cout << context.realtime_event_time << " ("
+                << context.monotonic_event_time << "): " << *builder << '\n';
+    }
   } else {
-    std::cout << context.realtime_event_time << " ("
-              << context.monotonic_event_time << "): " << *builder << '\n';
+    std::cout << *builder << '\n';
   }
 }
 
@@ -58,7 +65,7 @@
       aos::configuration::ReadConfig(FLAGS_config);
 
   const aos::Configuration *config_msg = &config.message();
-  ::aos::ShmEventLoop event_loop(config_msg);
+  aos::ShmEventLoop event_loop(config_msg);
   event_loop.SkipTimingReport();
   event_loop.SkipAosLog();
 
@@ -98,6 +105,8 @@
     LOG(FATAL) << "Multiple channels found with same type";
   }
 
+  uint64_t message_count = 0;
+
   aos::FastStringBuilder str_builder;
 
   for (const aos::Channel *channel : found_channels) {
@@ -106,13 +115,22 @@
           event_loop.MakeRawFetcher(channel);
       if (fetcher->Fetch()) {
         PrintMessage(channel, fetcher->context(), &str_builder);
+        ++message_count;
       }
     }
 
+    if (FLAGS_count > 0 && message_count >= FLAGS_count) {
+      return 0;
+    }
+
     event_loop.MakeRawWatcher(
-        channel, [channel, &str_builder](const aos::Context &context,
-                                         const void * /*message*/) {
+        channel, [channel, &str_builder, &event_loop, &message_count](
+                     const aos::Context &context, const void * /*message*/) {
           PrintMessage(channel, context, &str_builder);
+          ++message_count;
+          if (FLAGS_count > 0 && message_count >= FLAGS_count) {
+            event_loop.Exit();
+          }
         });
   }
 
diff --git a/aos/config.bzl b/aos/config.bzl
index d6dcf1e..8f040d6 100644
--- a/aos/config.bzl
+++ b/aos/config.bzl
@@ -5,16 +5,20 @@
     "transitive_src",
 ])
 
-def aos_config(name, src, flatbuffers = [], deps = [], visibility = None):
+def aos_config(name, src, flatbuffers = [], deps = [], visibility = None, testonly = False):
     _aos_config(
         name = name,
         src = src,
         deps = deps,
         flatbuffers = [expand_label(flatbuffer) + "_reflection_out" for flatbuffer in flatbuffers],
         visibility = visibility,
+        testonly = testonly,
     )
 
 def _aos_config_impl(ctx):
+    config = ctx.actions.declare_file(ctx.label.name + ".json")
+    stripped_config = ctx.actions.declare_file(ctx.label.name + ".stripped.json")
+
     flatbuffers_depset = depset(
         ctx.files.flatbuffers,
         transitive = [dep[AosConfigInfo].transitive_flatbuffers for dep in ctx.attr.deps],
@@ -27,16 +31,23 @@
 
     all_files = flatbuffers_depset.to_list() + src_depset.to_list()
     ctx.actions.run(
-        outputs = [ctx.outputs.config, ctx.outputs.stripped_config],
+        outputs = [config, stripped_config],
         inputs = all_files,
-        arguments = [ctx.outputs.config.path, ctx.outputs.stripped_config.path, ctx.files.src[0].short_path, ctx.bin_dir.path] + [f.path for f in flatbuffers_depset.to_list()],
+        arguments = [config.path, stripped_config.path, ctx.files.src[0].short_path, ctx.bin_dir.path] + [f.path for f in flatbuffers_depset.to_list()],
         progress_message = "Flattening config",
         executable = ctx.executable._config_flattener,
     )
-    return AosConfigInfo(
-        transitive_flatbuffers = flatbuffers_depset,
-        transitive_src = src_depset,
-    )
+    runfiles = ctx.runfiles(files = [config, stripped_config])
+    return [
+        DefaultInfo(
+            files = depset([config, stripped_config]),
+            runfiles = runfiles,
+        ),
+        AosConfigInfo(
+            transitive_flatbuffers = flatbuffers_depset,
+            transitive_src = src_depset,
+        ),
+    ]
 
 _aos_config = rule(
     attrs = {
@@ -56,9 +67,5 @@
             mandatory = False,
         ),
     },
-    outputs = {
-        "config": "%{name}.json",
-        "stripped_config": "%{name}.stripped.json",
-    },
     implementation = _aos_config_impl,
 )
diff --git a/aos/events/BUILD b/aos/events/BUILD
index 2a032e5..5912ac6 100644
--- a/aos/events/BUILD
+++ b/aos/events/BUILD
@@ -106,7 +106,7 @@
     srcs = [
         "ping.cc",
     ],
-    data = ["pingpong_config.json"],
+    data = [":pingpong_config"],
     deps = [
         ":ping_lib",
         ":shm_event_loop",
@@ -171,7 +171,7 @@
     srcs = [
         "pong.cc",
     ],
-    data = ["pingpong_config.json"],
+    data = [":pingpong_config"],
     deps = [
         ":ping_fbs",
         ":pong_fbs",
@@ -187,7 +187,7 @@
 cc_test(
     name = "pingpong_test",
     srcs = ["pingpong_test.cc"],
-    data = [":pingpong_config.json"],
+    data = [":pingpong_config"],
     deps = [
         ":ping_lib",
         ":pong_lib",
@@ -267,7 +267,7 @@
 cc_test(
     name = "simulated_event_loop_test",
     srcs = ["simulated_event_loop_test.cc"],
-    data = ["multinode_pingpong_config.json"],
+    data = [":multinode_pingpong_config"],
     shard_count = 4,
     deps = [
         ":event_loop_param_test",
diff --git a/aos/events/aos_logging.cc b/aos/events/aos_logging.cc
index f831071..d312925 100644
--- a/aos/events/aos_logging.cc
+++ b/aos/events/aos_logging.cc
@@ -19,7 +19,7 @@
           builder.add_message(message_str);
           builder.add_level(
               static_cast<::aos::logging::Level>(message_data.level));
-          builder.add_source(message_data.source);
+          builder.add_source_pid(message_data.source);
           builder.add_name(name_str);
 
           message.Send(builder.Finish());
diff --git a/aos/events/logging/BUILD b/aos/events/logging/BUILD
index 81ab90f..5aba387 100644
--- a/aos/events/logging/BUILD
+++ b/aos/events/logging/BUILD
@@ -148,8 +148,8 @@
     name = "logger_test",
     srcs = ["logger_test.cc"],
     data = [
-        ":multinode_pingpong_config.json",
-        "//aos/events:pingpong_config.json",
+        ":multinode_pingpong_config",
+        "//aos/events:pingpong_config",
     ],
     deps = [
         ":logger",
diff --git a/aos/events/simulated_event_loop.cc b/aos/events/simulated_event_loop.cc
index b2e54bb..a7301bf 100644
--- a/aos/events/simulated_event_loop.cc
+++ b/aos/events/simulated_event_loop.cc
@@ -741,20 +741,27 @@
   DoCallCallback([monotonic_now]() { return monotonic_now; }, context);
 
   msgs_.pop_front();
+  if (token_ != scheduler_->InvalidToken()) {
+    scheduler_->Deschedule(token_);
+    token_ = scheduler_->InvalidToken();
+  }
   if (msgs_.size() != 0) {
     event_.set_event_time(msgs_.front()->context.monotonic_event_time);
     simulated_event_loop_->AddEvent(&event_);
 
     DoSchedule(event_.event_time());
-  } else {
-    token_ = scheduler_->InvalidToken();
   }
 }
 
 void SimulatedWatcher::DoSchedule(monotonic_clock::time_point event_time) {
-  token_ =
-      scheduler_->Schedule(event_time + simulated_event_loop_->send_delay(),
-                           [this]() { simulated_event_loop_->HandleEvent(); });
+  CHECK(token_ == scheduler_->InvalidToken())
+      << ": May not schedule multiple times";
+  token_ = scheduler_->Schedule(
+      event_time + simulated_event_loop_->send_delay(), [this]() {
+        DCHECK(token_ != scheduler_->InvalidToken());
+        token_ = scheduler_->InvalidToken();
+        simulated_event_loop_->HandleEvent();
+      });
 }
 
 void SimulatedChannel::MakeRawWatcher(SimulatedWatcher *watcher) {
@@ -817,13 +824,11 @@
       simulated_event_loop_->monotonic_now();
   base_ = base;
   repeat_offset_ = repeat_offset;
-  if (base < monotonic_now) {
-    token_ = scheduler_->Schedule(
-        monotonic_now, [this]() { simulated_event_loop_->HandleEvent(); });
-  } else {
-    token_ = scheduler_->Schedule(
-        base, [this]() { simulated_event_loop_->HandleEvent(); });
-  }
+  token_ = scheduler_->Schedule(std::max(base, monotonic_now), [this]() {
+    DCHECK(token_ != scheduler_->InvalidToken());
+    token_ = scheduler_->InvalidToken();
+    simulated_event_loop_->HandleEvent();
+  });
   event_.set_event_time(base_);
   simulated_event_loop_->AddEvent(&event_);
 }
@@ -835,15 +840,20 @@
   if (simulated_event_loop_->log_impl_ != nullptr) {
     logging::SetImplementation(simulated_event_loop_->log_impl_);
   }
+  if (token_ != scheduler_->InvalidToken()) {
+    scheduler_->Deschedule(token_);
+    token_ = scheduler_->InvalidToken();
+  }
   if (repeat_offset_ != ::aos::monotonic_clock::zero()) {
     // Reschedule.
     while (base_ <= monotonic_now) base_ += repeat_offset_;
-    token_ = scheduler_->Schedule(
-        base_, [this]() { simulated_event_loop_->HandleEvent(); });
+    token_ = scheduler_->Schedule(base_, [this]() {
+      DCHECK(token_ != scheduler_->InvalidToken());
+      token_ = scheduler_->InvalidToken();
+      simulated_event_loop_->HandleEvent();
+    });
     event_.set_event_time(base_);
     simulated_event_loop_->AddEvent(&event_);
-  } else {
-    token_ = scheduler_->InvalidToken();
   }
 
   Call([monotonic_now]() { return monotonic_now; }, monotonic_now);
@@ -889,8 +899,15 @@
 
 void SimulatedPhasedLoopHandler::Schedule(
     monotonic_clock::time_point sleep_time) {
-  token_ = scheduler_->Schedule(
-      sleep_time, [this]() { simulated_event_loop_->HandleEvent(); });
+  if (token_ != scheduler_->InvalidToken()) {
+    scheduler_->Deschedule(token_);
+    token_ = scheduler_->InvalidToken();
+  }
+  token_ = scheduler_->Schedule(sleep_time, [this]() {
+    DCHECK(token_ != scheduler_->InvalidToken());
+    token_ = scheduler_->InvalidToken();
+    simulated_event_loop_->HandleEvent();
+  });
   event_.set_event_time(sleep_time);
   simulated_event_loop_->AddEvent(&event_);
 }
diff --git a/aos/ipc_lib/signalfd.cc b/aos/ipc_lib/signalfd.cc
index 363bf4a..051a654 100644
--- a/aos/ipc_lib/signalfd.cc
+++ b/aos/ipc_lib/signalfd.cc
@@ -2,6 +2,9 @@
 
 #include <signal.h>
 #include <sys/types.h>
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#endif
 #include <unistd.h>
 #include <initializer_list>
 
@@ -9,6 +12,50 @@
 
 namespace aos {
 namespace ipc_lib {
+namespace {
+
+// Wrapper which propagates msan information.
+// TODO(Brian): Drop this once we have <https://reviews.llvm.org/D82411> to
+// intercept this function natively.
+int wrapped_sigandset(sigset_t *dest, const sigset_t *left,
+                      const sigset_t *right) {
+#if __has_feature(memory_sanitizer)
+  if (left) {
+    __msan_check_mem_is_initialized(left, sizeof(*left));
+  }
+  if (right) {
+    __msan_check_mem_is_initialized(right, sizeof(*right));
+  }
+#endif
+  const int r = sigandset(dest, left, right);
+#if __has_feature(memory_sanitizer)
+  if (!r && dest) {
+    __msan_unpoison(dest, sizeof(*dest));
+  }
+#endif
+  return r;
+}
+
+// Wrapper which propagates msan information.
+// TODO(Brian): Drop this once we have
+// <https://reviews.llvm.org/rG89ae290b58e20fc5f56b7bfae4b34e7fef06e1b1> to
+// intercept this function natively.
+int wrapped_pthread_sigmask(int how, const sigset_t *set, sigset_t *oldset) {
+#if __has_feature(memory_sanitizer)
+  if (set) {
+    __msan_check_mem_is_initialized(set, sizeof(*set));
+  }
+#endif
+  const int r = pthread_sigmask(how, set, oldset);
+#if __has_feature(memory_sanitizer)
+  if (!r && oldset) {
+    __msan_unpoison(oldset, sizeof(*oldset));
+  }
+#endif
+  return r;
+}
+
+}  // namespace
 
 SignalFd::SignalFd(::std::initializer_list<unsigned int> signals) {
   // Build up the mask with the provided signals.
@@ -23,7 +70,7 @@
   // signalfd gets them. Record which ones we actually blocked, so we can
   // unblock just those later.
   sigset_t old_mask;
-  CHECK_EQ(0, pthread_sigmask(SIG_BLOCK, &blocked_mask_, &old_mask));
+  CHECK_EQ(0, wrapped_pthread_sigmask(SIG_BLOCK, &blocked_mask_, &old_mask));
   for (int signal : signals) {
     if (sigismember(&old_mask, signal)) {
       CHECK_EQ(0, sigdelset(&blocked_mask_, signal));
@@ -35,9 +82,9 @@
   // Unwind the constructor. Unblock the signals and close the fd. Verify nobody
   // else unblocked the signals we're supposed to unblock in the meantime.
   sigset_t old_mask;
-  CHECK_EQ(0, pthread_sigmask(SIG_UNBLOCK, &blocked_mask_, &old_mask));
+  CHECK_EQ(0, wrapped_pthread_sigmask(SIG_UNBLOCK, &blocked_mask_, &old_mask));
   sigset_t unblocked_mask;
-  CHECK_EQ(0, sigandset(&unblocked_mask, &blocked_mask_, &old_mask));
+  CHECK_EQ(0, wrapped_sigandset(&unblocked_mask, &blocked_mask_, &old_mask));
   if (memcmp(&unblocked_mask, &blocked_mask_, sizeof(unblocked_mask)) != 0) {
     LOG(FATAL) << "Some other code unblocked one or more of our signals";
   }
diff --git a/aos/logging/context.cc b/aos/logging/context.cc
index 72c1970..84e4e80 100644
--- a/aos/logging/context.cc
+++ b/aos/logging/context.cc
@@ -4,6 +4,9 @@
 #define _GNU_SOURCE /* See feature_test_macros(7) */
 #endif
 
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#endif
 #include <string.h>
 #include <sys/prctl.h>
 #include <sys/types.h>
@@ -16,8 +19,8 @@
 extern char *program_invocation_name;
 extern char *program_invocation_short_name;
 
-#include "aos/die.h"
 #include "aos/complex_thread_local.h"
+#include "aos/die.h"
 
 namespace aos {
 namespace logging {
@@ -39,6 +42,10 @@
   if (prctl(PR_GET_NAME, thread_name_array) != 0) {
     PDie("prctl(PR_GET_NAME, %p) failed", thread_name_array);
   }
+#if __has_feature(memory_sanitizer)
+  // msan doesn't understand PR_GET_NAME, so help it along.
+  __msan_unpoison(thread_name_array, sizeof(thread_name_array));
+#endif
   thread_name_array[sizeof(thread_name_array) - 1] = '\0';
   ::std::string thread_name(thread_name_array);
 
@@ -67,8 +74,7 @@
 ::std::atomic<LogImplementation *> global_top_implementation(NULL);
 
 Context::Context()
-    : implementation(global_top_implementation.load()),
-      sequence(0) {
+    : implementation(global_top_implementation.load()), sequence(0) {
   cork_data.Reset();
 }
 
@@ -77,8 +83,7 @@
   if (my_context.created()) {
     ::std::string my_name = GetMyName();
     if (my_name.size() + 1 > sizeof(Context::name)) {
-      Die("logging: process/thread name '%s' is too long\n",
-          my_name.c_str());
+      Die("logging: process/thread name '%s' is too long\n", my_name.c_str());
     }
     strcpy(my_context->name, my_name.c_str());
     my_context->name_size = my_name.size();
@@ -98,9 +103,7 @@
   return my_context.get();
 }
 
-void Context::Delete() {
-  delete_current_context = true;
-}
+void Context::Delete() { delete_current_context = true; }
 
 }  // namespace internal
 }  // namespace logging
diff --git a/aos/logging/log_message.fbs b/aos/logging/log_message.fbs
index 789724f..7e246cf 100644
--- a/aos/logging/log_message.fbs
+++ b/aos/logging/log_message.fbs
@@ -18,7 +18,7 @@
   level:Level (id: 1);
 
   // Pid of the process creating the log message
-  source:int (id:2);
+  source_pid:int (id:2);
 
   // Application name
   name:string (id:3);
diff --git a/aos/network/BUILD b/aos/network/BUILD
index 69482e1..98a271c 100644
--- a/aos/network/BUILD
+++ b/aos/network/BUILD
@@ -296,8 +296,8 @@
         "message_bridge_test.cc",
     ],
     data = [
-        ":message_bridge_test_client_config.json",
-        ":message_bridge_test_server_config.json",
+        ":message_bridge_test_client_config",
+        ":message_bridge_test_server_config",
     ],
     shard_count = 3,
     deps = [
diff --git a/aos/network/www/BUILD b/aos/network/www/BUILD
index 33291b2..60bea09 100644
--- a/aos/network/www/BUILD
+++ b/aos/network/www/BUILD
@@ -106,8 +106,8 @@
         ":flatbuffers",
         ":reflection_test.html",
         ":reflection_test_bundle",
-        ":test_config.json",
+        ":test_config",
         "//aos/network:web_proxy_main",
-        "//y2020:config.json",
+        "//y2020:config",
     ],
 )
diff --git a/aos/realtime.cc b/aos/realtime.cc
index ff05f32..a0af97a 100644
--- a/aos/realtime.cc
+++ b/aos/realtime.cc
@@ -74,10 +74,12 @@
   WriteCoreDumps();
   PCHECK(mlockall(MCL_CURRENT | MCL_FUTURE) == 0);
 
+#if !__has_feature(address_sanitizer)
   // Don't give freed memory back to the OS.
   CHECK_EQ(1, mallopt(M_TRIM_THRESHOLD, -1));
   // Don't use mmap for large malloc chunks.
   CHECK_EQ(1, mallopt(M_MMAP_MAX, 0));
+#endif
 
   if (&FLAGS_tcmalloc_release_rate) {
     // Tell tcmalloc not to return memory.
diff --git a/aos/seasocks/gen_embedded.bzl b/aos/seasocks/gen_embedded.bzl
index 93cdc39..5bdb80d 100644
--- a/aos/seasocks/gen_embedded.bzl
+++ b/aos/seasocks/gen_embedded.bzl
@@ -16,7 +16,7 @@
     attrs = {
         "srcs": attr.label_list(
             mandatory = True,
-            non_empty = True,
+            allow_empty = False,
             allow_files = True,
         ),
         "_gen_embedded": attr.label(
diff --git a/frc971/codelab/BUILD b/frc971/codelab/BUILD
index ac0b80c..ddc5466 100644
--- a/frc971/codelab/BUILD
+++ b/frc971/codelab/BUILD
@@ -7,7 +7,7 @@
     name = "basic_test",
     testonly = 1,
     srcs = ["basic_test.cc"],
-    data = [":config.json"],
+    data = [":config"],
     deps = [
         ":basic",
         ":basic_goal_fbs",
diff --git a/frc971/control_loops/drivetrain/BUILD b/frc971/control_loops/drivetrain/BUILD
index 2e357c7..ed905cf 100644
--- a/frc971/control_loops/drivetrain/BUILD
+++ b/frc971/control_loops/drivetrain/BUILD
@@ -462,7 +462,7 @@
     srcs = [
         "drivetrain_lib_test.cc",
     ],
-    data = ["simulation_config.json"],
+    data = [":simulation_config"],
     defines =
         cpu_select({
             "amd64": [
diff --git a/frc971/wpilib/BUILD b/frc971/wpilib/BUILD
index 734a231..8010edc 100644
--- a/frc971/wpilib/BUILD
+++ b/frc971/wpilib/BUILD
@@ -175,7 +175,7 @@
         "loop_output_handler_test.cc",
     ],
     data = [
-        "loop_output_handler_test_config.json",
+        ":loop_output_handler_test_config",
     ],
     deps = [
         ":loop_output_handler",
diff --git a/third_party/gmp/BUILD b/third_party/gmp/BUILD
index e4f7029..77e9f34 100644
--- a/third_party/gmp/BUILD
+++ b/third_party/gmp/BUILD
@@ -4,6 +4,7 @@
     ":mpn.bzl",
     "architecture_includes",
     "config_include_from_architecture",
+    "current_directory",
     "file_from_architecture",
     "mparam_path",
     "mpn_cc_library",
@@ -66,10 +67,10 @@
     "-Wno-unused-parameter",
     "-Wno-missing-field-initializers",
     "-DHAVE_CONFIG_H",
-    "-Ithird_party/gmp",
-    "-I$(GENDIR)/third_party/gmp",
-    "-Ithird_party/gmp/mpn",
-    "-I$(GENDIR)/third_party/gmp/mpn",
+    "-I" + current_directory(),
+    "-I$(GENDIR)/" + current_directory(),
+    "-I" + current_directory() + "/mpn",
+    "-I$(GENDIR)/" + current_directory() + "/mpn",
     "-Wno-cast-align",
     "-Wno-dangling-else",
     "-Wno-cast-qual",
@@ -926,7 +927,7 @@
 
 genrule(
     name = "call_m4",
-    srcs = native.glob([
+    srcs = glob([
         "**/*.m4",
         "**/*.asm",
     ]) + ["config.m4"],
diff --git a/third_party/gmp/mpn.bzl b/third_party/gmp/mpn.bzl
index 8f50773..4c16dfa 100644
--- a/third_party/gmp/mpn.bzl
+++ b/third_party/gmp/mpn.bzl
@@ -48,6 +48,9 @@
     "sec_pi1_div_r": ["sec_pi1_div"],
 }
 
+def current_directory():
+    return native.package_name()
+
 def mpn_cc_library(
         name,
         srcs,
@@ -60,9 +63,9 @@
         hdrs = hdrs,
         copts = copts + [
             "-DHAVE_CONFIG_H",
-            "-Ithird_party/gmp/mpn",
-            "-Ithird_party/gmp",
-            "-I$(GENDIR)/third_party/gmp",
+            "-I" + current_directory() + "/mpn",
+            "-I" + current_directory(),
+            "-I$(GENDIR)/" + current_directory(),
             "-D__GMP_WITHIN_GMP",
             "-DOPERATION_" + name,
         ],
@@ -87,17 +90,19 @@
 
     out = ctx.actions.declare_file("mpn/" + ctx.attr.operation + ".s")
 
+    ruledir = ctx.label.workspace_root + "/" + ctx.label.package
     ctx.actions.run_shell(
         inputs = [ctx.files.files[0]] + ctx.files.deps,
         outputs = [out],
         progress_message = "Generating " + out.short_path,
         tools = [ctx.executable._m4],
-        command = "&&".join([
-            "cd third_party/gmp/mpn",
-            "echo '#define OPERATION_" + ctx.attr.operation + " 1' > ../../../" + out.path,
-            "../../../" + ctx.executable._m4.path + " -I ../../../" + ctx.var["GENDIR"] + "/third_party/gmp/mpn/ " +
+        command = " && ".join([
+            "ROOT=$(pwd)",
+            "cd ./" + ruledir + "/mpn",
+            "echo '#define OPERATION_" + ctx.attr.operation + " 1' > ${ROOT}/" + out.path,
+            "${ROOT}/" + ctx.executable._m4.path + " -I ${ROOT}/" + ctx.var["GENDIR"] + "/" + ruledir + "/mpn" +
             " -DHAVE_CONFIG_H -D__GMP_WITHIN_GMP -DOPERATION_" + ctx.attr.operation +
-            " -DPIC ../../../" + ctx.files.files[0].path + " >> ../../../" + out.path,
+            " -DPIC ${ROOT}/" + ctx.files.files[0].path + " >> ${ROOT}/" + out.path,
         ]),
     )
 
@@ -140,7 +145,7 @@
 def architecture_includes(architecture_paths):
     result = dict()
     for key in architecture_paths:
-        result[key] = ["-Ithird_party/gmp/mpn/" + p for p in architecture_paths[key]]
+        result[key] = ["-I" + current_directory() + "/mpn/" + p for p in architecture_paths[key]]
     return select(result)
 
 def file_from_architecture(architecture_paths, f):
@@ -152,7 +157,7 @@
 def config_include_from_architecture(architecture_paths):
     result = dict()
     for key in architecture_paths:
-        result[key] = ["-Ithird_party/gmp/config/" + architecture_paths[key][0] + "/"]
+        result[key] = ["-I" + current_directory() + "/config/" + architecture_paths[key][0] + "/"]
     return select(result)
 
 def mpn_m4_cc_library(name, architecture_paths):
diff --git a/y2014/control_loops/claw/BUILD b/y2014/control_loops/claw/BUILD
index 670dd76..2ae59b0 100644
--- a/y2014/control_loops/claw/BUILD
+++ b/y2014/control_loops/claw/BUILD
@@ -83,7 +83,7 @@
     srcs = [
         "claw_lib_test.cc",
     ],
-    data = ["//y2014:config.json"],
+    data = ["//y2014:config"],
     deps = [
         ":claw_goal_fbs",
         ":claw_lib",
diff --git a/y2014/control_loops/shooter/BUILD b/y2014/control_loops/shooter/BUILD
index a2073c9..ed95317 100644
--- a/y2014/control_loops/shooter/BUILD
+++ b/y2014/control_loops/shooter/BUILD
@@ -84,7 +84,7 @@
     srcs = [
         "shooter_lib_test.cc",
     ],
-    data = ["//y2014:config.json"],
+    data = ["//y2014:config"],
     deps = [
         ":shooter_goal_fbs",
         ":shooter_lib",
diff --git a/y2016/BUILD b/y2016/BUILD
index a96ea5a..190e0e0 100644
--- a/y2016/BUILD
+++ b/y2016/BUILD
@@ -52,7 +52,7 @@
 
 robot_downloader(
     data = [
-        ":config.json",
+        ":config",
     ],
     dirs = [
         "//y2016/dashboard:www_files",
diff --git a/y2016/control_loops/shooter/BUILD b/y2016/control_loops/shooter/BUILD
index 794c4fc..3ffc9cc 100644
--- a/y2016/control_loops/shooter/BUILD
+++ b/y2016/control_loops/shooter/BUILD
@@ -87,7 +87,7 @@
     srcs = [
         "shooter_lib_test.cc",
     ],
-    data = ["//y2016:config.json"],
+    data = ["//y2016:config"],
     deps = [
         ":shooter_goal_fbs",
         ":shooter_lib",
diff --git a/y2016/control_loops/superstructure/BUILD b/y2016/control_loops/superstructure/BUILD
index 4048cdc..aecfd98 100644
--- a/y2016/control_loops/superstructure/BUILD
+++ b/y2016/control_loops/superstructure/BUILD
@@ -122,7 +122,7 @@
     srcs = [
         "superstructure_lib_test.cc",
     ],
-    data = ["//y2016:config.json"],
+    data = ["//y2016:config"],
     deps = [
         ":superstructure_goal_fbs",
         ":superstructure_lib",
diff --git a/y2017/control_loops/superstructure/BUILD b/y2017/control_loops/superstructure/BUILD
index 535475d..7107e23 100644
--- a/y2017/control_loops/superstructure/BUILD
+++ b/y2017/control_loops/superstructure/BUILD
@@ -73,7 +73,7 @@
     srcs = [
         "superstructure_lib_test.cc",
     ],
-    data = ["//y2017:config.json"],
+    data = ["//y2017:config"],
     deps = [
         ":superstructure_goal_fbs",
         ":superstructure_lib",
@@ -128,7 +128,7 @@
     srcs = [
         "vision_time_adjuster_test.cc",
     ],
-    data = ["//y2017:config.json"],
+    data = ["//y2017:config"],
     deps = [
         ":vision_time_adjuster",
         "//aos/events:simulated_event_loop",
diff --git a/y2018/control_loops/superstructure/BUILD b/y2018/control_loops/superstructure/BUILD
index 4e97571..db01298 100644
--- a/y2018/control_loops/superstructure/BUILD
+++ b/y2018/control_loops/superstructure/BUILD
@@ -74,7 +74,7 @@
     srcs = [
         "superstructure_lib_test.cc",
     ],
-    data = ["//y2018:config.json"],
+    data = ["//y2018:config"],
     shard_count = 5,
     deps = [
         ":superstructure_goal_fbs",
diff --git a/y2019/BUILD b/y2019/BUILD
index e286fc7..1d8b996 100644
--- a/y2019/BUILD
+++ b/y2019/BUILD
@@ -5,7 +5,7 @@
 
 robot_downloader(
     data = [
-        ":config.json",
+        ":config",
     ],
     dirs = [
         "//y2019/vision/server:www_files",
diff --git a/y2019/control_loops/drivetrain/BUILD b/y2019/control_loops/drivetrain/BUILD
index cd3a793..c500ce6 100644
--- a/y2019/control_loops/drivetrain/BUILD
+++ b/y2019/control_loops/drivetrain/BUILD
@@ -127,7 +127,7 @@
 cc_test(
     name = "target_selector_test",
     srcs = ["target_selector_test.cc"],
-    data = ["//y2019:config.json"],
+    data = ["//y2019:config"],
     deps = [
         ":target_selector",
         "//aos/events:simulated_event_loop",
@@ -192,7 +192,7 @@
 cc_test(
     name = "localized_drivetrain_test",
     srcs = ["localized_drivetrain_test.cc"],
-    data = [":simulation_config.json"],
+    data = [":simulation_config"],
     deps = [
         ":camera_fbs",
         ":drivetrain_base",
@@ -210,7 +210,7 @@
 cc_binary(
     name = "drivetrain_replay",
     srcs = ["drivetrain_replay.cc"],
-    data = ["//y2019:config.json"],
+    data = ["//y2019:config"],
     deps = [
         ":drivetrain_base",
         ":event_loop_localizer",
diff --git a/y2019/control_loops/superstructure/BUILD b/y2019/control_loops/superstructure/BUILD
index ed0c916..c352ba6 100644
--- a/y2019/control_loops/superstructure/BUILD
+++ b/y2019/control_loops/superstructure/BUILD
@@ -75,7 +75,7 @@
         "superstructure_lib_test.cc",
     ],
     data = [
-        "//y2019:config.json",
+        "//y2019:config",
     ],
     deps = [
         ":superstructure_goal_fbs",
diff --git a/y2020/BUILD b/y2020/BUILD
index 918ae1d..ba2f3a6 100644
--- a/y2020/BUILD
+++ b/y2020/BUILD
@@ -9,7 +9,7 @@
         ":setpoint_setter",
     ],
     data = [
-        ":config.json",
+        ":config",
     ],
     start_binaries = [
         "//aos/events/logging:logger_main",
@@ -29,7 +29,7 @@
         "//y2020/vision:viewer",
     ],
     data = [
-        ":config.json",
+        ":config",
     ],
     dirs = [
         "//y2020/www:www_files",
@@ -219,7 +219,7 @@
     name = "web_proxy",
     srcs = ["web_proxy.sh"],
     data = [
-        ":config.json",
+        ":config",
         "//aos/network:web_proxy_main",
         "//y2020/www:camera_main_bundle",
         "//y2020/www:field_main_bundle",
diff --git a/y2020/control_loops/drivetrain/BUILD b/y2020/control_loops/drivetrain/BUILD
index 0e06057..7e2ba18 100644
--- a/y2020/control_loops/drivetrain/BUILD
+++ b/y2020/control_loops/drivetrain/BUILD
@@ -122,7 +122,7 @@
 cc_test(
     name = "localizer_test",
     srcs = ["localizer_test.cc"],
-    data = [":simulation_config.json"],
+    data = [":simulation_config"],
     deps = [
         ":drivetrain_base",
         ":localizer",
@@ -140,7 +140,7 @@
     name = "drivetrain_replay_test",
     srcs = ["drivetrain_replay_test.cc"],
     data = [
-        ":replay_config.json",
+        ":replay_config",
         "@drivetrain_replay//file:spinning_wheels_while_still.bfbs",
     ],
     deps = [
@@ -160,7 +160,7 @@
 cc_binary(
     name = "drivetrain_replay",
     srcs = ["drivetrain_replay.cc"],
-    data = ["//y2020:config.json"],
+    data = ["//y2020:config"],
     deps = [
         ":drivetrain_base",
         ":localizer",
diff --git a/y2020/control_loops/superstructure/BUILD b/y2020/control_loops/superstructure/BUILD
index 4534404..e97fb12 100644
--- a/y2020/control_loops/superstructure/BUILD
+++ b/y2020/control_loops/superstructure/BUILD
@@ -88,7 +88,7 @@
         "superstructure_lib_test.cc",
     ],
     data = [
-        "//y2020:config.json",
+        "//y2020:config",
     ],
     deps = [
         ":superstructure_goal_fbs",
diff --git a/y2020/vision/BUILD b/y2020/vision/BUILD
index 8b73691..aaad085 100644
--- a/y2020/vision/BUILD
+++ b/y2020/vision/BUILD
@@ -32,7 +32,7 @@
         "camera_reader.cc",
     ],
     data = [
-        "//y2020:config.json",
+        "//y2020:config",
     ],
     restricted_to = [
         "//tools:k8",
@@ -66,7 +66,7 @@
         "viewer.cc",
     ],
     data = [
-        "//y2020:config.json",
+        "//y2020:config",
     ],
     restricted_to = [
         "//tools:k8",
@@ -88,7 +88,7 @@
         "calibration.cc",
     ],
     data = [
-        "//y2020:config.json",
+        "//y2020:config",
     ],
     restricted_to = [
         "//tools:k8",
@@ -115,7 +115,7 @@
         "viewer_replay.cc",
     ],
     data = [
-        "//y2020:config.json",
+        "//y2020:config",
     ],
     restricted_to = [
         "//tools:k8",