Reduce gsl::span usage so we can remove it

We already have absl::Span, no need to add more animals to the zoo.
This should let us delete 2 libraries out of third_party.

While we are here, the teensy code for 2019 wasn't being built.  Fix
that.

Change-Id: I247750016926122240bc76e6194cf2ddfc15e9c2
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
diff --git a/y2019/jevois/BUILD b/y2019/jevois/BUILD
index 915e37b..674924a 100644
--- a/y2019/jevois/BUILD
+++ b/y2019/jevois/BUILD
@@ -46,7 +46,6 @@
             "$(location jevois_crc.c)",
         ]),
     ]),
-    target_compatible_with = ["@platforms//os:linux"],
     tools = [
         "//third_party/pycrc:pycrc_main",
     ],
@@ -60,9 +59,8 @@
     hdrs = [
         "jevois_crc.h",
     ],
-    target_compatible_with = ["@platforms//os:linux"],
     deps = [
-        "//third_party/GSL",
+        "@com_google_absl//absl/types:span",
     ],
 )
 
@@ -92,7 +90,7 @@
         ":jevois_crc",
         ":structures",
         "//aos/util:bitpacking",
-        "//third_party/GSL",
+        "@com_google_absl//absl/types:span",
     ] + select({
         "@platforms//os:linux": ["//aos/logging"],
         "//conditions:default": [],
@@ -114,7 +112,7 @@
         ":structures",
         "//aos/containers:sized_array",
         "//aos/util:bitpacking",
-        "//third_party/GSL",
+        "@com_google_absl//absl/types:span",
     ] + select({
         "@platforms//os:linux": ["//aos/logging"],
         "//conditions:default": [],
@@ -151,7 +149,7 @@
         "cobs.h",
     ],
     deps = [
-        "//third_party/GSL",
+        "@com_google_absl//absl/types:span",
     ],
 )
 
@@ -165,7 +163,7 @@
         ":cobs",
         "//aos/testing:googletest",
         "//aos/testing:test_logging",
-        "//third_party/GSL",
+        "@com_google_absl//absl/types:span",
     ],
 )
 
@@ -197,8 +195,8 @@
         "//motors/peripheral:spi",
         "//motors/peripheral:uart",
         "//motors/print:usb",
-        "//third_party/GSL",
         "//y2019/vision:constants",
+        "@com_google_absl//absl/types:span",
     ],
 )
 
diff --git a/y2019/jevois/cobs.h b/y2019/jevois/cobs.h
index 75761c9..b8a6e4b 100644
--- a/y2019/jevois/cobs.h
+++ b/y2019/jevois/cobs.h
@@ -5,7 +5,7 @@
 #include <array>
 #include <cstdint>
 
-#include "third_party/GSL/include/gsl/gsl"
+#include "absl/types/span.h"
 
 // This file contains code for encoding and decoding Consistent Overhead Byte
 // Stuffing data. <http://www.stuartcheshire.org/papers/cobsforton.pdf> has
@@ -23,8 +23,8 @@
 // output_buffer is where to store the result.
 // Returns a span in output_buffer which has no 0 bytes.
 template <size_t max_decoded_size>
