Merge topic 'custom-command-multiple-outputs'

9660a3cc Makefile: Fix multiple custom command outputs with one missing
5c08e255 KWSys SystemTools: Teach Touch with !create to succeed on missing file
This commit is contained in:
Brad King 2015-04-13 09:06:07 -04:00 committed by CMake Topic Stage
commit e0adfe6112
4 changed files with 118 additions and 26 deletions

View File

@ -778,7 +778,7 @@ cmMakefileTargetGenerator
// Write the rule.
this->WriteMakeRule(*this->BuildFileStream, 0, outputs,
depends, commands, false);
depends, commands);
bool do_preprocess_rules = lang_has_preprocessor &&
this->LocalGenerator->GetCreatePreprocessedSourceRules();
@ -1000,18 +1000,30 @@ void cmMakefileTargetGenerator::WriteTargetCleanRules()
}
//----------------------------------------------------------------------------
void cmMakefileTargetGenerator::WriteMakeRule(
bool cmMakefileTargetGenerator::WriteMakeRule(
std::ostream& os,
const char* comment,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
const std::vector<std::string>& commands,
bool symbolic,
bool in_help)
{
bool symbolic = false;
if (outputs.size() == 0)
{
return;
return symbolic;
}
// Check whether we need to bother checking for a symbolic output.
bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
// Check whether the first output is marked as symbolic.
if(need_symbolic)
{
if(cmSourceFile* sf = this->Makefile->GetSource(outputs[0]))
{
symbolic = sf->GetPropertyAsBool("SYMBOLIC");
}
}
// We always attach the actual commands to the first output.
@ -1021,7 +1033,7 @@ void cmMakefileTargetGenerator::WriteMakeRule(
// For single outputs, we are done.
if (outputs.size() == 1)
{
return;
return symbolic;
}
// For multiple outputs, make the extra ones depend on the first one.
@ -1034,14 +1046,25 @@ void cmMakefileTargetGenerator::WriteMakeRule(
std::string const out = this->Convert(*o, cmLocalGenerator::HOME_OUTPUT,
cmLocalGenerator::SHELL);
std::vector<std::string> output_commands;
if (!symbolic)
bool o_symbolic = false;
if(need_symbolic)
{
if(cmSourceFile* sf = this->Makefile->GetSource(*o))
{
o_symbolic = sf->GetPropertyAsBool("SYMBOLIC");
}
}
symbolic = symbolic && o_symbolic;
if (!o_symbolic)
{
output_commands.push_back("@$(CMAKE_COMMAND) -E touch_nocreate " + out);
}
this->LocalGenerator->WriteMakeRule(os, 0, *o, output_depends,
output_commands, symbolic, in_help);
output_commands, o_symbolic, in_help);
if (!symbolic)
if (!o_symbolic)
{
// At build time, remove the first output if this one does not exist
// so that "make" will rerun the real commands that create this one.
@ -1049,6 +1072,7 @@ void cmMakefileTargetGenerator::WriteMakeRule(
this->MultipleOutputPairs.insert(p);
}
}
return symbolic;
}
//----------------------------------------------------------------------------
@ -1269,30 +1293,16 @@ void cmMakefileTargetGenerator
std::vector<std::string> depends;
this->LocalGenerator->AppendCustomDepend(depends, ccg);
// Check whether we need to bother checking for a symbolic output.
bool need_symbolic = this->GlobalGenerator->GetNeedSymbolicMark();
// Write the rule.
const std::vector<std::string>& outputs = ccg.GetOutputs();
std::vector<std::string>::const_iterator o = outputs.begin();
{
bool symbolic = false;
if(need_symbolic)
{
if(cmSourceFile* sf = this->Makefile->GetSource(*o))
{
symbolic = sf->GetPropertyAsBool("SYMBOLIC");
}
}
this->WriteMakeRule(*this->BuildFileStream, 0, outputs,
depends, commands, symbolic);
bool symbolic = this->WriteMakeRule(*this->BuildFileStream, 0,
outputs, depends, commands);
// If the rule has changed make sure the output is rebuilt.
if(!symbolic)
{
this->GlobalGenerator->AddRuleHash(ccg.GetOutputs(), content.str());
}
}
// Setup implicit dependency scanning.
for(cmCustomCommand::ImplicitDependsList::const_iterator

View File

@ -224,12 +224,11 @@ protected:
typedef std::map<std::string, std::string> MultipleOutputPairsType;
MultipleOutputPairsType MultipleOutputPairs;
void WriteMakeRule(std::ostream& os,
bool WriteMakeRule(std::ostream& os,
const char* comment,
const std::vector<std::string>& outputs,
const std::vector<std::string>& depends,
const std::vector<std::string>& commands,
bool symbolic,
bool in_help = false);
// Target name info.

View File

@ -42,6 +42,11 @@ list(APPEND _cmake_options "-DTEST_LINK_DEPENDS=${TEST_LINK_DEPENDS}")
list(APPEND _cmake_options "-DCMAKE_FORCE_DEPFILES=1")
if(NOT CMAKE_GENERATOR MATCHES "Visual Studio ([^6789]|[6789][0-9])")
set(TEST_MULTI3 1)
list(APPEND _cmake_options "-DTEST_MULTI3=1")
endif()
file(MAKE_DIRECTORY ${BuildDepends_BINARY_DIR}/Project)
message("Creating Project/foo.cxx")
write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx
@ -66,6 +71,8 @@ set(link_depends_no_shared_check_txt ${BuildDepends_BINARY_DIR}/Project/link_dep
file(WRITE ${BuildDepends_BINARY_DIR}/Project/external.in "external original\n")
file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi1-in.txt "multi1-in original\n")
file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt "multi2-stamp original\n")
file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt "multi3-stamp original\n")
help_xcode_depends()
@ -191,6 +198,34 @@ else()
"multi1-out2-copy.txt is missing")
endif()
if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi2-real.txt)
if(${BuildDepends_BINARY_DIR}/Project/multi2-real.txt
IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt)
message(STATUS "multi2-real.txt is newer than multi2-stamp.txt")
else()
message(SEND_ERROR "Project did not initially build properly: "
"multi2-real.txt is not newer than multi2-stamp.txt")
endif()
else()
message(SEND_ERROR "Project did not initially build properly: "
"multi2-real.txt is missing")
endif()
if(TEST_MULTI3)
if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi3-real.txt)
if(${BuildDepends_BINARY_DIR}/Project/multi3-real.txt
IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt)
message(STATUS "multi3-real.txt is newer than multi3-stamp.txt")
else()
message(SEND_ERROR "Project did not initially build properly: "
"multi3-real.txt is not newer than multi3-stamp.txt")
endif()
else()
message(SEND_ERROR "Project did not initially build properly: "
"multi3-real.txt is missing")
endif()
endif()
message("Waiting 3 seconds...")
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 3)
@ -217,6 +252,8 @@ endif()
file(WRITE ${BuildDepends_BINARY_DIR}/Project/external.in "external changed\n")
file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi1-in.txt "multi1-in changed\n")
file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt "multi2-stamp changed\n")
file(WRITE ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt "multi3-stamp changed\n")
help_xcode_depends()
@ -347,3 +384,31 @@ else()
message(SEND_ERROR "Project did not rebuild properly: "
"multi1-out2-copy.txt is missing")
endif()
if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi2-real.txt)
if(${BuildDepends_BINARY_DIR}/Project/multi2-real.txt
IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi2-stamp.txt)
message(STATUS "multi2-real.txt is newer than multi2-stamp.txt")
else()
message(SEND_ERROR "Project did not rebuild properly: "
"multi2-real.txt is not newer than multi2-stamp.txt")
endif()
else()
message(SEND_ERROR "Project did not rebuild properly: "
"multi2-real.txt is missing")
endif()
if(TEST_MULTI3)
if(EXISTS ${BuildDepends_BINARY_DIR}/Project/multi3-real.txt)
if(${BuildDepends_BINARY_DIR}/Project/multi3-real.txt
IS_NEWER_THAN ${BuildDepends_BINARY_DIR}/Project/multi3-stamp.txt)
message(STATUS "multi3-real.txt is newer than multi3-stamp.txt")
else()
message(SEND_ERROR "Project did not rebuild properly: "
"multi3-real.txt is not newer than multi3-stamp.txt")
endif()
else()
message(SEND_ERROR "Project did not rebuild properly: "
"multi3-real.txt is missing")
endif()
endif()

View File

@ -164,3 +164,21 @@ add_custom_command(
DEPENDS multi1-out2.txt
)
add_custom_target(multi1 ALL DEPENDS multi1-out2-copy.txt)
# Test having the first output never created.
add_custom_command(
OUTPUT multi2-dummy.txt multi2-real.txt
COMMAND ${CMAKE_COMMAND} -E touch multi2-real.txt
)
set_property(SOURCE multi2-real.txt multi2-dummy.txt PROPERTY SYMBOLIC 1)
add_custom_target(multi2 ALL DEPENDS multi2-real.txt)
if(TEST_MULTI3)
# Test having the second output never created. Does not work with msbuild.
add_custom_command(
OUTPUT multi3-real.txt multi3-dummy.txt
COMMAND ${CMAKE_COMMAND} -E touch multi3-real.txt
)
set_property(SOURCE multi3-real.txt multi3-dummy.txt PROPERTY SYMBOLIC 1)
add_custom_target(multi3 ALL DEPENDS multi3-real.txt)
endif()