summaryrefslogtreecommitdiffstats
path: root/Source/cmTarget.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r--Source/cmTarget.cxx622
1 files changed, 264 insertions, 358 deletions
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 54e0bea..6f47f85 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -8,11 +8,14 @@
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
+#include "cmMessenger.h"
#include "cmOutputConverter.h"
#include "cmProperty.h"
#include "cmSourceFile.h"
#include "cmSourceFileLocation.h"
+#include "cmState.h"
#include "cmSystemTools.h"
+#include "cmTargetPropertyComputer.h"
#include "cmake.h"
#include <algorithm>
@@ -33,6 +36,134 @@
#define UNORDERED_SET std::set
#endif
+template <>
+const char* cmTargetPropertyComputer::ComputeLocationForBuild<cmTarget>(
+ cmTarget const* tgt)
+{
+ static std::string loc;
+ if (tgt->IsImported()) {
+ loc = tgt->ImportedGetFullPath("", false);
+ return loc.c_str();
+ }
+
+ cmGlobalGenerator* gg = tgt->GetGlobalGenerator();
+ if (!gg->GetConfigureDoneCMP0026()) {
+ gg->CreateGenerationObjects();
+ }
+ cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName());
+ loc = gt->GetLocationForBuild();
+ return loc.c_str();
+}
+
+template <>
+const char* cmTargetPropertyComputer::ComputeLocation<cmTarget>(
+ cmTarget const* tgt, const std::string& config)
+{
+ static std::string loc;
+ if (tgt->IsImported()) {
+ loc = tgt->ImportedGetFullPath(config, false);
+ return loc.c_str();
+ }
+
+ cmGlobalGenerator* gg = tgt->GetGlobalGenerator();
+ if (!gg->GetConfigureDoneCMP0026()) {
+ gg->CreateGenerationObjects();
+ }
+ cmGeneratorTarget* gt = gg->FindGeneratorTarget(tgt->GetName());
+ loc = gt->GetFullPath(config, false);
+ return loc.c_str();
+}
+
+template <>
+const char* cmTargetPropertyComputer::GetSources<cmTarget>(
+ cmTarget const* tgt, cmMessenger* messenger,
+ cmListFileBacktrace const& context)
+{
+ cmStringRange entries = tgt->GetSourceEntries();
+ if (entries.empty()) {
+ return CM_NULLPTR;
+ }
+
+ std::ostringstream ss;
+ const char* sep = "";
+ for (std::vector<std::string>::const_iterator i = entries.begin();
+ i != entries.end(); ++i) {
+ std::string const& entry = *i;
+
+ std::vector<std::string> files;
+ cmSystemTools::ExpandListArgument(entry, files);
+ for (std::vector<std::string>::const_iterator li = files.begin();
+ li != files.end(); ++li) {
+ if (cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
+ (*li)[li->size() - 1] == '>') {
+ std::string objLibName = li->substr(17, li->size() - 18);
+
+ if (cmGeneratorExpression::Find(objLibName) != std::string::npos) {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ continue;
+ }
+
+ bool addContent = false;
+ bool noMessage = true;
+ std::ostringstream e;
+ cmake::MessageType messageType = cmake::AUTHOR_WARNING;
+ switch (context.GetBottom().GetPolicy(cmPolicies::CMP0051)) {
+ case cmPolicies::WARN:
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0051) << "\n";
+ noMessage = false;
+ case cmPolicies::OLD:
+ break;
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::NEW:
+ addContent = true;
+ }
+ if (!noMessage) {
+ e << "Target \"" << tgt->GetName()
+ << "\" contains "
+ "$<TARGET_OBJECTS> generator expression in its sources "
+ "list. "
+ "This content was not previously part of the SOURCES "
+ "property "
+ "when that property was read at configure time. Code "
+ "reading "
+ "that property needs to be adapted to ignore the generator "
+ "expression using the string(GENEX_STRIP) command.";
+ messenger->IssueMessage(messageType, e.str(), context);
+ }
+ if (addContent) {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ }
+ } else if (cmGeneratorExpression::Find(*li) == std::string::npos) {
+ ss << sep;
+ sep = ";";
+ ss << *li;
+ } else {
+ cmSourceFile* sf = tgt->GetMakefile()->GetOrCreateSource(*li);
+ // Construct what is known about this source file location.
+ cmSourceFileLocation const& location = sf->GetLocation();
+ std::string sname = location.GetDirectory();
+ if (!sname.empty()) {
+ sname += "/";
+ }
+ sname += location.GetName();
+
+ ss << sep;
+ sep = ";";
+ // Append this list entry.
+ ss << sname;
+ }
+ }
+ }
+ static std::string srcs;
+ srcs = ss.str();
+ return srcs.c_str();
+}
+
class cmTargetInternals
{
public:
@@ -50,7 +181,7 @@ public:
std::vector<cmListFileBacktrace> LinkImplementationPropertyBacktraces;
};
-cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
+cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
Visibility vis, cmMakefile* mf)
{
assert(mf);
@@ -66,8 +197,8 @@ cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
this->BuildInterfaceIncludesAppended = false;
// only add dependency information for library targets
- if (this->TargetTypeValue >= cmState::STATIC_LIBRARY &&
- this->TargetTypeValue <= cmState::MODULE_LIBRARY) {
+ if (this->TargetTypeValue >= cmStateEnums::STATIC_LIBRARY &&
+ this->TargetTypeValue <= cmStateEnums::MODULE_LIBRARY) {
this->RecordDependencies = true;
} else {
this->RecordDependencies = false;
@@ -84,8 +215,8 @@ cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
"Android") == 0;
// Setup default property values.
- if (this->GetType() != cmState::INTERFACE_LIBRARY &&
- this->GetType() != cmState::UTILITY) {
+ if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+ this->GetType() != cmStateEnums::UTILITY) {
this->SetPropertyDefault("ANDROID_API", CM_NULLPTR);
this->SetPropertyDefault("ANDROID_API_MIN", CM_NULLPTR);
this->SetPropertyDefault("ANDROID_ARCH", CM_NULLPTR);
@@ -102,6 +233,7 @@ cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
this->SetPropertyDefault("ANDROID_JAR_DEPENDENCIES", CM_NULLPTR);
this->SetPropertyDefault("ANDROID_ASSETS_DIRECTORIES", CM_NULLPTR);
this->SetPropertyDefault("ANDROID_ANT_ADDITIONAL_OPTIONS", CM_NULLPTR);
+ this->SetPropertyDefault("BUILD_RPATH", CM_NULLPTR);
this->SetPropertyDefault("INSTALL_NAME_DIR", CM_NULLPTR);
this->SetPropertyDefault("INSTALL_RPATH", "");
this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
@@ -151,7 +283,7 @@ cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
mf->GetConfigurations(configNames);
// Setup per-configuration property default values.
- if (this->GetType() != cmState::UTILITY) {
+ if (this->GetType() != cmStateEnums::UTILITY) {
const char* configProps[] = {
/* clang-format needs this comment to break after the opening brace */
"ARCHIVE_OUTPUT_DIRECTORY_",
@@ -166,7 +298,7 @@ cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
ci != configNames.end(); ++ci) {
std::string configUpper = cmSystemTools::UpperCase(*ci);
for (const char** p = configProps; *p; ++p) {
- if (this->TargetTypeValue == cmState::INTERFACE_LIBRARY &&
+ if (this->TargetTypeValue == cmStateEnums::INTERFACE_LIBRARY &&
strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0) {
continue;
}
@@ -180,8 +312,8 @@ cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
// compatibility with previous CMake versions in which executables
// did not support this variable. Projects may still specify the
// property directly.
- if (this->TargetTypeValue != cmState::EXECUTABLE &&
- this->TargetTypeValue != cmState::INTERFACE_LIBRARY) {
+ if (this->TargetTypeValue != cmStateEnums::EXECUTABLE &&
+ this->TargetTypeValue != cmStateEnums::INTERFACE_LIBRARY) {
std::string property = cmSystemTools::UpperCase(*ci);
property += "_POSTFIX";
this->SetPropertyDefault(property, CM_NULLPTR);
@@ -226,49 +358,55 @@ cmTarget::cmTarget(std::string const& name, cmState::TargetType type,
parentOptionsBts.end());
}
- if (this->GetType() != cmState::INTERFACE_LIBRARY &&
- this->GetType() != cmState::UTILITY) {
+ if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+ this->GetType() != cmStateEnums::UTILITY) {
this->SetPropertyDefault("C_VISIBILITY_PRESET", CM_NULLPTR);
this->SetPropertyDefault("CXX_VISIBILITY_PRESET", CM_NULLPTR);
this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", CM_NULLPTR);
}
- if (this->TargetTypeValue == cmState::EXECUTABLE) {
+ if (this->TargetTypeValue == cmStateEnums::EXECUTABLE) {
this->SetPropertyDefault("ANDROID_GUI", CM_NULLPTR);
this->SetPropertyDefault("CROSSCOMPILING_EMULATOR", CM_NULLPTR);
this->SetPropertyDefault("ENABLE_EXPORTS", CM_NULLPTR);
}
- if (this->TargetTypeValue == cmState::SHARED_LIBRARY ||
- this->TargetTypeValue == cmState::MODULE_LIBRARY) {
+ if (this->TargetTypeValue == cmStateEnums::SHARED_LIBRARY ||
+ this->TargetTypeValue == cmStateEnums::MODULE_LIBRARY) {
this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
}
- if (this->TargetTypeValue == cmState::SHARED_LIBRARY ||
- this->TargetTypeValue == cmState::EXECUTABLE) {
+ if (this->TargetTypeValue == cmStateEnums::SHARED_LIBRARY ||
+ this->TargetTypeValue == cmStateEnums::EXECUTABLE) {
this->SetPropertyDefault("WINDOWS_EXPORT_ALL_SYMBOLS", CM_NULLPTR);
}
- if (this->GetType() != cmState::INTERFACE_LIBRARY &&
- this->GetType() != cmState::UTILITY) {
+ if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+ this->GetType() != cmStateEnums::UTILITY) {
this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", CM_NULLPTR);
}
// Record current policies for later use.
this->Makefile->RecordPolicies(this->PolicyMap);
- if (this->TargetTypeValue == cmState::INTERFACE_LIBRARY) {
+ if (this->TargetTypeValue == cmStateEnums::INTERFACE_LIBRARY) {
// This policy is checked in a few conditions. The properties relevant
- // to the policy are always ignored for cmState::INTERFACE_LIBRARY targets,
+ // to the policy are always ignored for cmStateEnums::INTERFACE_LIBRARY
+ // targets,
// so ensure that the conditions don't lead to nonsense.
this->PolicyMap.Set(cmPolicies::CMP0022, cmPolicies::NEW);
}
- if (this->GetType() != cmState::INTERFACE_LIBRARY &&
- this->GetType() != cmState::UTILITY) {
+ if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
+ this->GetType() != cmStateEnums::UTILITY) {
this->SetPropertyDefault("JOB_POOL_COMPILE", CM_NULLPTR);
this->SetPropertyDefault("JOB_POOL_LINK", CM_NULLPTR);
}
}
+cmGlobalGenerator* cmTarget::GetGlobalGenerator() const
+{
+ return this->GetMakefile()->GetGlobalGenerator();
+}
+
void cmTarget::AddUtility(const std::string& u, cmMakefile* makefile)
{
if (this->Utilities.insert(u).second && makefile) {
@@ -296,26 +434,27 @@ cmListFileBacktrace const& cmTarget::GetBacktrace() const
bool cmTarget::IsExecutableWithExports() const
{
- return (this->GetType() == cmState::EXECUTABLE &&
+ return (this->GetType() == cmStateEnums::EXECUTABLE &&
this->GetPropertyAsBool("ENABLE_EXPORTS"));
}
bool cmTarget::HasImportLibrary() const
{
- return (this->DLLPlatform && (this->GetType() == cmState::SHARED_LIBRARY ||
- this->IsExecutableWithExports()));
+ return (this->DLLPlatform &&
+ (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ this->IsExecutableWithExports()));
}
bool cmTarget::IsFrameworkOnApple() const
{
- return (this->GetType() == cmState::SHARED_LIBRARY &&
+ return (this->GetType() == cmStateEnums::SHARED_LIBRARY &&
this->Makefile->IsOn("APPLE") &&
this->GetPropertyAsBool("FRAMEWORK"));
}
bool cmTarget::IsAppBundleOnApple() const
{
- return (this->GetType() == cmState::EXECUTABLE &&
+ return (this->GetType() == cmStateEnums::EXECUTABLE &&
this->Makefile->IsOn("APPLE") &&
this->GetPropertyAsBool("MACOSX_BUNDLE"));
}
@@ -475,23 +614,6 @@ cmSourceFile* cmTarget::AddSource(const std::string& src)
return this->Makefile->GetOrCreateSource(src);
}
-void cmTarget::MergeLinkLibraries(cmMakefile& mf, const std::string& selfname,
- const LinkLibraryVectorType& libs)
-{
- // Only add on libraries we haven't added on before.
- // Assumption: the global link libraries could only grow, never shrink
- LinkLibraryVectorType::const_iterator i = libs.begin();
- i += this->PrevLinkedLibraries.size();
- for (; i != libs.end(); ++i) {
- // This is equivalent to the target_link_libraries plain signature.
- this->AddLinkLibrary(mf, selfname, i->first, i->second);
- this->AppendProperty(
- "INTERFACE_LINK_LIBRARIES",
- this->GetDebugGeneratorExpressions(i->first, i->second).c_str());
- }
- this->PrevLinkedLibraries = libs;
-}
-
void cmTarget::AddLinkDirectory(const std::string& d)
{
// Make sure we don't add unnecessary search directories.
@@ -514,7 +636,7 @@ void cmTarget::ClearDependencyInformation(cmMakefile& mf,
depname += "_LIB_DEPENDS";
if (this->RecordDependencies) {
mf.AddCacheDefinition(depname, "", "Dependencies for target",
- cmState::STATIC);
+ cmStateEnums::STATIC);
} else {
if (mf.GetDefinition(depname)) {
std::string message = "Target ";
@@ -594,8 +716,7 @@ void cmTarget::GetTllSignatureTraces(std::ostream& s, TLLSignature sig) const
}
}
-void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& target,
- const std::string& lib,
+void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& lib,
cmTargetLinkLibraryType llt)
{
cmTarget* tgt = this->Makefile->FindTargetToUse(lib);
@@ -612,8 +733,8 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& target,
}
if (cmGeneratorExpression::Find(lib) != std::string::npos ||
- (tgt && tgt->GetType() == cmState::INTERFACE_LIBRARY) ||
- (target == lib)) {
+ (tgt && tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) ||
+ (this->Name == lib)) {
return;
}
@@ -631,7 +752,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& target,
// and we removing one instance will break the link line. Duplicates
// will be appropriately eliminated at emit time.
if (this->RecordDependencies) {
- std::string targetEntry = target;
+ std::string targetEntry = this->Name;
targetEntry += "_LIB_DEPENDS";
std::string dependencies;
const char* old_val = mf.GetDefinition(targetEntry);
@@ -653,7 +774,7 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& target,
dependencies += lib;
dependencies += ";";
mf.AddCacheDefinition(targetEntry, dependencies.c_str(),
- "Dependencies for the target", cmState::STATIC);
+ "Dependencies for the target", cmStateEnums::STATIC);
}
}
@@ -722,51 +843,34 @@ cmBacktraceRange cmTarget::GetLinkImplementationBacktraces() const
return cmMakeRange(this->Internal->LinkImplementationPropertyBacktraces);
}
-static bool whiteListedInterfaceProperty(const std::string& prop)
+void cmTarget::SetProperty(const std::string& prop, const char* value)
{
- if (cmHasLiteralPrefix(prop, "INTERFACE_")) {
- return true;
- }
- static UNORDERED_SET<std::string> builtIns;
- if (builtIns.empty()) {
- builtIns.insert("COMPATIBLE_INTERFACE_BOOL");
- builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MAX");
- builtIns.insert("COMPATIBLE_INTERFACE_NUMBER_MIN");
- builtIns.insert("COMPATIBLE_INTERFACE_STRING");
- builtIns.insert("EXPORT_NAME");
- builtIns.insert("IMPORTED");
- builtIns.insert("NAME");
- builtIns.insert("TYPE");
- }
-
- if (builtIns.count(prop)) {
- return true;
+ if (!cmTargetPropertyComputer::PassesWhitelist(
+ this->GetType(), prop, this->Makefile->GetMessenger(),
+ this->Makefile->GetBacktrace())) {
+ return;
}
-
- if (cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) {
- return true;
+ if (prop == "NAME") {
+ std::ostringstream e;
+ e << "NAME property is read-only\n";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
}
-
- return false;
-}
-
-void cmTarget::SetProperty(const std::string& prop, const char* value)
-{
- if (this->GetType() == cmState::INTERFACE_LIBRARY &&
- !whiteListedInterfaceProperty(prop)) {
+ if (prop == "EXPORT_NAME" && this->IsImported()) {
std::ostringstream e;
- e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
- "The property \""
- << prop << "\" is not allowed.";
+ e << "EXPORT_NAME property can't be set on imported targets (\""
+ << this->Name << "\")\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
- if (prop == "NAME") {
+ if (prop == "SOURCES" && this->IsImported()) {
std::ostringstream e;
- e << "NAME property is read-only\n";
+ e << "SOURCES property can't be set on imported targets (\"" << this->Name
+ << "\")\n";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
+
if (prop == "INCLUDE_DIRECTORIES") {
this->Internal->IncludeDirectoriesEntries.clear();
this->Internal->IncludeDirectoriesBacktraces.clear();
@@ -799,11 +903,6 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
}
- } else if (prop == "EXPORT_NAME" && this->IsImported()) {
- std::ostringstream e;
- e << "EXPORT_NAME property can't be set on imported targets (\""
- << this->Name << "\")\n";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
} else if (prop == "LINK_LIBRARIES") {
this->Internal->LinkImplementationPropertyEntries.clear();
this->Internal->LinkImplementationPropertyBacktraces.clear();
@@ -813,14 +912,6 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
}
} else if (prop == "SOURCES") {
- if (this->IsImported()) {
- std::ostringstream e;
- e << "SOURCES property can't be set on imported targets (\""
- << this->Name << "\")\n";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- return;
- }
-
this->Internal->SourceEntries.clear();
this->Internal->SourceBacktraces.clear();
if (value) {
@@ -836,13 +927,9 @@ void cmTarget::SetProperty(const std::string& prop, const char* value)
void cmTarget::AppendProperty(const std::string& prop, const char* value,
bool asString)
{
- if (this->GetType() == cmState::INTERFACE_LIBRARY &&
- !whiteListedInterfaceProperty(prop)) {
- std::ostringstream e;
- e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
- "The property \""
- << prop << "\" is not allowed.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ if (!cmTargetPropertyComputer::PassesWhitelist(
+ this->GetType(), prop, this->Makefile->GetMessenger(),
+ this->Makefile->GetBacktrace())) {
return;
}
if (prop == "NAME") {
@@ -851,6 +938,20 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
return;
}
+ if (prop == "EXPORT_NAME" && this->IsImported()) {
+ std::ostringstream e;
+ e << "EXPORT_NAME property can't be set on imported targets (\""
+ << this->Name << "\")\n";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+ if (prop == "SOURCES" && this->IsImported()) {
+ std::ostringstream e;
+ e << "SOURCES property can't be set on imported targets (\"" << this->Name
+ << "\")\n";
+ this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
if (prop == "INCLUDE_DIRECTORIES") {
if (value && *value) {
this->Internal->IncludeDirectoriesEntries.push_back(value);
@@ -875,11 +976,6 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->CompileDefinitionsBacktraces.push_back(lfbt);
}
- } else if (prop == "EXPORT_NAME" && this->IsImported()) {
- std::ostringstream e;
- e << "EXPORT_NAME property can't be set on imported targets (\""
- << this->Name << "\")\n";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
} else if (prop == "LINK_LIBRARIES") {
if (value && *value) {
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
@@ -887,13 +983,6 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
this->Internal->LinkImplementationPropertyBacktraces.push_back(lfbt);
}
} else if (prop == "SOURCES") {
- if (this->IsImported()) {
- std::ostringstream e;
- e << "SOURCES property can't be set on imported targets (\""
- << this->Name << "\")\n";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- return;
- }
cmListFileBacktrace lfbt = this->Makefile->GetBacktrace();
this->Internal->SourceEntries.push_back(value);
this->Internal->SourceBacktraces.push_back(lfbt);
@@ -904,10 +993,10 @@ void cmTarget::AppendProperty(const std::string& prop, const char* value,
void cmTarget::AppendBuildInterfaceIncludes()
{
- if (this->GetType() != cmState::SHARED_LIBRARY &&
- this->GetType() != cmState::STATIC_LIBRARY &&
- this->GetType() != cmState::MODULE_LIBRARY &&
- this->GetType() != cmState::INTERFACE_LIBRARY &&
+ if (this->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ this->GetType() != cmStateEnums::STATIC_LIBRARY &&
+ this->GetType() != cmStateEnums::MODULE_LIBRARY &&
+ this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
!this->IsExecutableWithExports()) {
return;
}
@@ -1047,136 +1136,15 @@ void cmTarget::CheckProperty(const std::string& prop,
}
}
-bool cmTarget::HandleLocationPropertyPolicy(cmMakefile* context) const
+const char* cmTarget::GetComputedProperty(
+ const std::string& prop, cmMessenger* messenger,
+ cmListFileBacktrace const& context) const
{
- if (this->IsImported()) {
- return true;
- }
- std::ostringstream e;
- const char* modal = CM_NULLPTR;
- cmake::MessageType messageType = cmake::AUTHOR_WARNING;
- switch (context->GetPolicyStatus(cmPolicies::CMP0026)) {
- case cmPolicies::WARN:
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0026) << "\n";
- modal = "should";
- case cmPolicies::OLD:
- break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::NEW:
- modal = "may";
- messageType = cmake::FATAL_ERROR;
- }
-
- if (modal) {
- e << "The LOCATION property " << modal << " not be read from target \""
- << this->GetName()
- << "\". Use the target name directly with "
- "add_custom_command, or use the generator expression $<TARGET_FILE>, "
- "as appropriate.\n";
- context->IssueMessage(messageType, e.str());
- }
-
- return messageType != cmake::FATAL_ERROR;
+ return cmTargetPropertyComputer::GetProperty(this, prop, messenger, context);
}
const char* cmTarget::GetProperty(const std::string& prop) const
{
- return this->GetProperty(prop, this->Makefile);
-}
-
-const char* cmTarget::GetProperty(const std::string& prop,
- cmMakefile* context) const
-{
- if (this->GetType() == cmState::INTERFACE_LIBRARY &&
- !whiteListedInterfaceProperty(prop)) {
- std::ostringstream e;
- e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
- "The property \""
- << prop << "\" is not allowed.";
- context->IssueMessage(cmake::FATAL_ERROR, e.str());
- return CM_NULLPTR;
- }
-
- // Watch for special "computed" properties that are dependent on
- // other properties or variables. Always recompute them.
- if (this->GetType() == cmState::EXECUTABLE ||
- this->GetType() == cmState::STATIC_LIBRARY ||
- this->GetType() == cmState::SHARED_LIBRARY ||
- this->GetType() == cmState::MODULE_LIBRARY ||
- this->GetType() == cmState::UNKNOWN_LIBRARY) {
- static const std::string propLOCATION = "LOCATION";
- if (prop == propLOCATION) {
- if (!this->HandleLocationPropertyPolicy(context)) {
- return CM_NULLPTR;
- }
-
- // Set the LOCATION property of the target.
- //
- // For an imported target this is the location of an arbitrary
- // available configuration.
- //
- if (this->IsImported()) {
- this->Properties.SetProperty(
- propLOCATION, this->ImportedGetFullPath("", false).c_str());
- } else {
- // For a non-imported target this is deprecated because it
- // cannot take into account the per-configuration name of the
- // target because the configuration type may not be known at
- // CMake time.
- cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
- if (!gg->GetConfigureDoneCMP0026()) {
- gg->CreateGenerationObjects();
- }
- cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName());
- this->Properties.SetProperty(propLOCATION, gt->GetLocationForBuild());
- }
-
- }
-
- // Support "LOCATION_<CONFIG>".
- else if (cmHasLiteralPrefix(prop, "LOCATION_")) {
- if (!this->HandleLocationPropertyPolicy(context)) {
- return CM_NULLPTR;
- }
- const char* configName = prop.c_str() + 9;
-
- if (this->IsImported()) {
- this->Properties.SetProperty(
- prop, this->ImportedGetFullPath(configName, false).c_str());
- } else {
- cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
- if (!gg->GetConfigureDoneCMP0026()) {
- gg->CreateGenerationObjects();
- }
- cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName());
- this->Properties.SetProperty(
- prop, gt->GetFullPath(configName, false).c_str());
- }
- }
- // Support "<CONFIG>_LOCATION".
- else if (cmHasLiteralSuffix(prop, "_LOCATION") &&
- !cmHasLiteralPrefix(prop, "XCODE_ATTRIBUTE_")) {
- std::string configName(prop.c_str(), prop.size() - 9);
- if (configName != "IMPORTED") {
- if (!this->HandleLocationPropertyPolicy(context)) {
- return CM_NULLPTR;
- }
- if (this->IsImported()) {
- this->Properties.SetProperty(
- prop, this->ImportedGetFullPath(configName, false).c_str());
- } else {
- cmGlobalGenerator* gg = this->Makefile->GetGlobalGenerator();
- if (!gg->GetConfigureDoneCMP0026()) {
- gg->CreateGenerationObjects();
- }
- cmGeneratorTarget* gt = gg->FindGeneratorTarget(this->GetName());
- this->Properties.SetProperty(
- prop, gt->GetFullPath(configName, false).c_str());
- }
- }
- }
- }
static UNORDERED_SET<std::string> specialProps;
#define MAKE_STATIC_PROP(PROP) static const std::string prop##PROP = #PROP
MAKE_STATIC_PROP(LINK_LIBRARIES);
@@ -1261,93 +1229,16 @@ const char* cmTarget::GetProperty(const std::string& prop,
return this->GetName().c_str();
}
if (prop == propBINARY_DIR) {
- return this->GetMakefile()->GetCurrentBinaryDirectory();
+ return this->GetMakefile()
+ ->GetStateSnapshot()
+ .GetDirectory()
+ .GetCurrentBinary();
}
if (prop == propSOURCE_DIR) {
- return this->GetMakefile()->GetCurrentSourceDirectory();
- }
- if (prop == propSOURCES) {
- if (this->Internal->SourceEntries.empty()) {
- return CM_NULLPTR;
- }
-
- std::ostringstream ss;
- const char* sep = "";
- for (std::vector<std::string>::const_iterator i =
- this->Internal->SourceEntries.begin();
- i != this->Internal->SourceEntries.end(); ++i) {
- std::string const& entry = *i;
-
- std::vector<std::string> files;
- cmSystemTools::ExpandListArgument(entry, files);
- for (std::vector<std::string>::const_iterator li = files.begin();
- li != files.end(); ++li) {
- if (cmHasLiteralPrefix(*li, "$<TARGET_OBJECTS:") &&
- (*li)[li->size() - 1] == '>') {
- std::string objLibName = li->substr(17, li->size() - 18);
-
- if (cmGeneratorExpression::Find(objLibName) != std::string::npos) {
- ss << sep;
- sep = ";";
- ss << *li;
- continue;
- }
-
- bool addContent = false;
- bool noMessage = true;
- std::ostringstream e;
- cmake::MessageType messageType = cmake::AUTHOR_WARNING;
- switch (context->GetPolicyStatus(cmPolicies::CMP0051)) {
- case cmPolicies::WARN:
- e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0051) << "\n";
- noMessage = false;
- case cmPolicies::OLD:
- break;
- case cmPolicies::REQUIRED_ALWAYS:
- case cmPolicies::REQUIRED_IF_USED:
- case cmPolicies::NEW:
- addContent = true;
- }
- if (!noMessage) {
- e << "Target \"" << this->Name
- << "\" contains "
- "$<TARGET_OBJECTS> generator expression in its sources "
- "list. "
- "This content was not previously part of the SOURCES "
- "property "
- "when that property was read at configure time. Code "
- "reading "
- "that property needs to be adapted to ignore the generator "
- "expression using the string(GENEX_STRIP) command.";
- context->IssueMessage(messageType, e.str());
- }
- if (addContent) {
- ss << sep;
- sep = ";";
- ss << *li;
- }
- } else if (cmGeneratorExpression::Find(*li) == std::string::npos) {
- ss << sep;
- sep = ";";
- ss << *li;
- } else {
- cmSourceFile* sf = this->Makefile->GetOrCreateSource(*li);
- // Construct what is known about this source file location.
- cmSourceFileLocation const& location = sf->GetLocation();
- std::string sname = location.GetDirectory();
- if (!sname.empty()) {
- sname += "/";
- }
- sname += location.GetName();
-
- ss << sep;
- sep = ";";
- // Append this list entry.
- ss << sname;
- }
- }
- }
- this->Properties.SetProperty("SOURCES", ss.str().c_str());
+ return this->GetMakefile()
+ ->GetStateSnapshot()
+ .GetDirectory()
+ .GetCurrentSource();
}
}
@@ -1356,7 +1247,8 @@ const char* cmTarget::GetProperty(const std::string& prop,
const bool chain = this->GetMakefile()->GetState()->IsPropertyChained(
prop, cmProperty::TARGET);
if (chain) {
- return this->Makefile->GetProperty(prop, chain);
+ return this->Makefile->GetStateSnapshot().GetDirectory().GetProperty(
+ prop, chain);
}
}
return retVal;
@@ -1370,15 +1262,15 @@ bool cmTarget::GetPropertyAsBool(const std::string& prop) const
const char* cmTarget::GetSuffixVariableInternal(bool implib) const
{
switch (this->GetType()) {
- case cmState::STATIC_LIBRARY:
+ case cmStateEnums::STATIC_LIBRARY:
return "CMAKE_STATIC_LIBRARY_SUFFIX";
- case cmState::SHARED_LIBRARY:
+ case cmStateEnums::SHARED_LIBRARY:
return (implib ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_SHARED_LIBRARY_SUFFIX");
- case cmState::MODULE_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
return (implib ? "CMAKE_IMPORT_LIBRARY_SUFFIX"
: "CMAKE_SHARED_MODULE_SUFFIX");
- case cmState::EXECUTABLE:
+ case cmStateEnums::EXECUTABLE:
return (implib
? "CMAKE_IMPORT_LIBRARY_SUFFIX"
// Android GUI application packages store the native
@@ -1395,15 +1287,15 @@ const char* cmTarget::GetSuffixVariableInternal(bool implib) const
const char* cmTarget::GetPrefixVariableInternal(bool implib) const
{
switch (this->GetType()) {
- case cmState::STATIC_LIBRARY:
+ case cmStateEnums::STATIC_LIBRARY:
return "CMAKE_STATIC_LIBRARY_PREFIX";
- case cmState::SHARED_LIBRARY:
+ case cmStateEnums::SHARED_LIBRARY:
return (implib ? "CMAKE_IMPORT_LIBRARY_PREFIX"
: "CMAKE_SHARED_LIBRARY_PREFIX");
- case cmState::MODULE_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
return (implib ? "CMAKE_IMPORT_LIBRARY_PREFIX"
: "CMAKE_SHARED_MODULE_PREFIX");
- case cmState::EXECUTABLE:
+ case cmStateEnums::EXECUTABLE:
return (implib
? "CMAKE_IMPORT_LIBRARY_PREFIX"
// Android GUI application packages store the native
@@ -1437,7 +1329,7 @@ std::string cmTarget::ImportedGetFullPath(const std::string& config,
const char* imp = CM_NULLPTR;
std::string suffix;
- if (this->GetType() != cmState::INTERFACE_LIBRARY &&
+ if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
this->GetMappedConfig(config_upper, &loc, &imp, suffix)) {
if (!pimplib) {
if (loc) {
@@ -1455,7 +1347,7 @@ std::string cmTarget::ImportedGetFullPath(const std::string& config,
} else {
if (imp) {
result = imp;
- } else if (this->GetType() == cmState::SHARED_LIBRARY ||
+ } else if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->IsExecutableWithExports()) {
std::string impProp = "IMPORTED_IMPLIB";
impProp += suffix;
@@ -1493,9 +1385,10 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
const char** loc, const char** imp,
std::string& suffix) const
{
- if (this->GetType() == cmState::INTERFACE_LIBRARY) {
+ if (this->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
// This method attempts to find a config-specific LOCATION for the
- // IMPORTED library. In the case of cmState::INTERFACE_LIBRARY, there is no
+ // IMPORTED library. In the case of cmStateEnums::INTERFACE_LIBRARY, there
+ // is no
// LOCATION at all, so leaving *loc and *imp unchanged is the appropriate
// and valid response.
return true;
@@ -1510,7 +1403,7 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
std::string mapProp = "MAP_IMPORTED_CONFIG_";
mapProp += desired_config;
if (const char* mapValue = this->GetProperty(mapProp)) {
- cmSystemTools::ExpandListArgument(mapValue, mappedConfigs);
+ cmSystemTools::ExpandListArgument(mapValue, mappedConfigs, true);
}
}
@@ -1523,20 +1416,33 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config,
for (std::vector<std::string>::const_iterator mci = mappedConfigs.begin();
!*loc && !*imp && mci != mappedConfigs.end(); ++mci) {
// Look for this configuration.
- std::string mcUpper = cmSystemTools::UpperCase(*mci);
- std::string locProp = "IMPORTED_LOCATION_";
- locProp += mcUpper;
- *loc = this->GetProperty(locProp);
- if (allowImp) {
- std::string impProp = "IMPORTED_IMPLIB_";
- impProp += mcUpper;
- *imp = this->GetProperty(impProp);
- }
+ if (mci->empty()) {
+ // An empty string in the mapping has a special meaning:
+ // look up the config-less properties.
+ *loc = this->GetProperty("IMPORTED_LOCATION");
+ if (allowImp) {
+ *imp = this->GetProperty("IMPORTED_IMPLIB");
+ }
+ // If it was found, set the suffix.
+ if (*loc || *imp) {
+ suffix = "";
+ }
+ } else {
+ std::string mcUpper = cmSystemTools::UpperCase(*mci);
+ std::string locProp = "IMPORTED_LOCATION_";
+ locProp += mcUpper;
+ *loc = this->GetProperty(locProp);
+ if (allowImp) {
+ std::string impProp = "IMPORTED_IMPLIB_";
+ impProp += mcUpper;
+ *imp = this->GetProperty(impProp);
+ }
- // If it was found, use it for all properties below.
- if (*loc || *imp) {
- suffix = "_";
- suffix += mcUpper;
+ // If it was found, use it for all properties below.
+ if (*loc || *imp) {
+ suffix = "_";
+ suffix += mcUpper;
+ }
}
}