ENH: Add a depends check step to custom targets. Add support for the IMPLICIT_DEPENDS feature of custom commands when building in custom targets. Convert multiple-output pair checks to be per-target instead of global.
This commit is contained in:
parent
6586149d64
commit
d83b4cd255
|
@ -1680,13 +1680,6 @@ void cmGlobalGenerator::AppendDirectoryForConfig(const char*, const char*,
|
|||
// configuration.
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalGenerator::CheckMultipleOutputs(cmMakefile*, bool)
|
||||
{
|
||||
// Only certain generators need this check. They define this
|
||||
// method.
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
std::vector<cmTarget *>& cmGlobalGenerator
|
||||
::GetTargetDepends(cmTarget& target)
|
||||
|
|
|
@ -211,9 +211,6 @@ public:
|
|||
|
||||
void AddTarget(cmTargets::value_type &v);
|
||||
|
||||
/** Support for multiple custom command outputs. */
|
||||
virtual void CheckMultipleOutputs(cmMakefile* mf, bool verbose);
|
||||
|
||||
virtual const char* GetAllTargetName() { return "ALL_BUILD"; }
|
||||
virtual const char* GetInstallTargetName() { return "INSTALL"; }
|
||||
virtual const char* GetInstallLocalTargetName() { return 0; }
|
||||
|
|
|
@ -132,16 +132,6 @@ void cmGlobalUnixMakefileGenerator3
|
|||
"default make target. A \"make install\" target is also provided.";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmGlobalUnixMakefileGenerator3
|
||||
::AddMultipleOutputPair(const char* depender, const char* dependee)
|
||||
{
|
||||
MultipleOutputPairsType::value_type p(depender, dependee);
|
||||
this->MultipleOutputPairs.insert(p);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalUnixMakefileGenerator3::Generate()
|
||||
{
|
||||
|
@ -373,62 +363,6 @@ void cmGlobalUnixMakefileGenerator3::WriteMainCMakefile()
|
|||
|
||||
this->WriteMainCMakefileLanguageRules(cmakefileStream,
|
||||
this->LocalGenerators);
|
||||
|
||||
if(!this->MultipleOutputPairs.empty())
|
||||
{
|
||||
cmakefileStream
|
||||
<< "\n"
|
||||
<< "SET(CMAKE_MULTIPLE_OUTPUT_PAIRS\n";
|
||||
for(MultipleOutputPairsType::const_iterator pi =
|
||||
this->MultipleOutputPairs.begin();
|
||||
pi != this->MultipleOutputPairs.end(); ++pi)
|
||||
{
|
||||
cmakefileStream << " \"" << pi->first << "\" \""
|
||||
<< pi->second << "\"\n";
|
||||
}
|
||||
cmakefileStream << " )\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmGlobalUnixMakefileGenerator3::CheckMultipleOutputs(cmMakefile* mf,
|
||||
bool verbose)
|
||||
{
|
||||
// Get the string listing the multiple output pairs.
|
||||
const char* pairs_string = mf->GetDefinition("CMAKE_MULTIPLE_OUTPUT_PAIRS");
|
||||
if(!pairs_string)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert the string to a list and preserve empty entries.
|
||||
std::vector<std::string> pairs;
|
||||
cmSystemTools::ExpandListArgument(pairs_string, pairs, true);
|
||||
for(std::vector<std::string>::const_iterator i = pairs.begin();
|
||||
i != pairs.end(); ++i)
|
||||
{
|
||||
const std::string& depender = *i;
|
||||
if(++i != pairs.end())
|
||||
{
|
||||
const std::string& dependee = *i;
|
||||
|
||||
// If the depender is missing then delete the dependee to make
|
||||
// sure both will be regenerated.
|
||||
if(cmSystemTools::FileExists(dependee.c_str()) &&
|
||||
!cmSystemTools::FileExists(depender.c_str()))
|
||||
{
|
||||
if(verbose)
|
||||
{
|
||||
cmOStringStream msg;
|
||||
msg << "Deleting primary custom command output \"" << dependee
|
||||
<< "\" because another output \""
|
||||
<< depender << "\" does not exist." << std::endl;
|
||||
cmSystemTools::Stdout(msg.str().c_str());
|
||||
}
|
||||
cmSystemTools::RemoveFile(dependee.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalUnixMakefileGenerator3
|
||||
|
@ -763,21 +697,18 @@ cmGlobalUnixMakefileGenerator3
|
|||
<< localName << "\n\n";
|
||||
|
||||
commands.clear();
|
||||
if (t->second.GetType() != cmTarget::UTILITY)
|
||||
makeTargetName = localName;
|
||||
makeTargetName += "/depend";
|
||||
commands.push_back(lg->GetRecursiveMakeCall
|
||||
(makefileName.c_str(),makeTargetName.c_str()));
|
||||
|
||||
// add requires if we need it for this generator
|
||||
if (needRequiresStep)
|
||||
{
|
||||
makeTargetName = localName;
|
||||
makeTargetName += "/depend";
|
||||
makeTargetName += "/requires";
|
||||
commands.push_back(lg->GetRecursiveMakeCall
|
||||
(makefileName.c_str(),makeTargetName.c_str()));
|
||||
|
||||
// add requires if we need it for this generator
|
||||
if (needRequiresStep)
|
||||
{
|
||||
makeTargetName = localName;
|
||||
makeTargetName += "/requires";
|
||||
commands.push_back(lg->GetRecursiveMakeCall
|
||||
(makefileName.c_str(),makeTargetName.c_str()));
|
||||
}
|
||||
(makefileName.c_str(),makeTargetName.c_str()));
|
||||
}
|
||||
makeTargetName = localName;
|
||||
makeTargetName += "/build";
|
||||
|
|
|
@ -98,19 +98,6 @@ public:
|
|||
void WriteConvenienceRules(std::ostream& ruleFileStream,
|
||||
std::set<cmStdString> &emitted);
|
||||
|
||||
/** In order to support parallel builds for custom commands with
|
||||
multiple outputs the outputs are given a serial order, and only
|
||||
the first output actually has the build rule. Other outputs
|
||||
just depend on the first one. The check-build-system step must
|
||||
remove a dependee if the depender is missing to make sure both
|
||||
are regenerated properly. This method is used by the local
|
||||
makefile generators to register such pairs. */
|
||||
void AddMultipleOutputPair(const char* depender, const char* dependee);
|
||||
|
||||
/** Support for multiple custom command outputs. Called during
|
||||
check-build-system step. */
|
||||
virtual void CheckMultipleOutputs(cmMakefile* mf, bool verbose);
|
||||
|
||||
/** Get the command to use for a target that has no rule. This is
|
||||
used for multiple output dependencies and for cmake_force. */
|
||||
std::string GetEmptyRuleHackCommand() { return this->EmptyRuleHackCommand; }
|
||||
|
@ -191,9 +178,6 @@ protected:
|
|||
// in the rule to satisfy the make program.
|
||||
std::string EmptyRuleHackCommand;
|
||||
|
||||
typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType;
|
||||
MultipleOutputPairsType MultipleOutputPairs;
|
||||
|
||||
std::map<cmStdString, int > TargetSourceFileCount;
|
||||
bool ForceVerboseMakefiles;
|
||||
};
|
||||
|
|
|
@ -1229,6 +1229,16 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
|
|||
bool verbose,
|
||||
bool color)
|
||||
{
|
||||
// read in the target info file
|
||||
if(!this->Makefile->ReadListFile(0, tgtInfo) ||
|
||||
cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
cmSystemTools::Error("Target DependInfo.cmake file not found");
|
||||
}
|
||||
|
||||
// Check if any multiple output pairs have a missing file.
|
||||
this->CheckMultipleOutputs(verbose);
|
||||
|
||||
std::string dir = cmSystemTools::GetFilenamePath(tgtInfo);
|
||||
std::string internalDependFile = dir + "/depend.internal";
|
||||
std::string dependFile = dir + "/depend.make";
|
||||
|
@ -1257,7 +1267,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
|
|||
fprintf(stdout, "%s\n", message.c_str());
|
||||
#endif
|
||||
|
||||
return this->ScanDependencies(tgtInfo);
|
||||
return this->ScanDependencies(dir.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1267,11 +1277,10 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(const char* tgtInfo,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmLocalUnixMakefileGenerator3::ScanDependencies(const char* tgtInfo)
|
||||
bool
|
||||
cmLocalUnixMakefileGenerator3
|
||||
::ScanDependencies(const char* targetDir)
|
||||
{
|
||||
// The info file for this target
|
||||
std::string infoFile = tgtInfo;
|
||||
|
||||
// Read the directory information file.
|
||||
cmMakefile* mf = this->Makefile;
|
||||
bool haveDirectoryInfo = false;
|
||||
|
@ -1284,13 +1293,6 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(const char* tgtInfo)
|
|||
haveDirectoryInfo = true;
|
||||
}
|
||||
|
||||
// read in the target info file
|
||||
if(!mf->ReadListFile(0, infoFile.c_str()) ||
|
||||
cmSystemTools::GetErrorOccuredFlag())
|
||||
{
|
||||
cmSystemTools::Error("Target DependInfo.cmake file not found");
|
||||
}
|
||||
|
||||
// Lookup useful directory information.
|
||||
if(haveDirectoryInfo)
|
||||
{
|
||||
|
@ -1322,7 +1324,7 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(const char* tgtInfo)
|
|||
}
|
||||
|
||||
// create the file stream for the depends file
|
||||
std::string dir = cmSystemTools::GetFilenamePath(infoFile);
|
||||
std::string dir = targetDir;
|
||||
|
||||
// Open the rule file. This should be copy-if-different because the
|
||||
// rules may depend on this file itself.
|
||||
|
@ -1449,6 +1451,48 @@ bool cmLocalUnixMakefileGenerator3::ScanDependencies(const char* tgtInfo)
|
|||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmLocalUnixMakefileGenerator3::CheckMultipleOutputs(bool verbose)
|
||||
{
|
||||
cmMakefile* mf = this->Makefile;
|
||||
|
||||
// Get the string listing the multiple output pairs.
|
||||
const char* pairs_string = mf->GetDefinition("CMAKE_MULTIPLE_OUTPUT_PAIRS");
|
||||
if(!pairs_string)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert the string to a list and preserve empty entries.
|
||||
std::vector<std::string> pairs;
|
||||
cmSystemTools::ExpandListArgument(pairs_string, pairs, true);
|
||||
for(std::vector<std::string>::const_iterator i = pairs.begin();
|
||||
i != pairs.end(); ++i)
|
||||
{
|
||||
const std::string& depender = *i;
|
||||
if(++i != pairs.end())
|
||||
{
|
||||
const std::string& dependee = *i;
|
||||
|
||||
// If the depender is missing then delete the dependee to make
|
||||
// sure both will be regenerated.
|
||||
if(cmSystemTools::FileExists(dependee.c_str()) &&
|
||||
!cmSystemTools::FileExists(depender.c_str()))
|
||||
{
|
||||
if(verbose)
|
||||
{
|
||||
cmOStringStream msg;
|
||||
msg << "Deleting primary custom command output \"" << dependee
|
||||
<< "\" because another output \""
|
||||
<< depender << "\" does not exist." << std::endl;
|
||||
cmSystemTools::Stdout(msg.str().c_str());
|
||||
}
|
||||
cmSystemTools::RemoveFile(dependee.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void cmLocalUnixMakefileGenerator3
|
||||
::WriteLocalAllRules(std::ostream& ruleFileStream)
|
||||
|
|
|
@ -203,9 +203,6 @@ public:
|
|||
virtual bool UpdateDependencies(const char* tgtInfo,
|
||||
bool verbose, bool color);
|
||||
|
||||
/** Called from command-line hook to scan dependencies. */
|
||||
bool ScanDependencies(const char* tgtInfo);
|
||||
|
||||
/** Called from command-line hook to clear dependencies. */
|
||||
virtual void ClearDependencies(cmMakefile* mf, bool verbose);
|
||||
|
||||
|
@ -325,6 +322,10 @@ protected:
|
|||
|
||||
std::map<cmStdString, std::vector<int> > ProgressFiles;
|
||||
|
||||
// Helper methods for dependeny updates.
|
||||
bool ScanDependencies(const char* targetDir);
|
||||
void CheckMultipleOutputs(bool verbose);
|
||||
|
||||
private:
|
||||
friend class cmMakefileTargetGenerator;
|
||||
friend class cmMakefileExecutableTargetGenerator;
|
||||
|
|
|
@ -45,9 +45,6 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
|
|||
// write the per-target per-language flags
|
||||
this->WriteTargetLanguageFlags();
|
||||
|
||||
// Write the dependency generation rule.
|
||||
this->WriteTargetDependRules();
|
||||
|
||||
// write the link rules
|
||||
this->WriteExecutableRule(false);
|
||||
if(this->Target->NeedRelinkBeforeInstall())
|
||||
|
@ -62,6 +59,10 @@ void cmMakefileExecutableTargetGenerator::WriteRuleFiles()
|
|||
// Write clean target
|
||||
this->WriteTargetCleanRules();
|
||||
|
||||
// Write the dependency generation rule. This must be done last so
|
||||
// that multiple output pair information is available.
|
||||
this->WriteTargetDependRules();
|
||||
|
||||
// close the streams
|
||||
this->CloseFileStreams();
|
||||
}
|
||||
|
|
|
@ -47,9 +47,6 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
|
|||
// write the per-target per-language flags
|
||||
this->WriteTargetLanguageFlags();
|
||||
|
||||
// Write the dependency generation rule.
|
||||
this->WriteTargetDependRules();
|
||||
|
||||
// write the link rules
|
||||
// Write the rule for this target type.
|
||||
switch(this->Target->GetType())
|
||||
|
@ -85,6 +82,10 @@ void cmMakefileLibraryTargetGenerator::WriteRuleFiles()
|
|||
// Write clean target
|
||||
this->WriteTargetCleanRules();
|
||||
|
||||
// Write the dependency generation rule. This must be done last so
|
||||
// that multiple output pair information is available.
|
||||
this->WriteTargetDependRules();
|
||||
|
||||
// close the streams
|
||||
this->CloseFileStreams();
|
||||
}
|
||||
|
|
|
@ -775,6 +775,23 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
|
|||
this->LocalGenerator->
|
||||
WriteDependLanguageInfo(*this->InfoFileStream,*this->Target);
|
||||
|
||||
// Store multiple output pairs in the depend info file.
|
||||
if(!this->MultipleOutputPairs.empty())
|
||||
{
|
||||
*this->InfoFileStream
|
||||
<< "\n"
|
||||
<< "# Pairs of files generated by the same build rule.\n"
|
||||
<< "SET(CMAKE_MULTIPLE_OUTPUT_PAIRS\n";
|
||||
for(MultipleOutputPairsType::const_iterator pi =
|
||||
this->MultipleOutputPairs.begin();
|
||||
pi != this->MultipleOutputPairs.end(); ++pi)
|
||||
{
|
||||
*this->InfoFileStream << " \"" << pi->first << "\" \""
|
||||
<< pi->second << "\"\n";
|
||||
}
|
||||
*this->InfoFileStream << " )\n\n";
|
||||
}
|
||||
|
||||
// and now write the rule to use it
|
||||
std::vector<std::string> depends;
|
||||
std::vector<std::string> commands;
|
||||
|
@ -993,7 +1010,7 @@ cmMakefileTargetGenerator
|
|||
// the check-build-system step will remove the primary output if any
|
||||
// extra outputs are missing. This forces the rule to regenerate
|
||||
// all outputs.
|
||||
this->GlobalGenerator->AddMultipleOutputPair(out, in);
|
||||
this->AddMultipleOutputPair(out, in);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1334,3 +1351,12 @@ void cmMakefileTargetGenerator::WriteProgressVariables(unsigned long total,
|
|||
current += this->NumberOfProgressActions;
|
||||
delete progressFileStream;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
cmMakefileTargetGenerator
|
||||
::AddMultipleOutputPair(const char* depender, const char* dependee)
|
||||
{
|
||||
MultipleOutputPairsType::value_type p(depender, dependee);
|
||||
this->MultipleOutputPairs.insert(p);
|
||||
}
|
||||
|
|
|
@ -119,6 +119,15 @@ protected:
|
|||
// append intertarget dependencies
|
||||
void AppendTargetDepends(std::vector<std::string>& depends);
|
||||
|
||||
/** In order to support parallel builds for custom commands with
|
||||
multiple outputs the outputs are given a serial order, and only
|
||||
the first output actually has the build rule. Other outputs
|
||||
just depend on the first one. The check-build-system step must
|
||||
remove a dependee if the depender is missing to make sure both
|
||||
are regenerated properly. This method is used by the local
|
||||
makefile generators to register such pairs. */
|
||||
void AddMultipleOutputPair(const char* depender, const char* dependee);
|
||||
|
||||
virtual void CloseFileStreams();
|
||||
void RemoveForbiddenFlags(const char* flagVar, const char* linkLang,
|
||||
std::string& linkFlags);
|
||||
|
@ -166,6 +175,8 @@ protected:
|
|||
// Set of object file names that will be built in this directory.
|
||||
std::set<cmStdString> ObjectFiles;
|
||||
|
||||
typedef std::map<cmStdString, cmStdString> MultipleOutputPairsType;
|
||||
MultipleOutputPairsType MultipleOutputPairs;
|
||||
|
||||
//==================================================================
|
||||
// Convenience routines that do nothing more than forward to
|
||||
|
|
|
@ -89,6 +89,10 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
|
|||
// Write clean target
|
||||
this->WriteTargetCleanRules();
|
||||
|
||||
// Write the dependency generation rule. This must be done last so
|
||||
// that multiple output pair information is available.
|
||||
this->WriteTargetDependRules();
|
||||
|
||||
// close the streams
|
||||
this->CloseFileStreams();
|
||||
}
|
||||
|
|
|
@ -2547,29 +2547,24 @@ int cmake::CheckBuildSystem()
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Now that we know the generator used to build the project, use it
|
||||
// to check the dependency integrity.
|
||||
const char* genName = mf->GetDefinition("CMAKE_DEPENDS_GENERATOR");
|
||||
if (!genName || genName[0] == '\0')
|
||||
if(this->ClearBuildSystem)
|
||||
{
|
||||
genName = "Unix Makefiles";
|
||||
}
|
||||
// this global generator is never set to the cmake object so it is never
|
||||
// deleted, so make it an auto_ptr
|
||||
std::auto_ptr<cmGlobalGenerator> ggd(this->CreateGlobalGenerator(genName));
|
||||
if (ggd.get())
|
||||
{
|
||||
// Check the dependencies in case source files were removed.
|
||||
std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
|
||||
lgd->SetGlobalGenerator(ggd.get());
|
||||
|
||||
if(this->ClearBuildSystem)
|
||||
// Get the generator used for this build system.
|
||||
const char* genName = mf->GetDefinition("CMAKE_DEPENDS_GENERATOR");
|
||||
if(!genName || genName[0] == '\0')
|
||||
{
|
||||
lgd->ClearDependencies(mf, verbose);
|
||||
genName = "Unix Makefiles";
|
||||
}
|
||||
|
||||
// Check for multiple output pairs.
|
||||
ggd->CheckMultipleOutputs(mf, verbose);
|
||||
// Create the generator and use it to clear the dependencies.
|
||||
std::auto_ptr<cmGlobalGenerator>
|
||||
ggd(this->CreateGlobalGenerator(genName));
|
||||
if(ggd.get())
|
||||
{
|
||||
std::auto_ptr<cmLocalGenerator> lgd(ggd->CreateLocalGenerator());
|
||||
lgd->SetGlobalGenerator(ggd.get());
|
||||
lgd->ClearDependencies(mf, verbose);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the set of dependencies and outputs.
|
||||
|
|
|
@ -13,6 +13,8 @@ write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx
|
|||
|
||||
file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot.hxx.in
|
||||
"static const char* zot = \"zot\";\n")
|
||||
file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_custom.hxx.in
|
||||
"static const char* zot_custom = \"zot_custom\";\n")
|
||||
|
||||
message("Building project first time")
|
||||
try_compile(RESULT
|
||||
|
@ -70,11 +72,11 @@ execute_process(COMMAND ${zot} OUTPUT_VARIABLE out RESULT_VARIABLE runResult)
|
|||
string(REGEX REPLACE "[\r\n]" " " out "${out}")
|
||||
message("Run result: ${runResult} Output: \"${out}\"")
|
||||
|
||||
if("${out}" STREQUAL "zot ")
|
||||
if("${out}" STREQUAL "[zot] [zot_custom] ")
|
||||
message("Worked!")
|
||||
else("${out}" STREQUAL "zot ")
|
||||
else("${out}" STREQUAL "[zot] [zot_custom] ")
|
||||
message(SEND_ERROR "Project did not initially build properly: ${out}")
|
||||
endif("${out}" STREQUAL "zot ")
|
||||
endif("${out}" STREQUAL "[zot] [zot_custom] ")
|
||||
|
||||
message("Waiting 3 seconds...")
|
||||
# any additional argument will cause ${bar} to wait forever
|
||||
|
@ -85,6 +87,8 @@ write_file(${BuildDepends_BINARY_DIR}/Project/foo.cxx
|
|||
"const char* foo() { return \"foo changed\";}" )
|
||||
file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot.hxx.in
|
||||
"static const char* zot = \"zot changed\";\n")
|
||||
file(WRITE ${BuildDepends_BINARY_DIR}/Project/zot_custom.hxx.in
|
||||
"static const char* zot_custom = \"zot_custom changed\";\n")
|
||||
|
||||
message("Building project second time")
|
||||
try_compile(RESULT
|
||||
|
@ -137,8 +141,8 @@ execute_process(COMMAND ${zot} OUTPUT_VARIABLE out RESULT_VARIABLE runResult)
|
|||
string(REGEX REPLACE "[\r\n]" " " out "${out}")
|
||||
message("Run result: ${runResult} Output: \"${out}\"")
|
||||
|
||||
if("${out}" STREQUAL "zot changed ")
|
||||
if("${out}" STREQUAL "[zot changed] [zot_custom changed] ")
|
||||
message("Worked!")
|
||||
else("${out}" STREQUAL "zot changed ")
|
||||
else("${out}" STREQUAL "[zot changed] [zot_custom changed] ")
|
||||
message(SEND_ERROR "Project did not rebuild properly!")
|
||||
endif("${out}" STREQUAL "zot changed ")
|
||||
endif("${out}" STREQUAL "[zot changed] [zot_custom changed] ")
|
||||
|
|
|
@ -32,9 +32,12 @@ add_executable(bar bar.cxx
|
|||
IF("${CMAKE_GENERATOR}" MATCHES "Make")
|
||||
# Test the IMPLICIT_DEPENDS feature.
|
||||
SET(ZOT_DEPENDS IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep.cxx)
|
||||
SET(ZOT_CUSTOM_DEP
|
||||
IMPLICIT_DEPENDS CXX ${CMAKE_CURRENT_SOURCE_DIR}/dep_custom.cxx)
|
||||
ELSE("${CMAKE_GENERATOR}" MATCHES "Make")
|
||||
# No IMPLICIT_DEPENDS...just depend directly.
|
||||
SET(ZOT_DEPENDS DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx.in)
|
||||
SET(ZOT_CUSTOM_DEP DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx.in)
|
||||
ENDIF("${CMAKE_GENERATOR}" MATCHES "Make")
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx
|
||||
|
@ -44,4 +47,15 @@ add_custom_command(
|
|||
${ZOT_DEPENDS}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx
|
||||
${ZOT_CUSTOM_DEP}
|
||||
)
|
||||
add_custom_target(zot_custom ALL DEPENDS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/zot_custom.hxx)
|
||||
|
||||
add_executable(zot zot.cxx ${CMAKE_CURRENT_BINARY_DIR}/zot.hxx)
|
||||
add_dependencies(zot zot_custom)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include <zot_custom.hxx.in>
|
|
@ -1,9 +1,10 @@
|
|||
#include <zot.hxx>
|
||||
#include <zot_custom.hxx>
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("%s\n", zot);
|
||||
printf("[%s] [%s]\n", zot, zot_custom);
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue