1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-14 10:47:59 +08:00

Xcode: Refactor build setting append code and attribute getter naming

Support both STRING and OBJECT_LIST types in build setting attributes and make it possible to mix them
This commit is contained in:
Gusts Kaksis
2020-07-23 13:13:57 +03:00
parent c268e26d33
commit 7b3d8411a2
4 changed files with 76 additions and 51 deletions

View File

@@ -1106,7 +1106,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeFileReferenceFromPath(
group = this->FrameworkGroup; group = this->FrameworkGroup;
this->GroupMap[key] = group; this->GroupMap[key] = group;
} }
cmXCodeObject* children = group->GetObject("children"); cmXCodeObject* children = group->GetAttribute("children");
if (!children->HasObject(fileRef)) { if (!children->HasObject(fileRef)) {
children->AddObject(fileRef); children->AddObject(fileRef);
} }
@@ -1243,10 +1243,11 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
for (auto sourceFile : commonSourceFiles) { for (auto sourceFile : commonSourceFiles) {
cmXCodeObject* xsf = this->CreateXCodeSourceFile( cmXCodeObject* xsf = this->CreateXCodeSourceFile(
this->CurrentLocalGenerator, sourceFile, gtgt); this->CurrentLocalGenerator, sourceFile, gtgt);
cmXCodeObject* fr = xsf->GetObject("fileRef"); cmXCodeObject* fr = xsf->GetAttribute("fileRef");
cmXCodeObject* filetype = fr->GetObject()->GetObject("explicitFileType"); cmXCodeObject* filetype =
fr->GetObject()->GetAttribute("explicitFileType");
if (!filetype) { if (!filetype) {
filetype = fr->GetObject()->GetObject("lastKnownFileType"); filetype = fr->GetObject()->GetAttribute("lastKnownFileType");
} }
cmGeneratorTarget::SourceFileFlags tsFlags = cmGeneratorTarget::SourceFileFlags tsFlags =
@@ -2321,7 +2322,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
if (stdlib.size() > 8) { if (stdlib.size() > 8) {
const auto cxxLibrary = stdlib.substr(8); const auto cxxLibrary = stdlib.substr(8);
if (language == "CXX" || if (language == "CXX" ||
!buildSettings->GetObject("CLANG_CXX_LIBRARY")) { !buildSettings->GetAttribute("CLANG_CXX_LIBRARY")) {
buildSettings->AddAttribute("CLANG_CXX_LIBRARY", buildSettings->AddAttribute("CLANG_CXX_LIBRARY",
this->CreateString(cxxLibrary)); this->CreateString(cxxLibrary));
} }
@@ -2343,7 +2344,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string flags = cflags[language] + " " + defFlags; std::string flags = cflags[language] + " " + defFlags;
if (language == "CXX" || language == "OBJCXX") { if (language == "CXX" || language == "OBJCXX") {
if (language == "CXX" || if (language == "CXX" ||
!buildSettings->GetObject("OTHER_CPLUSPLUSFLAGS")) { !buildSettings->GetAttribute("OTHER_CPLUSPLUSFLAGS")) {
buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS", buildSettings->AddAttribute("OTHER_CPLUSPLUSFLAGS",
this->CreateString(flags)); this->CreateString(flags));
} }
@@ -2351,7 +2352,7 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("IFORT_OTHER_FLAGS", buildSettings->AddAttribute("IFORT_OTHER_FLAGS",
this->CreateString(flags)); this->CreateString(flags));
} else if (language == "C" || language == "OBJC") { } else if (language == "C" || language == "OBJC") {
if (language == "C" || !buildSettings->GetObject("OTHER_CFLAGS")) { if (language == "C" || !buildSettings->GetAttribute("OTHER_CFLAGS")) {
buildSettings->AddAttribute("OTHER_CFLAGS", this->CreateString(flags)); buildSettings->AddAttribute("OTHER_CFLAGS", this->CreateString(flags));
} }
} else if (language == "Swift") { } else if (language == "Swift") {
@@ -2771,7 +2772,7 @@ void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target,
targetdep->AddAttribute("targetProxy", targetdep->AddAttribute("targetProxy",
this->CreateObjectReference(container)); this->CreateObjectReference(container));
cmXCodeObject* depends = target->GetObject("dependencies"); cmXCodeObject* depends = target->GetAttribute("dependencies");
if (!depends) { if (!depends) {
cmSystemTools::Error( cmSystemTools::Error(
"target does not have dependencies attribute error.."); "target does not have dependencies attribute error..");
@@ -2783,33 +2784,60 @@ void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target,
void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings, void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings,
const char* attribute, const char* attribute,
const char* value) cmXCodeObject* value)
{ {
if (settings) { if (settings) {
cmXCodeObject* attr = settings->GetObject(attribute); cmXCodeObject* attr = settings->GetAttribute(attribute);
if (!attr) { if (!attr) {
settings->AddAttribute(attribute, this->CreateString(value)); settings->AddAttribute(attribute, value);
} else { } else {
std::string oldValue = cmStrCat(attr->GetString(), ' ', value); if (value->GetType() != cmXCodeObject::OBJECT_LIST &&
attr->SetString(oldValue); value->GetType() != cmXCodeObject::STRING) {
cmSystemTools::Error("Unsupported value type for appending: " +
std::string(attribute));
return;
}
if (attr->GetType() == cmXCodeObject::OBJECT_LIST) {
if (value->GetType() == cmXCodeObject::OBJECT_LIST) {
for (auto* obj : value->GetObjectList()) {
attr->AddObject(obj);
}
} else {
attr->AddObject(value);
}
} else if (attr->GetType() == cmXCodeObject::STRING) {
if (value->GetType() == cmXCodeObject::OBJECT_LIST) {
// Add old value as a list item to new object list
// and replace the attribute with the new list
value->PrependObject(attr);
settings->AddAttribute(attribute, value);
} else {
std::string newValue =
cmStrCat(attr->GetString(), ' ', value->GetString());
attr->SetString(newValue);
}
} else {
cmSystemTools::Error("Unsupported attribute type for appending: " +
std::string(attribute));
}
} }
} }
} }
void cmGlobalXCodeGenerator::AppendBuildSettingAttribute( void cmGlobalXCodeGenerator::AppendBuildSettingAttribute(
cmXCodeObject* target, const char* attribute, const char* value, cmXCodeObject* target, const char* attribute, cmXCodeObject* value,
const std::string& configName) const std::string& configName)
{ {
// There are multiple configurations. Add the setting to the // There are multiple configurations. Add the setting to the
// buildSettings of the configuration name given. // buildSettings of the configuration name given.
cmXCodeObject* configurationList = cmXCodeObject* configurationList =
target->GetObject("buildConfigurationList")->GetObject(); target->GetAttribute("buildConfigurationList")->GetObject();
cmXCodeObject* buildConfigs = cmXCodeObject* buildConfigs =
configurationList->GetObject("buildConfigurations"); configurationList->GetAttribute("buildConfigurations");
for (auto obj : buildConfigs->GetObjectList()) { for (auto obj : buildConfigs->GetObjectList()) {
if (configName.empty() || if (configName.empty() ||
obj->GetObject("name")->GetString() == configName) { obj->GetAttribute("name")->GetString() == configName) {
cmXCodeObject* settings = obj->GetObject("buildSettings"); cmXCodeObject* settings = obj->GetAttribute("buildSettings");
this->AppendOrAddBuildSetting(settings, attribute, value); this->AppendOrAddBuildSetting(settings, attribute, value);
} }
} }
@@ -2981,7 +3009,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
} else { } else {
// Add the target output file as a build reference for other targets // Add the target output file as a build reference for other targets
// to link against // to link against
auto* fileRefObject = libTarget->GetObject("productReference"); auto* fileRefObject = libTarget->GetAttribute("productReference");
if (!fileRefObject) { if (!fileRefObject) {
// Add this library item back to a regular linker flag list // Add this library item back to a regular linker flag list
for (const auto& conf : configItemMap) { for (const auto& conf : configItemMap) {
@@ -2999,7 +3027,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
} }
} }
// Add this reference to current target // Add this reference to current target
auto* buildPhases = target->GetObject("buildPhases"); auto* buildPhases = target->GetAttribute("buildPhases");
if (!buildPhases) { if (!buildPhases) {
continue; continue;
} }
@@ -3008,7 +3036,7 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
if (!frameworkBuildPhase) { if (!frameworkBuildPhase) {
continue; continue;
} }
auto* buildFiles = frameworkBuildPhase->GetObject("files"); auto* buildFiles = frameworkBuildPhase->GetAttribute("files");
if (!buildFiles) { if (!buildFiles) {
continue; continue;
} }
@@ -3021,20 +3049,18 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
for (auto const& configName : this->CurrentConfigurationTypes) { for (auto const& configName : this->CurrentConfigurationTypes) {
{ {
// Add object library contents as link flags. // Add object library contents as link flags.
std::string linkObjs; BuildObjectListOrString libSearchPaths(this, true);
const char* sep = "";
std::vector<cmSourceFile const*> objs; std::vector<cmSourceFile const*> objs;
gt->GetExternalObjects(objs, configName); gt->GetExternalObjects(objs, configName);
for (auto sourceFile : objs) { for (auto sourceFile : objs) {
if (sourceFile->GetObjectLibrary().empty()) { if (sourceFile->GetObjectLibrary().empty()) {
continue; continue;
} }
linkObjs += sep; libSearchPaths.Add(this->XCodeEscapePath(sourceFile->GetFullPath()));
sep = " ";
linkObjs += this->XCodeEscapePath(sourceFile->GetFullPath());
} }
this->AppendBuildSettingAttribute( this->AppendBuildSettingAttribute(
target, this->GetTargetLinkFlagsVar(gt), linkObjs.c_str(), configName); target, this->GetTargetLinkFlagsVar(gt), libSearchPaths.CreateList(),
configName);
} }
// Skip link information for object libraries. // Skip link information for object libraries.
@@ -3056,49 +3082,44 @@ void cmGlobalXCodeGenerator::AddDependAndLinkInformation(cmXCodeObject* target)
// add the library search paths // add the library search paths
{ {
BuildObjectListOrString libSearchPaths(this, true);
std::string linkDirs; std::string linkDirs;
for (auto const& libDir : cli->GetDirectories()) { for (auto const& libDir : cli->GetDirectories()) {
if (!libDir.empty() && libDir != "/usr/lib") { if (!libDir.empty() && libDir != "/usr/lib") {
// Now add the same one but append libSearchPaths.Add(this->XCodeEscapePath(
// $(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) to it: libDir + "/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"));
linkDirs += " "; libSearchPaths.Add(this->XCodeEscapePath(libDir));
linkDirs += this->XCodeEscapePath(
libDir + "/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)");
linkDirs += " ";
linkDirs += this->XCodeEscapePath(libDir);
} }
} }
// Add previously collected paths where to look for libraries // Add previously collected paths where to look for libraries
// that were added to "Link Binary With Libraries" // that were added to "Link Binary With Libraries"
for (auto& linkDir : linkSearchPaths) { for (auto& libDir : linkSearchPaths) {
linkDirs += " "; libSearchPaths.Add(this->XCodeEscapePath(libDir));
linkDirs += this->XCodeEscapePath(linkDir);
} }
this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS", this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
linkDirs.c_str(), configName); libSearchPaths.CreateList(),
configName);
} }
// now add the left-over link libraries // now add the left-over link libraries
{ {
std::string linkLibs; BuildObjectListOrString libSearchPaths(this, true);
const char* sep = "";
for (auto const& libItem : configItemMap[configName]) { for (auto const& libItem : configItemMap[configName]) {
auto const& libName = *libItem; auto const& libName = *libItem;
linkLibs += sep;
sep = " ";
if (libName.IsPath) { if (libName.IsPath) {
linkLibs += this->XCodeEscapePath(libName.Value.Value); libSearchPaths.Add(this->XCodeEscapePath(libName.Value.Value));
} else if (!libName.Target || } else if (!libName.Target ||
libName.Target->GetType() != libName.Target->GetType() !=
cmStateEnums::INTERFACE_LIBRARY) { cmStateEnums::INTERFACE_LIBRARY) {
linkLibs += libName.Value.Value; libSearchPaths.Add(libName.Value.Value);
} }
if (libName.Target && !libName.Target->IsImported()) { if (libName.Target && !libName.Target->IsImported()) {
target->AddDependTarget(configName, libName.Target->GetName()); target->AddDependTarget(configName, libName.Target->GetName());
} }
} }
this->AppendBuildSettingAttribute( this->AppendBuildSettingAttribute(
target, this->GetTargetLinkFlagsVar(gt), linkLibs.c_str(), configName); target, this->GetTargetLinkFlagsVar(gt), libSearchPaths.CreateList(),
configName);
} }
} }
} }
@@ -3166,7 +3187,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreatePBXGroup(cmXCodeObject* parent,
{ {
cmXCodeObject* parentChildren = nullptr; cmXCodeObject* parentChildren = nullptr;
if (parent) { if (parent) {
parentChildren = parent->GetObject("children"); parentChildren = parent->GetAttribute("children");
} }
cmXCodeObject* group = this->CreateObject(cmXCodeObject::PBXGroup); cmXCodeObject* group = this->CreateObject(cmXCodeObject::PBXGroup);
cmXCodeObject* groupChildren = cmXCodeObject* groupChildren =
@@ -3465,7 +3486,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
cmXCodeObject* allTargets = this->CreateObject(cmXCodeObject::OBJECT_LIST); cmXCodeObject* allTargets = this->CreateObject(cmXCodeObject::OBJECT_LIST);
for (auto t : targets) { for (auto t : targets) {
allTargets->AddObject(t); allTargets->AddObject(t);
cmXCodeObject* productRef = t->GetObject("productReference"); cmXCodeObject* productRef = t->GetAttribute("productReference");
if (productRef) { if (productRef) {
productGroupChildren->AddObject(productRef->GetObject()); productGroupChildren->AddObject(productRef->GetObject());
} }

View File

@@ -168,9 +168,9 @@ private:
std::string AddConfigurations(cmXCodeObject* target, std::string AddConfigurations(cmXCodeObject* target,
cmGeneratorTarget* gtgt); cmGeneratorTarget* gtgt);
void AppendOrAddBuildSetting(cmXCodeObject* settings, const char* attr, void AppendOrAddBuildSetting(cmXCodeObject* settings, const char* attr,
const char* value); cmXCodeObject* value);
void AppendBuildSettingAttribute(cmXCodeObject* target, const char* attr, void AppendBuildSettingAttribute(cmXCodeObject* target, const char* attr,
const char* value, cmXCodeObject* value,
const std::string& configName); const std::string& configName);
cmXCodeObject* CreateUtilityTarget(cmGeneratorTarget* gtgt); cmXCodeObject* CreateUtilityTarget(cmGeneratorTarget* gtgt);
void AddDependAndLinkInformation(cmXCodeObject* target); void AddDependAndLinkInformation(cmXCodeObject* target);

View File

@@ -16,7 +16,7 @@ cmXCode21Object::cmXCode21Object(PBXType ptype, Type type)
void cmXCode21Object::PrintComment(std::ostream& out) void cmXCode21Object::PrintComment(std::ostream& out)
{ {
if (this->Comment.empty()) { if (this->Comment.empty()) {
cmXCodeObject* n = this->GetObject("name"); cmXCodeObject* n = this->GetAttribute("name");
if (n) { if (n) {
this->Comment = n->GetString(); this->Comment = n->GetString();
cmSystemTools::ReplaceString(this->Comment, "\"", ""); cmSystemTools::ReplaceString(this->Comment, "\"", "");

View File

@@ -82,6 +82,10 @@ public:
void SetObject(cmXCodeObject* value) { this->Object = value; } void SetObject(cmXCodeObject* value) { this->Object = value; }
cmXCodeObject* GetObject() { return this->Object; } cmXCodeObject* GetObject() { return this->Object; }
void AddObject(cmXCodeObject* value) { this->List.push_back(value); } void AddObject(cmXCodeObject* value) { this->List.push_back(value); }
void PrependObject(cmXCodeObject* value)
{
this->List.insert(this->List.begin(), value);
}
bool HasObject(cmXCodeObject* o) const bool HasObject(cmXCodeObject* o) const
{ {
return cm::contains(this->List, o); return cm::contains(this->List, o);
@@ -107,7 +111,7 @@ public:
void SetTarget(cmGeneratorTarget* t) { this->Target = t; } void SetTarget(cmGeneratorTarget* t) { this->Target = t; }
const std::string& GetComment() const { return this->Comment; } const std::string& GetComment() const { return this->Comment; }
bool HasComment() const { return (!this->Comment.empty()); } bool HasComment() const { return (!this->Comment.empty()); }
cmXCodeObject* GetObject(const char* name) const cmXCodeObject* GetAttribute(const char* name) const
{ {
auto const i = this->ObjectAttributes.find(name); auto const i = this->ObjectAttributes.find(name);
if (i != this->ObjectAttributes.end()) { if (i != this->ObjectAttributes.end()) {