diff options
21 files changed, 110 insertions, 32 deletions
diff --git a/Help/command/add_custom_command.rst b/Help/command/add_custom_command.rst index d421364..4ab4298 100644 --- a/Help/command/add_custom_command.rst +++ b/Help/command/add_custom_command.rst @@ -20,6 +20,7 @@ The first signature is for adding a custom command to produce an output:: [<lang2> depend2] ...] [WORKING_DIRECTORY dir] [COMMENT comment] + [DEPFILE depfile] [VERBATIM] [APPEND] [USES_TERMINAL]) This defines a command to generate specified ``OUTPUT`` file(s). @@ -170,6 +171,12 @@ The options are: If it is a relative path it will be interpreted relative to the build tree directory corresponding to the current source directory. +``DEPFILE`` + Specify a ``.d`` depfile for the :generator:`Ninja` generator. + A ``.d`` file holds dependencies usually emitted by the custom + command itself. + Using ``DEPFILE`` with other generators than Ninja is an error. + Build Events ^^^^^^^^^^^^ diff --git a/Help/release/dev/ninja-add_custom_command-depfile.rst b/Help/release/dev/ninja-add_custom_command-depfile.rst new file mode 100644 index 0000000..c8099fe --- /dev/null +++ b/Help/release/dev/ninja-add_custom_command-depfile.rst @@ -0,0 +1,6 @@ +ninja-add_custom_command-depfile +-------------------------------- + +* The :command:`add_custom_command` command gained a new ``DEPFILE`` + option that works with the :generator:`Ninja` generator to provide + implicit dependency information to the build tool. diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index e8a4d2c..52986e2 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 6) -set(CMake_VERSION_PATCH 20160826) +set(CMake_VERSION_PATCH 20160830) #set(CMake_VERSION_RC 1) diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index 400be77..2c4a4ca 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -15,6 +15,8 @@ #include "cmSourceFile.h" +#include "cmGlobalGenerator.h" + // cmAddCustomCommandCommand bool cmAddCustomCommandCommand::InitialPass( std::vector<std::string> const& args, cmExecutionStatus&) @@ -28,7 +30,7 @@ bool cmAddCustomCommandCommand::InitialPass( return false; } - std::string source, target, main_dependency, working; + std::string source, target, main_dependency, working, depfile; std::string comment_buffer; const char* comment = CM_NULLPTR; std::vector<std::string> depends, outputs, output, byproducts; @@ -60,6 +62,7 @@ bool cmAddCustomCommandCommand::InitialPass( doing_byproducts, doing_comment, doing_working_directory, + doing_depfile, doing_nothing }; @@ -110,6 +113,13 @@ bool cmAddCustomCommandCommand::InitialPass( doing = doing_implicit_depends_lang; } else if (copy == "COMMENT") { doing = doing_comment; + } else if (copy == "DEPFILE") { + doing = doing_depfile; + if (this->Makefile->GetGlobalGenerator()->GetName() != "Ninja") { + this->SetError("Option DEPFILE not supported by " + + this->Makefile->GetGlobalGenerator()->GetName()); + return false; + } } else { std::string filename; switch (doing) { @@ -147,6 +157,9 @@ bool cmAddCustomCommandCommand::InitialPass( filename = cmSystemTools::CollapseFullPath(filename); } switch (doing) { + case doing_depfile: + depfile = copy; + break; case doing_working_directory: working = copy; break; @@ -269,12 +282,12 @@ bool cmAddCustomCommandCommand::InitialPass( std::vector<std::string> no_depends; this->Makefile->AddCustomCommandToTarget( target, byproducts, no_depends, commandLines, cctype, comment, - working.c_str(), escapeOldStyle, uses_terminal); + working.c_str(), escapeOldStyle, uses_terminal, depfile); } else if (target.empty()) { // Target is empty, use the output. this->Makefile->AddCustomCommandToOutput( output, byproducts, depends, main_dependency, commandLines, comment, - working.c_str(), false, escapeOldStyle, uses_terminal); + working.c_str(), false, escapeOldStyle, uses_terminal, depfile); // Add implicit dependency scanning requests if any were given. if (!implicit_depends.empty()) { diff --git a/Source/cmCustomCommand.cxx b/Source/cmCustomCommand.cxx index 7533369..eaa49b0 100644 --- a/Source/cmCustomCommand.cxx +++ b/Source/cmCustomCommand.cxx @@ -135,3 +135,13 @@ void cmCustomCommand::SetUsesTerminal(bool b) { this->UsesTerminal = b; } + +const std::string& cmCustomCommand::GetDepfile() const +{ + return this->Depfile; +} + +void cmCustomCommand::SetDepfile(const std::string& depfile) +{ + this->Depfile = depfile; +} diff --git a/Source/cmCustomCommand.h b/Source/cmCustomCommand.h index c2b9738..34753f4 100644 --- a/Source/cmCustomCommand.h +++ b/Source/cmCustomCommand.h @@ -88,6 +88,10 @@ public: bool GetUsesTerminal() const; void SetUsesTerminal(bool b); + /** Set/Get the depfile (used by the Ninja generator) */ + const std::string& GetDepfile() const; + void SetDepfile(const std::string& depfile); + private: std::vector<std::string> Outputs; std::vector<std::string> Byproducts; @@ -97,6 +101,7 @@ private: ImplicitDependsList ImplicitDepends; std::string Comment; std::string WorkingDirectory; + std::string Depfile; bool HaveComment; bool EscapeAllowMakeVars; bool EscapeOldStyle; diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 559974e..6eae26b 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -593,7 +593,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget( includes.end()); std::string systemIncludeDirs = makefile->GetSafeDefinition( - "CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS"); + "CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS"); if (!systemIncludeDirs.empty()) { std::vector<std::string> dirs; cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs); @@ -601,7 +601,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget( } systemIncludeDirs = makefile->GetSafeDefinition( - "CMAKE_EXTRA_GENERATOR_CXX_SYSTEM_INCLUDE_DIRS"); + "CMAKE_EXTRA_GENERATOR_C_SYSTEM_INCLUDE_DIRS"); if (!systemIncludeDirs.empty()) { std::vector<std::string> dirs; cmSystemTools::ExpandListArgument(systemIncludeDirs, dirs); diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 939c5ad..590f207 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -251,8 +251,8 @@ void cmGlobalNinjaGenerator::AddCustomCommandRule() void cmGlobalNinjaGenerator::WriteCustomCommandBuild( const std::string& command, const std::string& description, - const std::string& comment, bool uses_terminal, bool restat, - const cmNinjaDeps& outputs, const cmNinjaDeps& deps, + const std::string& comment, const std::string& depfile, bool uses_terminal, + bool restat, const cmNinjaDeps& outputs, const cmNinjaDeps& deps, const cmNinjaDeps& orderOnly) { std::string cmd = command; @@ -273,7 +273,9 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( if (uses_terminal && SupportsConsolePool()) { vars["pool"] = "console"; } - + if (!depfile.empty()) { + vars["depfile"] = depfile; + } this->WriteBuild(*this->BuildFileStream, comment, "CUSTOM_COMMAND", outputs, deps, cmNinjaDeps(), orderOnly, vars); @@ -841,7 +843,7 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() std::copy(i->second.begin(), i->second.end(), std::back_inserter(deps)); WriteCustomCommandBuild(/*command=*/"", /*description=*/"", "Assume dependencies for generated source file.", - /*uses_terminal*/ false, + /*depfile*/ "", /*uses_terminal*/ false, /*restat*/ true, cmNinjaDeps(1, i->first), deps); } } diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 52fa5c9..082ee3a 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -113,7 +113,8 @@ public: void WriteCustomCommandBuild(const std::string& command, const std::string& description, - const std::string& comment, bool uses_terminal, + const std::string& comment, + const std::string& depfile, bool uses_terminal, bool restat, const cmNinjaDeps& outputs, const cmNinjaDeps& deps = cmNinjaDeps(), const cmNinjaDeps& orderOnly = cmNinjaDeps()); diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index d07bfaa..d15ee22 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -414,7 +414,8 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( } else { this->GetGlobalNinjaGenerator()->WriteCustomCommandBuild( this->BuildCommandLine(cmdLines), this->ConstructComment(ccg), - "Custom command for " + ninjaOutputs[0], cc->GetUsesTerminal(), + "Custom command for " + ninjaOutputs[0], cc->GetDepfile(), + cc->GetUsesTerminal(), /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, ninjaDeps, orderOnlyDeps); } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 6e47797..d1fddca 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -701,7 +701,7 @@ void cmMakefile::AddCustomCommandToTarget( const std::vector<std::string>& depends, const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, const char* comment, const char* workingDir, bool escapeOldStyle, - bool uses_terminal) + bool uses_terminal, const std::string& depfile) { // Find the target to which to add the custom command. cmTargets::iterator ti = this->Targets.find(target); @@ -773,6 +773,7 @@ void cmMakefile::AddCustomCommandToTarget( cc.SetEscapeOldStyle(escapeOldStyle); cc.SetEscapeAllowMakeVars(true); cc.SetUsesTerminal(uses_terminal); + cc.SetDepfile(depfile); switch (type) { case cmTarget::PRE_BUILD: ti->second.AddPreBuildCommand(cc); @@ -792,7 +793,7 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput( const std::vector<std::string>& depends, const std::string& main_dependency, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace, bool escapeOldStyle, - bool uses_terminal) + bool uses_terminal, const std::string& depfile) { // Make sure there is at least one output. if (outputs.empty()) { @@ -886,6 +887,7 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput( cc->SetEscapeOldStyle(escapeOldStyle); cc->SetEscapeAllowMakeVars(true); cc->SetUsesTerminal(uses_terminal); + cc->SetDepfile(depfile); file->SetCustomCommand(cc); this->UpdateOutputToSourceMap(outputs, file); } @@ -923,14 +925,14 @@ cmSourceFile* cmMakefile::AddCustomCommandToOutput( const std::string& output, const std::vector<std::string>& depends, const std::string& main_dependency, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace, - bool escapeOldStyle, bool uses_terminal) + bool escapeOldStyle, bool uses_terminal, const std::string& depfile) { std::vector<std::string> outputs; outputs.push_back(output); std::vector<std::string> no_byproducts; return this->AddCustomCommandToOutput( outputs, no_byproducts, depends, main_dependency, commandLines, comment, - workingDir, replace, escapeOldStyle, uses_terminal); + workingDir, replace, escapeOldStyle, uses_terminal, depfile); } void cmMakefile::AddCustomCommandOldStyle( diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index b3587c5..4d137db 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -135,14 +135,12 @@ public: void FinalPass(); /** Add a custom command to the build. */ - void AddCustomCommandToTarget(const std::string& target, - const std::vector<std::string>& byproducts, - const std::vector<std::string>& depends, - const cmCustomCommandLines& commandLines, - cmTarget::CustomCommandType type, - const char* comment, const char* workingDir, - bool escapeOldStyle = true, - bool uses_terminal = false); + void AddCustomCommandToTarget( + const std::string& target, const std::vector<std::string>& byproducts, + const std::vector<std::string>& depends, + const cmCustomCommandLines& commandLines, cmTarget::CustomCommandType type, + const char* comment, const char* workingDir, bool escapeOldStyle = true, + bool uses_terminal = false, const std::string& depfile = ""); cmSourceFile* AddCustomCommandToOutput( const std::vector<std::string>& outputs, const std::vector<std::string>& byproducts, @@ -150,13 +148,13 @@ public: const std::string& main_dependency, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace = false, bool escapeOldStyle = true, - bool uses_terminal = false); + bool uses_terminal = false, const std::string& depfile = ""); cmSourceFile* AddCustomCommandToOutput( const std::string& output, const std::vector<std::string>& depends, const std::string& main_dependency, const cmCustomCommandLines& commandLines, const char* comment, const char* workingDir, bool replace = false, bool escapeOldStyle = true, - bool uses_terminal = false); + bool uses_terminal = false, const std::string& depfile = ""); void AddCustomCommandOldStyle(const std::string& target, const std::vector<std::string>& outputs, const std::vector<std::string>& depends, diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 49836f2..0664104 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -150,7 +150,7 @@ void cmNinjaUtilityTargetGenerator::Generate() this->GetGlobalGenerator()->WriteCustomCommandBuild( command, desc, "Utility command for " + this->GetTargetName(), - uses_terminal, + /*depfile*/ "", uses_terminal, /*restat*/ true, util_outputs, deps); this->GetGlobalGenerator()->WritePhonyBuild( diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 216de03..907b65b 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -185,13 +185,12 @@ cmVisualStudio10TargetGenerator::cmVisualStudio10TargetGenerator( this->GUID = this->GlobalGenerator->GetGUID(this->Name.c_str()); this->Platform = gg->GetPlatformName(); this->NsightTegra = gg->IsNsightTegra(); - for (int i = - sscanf(gg->GetNsightTegraVersion().c_str(), "%u.%u.%u.%u", - &this->NsightTegraVersion[0], &this->NsightTegraVersion[1], - &this->NsightTegraVersion[2], &this->NsightTegraVersion[3]); - i < 4; ++i) { + for (int i = 0; i < 4; ++i) { this->NsightTegraVersion[i] = 0; } + sscanf(gg->GetNsightTegraVersion().c_str(), "%u.%u.%u.%u", + &this->NsightTegraVersion[0], &this->NsightTegraVersion[1], + &this->NsightTegraVersion[2], &this->NsightTegraVersion[3]); this->MSTools = !this->NsightTegra; this->TargetCompileAsWinRT = false; this->BuildFileStream = 0; diff --git a/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-result.txt b/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-stderr.txt b/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-stderr.txt new file mode 100644 index 0000000..74d62a4 --- /dev/null +++ b/Tests/RunCMake/Make/CustomCommandDepfile-ERROR-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error at CustomCommandDepfile-ERROR.cmake:1 \(add_custom_command\): + add_custom_command Option DEPFILE not supported by [^ +]+ +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/Make/CustomCommandDepfile-ERROR.cmake b/Tests/RunCMake/Make/CustomCommandDepfile-ERROR.cmake new file mode 100644 index 0000000..bad7955 --- /dev/null +++ b/Tests/RunCMake/Make/CustomCommandDepfile-ERROR.cmake @@ -0,0 +1,8 @@ +add_custom_command( + OUTPUT hello.copy.c + COMMAND "${CMAKE_COMMAND}" -E copy + "${CMAKE_CURRENT_SOURCE_DIR}/hello.c" + hello.copy.c + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + DEPFILE "test.d" + ) diff --git a/Tests/RunCMake/Make/RunCMakeTest.cmake b/Tests/RunCMake/Make/RunCMakeTest.cmake index c6bbd03..869d11e 100644 --- a/Tests/RunCMake/Make/RunCMakeTest.cmake +++ b/Tests/RunCMake/Make/RunCMakeTest.cmake @@ -15,3 +15,5 @@ run_TargetMessages(OFF) run_TargetMessages(VAR-ON -DCMAKE_TARGET_MESSAGES=ON) run_TargetMessages(VAR-OFF -DCMAKE_TARGET_MESSAGES=OFF) + +run_cmake(CustomCommandDepfile-ERROR) diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake new file mode 100644 index 0000000..189de64 --- /dev/null +++ b/Tests/RunCMake/Ninja/CustomCommandDepfile-check.cmake @@ -0,0 +1,5 @@ +set(log "${RunCMake_BINARY_DIR}/CustomCommandDepfile-build/build.ninja") +file(READ "${log}" build_file) +if(NOT "${build_file}" MATCHES "depfile = test\\.d") + set(RunCMake_TEST_FAILED "Log file:\n ${log}\ndoes not have expected line: depfile = test.d") +endif() diff --git a/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake b/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake new file mode 100644 index 0000000..dbef2a5 --- /dev/null +++ b/Tests/RunCMake/Ninja/CustomCommandDepfile.cmake @@ -0,0 +1,11 @@ +add_custom_command( + OUTPUT hello.copy.c + COMMAND "${CMAKE_COMMAND}" -E copy + "${CMAKE_CURRENT_SOURCE_DIR}/hello.c" + hello.copy.c + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + DEPFILE "test.d" + ) +add_custom_target(copy ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/hello.copy.c") + +include(CheckNoPrefixSubDir.cmake) diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index 622c327..778f2c1 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -32,6 +32,8 @@ run_CMP0058(WARN-by) run_CMP0058(NEW-no) run_CMP0058(NEW-by) +run_cmake(CustomCommandDepfile) + function(run_SubDir) # Use a single build tree for a few tests without cleaning. set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SubDir-build) |