Commit 66efdbd2 authored by Brad King's avatar Brad King Committed by Kitware Robot

Merge topic 'additional_clean_files'

b5bf369e Release notes: Add release notes for ADDITIONAL_CLEAN_FILES properties
4e2ce0a6 Doc: Update and deprecate ADDITIONAL_MAKE_CLEAN_FILES directory property
338994d6 Doc: Add documentation for ADDITIONAL_CLEAN_FILES properties
c11f089d Tests: Extend MakeClean test to cover ADDITIONAL_CLEAN_FILES
012d599e Ninja: Add support for ADDITIONAL_CLEAN_FILES target property
890a1b9d Ninja: Add support for ADDITIONAL_CLEAN_FILES directory property
7b23001f Ninja: Add support for additional clean files
d745df4b Makefiles: Add support for ADDITIONAL_CLEAN_FILES target property
...
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !3318
parents 0064edf4 b5bf369e
Pipeline #137048 failed with stage
in 0 seconds
......@@ -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
......
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.
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.
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.
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.
......@@ -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)
......
......@@ -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
......@@ -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));
}
}
}
......@@ -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*>>
......
......@@ -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();
......
......@@ -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);
......
......@@ -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());
}
......@@ -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());
}
......@@ -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.
......
......@@ -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;
......
......@@ -83,6 +83,8 @@ void cmNinjaNormalTargetGenerator::Generate()
this->WriteDeviceLinkStatement();
this->WriteLinkStatement();
}
this->AdditionalCleanFiles();
}
void cmNinjaNormalTargetGenerator::WriteLanguagesRules()
......
......@@ -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
{
......
......@@ -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;
......
......@@ -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"
......
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}
)