-gsl::span<char> CobsEncode(
-    gsl::span<const char> input,
+absl::Span<char> CobsEncode(
+    absl::Span<const char> input,
     std::array<char, CobsMaxEncodedSize(max_decoded_size)> *output_buffer);
 
 // Decodes some COBS-encoded data.
@@ -35,7 +35,7 @@
 // If the input data is invalid, this will simply stop when either the input or
 // output buffer is exhausted and return the result.
 template <size_t max_decoded_size>
-gsl::span<char> CobsDecode(gsl::span<const char> input,
+absl::Span<char> CobsDecode(absl::Span<const char> input,
                            std::array<char, max_decoded_size> *output_buffer);
 
 // Manages scanning a stream of bytes for 0s and exposing the resulting buffers.
@@ -53,17 +53,17 @@
   // a packet if the end delimeters for any packets are present in new_data. If
   // multiple end delimiters are present, received_packet() will be filled out
   // to an arbitrary one of them.
-  void ParseData(gsl::span<const char> new_data);
+  void ParseData(absl::Span<const char> new_data);
 
   // Returns the most-recently-parsed packet.
   // If this is empty, it indicates no packet was received.
-  gsl::span<const char> received_packet() const { return complete_packet_; }
-  void clear_received_packet() { complete_packet_ = gsl::span<char>(); }
+  absl::Span<const char> received_packet() const { return complete_packet_; }
+  void clear_received_packet() { complete_packet_ = absl::Span<char>(); }
 
  private:
   using Buffer = std::array<char, CobsMaxEncodedSize(max_decoded_size)>;
 
-  void CopyData(gsl::span<const char> input) {
+  void CopyData(absl::Span<const char> input) {
     const size_t size = std::min(input.size(), remaining_active_.size());
     for (size_t i = 0; i < size; ++i) {
       remaining_active_[i] = input[i];
@@ -74,24 +74,24 @@
   void FinishPacket() {
     const Buffer &active_buffer = buffers_[active_index_];
     complete_packet_ =
-        gsl::span<const char>(active_buffer)
+        absl::Span<const char>(active_buffer)
             .first(active_buffer.size() - remaining_active_.size());
 
     active_index_ = 1 - active_index_;
-    remaining_active_ = buffers_[active_index_];
+    remaining_active_ = absl::Span<char>(buffers_[active_index_]);
   }
 
   Buffer buffers_[2];
   // The remaining space in the active buffer.
-  gsl::span<char> remaining_active_ = buffers_[0];
+  absl::Span<char> remaining_active_{buffers_[0]};
   // The last complete packet we parsed.
-  gsl::span<const char> complete_packet_;
+  absl::Span<const char> complete_packet_;
   int active_index_ = 0;
 };
 
 template <size_t max_decoded_size>
-gsl::span<char> CobsEncode(
-    gsl::span<const char> input,
+absl::Span<char> CobsEncode(
+    absl::Span<const char> input,
     std::array<char, CobsMaxEncodedSize(max_decoded_size)> *output_buffer) {
   static_assert(max_decoded_size > 0, "Empty buffers not supported");
   if (static_cast<size_t>(input.size()) > max_decoded_size) {
@@ -128,12 +128,12 @@
   if (output_pointer > output_buffer->end()) {
     __builtin_trap();
   }
-  return gsl::span<char>(*output_buffer)
+  return absl::Span<char>(*output_buffer)
       .subspan(0, output_pointer - output_buffer->begin());
 }
 
 template <size_t max_decoded_size>
-gsl::span<char> CobsDecode(gsl::span<const char> input,
+absl::Span<char> CobsDecode(absl::Span<const char> input,
                            std::array<char, max_decoded_size> *output_buffer) {
   static_assert(max_decoded_size > 0, "Empty buffers not supported");
   if (static_cast<size_t>(input.size()) >
@@ -150,27 +150,27 @@
         break;
       }
       if (output_pointer == output_buffer->end()) {
-        return gsl::span<char>(*output_buffer);
+        return absl::Span<char>(*output_buffer);
       }
       *output_pointer = *input_pointer;
       ++output_pointer;
       ++input_pointer;
     }
     if (output_pointer == output_buffer->end()) {
-      return gsl::span<char>(*output_buffer);
+      return absl::Span<char>(*output_buffer);
     }
     if (code < 0xFFu) {
       *output_pointer = 0;
       ++output_pointer;
     }
   }
-  return gsl::span<char>(*output_buffer)
+  return absl::Span<char>(*output_buffer)
       .subspan(0, output_pointer - output_buffer->begin() - 1);
 }
 
 template <size_t max_decoded_size>
 void CobsPacketizer<max_decoded_size>::ParseData(
-    gsl::span<const char> new_data) {
+    absl::Span<const char> new_data) {
   // Find where the active packet ends.
   const auto first_end = std::find(new_data.begin(), new_data.end(), 0);
   if (first_end == new_data.end()) {
diff --git a/y2019/jevois/cobs_test.cc b/y2019/jevois/cobs_test.cc
index d7b35b6..fd312f0 100644
--- a/y2019/jevois/cobs_test.cc
+++ b/y2019/jevois/cobs_test.cc
@@ -1,8 +1,8 @@
 #include "y2019/jevois/cobs.h"
 
+#include "absl/types/span.h"
 #include "aos/testing/test_logging.h"
 #include "gtest/gtest.h"
-#include "third_party/GSL/include/gsl/gsl"
 
 namespace frc971 {
 namespace jevois {
@@ -26,11 +26,11 @@
   void EncodeAndDecode(const char (&input_data)[number_elements]) {
     static constexpr size_t input_size =
         (min_buffer_size > number_elements) ? min_buffer_size : number_elements;
-    EncodeAndDecode<input_size>(gsl::span<const char>(input_data));
+    EncodeAndDecode<input_size>(absl::Span<const char>(input_data));
   }
 
   template <size_t max_decoded_size>
-  void EncodeAndDecode(const gsl::span<const char> decoded_input) {
+  void EncodeAndDecode(const absl::Span<const char> decoded_input) {
     std::array<char, CobsMaxEncodedSize(max_decoded_size)> encoded_buffer;
     const auto encoded =
         CobsEncode<max_decoded_size>(decoded_input, &encoded_buffer);
@@ -42,7 +42,7 @@
     ASSERT_LE(decoded.size(), decoded_buffer.size());
     ASSERT_EQ(decoded.data(), &decoded_buffer.front());
     ASSERT_EQ(decoded.size(), decoded_input.size());
-    for (int i = 0; i < decoded.size(); ++i) {
+    for (size_t i = 0; i < decoded.size(); ++i) {
       EXPECT_EQ(decoded[i], decoded_input[i]);
     }
   }
@@ -113,7 +113,7 @@
   for (size_t i = 0; i < sizeof(data); ++i) {
     data[i] = (i * 7) & 0xFF;
   }
-  const gsl::span<char> data_span = data;
+  const absl::Span<char> data_span(data);
   for (int i = 253; i <= 256; ++i) {
     EncodeAndDecode<256>(data_span.subspan(0, i));
   }
@@ -139,7 +139,7 @@
   ASSERT_TRUE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 1>{{0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 3>{{1, 2, 3}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 3>{{1, 2, 3}}),
             packetizer.received_packet());
   packetizer.clear_received_packet();
   ASSERT_TRUE(packetizer.received_packet().empty());
@@ -149,21 +149,21 @@
   ASSERT_TRUE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 1>{{0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 1>{{5}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 1>{{5}}),
             packetizer.received_packet());
 
   ASSERT_FALSE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 1>{{9}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 1>{{5}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 1>{{5}}),
             packetizer.received_packet());
   packetizer.ParseData(std::array<char, 1>{{7}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 1>{{5}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 1>{{5}}),
             packetizer.received_packet());
   packetizer.ParseData(std::array<char, 1>{{0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 2>{{9, 7}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 2>{{9, 7}}),
             packetizer.received_packet());
 }
 
@@ -176,7 +176,7 @@
   ASSERT_TRUE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 1>{{0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 3>{{1, 2, 3}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 3>{{1, 2, 3}}),
             packetizer.received_packet());
   packetizer.clear_received_packet();
   ASSERT_TRUE(packetizer.received_packet().empty());
@@ -186,17 +186,17 @@
   ASSERT_TRUE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 1>{{0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 1>{{5}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 1>{{5}}),
             packetizer.received_packet());
 
   ASSERT_FALSE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 2>{{9, 7}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 1>{{5}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 1>{{5}}),
             packetizer.received_packet());
   packetizer.ParseData(std::array<char, 1>{{0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 2>{{9, 7}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 2>{{9, 7}}),
             packetizer.received_packet());
 }
 
@@ -207,7 +207,7 @@
   ASSERT_TRUE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 4>{{1, 2, 3, 0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 3>{{1, 2, 3}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 3>{{1, 2, 3}}),
             packetizer.received_packet());
   packetizer.clear_received_packet();
   ASSERT_TRUE(packetizer.received_packet().empty());
@@ -215,13 +215,13 @@
   ASSERT_TRUE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 2>{{5, 0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 1>{{5}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 1>{{5}}),
             packetizer.received_packet());
 
   ASSERT_FALSE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 3>{{9, 7, 0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 2>{{9, 7}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 2>{{9, 7}}),
             packetizer.received_packet());
 }
 
@@ -236,13 +236,13 @@
   ASSERT_TRUE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 2>{{0, 5}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 3>{{1, 2, 3}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 3>{{1, 2, 3}}),
             packetizer.received_packet());
   packetizer.clear_received_packet();
   ASSERT_TRUE(packetizer.received_packet().empty());
   packetizer.ParseData(std::array<char, 1>{{0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 1>{{5}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 1>{{5}}),
             packetizer.received_packet());
 }
 
@@ -260,7 +260,7 @@
   ASSERT_FALSE(packetizer.received_packet().empty());
   // We skip the {{1, 2, 3}} packet (arbitrarily; either that packet or this one
   // has to be skipped).
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 1>{{5}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 1>{{5}}),
             packetizer.received_packet());
 }
 
@@ -279,12 +279,12 @@
   ASSERT_FALSE(packetizer.received_packet().empty());
   // We skip the {{5}} packet (arbitrarily; either that packet or this one has
   // to be skipped).
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 3>{{1, 2, 3}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 3>{{1, 2, 3}}),
             packetizer.received_packet());
 
   packetizer.ParseData(std::array<char, 1>{{0}});
   ASSERT_FALSE(packetizer.received_packet().empty());
-  EXPECT_EQ(gsl::span<const char>(std::array<char, 1>{{8}}),
+  EXPECT_EQ(absl::Span<const char>(std::array<char, 1>{{8}}),
             packetizer.received_packet());
 }
 
diff --git a/y2019/jevois/spi.cc b/y2019/jevois/spi.cc
index 5c504e2..b3b6550 100644
--- a/y2019/jevois/spi.cc
+++ b/y2019/jevois/spi.cc
@@ -47,13 +47,13 @@
 constexpr float heading_max() { return 3; }
 constexpr int heading_bits() { return 10; }
 constexpr int heading_offset() { return 0; }
-void heading_pack(float heading, gsl::span<char> destination) {
+void heading_pack(float heading, absl::Span<char> destination) {
   const auto integer = aos::FloatToIntLinear<heading_bits()>(
       heading_min(), heading_max(), heading);
   aos::PackBits<uint32_t, heading_bits(), heading_offset()>(integer,
                                                             destination);
 }
-float heading_unpack(gsl::span<const char> source) {
+float heading_unpack(absl::Span<const char> source) {
   const auto integer =
       aos::UnpackBits<uint32_t, heading_bits(), heading_offset()>(source);
   return aos::IntToFloatLinear<heading_bits()>(heading_min(), heading_max(),
@@ -64,13 +64,13 @@
 constexpr float distance_max() { return 10.0; }
 constexpr int distance_bits() { return 8; }
 constexpr int distance_offset() { return heading_offset() + heading_bits(); }
-void distance_pack(float distance, gsl::span<char> destination) {
+void distance_pack(float distance, absl::Span<char> destination) {
   const auto integer = aos::FloatToIntLinear<distance_bits()>(
       distance_min(), distance_max(), distance);
   aos::PackBits<uint32_t, distance_bits(), distance_offset()>(integer,
                                                               destination);
 }
-float distance_unpack(gsl::span<const char> source) {
+float distance_unpack(absl::Span<const char> source) {
   const auto integer =
       aos::UnpackBits<uint32_t, distance_bits(), distance_offset()>(source);
   return aos::IntToFloatLinear<distance_bits()>(distance_min(), distance_max(),
@@ -81,12 +81,12 @@
 constexpr float skew_max() { return 3; }
 constexpr int skew_bits() { return 6; }
 constexpr int skew_offset() { return distance_offset() + distance_bits(); }
-void skew_pack(float skew, gsl::span<char> destination) {
+void skew_pack(float skew, absl::Span<char> destination) {
   const auto integer =
       aos::FloatToIntLinear<skew_bits()>(skew_min(), skew_max(), skew);
   aos::PackBits<uint32_t, skew_bits(), skew_offset()>(integer, destination);
 }
-float skew_unpack(gsl::span<const char> source) {
+float skew_unpack(absl::Span<const char> source) {
   const auto integer =
       aos::UnpackBits<uint32_t, skew_bits(), skew_offset()>(source);
   return aos::IntToFloatLinear<skew_bits()>(skew_min(), skew_max(), integer);
@@ -96,37 +96,39 @@
 constexpr float height_max() { return 1.5; }
 constexpr int height_bits() { return 6; }
 constexpr int height_offset() { return skew_offset() + skew_bits(); }
-void height_pack(float height, gsl::span<char> destination) {
+void height_pack(float height, absl::Span<char> destination) {
   const auto integer =
       aos::FloatToIntLinear<height_bits()>(height_min(), height_max(), height);
   aos::PackBits<uint32_t, height_bits(), height_offset()>(integer, destination);
 }
-float height_unpack(gsl::span<const char> source) {
+float height_unpack(absl::Span<const char> source) {
   const auto integer =
       aos::UnpackBits<uint32_t, height_bits(), height_offset()>(source);
   return aos::IntToFloatLinear<height_bits()>(height_min(), height_max(),
                                               integer);
 }
 
-constexpr int quantity_index_offset() { return height_offset() + height_bits(); }
-void camera_index_pack(int camera_index, gsl::span<char> destination) {
+constexpr int quantity_index_offset() {
+  return height_offset() + height_bits();
+}
+void camera_index_pack(int camera_index, absl::Span<char> destination) {
   aos::PackBits<uint32_t, 2, quantity_index_offset()>(camera_index & 3,
                                                       destination);
   aos::PackBits<uint32_t, 2, quantity_index_offset() + 32>(
       (camera_index >> 2) & 3, destination);
 }
-int camera_index_unpack(gsl::span<const char> source) {
+int camera_index_unpack(absl::Span<const char> source) {
   int result = 0;
   result |= aos::UnpackBits<uint32_t, 2, quantity_index_offset()>(source);
   result |= aos::UnpackBits<uint32_t, 2, quantity_index_offset() + 32>(source)
             << 2;
   return result;
 }
-void target_count_pack(int target_count, gsl::span<char> destination) {
+void target_count_pack(int target_count, absl::Span<char> destination) {
   aos::PackBits<uint32_t, 2, quantity_index_offset() + 32 * 2>(target_count,
                                                                destination);
 }
-int target_count_unpack(gsl::span<const char> source) {
+int target_count_unpack(absl::Span<const char> source) {
   return aos::UnpackBits<uint32_t, 2, quantity_index_offset() + 32 * 2>(source);
 }
 
@@ -137,7 +139,7 @@
 
 SpiTransfer SpiPackToRoborio(const TeensyToRoborio &message) {
   SpiTransfer transfer;
-  gsl::span<char> remaining_space = transfer;
+  absl::Span<char> remaining_space = absl::Span<char>(transfer);
   for (int frame = 0; frame < 3; ++frame) {
     // Zero out all three targets and the age.
     for (int i = 0; i < 3 * 4 + 1; ++i) {
@@ -184,9 +186,12 @@
 }
 
 std::optional<TeensyToRoborio> SpiUnpackToRoborio(
-    gsl::span<const char, spi_transfer_size()> transfer) {
+    absl::Span<const char> transfer) {
+  if (transfer.size() != spi_transfer_size()) {
+    return std::nullopt;
+  }
   TeensyToRoborio message;
-  gsl::span<const char> remaining_input = transfer;
+  absl::Span<const char> remaining_input = transfer;
   for (int frame = 0; frame < 3; ++frame) {
     const int camera_index_plus = camera_index_unpack(remaining_input);
     if (camera_index_plus > 0) {
@@ -240,7 +245,7 @@
 
 SpiTransfer SpiPackToTeensy(const RoborioToTeensy &message) {
   SpiTransfer transfer;
-  gsl::span<char> remaining_space = transfer;
+  absl::Span<char> remaining_space = absl::Span<char>(transfer);
   for (size_t i = 0; i < message.beacon_brightness.size(); ++i) {
     remaining_space[0] = message.beacon_brightness[i];
     remaining_space = remaining_space.subspan(1);
@@ -268,9 +273,12 @@
 }
 
 std::optional<RoborioToTeensy> SpiUnpackToTeensy(
-    gsl::span<const char, spi_transfer_size()> transfer) {
+    absl::Span<const char> transfer) {
+  if (transfer.size() != spi_transfer_size()) {
+    return std::nullopt;
+  }
   RoborioToTeensy message;
-  gsl::span<const char> remaining_input = transfer;
+  absl::Span<const char> remaining_input = transfer;
   for (size_t i = 0; i < message.beacon_brightness.size(); ++i) {
     message.beacon_brightness[i] = remaining_input[0];
     remaining_input = remaining_input.subspan(1);
diff --git a/y2019/jevois/spi.h b/y2019/jevois/spi.h
index 59e321a..cdb0dfc 100644
--- a/y2019/jevois/spi.h
+++ b/y2019/jevois/spi.h
@@ -5,7 +5,7 @@
 #include <cstdint>
 #include <optional>
 
-#include "third_party/GSL/include/gsl/gsl"
+#include "absl/types/span.h"
 #include "y2019/jevois/structures.h"
 
 // This file manages serializing and deserializing the various structures for
@@ -27,10 +27,10 @@
 
 SpiTransfer SpiPackToRoborio(const TeensyToRoborio &message);
 std::optional<TeensyToRoborio> SpiUnpackToRoborio(
-    gsl::span<const char, spi_transfer_size()> transfer);
+    absl::Span<const char> transfer);
 SpiTransfer SpiPackToTeensy(const RoborioToTeensy &message);
 std::optional<RoborioToTeensy> SpiUnpackToTeensy(
-    gsl::span<const char, spi_transfer_size()> transfer);
+    absl::Span<const char> transfer);
 
 }  // namespace jevois
 }  // namespace frc971
diff --git a/y2019/jevois/structures.h b/y2019/jevois/structures.h
index b4bd755..73705b1 100644
--- a/y2019/jevois/structures.h
+++ b/y2019/jevois/structures.h
@@ -9,7 +9,6 @@
 #include "Eigen/Dense"
 #include "aos/containers/sized_array.h"
 #include "aos/time/time.h"
-#include "third_party/GSL/include/gsl/gsl"
 
 namespace frc971 {
 namespace jevois {
diff --git a/y2019/jevois/teensy.cc b/y2019/jevois/teensy.cc
index 038ece9..541fabe 100644
--- a/y2019/jevois/teensy.cc
+++ b/y2019/jevois/teensy.cc
@@ -116,7 +116,7 @@
   SpiQueue(const SpiQueue &) = delete;
   SpiQueue &operator=(const SpiQueue &) = delete;
 
-  std::optional<gsl::span<const char, spi_transfer_size()>> Tick() {
+  std::optional<absl::Span<const char>> Tick() {
     {
       DisableInterrupts disable_interrupts;
       if (waiting_for_enable_ || waiting_for_disable_) {
@@ -236,7 +236,7 @@
 
  private:
   void WaitForNextTransfer() {
-    to_receive_ = received_transfer_;
+    to_receive_ = absl::Span<char>(received_transfer_);
     received_dummy_ = false;
     {
       DisableInterrupts disable_interrupts;
@@ -268,7 +268,7 @@
   SpiTransfer transfer_;
   bool received_dummy_ = false;
   SpiTransfer received_transfer_;
-  gsl::span<char> to_receive_ = received_transfer_;
+  absl::Span<char> to_receive_{received_transfer_};
   aos::monotonic_clock::time_point receive_start_;
   aos::monotonic_clock::time_point cs_deassert_time_;
 };
@@ -343,7 +343,7 @@
     const int index = oldest_indices[i];
     const FrameData &frame = frames_[index];
     const auto age = aos::monotonic_clock::now() - frame.capture_time;
-    const auto rounded_age = aos::time::round<camera_duration>(age);
+    const auto rounded_age = std::chrono::round<camera_duration>(age);
     message.frames.push_back({frame.targets, rounded_age, frame.camera_index});
     last_frames_.push_back(index);
   }
diff --git a/y2019/jevois/uart.cc b/y2019/jevois/uart.cc
index b1fdcfb..71c37e5 100644
--- a/y2019/jevois/uart.cc
+++ b/y2019/jevois/uart.cc
@@ -3,7 +3,7 @@
 #include <array>
 
 #include "aos/util/bitpacking.h"
-#include "third_party/GSL/include/gsl/gsl"
+#include "absl/types/span.h"
 #include "y2019/jevois/jevois_crc.h"
 #ifdef __linux__
 #include "aos/logging/logging.h"
@@ -17,7 +17,7 @@
 
 UartToTeensyBuffer UartPackToTeensy(const CameraFrame &message) {
   std::array<char, uart_to_teensy_size()> buffer;
-  gsl::span<char> remaining_space = buffer;
+  absl::Span<char> remaining_space(buffer);
   remaining_space[0] = message.targets.size();
   remaining_space = remaining_space.subspan(1);
   for (size_t i = 0; i < 3; ++i) {
@@ -56,7 +56,7 @@
 }
 
 std::optional<CameraFrame> UartUnpackToTeensy(
-    gsl::span<const char> encoded_buffer) {
+    absl::Span<const char> encoded_buffer) {
   std::array<char, uart_to_teensy_size()> buffer;
   if (static_cast<size_t>(
           CobsDecode<uart_to_teensy_size()>(encoded_buffer, &buffer).size()) !=
@@ -65,7 +65,7 @@
   }
 
   CameraFrame message;
-  gsl::span<const char> remaining_input = buffer;
+  absl::Span<const char> remaining_input(buffer);
   const int number_targets = remaining_input[0];
   remaining_input = remaining_input.subspan(1);
   for (int i = 0; i < 3; ++i) {
@@ -106,7 +106,7 @@
 
 UartToCameraBuffer UartPackToCamera(const CameraCalibration &message) {
   std::array<char, uart_to_camera_size()> buffer;
-  gsl::span<char> remaining_space = buffer;
+  absl::Span<char> remaining_space(buffer);
   for (int i = 0; i < 3; ++i) {
     for (int j = 0; j < 4; ++j) {
       memcpy(remaining_space.data(), &message.calibration(i, j), sizeof(float));
@@ -144,7 +144,7 @@
 }
 
 std::optional<CameraCalibration> UartUnpackToCamera(
-    gsl::span<const char> encoded_buffer) {
+    absl::Span<const char> encoded_buffer) {
   std::array<char, uart_to_camera_size()> buffer;
   if (static_cast<size_t>(
           CobsDecode<uart_to_camera_size()>(encoded_buffer, &buffer).size()) !=
@@ -153,7 +153,7 @@
   }
 
   CameraCalibration message;
-  gsl::span<const char> remaining_input = buffer;
+  absl::Span<const char> remaining_input(buffer);
   for (int i = 0; i < 3; ++i) {
     for (int j = 0; j < 4; ++j) {
       memcpy(&message.calibration(i, j), remaining_input.data(), sizeof(float));
diff --git a/y2019/jevois/uart.h b/y2019/jevois/uart.h
index 14a46da..7a7f251 100644
--- a/y2019/jevois/uart.h
+++ b/y2019/jevois/uart.h
@@ -1,9 +1,10 @@
 #ifndef Y2019_JEVOIS_UART_H_
 #define Y2019_JEVOIS_UART_H_
 
-#include "aos/containers/sized_array.h"
-#include "third_party/GSL/include/gsl/gsl"
 #include <optional>
+
+#include "absl/types/span.h"
+#include "aos/containers/sized_array.h"
 #include "y2019/jevois/cobs.h"
 #include "y2019/jevois/structures.h"
 
@@ -30,11 +31,11 @@
     aos::SizedArray<char, CobsMaxEncodedSize(uart_to_camera_size())>;
 
 UartToTeensyBuffer UartPackToTeensy(const CameraFrame &message);
-std::optional<CameraFrame> UartUnpackToTeensy(gsl::span<const char> buffer);
+std::optional<CameraFrame> UartUnpackToTeensy(absl::Span<const char> buffer);
 
 UartToCameraBuffer UartPackToCamera(const CameraCalibration &message);
 std::optional<CameraCalibration> UartUnpackToCamera(
-    gsl::span<const char> buffer);
+    absl::Span<const char> buffer);
 
 }  // namespace jevois
 }  // namespace frc971
diff --git a/y2019/vision/BUILD b/y2019/vision/BUILD
index e005e70..87ce17e 100644
--- a/y2019/vision/BUILD
+++ b/y2019/vision/BUILD
@@ -15,7 +15,6 @@
         "constants_formatting.cc",
     ],
     hdrs = ["constants.h"],
-    target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
 )
 
diff --git a/y2019/vision/debug_serial.cc b/y2019/vision/debug_serial.cc
index d1c70c2..a658bd7 100644
--- a/y2019/vision/debug_serial.cc
+++ b/y2019/vision/debug_serial.cc
@@ -36,7 +36,7 @@
       char data[kBufferSize];
       ssize_t n = read(itsDev, &data[0], kBufferSize);
       if (n >= 1) {
-        cobs.ParseData(gsl::span<const char>(&data[0], n));
+        cobs.ParseData(absl::Span<const char>(&data[0], n));
         auto packet = cobs.received_packet();
         if (!packet.empty()) {
           // One we read data from the serial, Teensy code will return an
diff --git a/y2019/vision/target_sender.cc b/y2019/vision/target_sender.cc
index b7fed9a..4aa4b54 100644
--- a/y2019/vision/target_sender.cc
+++ b/y2019/vision/target_sender.cc
@@ -316,7 +316,7 @@
       char data[kBufferSize];
       ssize_t n = read(itsDev, &data[0], kBufferSize);
       if (n >= 1) {
-        cobs.ParseData(gsl::span<const char>(&data[0], n));
+        cobs.ParseData(absl::Span<const char>(&data[0], n));
         auto packet = cobs.received_packet();
         if (!packet.empty()) {
           auto calibration_question =
diff --git a/y2019/wpilib_interface.cc b/y2019/wpilib_interface.cc
index da076f2..f37b86c 100644
--- a/y2019/wpilib_interface.cc
+++ b/y2019/wpilib_interface.cc
@@ -399,7 +399,7 @@
     std::array<char, spi_transfer_size() + 1> to_send{};
     {
       const auto to_send_data =
-          gsl::make_span(to_send).last<spi_transfer_size()>();
+          absl::MakeSpan(to_send).last(spi_transfer_size());
       const auto encoded = SpiPackToTeensy(to_teensy);
       std::copy(encoded.begin(), encoded.end(), to_send_data.begin());
     }
@@ -407,9 +407,9 @@
     // First, send recieve a dummy byte because the Teensy can't control what it
     // sends for the first byte.
     std::array<char, spi_transfer_size() + 1> to_receive;
-    DoTransaction(to_send, to_receive);
+    DoTransaction(absl::Span<char>(to_send), absl::Span<char>(to_receive));
     const auto unpacked = SpiUnpackToRoborio(
-        gsl::make_span(to_receive).last(spi_transfer_size()));
+        absl::MakeSpan(to_receive).last(spi_transfer_size()));
     if (!unpacked) {
       AOS_LOG(INFO, "Decoding SPI data failed\n");
       return;
@@ -466,12 +466,12 @@
     }
   }
 
-  void DoTransaction(gsl::span<char> to_send, gsl::span<char> to_receive) {
+  void DoTransaction(absl::Span<char> to_send, absl::Span<char> to_receive) {
     AOS_CHECK_EQ(to_send.size(), to_receive.size());
-    const auto result = spi_->Transaction(
+    const int result = spi_->Transaction(
         reinterpret_cast<uint8_t *>(to_send.data()),
         reinterpret_cast<uint8_t *>(to_receive.data()), to_send.size());
-    if (result == to_send.size()) {
+    if (result == static_cast<int>(to_send.size())) {
       return;
     }
     if (result == -1) {