summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-08-13 14:38:54 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2015-08-13 14:38:54 (GMT)
commita07d16085b14e7257254d824b3e800406bc63873 (patch)
treef659b242224ddd7062befcbffbde00424a6d9686 /Source
parent0576aa6085823744c1cd594649e071688b207d5a (diff)
parentd25819bc2623b5144ffc57b694500993ac5759b4 (diff)
downloadCMake-a07d16085b14e7257254d824b3e800406bc63873.zip
CMake-a07d16085b14e7257254d824b3e800406bc63873.tar.gz
CMake-a07d16085b14e7257254d824b3e800406bc63873.tar.bz2
Merge topic 'OUTPUT_DIRECTORY-genex'
d25819bc Add generator expression support to OUTPUT_DIRECTORY target properties e36a05fd cmTarget: Detect and diagnose recursion in GetOutputInfo
Diffstat (limited to 'Source')
-rw-r--r--Source/cmTarget.cxx41
1 files changed, 36 insertions, 5 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 59d4da0..49b3239 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -66,6 +66,8 @@ struct cmTarget::OutputInfo
std::string OutDir;
std::string ImpDir;
std::string PdbDir;
+ bool empty() const
+ { return OutDir.empty() && ImpDir.empty() && PdbDir.empty(); }
};
//----------------------------------------------------------------------------
@@ -2604,19 +2606,35 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo(
config_upper = cmSystemTools::UpperCase(config);
}
typedef cmTargetInternals::OutputInfoMapType OutputInfoMapType;
- OutputInfoMapType::const_iterator i =
+ OutputInfoMapType::iterator i =
this->Internal->OutputInfoMap.find(config_upper);
if(i == this->Internal->OutputInfoMap.end())
{
+ // Add empty info in map to detect potential recursion.
OutputInfo info;
+ OutputInfoMapType::value_type entry(config_upper, info);
+ i = this->Internal->OutputInfoMap.insert(entry).first;
+
+ // Compute output directories.
this->ComputeOutputDir(config, false, info.OutDir);
this->ComputeOutputDir(config, true, info.ImpDir);
if(!this->ComputePDBOutputDir("PDB", config, info.PdbDir))
{
info.PdbDir = info.OutDir;
}
- OutputInfoMapType::value_type entry(config_upper, info);
- i = this->Internal->OutputInfoMap.insert(entry).first;
+
+ // Now update the previously-prepared map entry.
+ i->second = info;
+ }
+ else if(i->second.empty())
+ {
+ // An empty map entry indicates we have been called recursively
+ // from the above block.
+ this->Makefile->GetCMakeInstance()->IssueMessage(
+ cmake::FATAL_ERROR,
+ "Target '" + this->GetName() + "' OUTPUT_DIRECTORY depends on itself.",
+ this->GetBacktrace());
+ return 0;
}
return &i->second;
}
@@ -3497,7 +3515,10 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
if(const char* config_outdir = this->GetProperty(configProp))
{
// Use the user-specified per-configuration output directory.
- out = config_outdir;
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(config_outdir);
+ out = cge->Evaluate(this->Makefile, config);
// Skip per-configuration subdirectory.
conf = "";
@@ -3505,7 +3526,17 @@ bool cmTarget::ComputeOutputDir(const std::string& config,
else if(const char* outdir = this->GetProperty(propertyName))
{
// Use the user-specified output directory.
- out = outdir;
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(outdir);
+ out = cge->Evaluate(this->Makefile, config);
+
+ // Skip per-configuration subdirectory if the value contained a
+ // generator expression.
+ if (out != outdir)
+ {
+ conf = "";
+ }
}
else if(this->GetType() == cmTarget::EXECUTABLE)
{