diff options
author | Brad King <brad.king@kitware.com> | 2019-05-15 13:21:59 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-05-15 13:22:18 (GMT) |
commit | 66efdbd21a46b63572f5de677ed126a68e524e7a (patch) | |
tree | ca828de9a043ff83bd321185b1c23de9a6b2a788 | |
parent | 0064edf4173fad72749da2c66753387e9a671223 (diff) | |
parent | b5bf369ec68a60bf71297e941bcc742904aae148 (diff) | |
download | CMake-66efdbd21a46b63572f5de677ed126a68e524e7a.zip CMake-66efdbd21a46b63572f5de677ed126a68e524e7a.tar.gz CMake-66efdbd21a46b63572f5de677ed126a68e524e7a.tar.bz2 |
Merge topic 'additional_clean_files'
b5bf369ec6 Release notes: Add release notes for ADDITIONAL_CLEAN_FILES properties
4e2ce0a67a Doc: Update and deprecate ADDITIONAL_MAKE_CLEAN_FILES directory property
338994d65d Doc: Add documentation for ADDITIONAL_CLEAN_FILES properties
c11f089d73 Tests: Extend MakeClean test to cover ADDITIONAL_CLEAN_FILES
012d599e26 Ninja: Add support for ADDITIONAL_CLEAN_FILES target property
890a1b9dc3 Ninja: Add support for ADDITIONAL_CLEAN_FILES directory property
7b23001f20 Ninja: Add support for additional clean files
d745df4b01 Makefiles: Add support for ADDITIONAL_CLEAN_FILES target property
...
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3318
21 files changed, 370 insertions, 77 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index c11496c..28c2883 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -61,6 +61,7 @@ Properties on Directories .. toctree:: :maxdepth: 1 + /prop_dir/ADDITIONAL_CLEAN_FILES /prop_dir/ADDITIONAL_MAKE_CLEAN_FILES /prop_dir/BINARY_DIR /prop_dir/BUILDSYSTEM_TARGETS @@ -102,6 +103,7 @@ Properties on Targets .. toctree:: :maxdepth: 1 + /prop_tgt/ADDITIONAL_CLEAN_FILES /prop_tgt/ALIASED_TARGET /prop_tgt/ANDROID_ANT_ADDITIONAL_OPTIONS /prop_tgt/ANDROID_API diff --git a/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst b/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst new file mode 100644 index 0000000..54a78ef --- /dev/null +++ b/Help/prop_dir/ADDITIONAL_CLEAN_FILES.rst @@ -0,0 +1,16 @@ +ADDITIONAL_CLEAN_FILES +---------------------- + +Additional files to remove during the clean stage. + +A :ref:`;-list <CMake Language Lists>` of files that will be removed as a +part of the ``clean`` target. + +Relative paths are allowed and are interpreted relative to the +current binary directory. + +Arguments to :prop_dir:`ADDITIONAL_CLEAN_FILES` may use +:manual:`generator expressions <cmake-generator-expressions(7)>`. + +This property only works for the :generator:`Ninja` and the Makefile +generators. It is ignored on other generators. diff --git a/Help/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.rst b/Help/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.rst index 986ea5b..893a298 100644 --- a/Help/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.rst +++ b/Help/prop_dir/ADDITIONAL_MAKE_CLEAN_FILES.rst @@ -1,7 +1,17 @@ ADDITIONAL_MAKE_CLEAN_FILES --------------------------- -Additional files to clean during the make clean stage. +.. deprecated:: 3.15 -A list of files that will be cleaned as a part of the ``make clean`` -stage. + Use :prop_dir:`ADDITIONAL_CLEAN_FILES` instead. + +Additional files to remove during the clean stage. + +A :ref:`;-list <CMake Language Lists>` of files that will be removed as a +part of the ``make clean`` target. + +Arguments to :prop_dir:`ADDITIONAL_MAKE_CLEAN_FILES` may use +:manual:`generator expressions <cmake-generator-expressions(7)>`. + +This property only works for the the Makefile generators. +It is ignored on other generators. diff --git a/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst b/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst new file mode 100644 index 0000000..856bb38 --- /dev/null +++ b/Help/prop_tgt/ADDITIONAL_CLEAN_FILES.rst @@ -0,0 +1,16 @@ +ADDITIONAL_CLEAN_FILES +---------------------- + +Additional files to remove during the clean stage. + +A :ref:`;-list <CMake Language Lists>` of files that will be removed as a +part of the ``clean`` target. + +Relative paths are allowed and are interpreted relative to the +current binary directory. + +Arguments to :prop_tgt:`ADDITIONAL_CLEAN_FILES` may use +:manual:`generator expressions <cmake-generator-expressions(7)>`. + +This property only works for the :generator:`Ninja` and the Makefile +generators. It is ignored on other generators. diff --git a/Help/release/dev/additional_clean_files.rst b/Help/release/dev/additional_clean_files.rst new file mode 100644 index 0000000..9b56642 --- /dev/null +++ b/Help/release/dev/additional_clean_files.rst @@ -0,0 +1,10 @@ +additional_clean_files +---------------------- + +* New target property :prop_tgt:`ADDITIONAL_CLEAN_FILES` and directory property + :prop_dir:`ADDITIONAL_CLEAN_FILES` were added. They allow to register + additional files that should be removed during the clean stage. + +* Directory property :prop_dir:`ADDITIONAL_MAKE_CLEAN_FILES` was marked + deprecated. The new directory property :prop_dir:`ADDITIONAL_CLEAN_FILES` + should be used instead. diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 67c22a7..00276f8 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -855,6 +855,11 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath( .first->second; } +void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName) +{ + this->AdditionalCleanFiles.emplace(std::move(fileName)); +} + void cmGlobalNinjaGenerator::AddCXXCompileCommand( const std::string& commandLine, const std::string& sourceFile) { @@ -1468,8 +1473,80 @@ bool cmGlobalNinjaGenerator::SupportsMultilineDepfile() const return this->NinjaSupportsMultilineDepfile; } +bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os) +{ + cmLocalGenerator* lgr = this->LocalGenerators.at(0); + std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake"; + std::string cleanScriptAbs = lgr->GetBinaryDirectory(); + cleanScriptAbs += '/'; + cleanScriptAbs += cleanScriptRel; + + // Check if there are additional files to clean + if (this->AdditionalCleanFiles.empty()) { + // Remove cmake clean script file if it exists + cmSystemTools::RemoveFile(cleanScriptAbs); + return false; + } + + // Write cmake clean script file + { + cmGeneratedFileStream fout(cleanScriptAbs); + if (!fout) { + return false; + } + fout << "# Additional clean files\n\n"; + fout << "file(REMOVE_RECURSE\n"; + for (std::string const& acf : this->AdditionalCleanFiles) { + fout << " " + << cmOutputConverter::EscapeForCMake(ConvertToNinjaPath(acf)) + << '\n'; + } + fout << ")\n"; + } + // Register clean script file + lgr->GetMakefile()->AddCMakeOutputFile(cleanScriptAbs); + + // Write rule + { + std::string cmd = CMakeCmd(); + cmd += " -P "; + cmd += lgr->ConvertToOutputFormat(this->NinjaOutputPath(cleanScriptRel), + cmOutputConverter::SHELL); + WriteRule(*this->RulesFileStream, "CLEAN_ADDITIONAL", cmd, + "Cleaning additional files...", + "Rule for cleaning additional files.", + /*depfile=*/"", + /*deptype=*/"", + /*rspfile=*/"", + /*rspcontent*/ "", + /*restat=*/"", + /*generator=*/false); + } + + // Write build + { + cmNinjaDeps outputs; + outputs.emplace_back( + this->NinjaOutputPath(this->GetAdditionalCleanTargetName())); + WriteBuild(os, "Clean additional files.", "CLEAN_ADDITIONAL", + /*outputs=*/outputs, + /*implicitOuts=*/cmNinjaDeps(), + /*explicitDeps=*/cmNinjaDeps(), + /*implicitDeps=*/cmNinjaDeps(), + /*orderOnlyDeps=*/cmNinjaDeps(), + /*variables=*/cmNinjaVars()); + } + // Return success + return true; +} + void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) { + // -- Additional clean target + bool additionalFiles = WriteTargetCleanAdditional(os); + + // -- Default clean target + // Write rule WriteRule(*this->RulesFileStream, "CLEAN", NinjaCmd() + " -t clean", "Cleaning all built files...", "Rule for cleaning all built files.", @@ -1479,13 +1556,24 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) /*rspcontent*/ "", /*restat=*/"", /*generator=*/false); - WriteBuild(os, "Clean all the built files.", "CLEAN", - /*outputs=*/cmNinjaDeps(1, this->NinjaOutputPath("clean")), - /*implicitOuts=*/cmNinjaDeps(), - /*explicitDeps=*/cmNinjaDeps(), - /*implicitDeps=*/cmNinjaDeps(), - /*orderOnlyDeps=*/cmNinjaDeps(), - /*variables=*/cmNinjaVars()); + + // Write build + { + cmNinjaDeps explicitDeps; + if (additionalFiles) { + explicitDeps.emplace_back( + this->NinjaOutputPath(this->GetAdditionalCleanTargetName())); + } + cmNinjaDeps outputs; + outputs.emplace_back(this->NinjaOutputPath(this->GetCleanTargetName())); + WriteBuild(os, "Clean all the built files.", "CLEAN", + /*outputs=*/outputs, + /*implicitOuts=*/cmNinjaDeps(), + /*explicitDeps=*/explicitDeps, + /*implicitDeps=*/cmNinjaDeps(), + /*orderOnlyDeps=*/cmNinjaDeps(), + /*variables=*/cmNinjaVars()); + } } void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index cd232b3..47685c2 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -258,6 +258,13 @@ public: }; MapToNinjaPathImpl MapToNinjaPath() { return MapToNinjaPathImpl(this); } + // -- Additional clean files + void AddAdditionalCleanFile(std::string fileName); + const char* GetAdditionalCleanTargetName() const + { + return "CMakeFiles/clean.additional"; + } + void AddCXXCompileCommand(const std::string& commandLine, const std::string& sourceFile); @@ -399,6 +406,7 @@ private: void WriteBuiltinTargets(std::ostream& os); void WriteTargetAll(std::ostream& os); void WriteTargetRebuildManifest(std::ostream& os); + bool WriteTargetCleanAdditional(std::ostream& os); void WriteTargetClean(std::ostream& os); void WriteTargetHelp(std::ostream& os); @@ -471,6 +479,7 @@ private: std::string OutputPathPrefix; std::string TargetAll; std::string CMakeCacheFile; + std::set<std::string> AdditionalCleanFiles; }; #endif // ! cmGlobalNinjaGenerator_h diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 869d25d..7f7ee71 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -14,6 +14,7 @@ #include "cmCustomCommand.h" #include "cmCustomCommandGenerator.h" #include "cmGeneratedFileStream.h" +#include "cmGeneratorExpression.h" #include "cmGeneratorTarget.h" #include "cmGlobalGenerator.h" #include "cmGlobalNinjaGenerator.h" @@ -94,6 +95,7 @@ void cmLocalNinjaGenerator::Generate() } this->WriteCustomCommandBuildStatements(); + this->AdditionalCleanFiles(); } // TODO: Picked up from cmLocalUnixMakefileGenerator3. Refactor it. @@ -598,3 +600,26 @@ std::string cmLocalNinjaGenerator::MakeCustomLauncher( return launcher; } + +void cmLocalNinjaGenerator::AdditionalCleanFiles() +{ + if (const char* prop_value = + this->Makefile->GetProperty("ADDITIONAL_CLEAN_FILES")) { + std::vector<std::string> cleanFiles; + { + cmGeneratorExpression ge; + auto cge = ge.Parse(prop_value); + cmSystemTools::ExpandListArgument( + cge->Evaluate(this, + this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE")), + cleanFiles); + } + std::string const& binaryDir = this->GetCurrentBinaryDirectory(); + cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator(); + for (std::string const& cleanFile : cleanFiles) { + // Support relative paths + gg->AddAdditionalCleanFile( + cmSystemTools::CollapseFullPath(cleanFile, binaryDir)); + } + } +} diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h index f772fb0..3a30bbb 100644 --- a/Source/cmLocalNinjaGenerator.h +++ b/Source/cmLocalNinjaGenerator.h @@ -105,6 +105,8 @@ private: std::string const& customStep, cmGeneratorTarget const* target) const; + void AdditionalCleanFiles(); + std::string HomeRelativeOutputPath; typedef std::map<cmCustomCommand const*, std::set<cmGeneratorTarget*>> diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index bece12e..88966c8 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -1040,7 +1040,7 @@ void cmLocalUnixMakefileGenerator3::AppendCustomCommand( } void cmLocalUnixMakefileGenerator3::AppendCleanCommand( - std::vector<std::string>& commands, const std::vector<std::string>& files, + std::vector<std::string>& commands, const std::set<std::string>& files, cmGeneratorTarget* target, const char* filename) { std::string currentBinDir = this->GetCurrentBinaryDirectory(); diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h index 7a0ea98..fed25e1 100644 --- a/Source/cmLocalUnixMakefileGenerator3.h +++ b/Source/cmLocalUnixMakefileGenerator3.h @@ -224,7 +224,7 @@ protected: bool echo_comment = false, std::ostream* content = nullptr); void AppendCleanCommand(std::vector<std::string>& commands, - const std::vector<std::string>& files, + const std::set<std::string>& files, cmGeneratorTarget* target, const char* filename = nullptr); diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx index ebf5fc2..beabf91 100644 --- a/Source/cmMakefileExecutableTargetGenerator.cxx +++ b/Source/cmMakefileExecutableTargetGenerator.cxx @@ -4,6 +4,7 @@ #include <algorithm> #include <memory> // IWYU pragma: keep +#include <set> #include <sstream> #include <string> #include <utility> @@ -291,8 +292,7 @@ void cmMakefileExecutableTargetGenerator::WriteDeviceExecutableRule( this->WriteTargetDriverRule(targetOutputReal, relink); // Clean all the possible executable names and symlinks. - this->CleanFiles.insert(this->CleanFiles.end(), exeCleanFiles.begin(), - exeCleanFiles.end()); + this->CleanFiles.insert(exeCleanFiles.begin(), exeCleanFiles.end()); #else static_cast<void>(relink); #endif @@ -480,7 +480,7 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) // List the PDB for cleaning only when the whole target is // cleaned. We do not want to delete the .pdb file just before // linking the target. - this->CleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( + this->CleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathPDB)); // Add the pre-build and pre-link rules building but not when relinking. @@ -695,6 +695,5 @@ void cmMakefileExecutableTargetGenerator::WriteExecutableRule(bool relink) this->WriteTargetDriverRule(targetFullPath, relink); // Clean all the possible executable names and symlinks. - this->CleanFiles.insert(this->CleanFiles.end(), exeCleanFiles.begin(), - exeCleanFiles.end()); + this->CleanFiles.insert(exeCleanFiles.begin(), exeCleanFiles.end()); } diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index 0393e22..f5d1fc9 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -4,6 +4,7 @@ #include <algorithm> #include <memory> // IWYU pragma: keep +#include <set> #include <sstream> #include <stddef.h> #include <utility> @@ -304,8 +305,8 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( commands, buildEcho, cmLocalUnixMakefileGenerator3::EchoLink, &progress); } // Clean files associated with this library. - std::vector<std::string> libCleanFiles; - libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( + std::set<std::string> libCleanFiles; + libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), targetOutputReal)); // Determine whether a link script will be used. @@ -412,8 +413,7 @@ void cmMakefileLibraryTargetGenerator::WriteDeviceLibraryRules( this->LocalGenerator->SetLinkScriptShell(false); // Clean all the possible library names and symlinks. - this->CleanFiles.insert(this->CleanFiles.end(), libCleanFiles.begin(), - libCleanFiles.end()); + this->CleanFiles.insert(libCleanFiles.begin(), libCleanFiles.end()); } std::vector<std::string> commands1; @@ -593,8 +593,8 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( } // Clean files associated with this library. - std::vector<std::string> libCleanFiles; - libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( + std::set<std::string> libCleanFiles; + libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathReal)); std::vector<std::string> commands1; @@ -611,22 +611,22 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( } if (this->TargetNames.Output != this->TargetNames.Real) { - libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( + libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath)); } if (this->TargetNames.SharedObject != this->TargetNames.Real && this->TargetNames.SharedObject != this->TargetNames.Output) { - libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( + libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathSO)); } if (!this->TargetNames.ImportLibrary.empty()) { - libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( + libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathImport)); std::string implib; if (this->GeneratorTarget->GetImplibGNUtoMS( this->ConfigName, targetFullPathImport, implib)) { - libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( + libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), implib)); } } @@ -634,14 +634,14 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( // List the PDB for cleaning only when the whole target is // cleaned. We do not want to delete the .pdb file just before // linking the target. - this->CleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( + this->CleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPathPDB)); #ifdef _WIN32 // There may be a manifest file for this target. Add it to the // clean set just in case. if (this->GeneratorTarget->GetType() != cmStateEnums::STATIC_LIBRARY) { - libCleanFiles.push_back(this->LocalGenerator->MaybeConvertToRelativePath( + libCleanFiles.insert(this->LocalGenerator->MaybeConvertToRelativePath( this->LocalGenerator->GetCurrentBinaryDirectory(), targetFullPath + ".manifest")); } @@ -992,6 +992,5 @@ void cmMakefileLibraryTargetGenerator::WriteLibraryRules( this->WriteTargetDriverRule(targetFullPath, relink); // Clean all the possible library names and symlinks. - this->CleanFiles.insert(this->CleanFiles.end(), libCleanFiles.begin(), - libCleanFiles.end()); + this->CleanFiles.insert(libCleanFiles.begin(), libCleanFiles.end()); } diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 340e405..a751b24 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -147,21 +147,53 @@ void cmMakefileTargetGenerator::CreateRuleFile() void cmMakefileTargetGenerator::WriteTargetBuildRules() { + // -- Write the custom commands for this target + const std::string& config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - // write the custom commands for this target - // Look for files registered for cleaning in this directory. - if (const char* additional_clean_files = - this->Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) { + // Evaluates generator expressions and expands prop_value + auto evaluatedFiles = + [this, &config](const char* prop_value) -> std::vector<std::string> { + std::vector<std::string> files; cmGeneratorExpression ge; - std::unique_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(additional_clean_files); - + std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop_value); cmSystemTools::ExpandListArgument( cge->Evaluate(this->LocalGenerator, config, false, this->GeneratorTarget, nullptr, nullptr), - this->CleanFiles); + files); + return files; + }; + + // Look for additional files registered for cleaning in this directory. + if (const char* prop_value = + this->Makefile->GetProperty("ADDITIONAL_MAKE_CLEAN_FILES")) { + std::vector<std::string> const files = evaluatedFiles(prop_value); + 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<std::string> 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")) { + std::vector<std::string> 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)); + } } // add custom commands to the clean rules? @@ -181,13 +213,13 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() if (clean) { const std::vector<std::string>& outputs = ccg.GetOutputs(); for (std::string const& output : outputs) { - this->CleanFiles.push_back( + this->CleanFiles.insert( this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, output)); } const std::vector<std::string>& byproducts = ccg.GetByproducts(); for (std::string const& byproduct : byproducts) { - this->CleanFiles.push_back( + this->CleanFiles.insert( this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, byproduct)); } @@ -211,7 +243,7 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules() for (const auto& be : buildEventCommands) { const std::vector<std::string>& byproducts = be.GetByproducts(); for (std::string const& byproduct : byproducts) { - this->CleanFiles.push_back( + this->CleanFiles.insert( this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, byproduct)); } @@ -350,7 +382,7 @@ void cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()( std::string output = macdir; output += "/"; output += cmSystemTools::GetFilenameName(input); - this->Generator->CleanFiles.push_back( + this->Generator->CleanFiles.insert( this->Generator->LocalGenerator->MaybeConvertToRelativePath( this->Generator->LocalGenerator->GetCurrentBinaryDirectory(), output)); output = this->Generator->LocalGenerator->MaybeConvertToRelativePath( @@ -415,7 +447,7 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles( // Save this in the target's list of object files. this->Objects.push_back(obj); - this->CleanFiles.push_back(obj); + this->CleanFiles.insert(obj); // TODO: Remove // std::string relativeObj @@ -804,8 +836,7 @@ void cmMakefileTargetGenerator::WriteObjectBuildFile( if (const char* extra_outputs_str = source.GetProperty("OBJECT_OUTPUTS")) { // Register these as extra files to clean. cmSystemTools::ExpandListArgument(extra_outputs_str, outputs); - this->CleanFiles.insert(this->CleanFiles.end(), outputs.begin() + 1, - outputs.end()); + this->CleanFiles.insert(outputs.begin() + 1, outputs.end()); } // Write the rule. diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h index ec58d17..c570a7c 100644 --- a/Source/cmMakefileTargetGenerator.h +++ b/Source/cmMakefileTargetGenerator.h @@ -210,7 +210,7 @@ protected: cmGeneratedFileStream* InfoFileStream; // files to clean - std::vector<std::string> CleanFiles; + std::set<std::string> CleanFiles; // objects used by this target std::vector<std::string> Objects; diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index ebb7c15..680f881 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -83,6 +83,8 @@ void cmNinjaNormalTargetGenerator::Generate() this->WriteDeviceLinkStatement(); this->WriteLinkStatement(); } + + this->AdditionalCleanFiles(); } void cmNinjaNormalTargetGenerator::WriteLanguagesRules() diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 506711a..8afac70 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -1310,6 +1310,31 @@ void cmNinjaTargetGenerator::ExportObjectCompileCommand( this->GetGlobalGenerator()->AddCXXCompileCommand(cmdLine, sourceFileName); } +void cmNinjaTargetGenerator::AdditionalCleanFiles() +{ + if (const char* prop_value = + this->GeneratorTarget->GetProperty("ADDITIONAL_CLEAN_FILES")) { + cmLocalNinjaGenerator* lg = this->LocalGenerator; + std::vector<std::string> cleanFiles; + { + cmGeneratorExpression ge; + auto cge = ge.Parse(prop_value); + cmSystemTools::ExpandListArgument( + cge->Evaluate(lg, + this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"), + false, this->GeneratorTarget, nullptr, nullptr), + cleanFiles); + } + std::string const& binaryDir = lg->GetCurrentBinaryDirectory(); + cmGlobalNinjaGenerator* gg = lg->GetGlobalNinjaGenerator(); + for (std::string const& cleanFile : cleanFiles) { + // Support relative paths + gg->AddAdditionalCleanFile( + cmSystemTools::CollapseFullPath(cleanFile, binaryDir)); + } + } +} + void cmNinjaTargetGenerator::EnsureDirectoryExists( const std::string& path) const { diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index 3dbc1b5..235c60c 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -134,6 +134,8 @@ protected: std::string const& objectFileDir, std::string const& flags, std::string const& defines, std::string const& includes); + void AdditionalCleanFiles(); + cmNinjaDeps GetObjects() const { return this->Objects; } void EnsureDirectoryExists(const std::string& dir) const; diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index bc4812b..d992986 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2007,7 +2007,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release ADD_TEST_MACRO(CheckCompilerRelatedVariables CheckCompilerRelatedVariables) - if("${CMAKE_GENERATOR}" MATCHES "Makefile") + if("${CMAKE_GENERATOR}" MATCHES "Makefile" OR + "${CMAKE_GENERATOR}" MATCHES "Ninja") add_test(MakeClean ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/MakeClean" diff --git a/Tests/MakeClean/ToClean/CMakeLists.txt b/Tests/MakeClean/ToClean/CMakeLists.txt index d0e24ce..5d84e6c 100644 --- a/Tests/MakeClean/ToClean/CMakeLists.txt +++ b/Tests/MakeClean/ToClean/CMakeLists.txt @@ -1,42 +1,98 @@ -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 3.14) project(ToClean) -# Build a simple project. -add_executable(toclean toclean.cxx) +# Utility variables +set(TSD ${ToClean_SOURCE_DIR}) +set(TBD ${ToClean_BINARY_DIR}) +set(CLEAN_FILE_CONTENT "File registered for cleaning.\n") -# List some build-time-generated files. -set(TOCLEAN_FILES ${TOCLEAN_FILES} - "${ToClean_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toclean.dir/toclean.cxx${CMAKE_CXX_OUTPUT_EXTENSION}") +# Lists build-time-generated files that should be cleaned away +set(TOCLEAN_FILES) -# Create a file that must be registered for cleaning. -file(WRITE "${ToClean_BINARY_DIR}/Registered.txt" - "File registered for cleaning.\n") -set_directory_properties(PROPERTIES - ADDITIONAL_MAKE_CLEAN_FILES "${ToClean_BINARY_DIR}/Registered.txt") -set(TOCLEAN_FILES ${TOCLEAN_FILES} "${ToClean_BINARY_DIR}/Registered.txt") +# Build a simple project whose compiled objects should be cleaned. +add_executable(toclean toclean.cxx) +list(APPEND TOCLEAN_FILES + "${TBD}${CMAKE_FILES_DIRECTORY}/toclean.dir/toclean.cxx${CMAKE_CXX_OUTPUT_EXTENSION}") # Create a custom command whose output should be cleaned. -add_custom_command(OUTPUT ${ToClean_BINARY_DIR}/generated.txt - DEPENDS ${ToClean_SOURCE_DIR}/toclean.cxx +set(CustomCommandFile "${TBD}/CustomCommandFile.txt") +add_custom_command(OUTPUT ${CustomCommandFile} + DEPENDS ${TSD}/toclean.cxx COMMAND ${CMAKE_COMMAND} - ARGS -E copy ${ToClean_SOURCE_DIR}/toclean.cxx - ${ToClean_BINARY_DIR}/generated.txt - ) -add_custom_target(generate ALL DEPENDS ${ToClean_BINARY_DIR}/generated.txt) -set(TOCLEAN_FILES ${TOCLEAN_FILES} "${ToClean_BINARY_DIR}/generated.txt") + ARGS -E copy ${TSD}/toclean.cxx ${CustomCommandFile}) +add_custom_target(generate ALL DEPENDS ${CustomCommandFile}) +list(APPEND TOCLEAN_FILES ${CustomCommandFile}) + + +### Tests ADDITIONAL_MAKE_CLEAN_FILES directory property +if("${CMAKE_GENERATOR}" MATCHES "Makefile") + # Create a file that must be registered for cleaning. + set(MakeDirPropFile "${TBD}/MakeDirPropFile.txt") + file(WRITE "${MakeDirPropFile}" ${CLEAN_FILE_CONTENT}) + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${MakeDirPropFile}") + list(APPEND TOCLEAN_FILES "${MakeDirPropFile}") + + # Create a custom command whose output should be cleaned, but whose name + # is not known until generate-time + set(MakeDirPropExpFileRel "MakeDirProp_copy${CMAKE_EXECUTABLE_SUFFIX}") + set(MakeDirPropExpFile "$<TARGET_FILE_DIR:toclean>/${MakeDirPropExpFileRel}") + add_custom_command(TARGET toclean POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy $<TARGET_FILE:toclean> ${MakeDirPropExpFile}) + set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${MakeDirPropExpFile}) + list(APPEND TOCLEAN_FILES "${TBD}/${MakeDirPropExpFileRel}") +endif() + + +### Tests ADDITIONAL_CLEAN_FILES directory property + +# Register a file path relative to the build directory +set(DirPropFileRel "DirPropFileRel.txt") +file(WRITE "${TBD}/${DirPropFileRel}" ${CLEAN_FILE_CONTENT}) +set_directory_properties(PROPERTIES ADDITIONAL_CLEAN_FILES ${DirPropFileRel}) +list(APPEND TOCLEAN_FILES "${TBD}/${DirPropFileRel}") + +# Register an absolute file path +set(DirPropFileAbs "${TBD}/DirPropFileAbs.txt") +file(WRITE "${DirPropFileAbs}" ${CLEAN_FILE_CONTENT}) +set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${DirPropFileAbs}) +list(APPEND TOCLEAN_FILES "${DirPropFileAbs}") # Create a custom command whose output should be cleaned, but whose name # is not known until generate-time -set(copied_exe "$<TARGET_FILE_DIR:toclean>/toclean_copy${CMAKE_EXECUTABLE_SUFFIX}") +set(DirPropExpFileRel "DirProp_copy${CMAKE_EXECUTABLE_SUFFIX}") +set(DirPropExpFile "$<TARGET_FILE_DIR:toclean>/${DirPropExpFileRel}") add_custom_command(TARGET toclean POST_BUILD COMMAND ${CMAKE_COMMAND} - ARGS -E copy $<TARGET_FILE:toclean> - ${copied_exe} - ) -set_property(DIRECTORY APPEND PROPERTY - ADDITIONAL_MAKE_CLEAN_FILES ${copied_exe}) -list(APPEND TOCLEAN_FILES "${ToClean_BINARY_DIR}/toclean_copy${CMAKE_EXECUTABLE_SUFFIX}") + ARGS -E copy $<TARGET_FILE:toclean> ${DirPropExpFile}) +set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${DirPropExpFile}) +list(APPEND TOCLEAN_FILES "${TBD}/${DirPropExpFileRel}") + + +### Tests ADDITIONAL_CLEAN_FILES target property + +# Register a file path relative to the build directory +set(TgtPropFileRel "TargetPropFileRel.txt") +file(WRITE "${TBD}/${TgtPropFileRel}" ${CLEAN_FILE_CONTENT}) +set_target_properties(toclean PROPERTIES ADDITIONAL_CLEAN_FILES ${TgtPropFileRel}) +list(APPEND TOCLEAN_FILES "${TBD}/${TgtPropFileRel}") + +# Register an absolute file path +set(TgtPropFileAbs "${TBD}/TargetPropFileAbs.txt") +file(WRITE "${TgtPropFileAbs}" ${CLEAN_FILE_CONTENT}) +set_property(TARGET toclean APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${TgtPropFileAbs}) +list(APPEND TOCLEAN_FILES "${TgtPropFileAbs}") + +# Create a custom command whose output should be cleaned, but whose name +# is not known until generate-time +set(TgtPropExpFileRel "TgtProp_copy${CMAKE_EXECUTABLE_SUFFIX}") +set(TgtPropExpFile "$<TARGET_FILE_DIR:toclean>/${TgtPropExpFileRel}") +add_custom_command(TARGET toclean POST_BUILD + COMMAND ${CMAKE_COMMAND} + ARGS -E copy $<TARGET_FILE:toclean> ${TgtPropExpFile}) +set_property(TARGET toclean APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${TgtPropExpFile}) +list(APPEND TOCLEAN_FILES "${TBD}/${TgtPropExpFileRel}") + # Configure a file listing these build-time-generated files. -configure_file(${ToClean_SOURCE_DIR}/ToCleanFiles.cmake.in - ${ToClean_BINARY_DIR}/ToCleanFiles.cmake @ONLY) +configure_file(${TSD}/ToCleanFiles.cmake.in ${TBD}/ToCleanFiles.cmake @ONLY) diff --git a/Tests/MakeClean/check_clean.c.in b/Tests/MakeClean/check_clean.c.in index 5bc4ab8..e5a7945 100644 --- a/Tests/MakeClean/check_clean.c.in +++ b/Tests/MakeClean/check_clean.c.in @@ -18,7 +18,7 @@ int main() if(pf) { fclose(pf); - fprintf(stderr, "File \"%s\" exists!", *f); + fprintf(stderr, "File \"%s\" still exists!\n", *f); result = 1; } } |