summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Wang <wangkai86@huawei.com>2020-12-18 14:47:37 +0800
committerBrad King <brad.king@kitware.com>2021-01-05 07:48:27 -0500
commitb696f7807303b421c3f59ff2bf8229c96f09f1fa (patch)
tree246f99b964b4cf5b43178adde879025dc01c4c37
parentda2474626b8a02e957021b30453f5afc8d7246b9 (diff)
downloadcmake-b696f7807303b421c3f59ff2bf8229c96f09f1fa.tar.gz
cmDepends: merge dependers of depend makefile
Since one depender has multiple dependees, depend makefile generated same depender line by line, to reduce file size and refine make file parse speed, merge same dependers to one. And add a testcase for large depend.make which generated source file includes 20000 header files and run build and incremental build Signed-off-by: Wangkai <wangkai86@huawei.com> Signed-off-by: Zhaoyingdong <zhaoyingdong@huawei.com>
-rw-r--r--Source/cmDependsC.cxx31
-rw-r--r--Source/cmDependsCompiler.cxx19
-rw-r--r--Source/cmDependsFortran.cxx29
-rw-r--r--Source/cmGlobalBorlandMakefileGenerator.cxx9
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h10
-rw-r--r--Tests/IncludeDirectories/CMakeLists.txt8
-rw-r--r--Tests/RunCMake/BuildDepends/MakeDependencies.cmake13
-rw-r--r--Tests/RunCMake/BuildDepends/MakeDependencies.step1.cmake18
-rw-r--r--Tests/RunCMake/BuildDepends/MakeDependencies.step2.cmake3
-rw-r--r--Tests/RunCMake/BuildDepends/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/CommandLine/cmake_depends-check.cmake5
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()