Merge topic 'depend_make_refine'

b696f78073 cmDepends: merge dependers of depend makefile

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !5631
This commit is contained in:
Brad King
2021-01-06 15:19:33 +00:00
committed by Kitware Robot
11 changed files with 125 additions and 24 deletions

View File

@@ -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;
}

View File

@@ -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());

View File

@@ -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) {

View File

@@ -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(

View File

@@ -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

View File

@@ -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 "%")

View File

@@ -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>\"
)
")

View File

@@ -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"
)

View File

@@ -0,0 +1,3 @@
file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.h"
"#define COUNT 2\n"
)

View File

@@ -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()

View File

@@ -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()