From 1ded3599d698c1bfa0243d58ece8b619d2900a17 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Fri, 17 May 2019 17:15:50 +0200 Subject: Makefiles: Process ADDTIONAL_CLEAN_FILES dir prop at directory level In the "Unix Makefiles" generator, the `ADDTIONAL_CLEAN_FILES` directory property was evaluated on a per target basis. This had two drawbacks: - per directory clean files were repeated in every target clean script - per directory clean files weren't removed in directories without targets (issue #8164) This patch moves the `ADDTIONAL_CLEAN_FILES` directory property processing from the target to the directory level clean target. Fixes: #8164 "ADDITIONAL_CLEAN_FILES directory property not respected if no target present in directory" --- Source/cmGlobalUnixMakefileGenerator3.cxx | 14 ++++++--- Source/cmGlobalUnixMakefileGenerator3.h | 3 +- Source/cmLocalUnixMakefileGenerator3.cxx | 51 +++++++++++++++++++++++++++++++ Source/cmLocalUnixMakefileGenerator3.h | 1 + Source/cmMakefileTargetGenerator.cxx | 12 -------- 5 files changed, 63 insertions(+), 18 deletions(-) diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index f640d52..8053f61 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.cxx +++ b/Source/cmGlobalUnixMakefileGenerator3.cxx @@ -398,7 +398,8 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefileLanguageRules( void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2( std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg, - const char* pass, bool check_all, bool check_relink) + const char* pass, bool check_all, bool check_relink, + std::vector const& commands) { // Get the relative path to the subdirectory from the top. std::string makeTarget = lg->GetCurrentBinaryDirectory(); @@ -454,9 +455,8 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRule2( doc += pass; doc += "\" directory target."; } - std::vector no_commands; - lg->WriteMakeRule(ruleFileStream, doc.c_str(), makeTarget, depends, - no_commands, true); + lg->WriteMakeRule(ruleFileStream, doc.c_str(), makeTarget, depends, commands, + true); } void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2( @@ -480,7 +480,11 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2( this->WriteDirectoryRule2(ruleFileStream, lg, "all", true, false); // Write directory-level rules for "clean". - this->WriteDirectoryRule2(ruleFileStream, lg, "clean", false, false); + { + std::vector cmds; + lg->AppendDirectoryCleanCommand(cmds); + this->WriteDirectoryRule2(ruleFileStream, lg, "clean", false, false, cmds); + } // Write directory-level rules for "preinstall". this->WriteDirectoryRule2(ruleFileStream, lg, "preinstall", true, true); diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h index e919d38..287472c 100644 --- a/Source/cmGlobalUnixMakefileGenerator3.h +++ b/Source/cmGlobalUnixMakefileGenerator3.h @@ -165,7 +165,8 @@ protected: void WriteDirectoryRule2(std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg, const char* pass, - bool check_all, bool check_relink); + bool check_all, bool check_relink, + std::vector const& commands = {}); void WriteDirectoryRules2(std::ostream& ruleFileStream, cmLocalUnixMakefileGenerator3* lg); diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 857440c..6a08840 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -15,6 +15,7 @@ #include "cmCustomCommandGenerator.h" #include "cmFileTimeCache.h" #include "cmGeneratedFileStream.h" +#include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmGlobalUnixMakefileGenerator3.h" @@ -1089,6 +1090,56 @@ void cmLocalUnixMakefileGenerator3::AppendCleanCommand( } } +void cmLocalUnixMakefileGenerator3::AppendDirectoryCleanCommand( + std::vector& commands) +{ + std::vector cleanFiles; + // Look for additional files registered for cleaning in this directory. + if (const char* prop_value = + this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) { + cmGeneratorExpression ge; + std::unique_ptr cge = ge.Parse(prop_value); + cmSystemTools::ExpandListArgument( + cge->Evaluate(this, + this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")), + cleanFiles); + } + if (cleanFiles.empty()) { + return; + } + + cmLocalGenerator* rootLG = + this->GetGlobalGenerator()->GetLocalGenerators().at(0); + std::string const& binaryDir = rootLG->GetCurrentBinaryDirectory(); + std::string const& currentBinaryDir = this->GetCurrentBinaryDirectory(); + std::string cleanfile = currentBinaryDir; + cleanfile += "/CMakeFiles/cmake_directory_clean.cmake"; + // Write clean script + { + std::string cleanfilePath = cmSystemTools::CollapseFullPath(cleanfile); + cmsys::ofstream fout(cleanfilePath.c_str()); + if (!fout) { + cmSystemTools::Error("Could not create " + cleanfilePath); + return; + } + fout << "file(REMOVE_RECURSE\n"; + for (std::string const& cfl : cleanFiles) { + std::string fc = rootLG->MaybeConvertToRelativePath( + binaryDir, cmSystemTools::CollapseFullPath(cfl, currentBinaryDir)); + fout << " " << cmOutputConverter::EscapeForCMake(fc) << "\n"; + } + fout << ")\n"; + } + // Create command + { + std::string remove = "$(CMAKE_COMMAND) -P "; + remove += this->ConvertToOutputFormat( + rootLG->MaybeConvertToRelativePath(binaryDir, cleanfile), + cmOutputConverter::SHELL); + commands.push_back(std::move(remove)); + } +} + void cmLocalUnixMakefileGenerator3::AppendEcho( std::vector& commands, std::string const& text, EchoColor color, EchoProgress const* progress) diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index fed25e1..c8e4b0e 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -227,6 +227,7 @@ protected: const std::set& files, cmGeneratorTarget* target, const char* filename = nullptr); + void AppendDirectoryCleanCommand(std::vector& commands); // Helper methods for dependency updates. bool ScanDependencies(std::string const& targetDir, diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index e62b107..3a89d75 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -172,18 +172,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() this->CleanFiles.insert(files.begin(), files.end()); } - // Look for additional files registered for cleaning in this directory. - if (const char* prop_value = - this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) { - std::vector const files = evaluatedFiles(prop_value); - // For relative path support - std::string const& binaryDir = - this->LocalGenerator->GetCurrentBinaryDirectory(); - for (std::string const& cfl : files) { - this->CleanFiles.insert(cmSystemTools::CollapseFullPath(cfl, binaryDir)); - } - } - // Look for additional files registered for cleaning in this target. if (const char* prop_value = this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) { -- cgit v0.12