diff --git a/SystemTools.cxx b/SystemTools.cxx
index c5160a993a8971cd80f143407fb230605cdb707d..c635b6b2b72863497c3d254faf9d9568532559b3 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -2161,6 +2161,32 @@ bool SystemTools::FilesDiffer(const std::string& source,
   return false;
 }
 
+bool SystemTools::TextFilesDiffer(const std::string& path1,
+                                  const std::string& path2)
+{
+  kwsys::ifstream if1(path1.c_str());
+  kwsys::ifstream if2(path2.c_str());
+  if (!if1 || !if2) {
+    return true;
+  }
+
+  for (;;) {
+    std::string line1, line2;
+    bool hasData1 = GetLineFromStream(if1, line1);
+    bool hasData2 = GetLineFromStream(if2, line2);
+    if (hasData1 != hasData2) {
+      return true;
+    }
+    if (!hasData1) {
+      break;
+    }
+    if (line1 != line2) {
+      return true;
+    }
+  }
+  return false;
+}
+
 /**
  * Blockwise copy source to destination file
  */
diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in
index 8d1f78cf73aa8dce7734b3f5fc0f1ec8f66e4060..1967860ab405dd5c253920b33df2746d05e50d11 100644
--- a/SystemTools.hxx.in
+++ b/SystemTools.hxx.in
@@ -578,6 +578,13 @@ public:
   static bool FilesDiffer(const std::string& source,
                           const std::string& destination);
 
+  /**
+   * Compare the contents of two files, ignoring line ending differences.
+   * Return true if different
+   */
+  static bool TextFilesDiffer(const std::string& path1,
+                              const std::string& path2);
+
   /**
    * Return true if the two files are the same file
    */
diff --git a/testSystemTools.cxx b/testSystemTools.cxx
index 0477d5937a6b51198f5734a07bbb09e176482482..9a40b53302e0869813d593d9223aa71438480f5e 100644
--- a/testSystemTools.cxx
+++ b/testSystemTools.cxx
@@ -984,6 +984,50 @@ static bool CheckGetLineFromStreamLongLine()
   return true;
 }
 
+static bool writeFile(const char* fileName, const char* data)
+{
+  kwsys::ofstream out(fileName, std::ios::binary);
+  out << data;
+  if (!out) {
+    std::cerr << "Failed to write file: " << fileName << std::endl;
+    return false;
+  }
+  return true;
+}
+
+static bool CheckTextFilesDiffer()
+{
+  struct
+  {
+    const char* a;
+    const char* b;
+    bool differ;
+  } test_cases[] = { { "one", "one", false },
+                     { "one", "two", true },
+                     { "", "", false },
+                     { "\n", "\r\n", false },
+                     { "one\n", "one\n", false },
+                     { "one\r\n", "one\n", false },
+                     { "one\n", "one", false },
+                     { "one\ntwo", "one\ntwo", false },
+                     { "one\ntwo", "one\r\ntwo", false } };
+  const int num_test_cases = sizeof(test_cases) / sizeof(test_cases[0]);
+  for (int i = 0; i < num_test_cases; ++i) {
+    if (!writeFile("file_a", test_cases[i].a) ||
+        !writeFile("file_b", test_cases[i].b)) {
+      return false;
+    }
+    if (kwsys::SystemTools::TextFilesDiffer("file_a", "file_b") !=
+        test_cases[i].differ) {
+      std::cerr << "Incorrect TextFilesDiffer result for test case " << i + 1
+                << "." << std::endl;
+      return false;
+    }
+  }
+
+  return true;
+}
+
 int testSystemTools(int, char* [])
 {
   bool res = true;
@@ -1027,5 +1071,7 @@ int testSystemTools(int, char* [])
 
   res &= CheckGetFilenameName();
 
+  res &= CheckTextFilesDiffer();
+
   return res ? 0 : 1;
 }