diff options
Diffstat (limited to 'Source/cmTarget.cxx')
-rw-r--r-- | Source/cmTarget.cxx | 622 |
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; + } } } |