diff options
-rw-r--r-- | Source/cmDependsC.cxx | 31 | ||||
-rw-r--r-- | Source/cmDependsCompiler.cxx | 19 | ||||
-rw-r--r-- | Source/cmDependsFortran.cxx | 29 | ||||
-rw-r--r-- | Source/cmGlobalBorlandMakefileGenerator.cxx | 9 | ||||
-rw-r--r-- | Source/cmGlobalUnixMakefileGenerator3.h | 10 | ||||
-rw-r--r-- | Tests/IncludeDirectories/CMakeLists.txt | 8 | ||||
-rw-r--r-- | Tests/RunCMake/BuildDepends/MakeDependencies.cmake | 13 | ||||
-rw-r--r-- | Tests/RunCMake/BuildDepends/MakeDependencies.step1.cmake | 18 | ||||
-rw-r--r-- | Tests/RunCMake/BuildDepends/MakeDependencies.step2.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/BuildDepends/RunCMakeTest.cmake | 4 | ||||
-rw-r--r-- | Tests/RunCMake/CommandLine/cmake_depends-check.cmake | 5 |
11 files changed, 125 insertions, 24 deletions
diff --git a/Source/cmDependsC.cxx b/Source/cmDependsC.cxx index e6aef9289f..60e8cbf2c3 100644 --- a/Source/cmDependsC.cxx +++ b/Source/cmDependsC.cxx @@ -7,6 +7,7 @@ #include "cmsys/FStream.hxx" #include "cmFileTime.h" +#include "cmGlobalUnixMakefileGenerator3.h" #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" #include "cmProperty.h" @@ -215,16 +216,28 @@ bool cmDependsC::WriteDependencies(const std::set<std::string>& sources, // directory. We must do the same here. std::string obj_m = this->LocalGenerator->ConvertToMakefilePath(obj_i); internalDepends << obj_i << '\n'; - - for (std::string const& dep : dependencies) { - makeDepends << obj_m << ": " - << this->LocalGenerator->ConvertToMakefilePath( - this->LocalGenerator->MaybeConvertToRelativePath(binDir, - dep)) - << '\n'; - internalDepends << ' ' << dep << '\n'; + if (!dependencies.empty()) { + const auto& lineContinue = static_cast<cmGlobalUnixMakefileGenerator3*>( + this->LocalGenerator->GetGlobalGenerator()) + ->LineContinueDirective; + bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>( + this->LocalGenerator->GetGlobalGenerator()) + ->SupportsLongLineDependencies(); + if (supportLongLineDepend) { + makeDepends << obj_m << ':'; + } + for (std::string const& dep : dependencies) { + std::string dependee = this->LocalGenerator->ConvertToMakefilePath( + this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep)); + if (supportLongLineDepend) { + makeDepends << ' ' << lineContinue << ' ' << dependee; + } else { + makeDepends << obj_m << ": " << dependee << '\n'; + } + internalDepends << ' ' << dep << '\n'; + } + makeDepends << '\n'; } - makeDepends << '\n'; return true; } diff --git a/Source/cmDependsCompiler.cxx b/Source/cmDependsCompiler.cxx index beb080ffb3..97534bcdb7 100644 --- a/Source/cmDependsCompiler.cxx +++ b/Source/cmDependsCompiler.cxx @@ -196,6 +196,9 @@ void cmDependsCompiler::WriteDependencies( const auto& lineContinue = static_cast<cmGlobalUnixMakefileGenerator3*>( this->LocalGenerator->GetGlobalGenerator()) ->LineContinueDirective; + bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>( + this->LocalGenerator->GetGlobalGenerator()) + ->SupportsLongLineDependencies(); const auto& binDir = this->LocalGenerator->GetBinaryDirectory(); cmDepends::DependencyMap makeDependencies(dependencies); std::unordered_set<cm::string_view> phonyTargets; @@ -213,13 +216,19 @@ void cmDependsCompiler::WriteDependencies( }); bool first_dep = true; - makeDepends << target << ": "; + if (supportLongLineDepend) { + makeDepends << target << ": "; + } for (const auto& dep : deps) { - if (first_dep) { - first_dep = false; - makeDepends << dep; + if (supportLongLineDepend) { + if (first_dep) { + first_dep = false; + makeDepends << dep; + } else { + makeDepends << ' ' << lineContinue << " " << dep; + } } else { - makeDepends << ' ' << lineContinue << " " << dep; + makeDepends << target << ": " << dep << std::endl; } phonyTargets.emplace(dep.data(), dep.length()); diff --git a/Source/cmDependsFortran.cxx b/Source/cmDependsFortran.cxx index a239418fd0..1a06f31706 100644 --- a/Source/cmDependsFortran.cxx +++ b/Source/cmDependsFortran.cxx @@ -12,6 +12,7 @@ #include "cmFortranParser.h" /* Interface to parser object. */ #include "cmGeneratedFileStream.h" +#include "cmGlobalUnixMakefileGenerator3.h" #include "cmLocalUnixMakefileGenerator3.h" #include "cmMakefile.h" #include "cmOutputConverter.h" @@ -320,14 +321,28 @@ bool cmDependsFortran::WriteDependenciesReal(std::string const& obj, std::string obj_i = this->MaybeConvertToRelativePath(binDir, obj); std::string obj_m = cmSystemTools::ConvertToOutputPath(obj_i); internalDepends << obj_i << "\n " << src << '\n'; - for (std::string const& i : info.Includes) { - makeDepends << obj_m << ": " - << cmSystemTools::ConvertToOutputPath( - this->MaybeConvertToRelativePath(binDir, i)) - << '\n'; - internalDepends << ' ' << i << '\n'; + if (!info.Includes.empty()) { + const auto& lineContinue = static_cast<cmGlobalUnixMakefileGenerator3*>( + this->LocalGenerator->GetGlobalGenerator()) + ->LineContinueDirective; + bool supportLongLineDepend = static_cast<cmGlobalUnixMakefileGenerator3*>( + this->LocalGenerator->GetGlobalGenerator()) + ->SupportsLongLineDependencies(); + if (supportLongLineDepend) { + makeDepends << obj_m << ':'; + } + for (std::string const& i : info.Includes) { + std::string dependee = cmSystemTools::ConvertToOutputPath( + this->MaybeConvertToRelativePath(binDir, i)); + if (supportLongLineDepend) { + makeDepends << ' ' << lineContinue << ' ' << dependee; + } else { + makeDepends << obj_m << ": " << dependee << '\n'; + } + internalDepends << ' ' << i << '\n'; + } + makeDepends << '\n'; } - makeDepends << '\n'; // Write module requirements to the output stream. for (std::string const& i : info.Requires) { diff --git a/Source/cmGlobalBorlandMakefileGenerator.cxx b/Source/cmGlobalBorlandMakefileGenerator.cxx index 06943e7fff..996fcff1d8 100644 --- a/Source/cmGlobalBorlandMakefileGenerator.cxx +++ b/Source/cmGlobalBorlandMakefileGenerator.cxx @@ -26,6 +26,15 @@ cmGlobalBorlandMakefileGenerator::cmGlobalBorlandMakefileGenerator(cmake* cm) this->DefineWindowsNULL = true; this->PassMakeflags = true; this->UnixCD = false; + + /* + * Borland Make does not support long line depend rule, as we have tested + * generate one source file includes 40000 header files, and generate + * depend.make in one line(use line continued tag), and error occured: + * ** Fatal CMakeFiles\main.dir\depend.make 1224: Rule line too long ** + * we disable long line dependencies rule generation for Borland make + */ + this->ToolSupportsLongLineDependencies = false; } void cmGlobalBorlandMakefileGenerator::EnableLanguage( diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index 09679a73c7..c15f4911c5 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -139,6 +139,12 @@ public: return this->ToolSupportsCompilerDependencies; } + // Make tool supports long line dependencies + bool SupportsLongLineDependencies() + { + return this->ToolSupportsLongLineDependencies; + } + /** Get the command to use for a target that has no rule. This is used for multiple output dependencies and for cmake_force. */ std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; } @@ -235,6 +241,10 @@ protected: // generated by the compiler bool ToolSupportsCompilerDependencies = true; + // some Make generator, such as Borland not support long line dependencies, + // we add SupportsLongLineDependencies to predicate. + bool ToolSupportsLongLineDependencies = true; + // Some make programs (Borland) do not keep a rule if there are no // dependencies or commands. This is a problem for creating rules // that might not do anything but might have other dependencies diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt index d4c19c79b5..d980a5201f 100644 --- a/Tests/IncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/CMakeLists.txt @@ -67,7 +67,13 @@ else() endif() # Test escaping of special characters in include directory paths. -set(special_chars "~@&{}()!'") +set(special_chars "~@&{}()'") +if(NOT (CMAKE_GENERATOR STREQUAL "NMake Makefiles" AND + "x${CMAKE_C_COMPILER_ID}" STREQUAL "xMSVC" AND + "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS 13.0)) + # NMake from VS 6 mistakes '!' in a path after a line continuation for a directive. + string(APPEND special_chars "!") +endif() if(NOT CMAKE_GENERATOR MATCHES "(Unix|MinGW|MSYS) Makefiles") # when compiler is used for dependencies, special characters for make are not escaped string(APPEND special_chars "%") diff --git a/Tests/RunCMake/BuildDepends/MakeDependencies.cmake b/Tests/RunCMake/BuildDepends/MakeDependencies.cmake new file mode 100644 index 0000000000..33e8c7e227 --- /dev/null +++ b/Tests/RunCMake/BuildDepends/MakeDependencies.cmake @@ -0,0 +1,13 @@ +enable_language(C) + +add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/main.c) + +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT " +set(check_pairs + \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\" + \"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.h\" + ) +set(check_exes + \"$<TARGET_FILE:main>\" + ) +") diff --git a/Tests/RunCMake/BuildDepends/MakeDependencies.step1.cmake b/Tests/RunCMake/BuildDepends/MakeDependencies.step1.cmake new file mode 100644 index 0000000000..c74f03319c --- /dev/null +++ b/Tests/RunCMake/BuildDepends/MakeDependencies.step1.cmake @@ -0,0 +1,18 @@ +file(TOUCH "${RunCMake_TEST_BINARY_DIR}/main.c") +foreach(i RANGE 1 20000) + file(WRITE "${RunCMake_TEST_BINARY_DIR}/temp_header_file_${i}.h" + "#define HEADER_${i} ${i}\n" + ) + file(APPEND "${RunCMake_TEST_BINARY_DIR}/main.c" + "#include \"temp_header_file_${i}.h\"\n" + ) +endforeach() +file(APPEND "${RunCMake_TEST_BINARY_DIR}/main.c" + "#include \"main.h\"\n" + ) +file(APPEND "${RunCMake_TEST_BINARY_DIR}/main.c" + "int main(void) { return COUNT; }\n" + ) +file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.h" + "#define COUNT 1\n" + ) diff --git a/Tests/RunCMake/BuildDepends/MakeDependencies.step2.cmake b/Tests/RunCMake/BuildDepends/MakeDependencies.step2.cmake new file mode 100644 index 0000000000..c826d3c41c --- /dev/null +++ b/Tests/RunCMake/BuildDepends/MakeDependencies.step2.cmake @@ -0,0 +1,3 @@ +file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.h" + "#define COUNT 2\n" + ) diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake index 1b7b8d92ef..67da6ae68c 100644 --- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake +++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake @@ -143,3 +143,7 @@ if(RunCMake_GENERATOR MATCHES "Make|Ninja") run_BuildDepends(CustomCommandDepfile) set(run_BuildDepends_skip_step_3 1) endif() + +if(RunCMake_GENERATOR MATCHES "Make") + run_BuildDepends(MakeDependencies) +endif() diff --git a/Tests/RunCMake/CommandLine/cmake_depends-check.cmake b/Tests/RunCMake/CommandLine/cmake_depends-check.cmake index 031478b7bf..e0e3054ac1 100644 --- a/Tests/RunCMake/CommandLine/cmake_depends-check.cmake +++ b/Tests/RunCMake/CommandLine/cmake_depends-check.cmake @@ -3,8 +3,9 @@ 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$") +CMakeFiles/DepTarget.dir/test.c.o: \\\\ + .*/Tests/RunCMake/CommandLine/cmake_depends/test.c \\\\ + .*/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() |