diff options
author | Brad King <brad.king@kitware.com> | 2015-08-13 14:38:54 (GMT) |
---|---|---|
committer | CMake Topic Stage <kwrobot@kitware.com> | 2015-08-13 14:38:54 (GMT) |
commit | a07d16085b14e7257254d824b3e800406bc63873 (patch) | |
tree | f659b242224ddd7062befcbffbde00424a6d9686 /Source | |
parent | 0576aa6085823744c1cd594649e071688b207d5a (diff) | |
parent | d25819bc2623b5144ffc57b694500993ac5759b4 (diff) | |
download | CMake-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.cxx | 41 |
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) { |