Browse Source

Makefile: Tolerate a BOM while scanning source dependencies (#15493)

Otherwise an #include directive on the first line of a source file is
ignored if the file contains a Byte-Order-Mark.

Suggested-by: Aleksey Konovalov <[email protected]>
Brad King 10 years ago
parent
commit
af92482712

+ 15 - 6
Source/cmDependsC.cxx

@@ -242,13 +242,22 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources,
           cmsys::ifstream fin(fullName.c_str());
           if(fin)
             {
-            // Add this file as a dependency.
-            dependencies.insert(fullName);
+            cmsys::FStream::BOM bom = cmsys::FStream::ReadBOM(fin);
+            if(bom == cmsys::FStream::BOM_None ||
+               bom == cmsys::FStream::BOM_UTF8)
+              {
+              // Add this file as a dependency.
+              dependencies.insert(fullName);
 
-            // Scan this file for new dependencies.  Pass the directory
-            // containing the file to handle double-quote includes.
-            std::string dir = cmSystemTools::GetFilenamePath(fullName);
-            this->Scan(fin, dir.c_str(), fullName);
+              // Scan this file for new dependencies.  Pass the directory
+              // containing the file to handle double-quote includes.
+              std::string dir = cmSystemTools::GetFilenamePath(fullName);
+              this->Scan(fin, dir.c_str(), fullName);
+              }
+            else
+              {
+              // Skip file with encoding we do not implement.
+              }
             }
           }
         }

+ 26 - 0
Tests/RunCMake/CommandLine/RunCMakeTest.cmake

@@ -80,3 +80,29 @@ run_cmake(D_nested_cache)
 set(RunCMake_TEST_OPTIONS
   "-DFOO:STRING=-DBAR:BOOL=BAZ")
 run_cmake(D_typed_nested_cache)
+
+function(run_cmake_depends)
+  set(RunCMake_TEST_SOURCE_DIR "${RunCMake_SOURCE_DIR}/cmake_depends")
+  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/cmake_depends-build")
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  file(WRITE "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/DependInfo.cmake" "
+set(CMAKE_DEPENDS_LANGUAGES \"C\")
+set(CMAKE_DEPENDS_CHECK_C
+  \"${RunCMake_TEST_SOURCE_DIR}/test.c\"
+  \"${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/test.c.o\"
+  )
+")
+  file(WRITE "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/CMakeDirectoryInformation.cmake" "
+set(CMAKE_RELATIVE_PATH_TOP_SOURCE \"${RunCMake_TEST_SOURCE_DIR}\")
+set(CMAKE_RELATIVE_PATH_TOP_BINARY \"${RunCMake_TEST_BINARY_DIR}\")
+")
+  run_cmake_command(cmake_depends ${CMAKE_COMMAND} -E cmake_depends
+    "Unix Makefiles"
+    ${RunCMake_TEST_SOURCE_DIR} ${RunCMake_TEST_SOURCE_DIR}
+    ${RunCMake_TEST_BINARY_DIR} ${RunCMake_TEST_BINARY_DIR}
+    ${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/DependInfo.cmake
+    )
+endfunction()
+run_cmake_depends()

+ 13 - 0
Tests/RunCMake/CommandLine/cmake_depends-check.cmake

@@ -0,0 +1,13 @@
+set(depend_make "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/depend.make")
+if(EXISTS "${depend_make}")
+  file(READ "${depend_make}" depend_make_content)
+  string(REGEX REPLACE "\n+$" "" depend_make_content "${depend_make_content}")
+  if(NOT depend_make_content MATCHES "
+CMakeFiles/DepTarget.dir/test.c.o: .*/Tests/RunCMake/CommandLine/cmake_depends/test.c
+CMakeFiles/DepTarget.dir/test.c.o: .*/Tests/RunCMake/CommandLine/cmake_depends/test.h$")
+    string(REPLACE "\n" "\n  " depend_make_content "  ${depend_make_content}")
+    set(RunCMake_TEST_FAILED "depend.make does not have expected content:\n${depend_make_content}")
+  endif()
+else()
+  set(RunCMake_TEST_FAILED "depend.make missing:\n ${depend_make}")
+endif()

+ 1 - 0
Tests/RunCMake/CommandLine/cmake_depends-stdout.txt

@@ -0,0 +1 @@
+^Scanning dependencies of target DepTarget$

+ 2 - 0
Tests/RunCMake/CommandLine/cmake_depends/test.c

@@ -0,0 +1,2 @@
+#include "test.h"
+#include "test_UTF-16LE.h"

+ 1 - 0
Tests/RunCMake/CommandLine/cmake_depends/test.h

@@ -0,0 +1 @@
+void test(void) {}

BIN
Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h