summaryrefslogtreecommitdiffstats
path: root/Source/cmGeneratorTarget.cxx
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2015-08-05 16:55:14 (GMT)
committerStephen Kelly <steveire@gmail.com>2015-10-08 23:04:38 (GMT)
commit0bae4a416f9f1b9090499d26f8508660f4f3fc95 (patch)
treec1bf8a9d022cd056dbdb3ffa9278885f001be461 /Source/cmGeneratorTarget.cxx
parent1abc20d81df3ee9845904b356960870526fe3276 (diff)
downloadCMake-0bae4a416f9f1b9090499d26f8508660f4f3fc95.zip
CMake-0bae4a416f9f1b9090499d26f8508660f4f3fc95.tar.gz
CMake-0bae4a416f9f1b9090499d26f8508660f4f3fc95.tar.bz2
cmGeneratorTarget: Move output info from cmTarget.
Diffstat (limited to 'Source/cmGeneratorTarget.cxx')
-rw-r--r--Source/cmGeneratorTarget.cxx161
1 files changed, 157 insertions, 4 deletions
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 9f46909..2f2fb3b 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -4464,8 +4464,7 @@ std::string cmGeneratorTarget::GetDirectory(const std::string& config,
cmSystemTools::GetFilenamePath(
this->Target->ImportedGetFullPath(config, implib));
}
- else if(cmTarget::OutputInfo const* info =
- this->Target->GetOutputInfo(config))
+ else if(OutputInfo const* info = this->GetOutputInfo(config))
{
// Return the directory in which the target will be built.
return implib? info->ImpDir : info->OutDir;
@@ -4478,7 +4477,161 @@ bool cmGeneratorTarget::UsesDefaultOutputDir(const std::string& config,
bool implib) const
{
std::string dir;
- return this->Target->ComputeOutputDir(config, implib, dir);
+ return this->ComputeOutputDir(config, implib, dir);
+}
+
+//----------------------------------------------------------------------------
+cmGeneratorTarget::OutputInfo const* cmGeneratorTarget::GetOutputInfo(
+ const std::string& config) const
+{
+ // There is no output information for imported targets.
+ if(this->IsImported())
+ {
+ return 0;
+ }
+
+ // Only libraries and executables have well-defined output files.
+ if(!this->Target->HaveWellDefinedOutputFiles())
+ {
+ std::string msg = "cmGeneratorTarget::GetOutputInfo called for ";
+ msg += this->GetName();
+ msg += " which has type ";
+ msg += cmTarget::GetTargetTypeName(cmTarget::TargetType(this->GetType()));
+ this->LocalGenerator->IssueMessage(cmake::INTERNAL_ERROR, msg);
+ return 0;
+ }
+
+ // Lookup/compute/cache the output information for this configuration.
+ std::string config_upper;
+ if(!config.empty())
+ {
+ config_upper = cmSystemTools::UpperCase(config);
+ }
+ OutputInfoMapType::iterator i =
+ this->OutputInfoMap.find(config_upper);
+ if(i == this->OutputInfoMap.end())
+ {
+ // Add empty info in map to detect potential recursion.
+ OutputInfo info;
+ OutputInfoMapType::value_type entry(config_upper, info);
+ i = this->OutputInfoMap.insert(entry).first;
+
+ // Compute output directories.
+ this->ComputeOutputDir(config, false, info.OutDir);
+ this->ComputeOutputDir(config, true, info.ImpDir);
+ if(!this->Target->ComputePDBOutputDir("PDB", config, info.PdbDir))
+ {
+ info.PdbDir = info.OutDir;
+ }
+
+ // 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->LocalGenerator->GetCMakeInstance()->IssueMessage(
+ cmake::FATAL_ERROR,
+ "Target '" + this->GetName() + "' OUTPUT_DIRECTORY depends on itself.",
+ this->Target->GetBacktrace());
+ return 0;
+ }
+ return &i->second;
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorTarget::ComputeOutputDir(const std::string& config,
+ bool implib, std::string& out) const
+{
+ bool usesDefaultOutputDir = false;
+ std::string conf = config;
+
+ // Look for a target property defining the target output directory
+ // based on the target type.
+ std::string targetTypeName = this->Target->GetOutputTargetType(implib);
+ const char* propertyName = 0;
+ std::string propertyNameStr = targetTypeName;
+ if(!propertyNameStr.empty())
+ {
+ propertyNameStr += "_OUTPUT_DIRECTORY";
+ propertyName = propertyNameStr.c_str();
+ }
+
+ // Check for a per-configuration output directory target property.
+ std::string configUpper = cmSystemTools::UpperCase(conf);
+ const char* configProp = 0;
+ std::string configPropStr = targetTypeName;
+ if(!configPropStr.empty())
+ {
+ configPropStr += "_OUTPUT_DIRECTORY_";
+ configPropStr += configUpper;
+ configProp = configPropStr.c_str();
+ }
+
+ // Select an output directory.
+ if(const char* config_outdir = this->GetProperty(configProp))
+ {
+ // Use the user-specified per-configuration output directory.
+ cmGeneratorExpression ge;
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge =
+ ge.Parse(config_outdir);
+ out = cge->Evaluate(this->Makefile, config);
+
+ // Skip per-configuration subdirectory.
+ conf = "";
+ }
+ else if(const char* outdir = this->Target->GetProperty(propertyName))
+ {
+ // Use the user-specified output directory.
+ 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)
+ {
+ // Lookup the output path for executables.
+ out = this->Makefile->GetSafeDefinition("EXECUTABLE_OUTPUT_PATH");
+ }
+ else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
+ this->GetType() == cmTarget::SHARED_LIBRARY ||
+ this->GetType() == cmTarget::MODULE_LIBRARY)
+ {
+ // Lookup the output path for libraries.
+ out = this->Makefile->GetSafeDefinition("LIBRARY_OUTPUT_PATH");
+ }
+ if(out.empty())
+ {
+ // Default to the current output directory.
+ usesDefaultOutputDir = true;
+ out = ".";
+ }
+
+ // Convert the output path to a full path in case it is
+ // specified as a relative path. Treat a relative path as
+ // relative to the current output directory for this makefile.
+ out = (cmSystemTools::CollapseFullPath
+ (out, this->Makefile->GetCurrentBinaryDirectory()));
+
+ // The generator may add the configuration's subdirectory.
+ if(!conf.empty())
+ {
+ bool iosPlatform = this->Makefile->PlatformIsAppleIos();
+ std::string suffix =
+ usesDefaultOutputDir && iosPlatform ? "${EFFECTIVE_PLATFORM_NAME}" : "";
+ this->LocalGenerator->GetGlobalGenerator()->
+ AppendDirectoryForConfig("/", conf, suffix, out);
+ }
+
+ return usesDefaultOutputDir;
}
//----------------------------------------------------------------------------
@@ -5008,7 +5161,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
std::string
cmGeneratorTarget::GetPDBDirectory(const std::string& config) const
{
- if(cmTarget::OutputInfo const* info = this->Target->GetOutputInfo(config))
+ if(OutputInfo const* info = this->GetOutputInfo(config))
{
// Return the directory in which the target will be built.
return info->PdbDir;