diff --git a/bootstrap.sh b/bootstrap.sh
index 50953546a87a6d1b1ca879b188a53eaf072cc009..d589a222a100ef53efca15fb4e3cbb866112b360 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -211,6 +211,7 @@ build_lib() {
       ;;
     protobuf)
       do_extract "protobuf"     "protobuf-${PROTOBUF_VERSION}.tar.bz2"
+      patch_external "protobuf" "fix-iterator-cxx17.patch"
       do_build "protobuf"
       ;;
     googlebench)
diff --git a/externals/protobuf/src/fix-iterator-cxx17.patch b/externals/protobuf/src/fix-iterator-cxx17.patch
new file mode 100644
index 0000000000000000000000000000000000000000..ca593094b7d783dea61a45667001c9a5dd2f014d
--- /dev/null
+++ b/externals/protobuf/src/fix-iterator-cxx17.patch
@@ -0,0 +1,89 @@
+--- src/google/protobuf/repeated_field.h.orig	2022-08-06 23:20:40.617171776 +0200
++++ src/google/protobuf/repeated_field.h	2022-08-06 23:38:02.113523647 +0200
+@@ -1250,23 +1250,14 @@
+ // This code based on net/proto/proto-array-internal.h by Jeffrey Yasskin
+ // (jyasskin@google.com).
+ template<typename Element>
+-class RepeatedPtrIterator
+-    : public std::iterator<
+-          std::random_access_iterator_tag, Element> {
++class RepeatedPtrIterator {
+  public:
+   typedef RepeatedPtrIterator<Element> iterator;
+-  typedef std::iterator<
+-          std::random_access_iterator_tag, Element> superclass;
+-
+-  // Shadow the value_type in std::iterator<> because const_iterator::value_type
+-  // needs to be T, not const T.
++  typedef std::random_access_iterator_tag iterator_category;
+   typedef typename remove_const<Element>::type value_type;
+-
+-  // Let the compiler know that these are type names, so we don't have to
+-  // write "typename" in front of them everywhere.
+-  typedef typename superclass::reference reference;
+-  typedef typename superclass::pointer pointer;
+-  typedef typename superclass::difference_type difference_type;
++  typedef std::ptrdiff_t difference_type;
++  typedef Element* pointer;
++  typedef Element& reference;
+ 
+   RepeatedPtrIterator() : it_(NULL) {}
+   explicit RepeatedPtrIterator(void* const* it) : it_(it) {}
+@@ -1346,22 +1337,14 @@
+ // referenced by the iterator.  It should either be "void *" for a mutable
+ // iterator, or "const void *" for a constant iterator.
+ template<typename Element, typename VoidPtr>
+-class RepeatedPtrOverPtrsIterator
+-    : public std::iterator<std::random_access_iterator_tag, Element*> {
++class RepeatedPtrOverPtrsIterator {
+  public:
+   typedef RepeatedPtrOverPtrsIterator<Element, VoidPtr> iterator;
+-  typedef std::iterator<
+-          std::random_access_iterator_tag, Element*> superclass;
+-
+-  // Shadow the value_type in std::iterator<> because const_iterator::value_type
+-  // needs to be T, not const T.
++  typedef std::random_access_iterator_tag iterator_category;
+   typedef typename remove_const<Element*>::type value_type;
+-
+-  // Let the compiler know that these are type names, so we don't have to
+-  // write "typename" in front of them everywhere.
+-  typedef typename superclass::reference reference;
+-  typedef typename superclass::pointer pointer;
+-  typedef typename superclass::difference_type difference_type;
++  typedef std::ptrdiff_t difference_type;
++  typedef Element* pointer;
++  typedef Element& reference;
+ 
+   RepeatedPtrOverPtrsIterator() : it_(NULL) {}
+   explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
+@@ -1479,8 +1462,7 @@
+ 
+ namespace internal {
+ // A back inserter for RepeatedField objects.
+-template<typename T> class RepeatedFieldBackInsertIterator
+-    : public std::iterator<std::output_iterator_tag, T> {
++template<typename T> class RepeatedFieldBackInsertIterator {
+  public:
+   explicit RepeatedFieldBackInsertIterator(
+       RepeatedField<T>* const mutable_field)
+@@ -1505,8 +1487,7 @@
+ };
+ 
+ // A back inserter for RepeatedPtrField objects.
+-template<typename T> class RepeatedPtrFieldBackInsertIterator
+-    : public std::iterator<std::output_iterator_tag, T> {
++template<typename T> class RepeatedPtrFieldBackInsertIterator {
+  public:
+   RepeatedPtrFieldBackInsertIterator(
+       RepeatedPtrField<T>* const mutable_field)
+@@ -1537,8 +1518,7 @@
+ 
+ // A back inserter for RepeatedPtrFields that inserts by transfering ownership
+ // of a pointer.
+-template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator
+-    : public std::iterator<std::output_iterator_tag, T> {
++template<typename T> class AllocatedRepeatedPtrFieldBackInsertIterator {
+  public:
+   explicit AllocatedRepeatedPtrFieldBackInsertIterator(
+       RepeatedPtrField<T>* const mutable_field)