Merge topic 'xcode-mig-support'

8be00e44 Help: Add release note about XCODE_FILE_ATTRIBUTES source file property
27eb657d Xcode: Add support for mig files
811f6c82 Xcode: Add XCODE_FILE_ATTRIBUTES source file property
ef494edf Xcode: Don't emit empty settings blocks.
82ebbf68 Xcode: Add function to conditionally add Xcode Attributes
025edea0 Xcode: Add const qualifiers
This commit is contained in:
Brad King 2016-06-17 11:06:47 -04:00 committed by CMake Topic Stage
commit 9e47255604
6 changed files with 87 additions and 22 deletions

View File

@ -346,6 +346,7 @@ Properties on Source Files
/prop_sf/VS_XAML_TYPE
/prop_sf/WRAP_EXCLUDE
/prop_sf/XCODE_EXPLICIT_FILE_TYPE
/prop_sf/XCODE_FILE_ATTRIBUTES
/prop_sf/XCODE_LAST_KNOWN_FILE_TYPE
.. _`Cache Entry Properties`:

View File

@ -0,0 +1,11 @@
XCODE_FILE_ATTRIBUTES
---------------------
Add values to the Xcode ``ATTRIBUTES`` setting on its reference to a
source file. Among other things, this can be used to set the role on
a mig file::
set_source_files_properties(defs.mig
PROPERTIES
XCODE_FILE_ATTRIBUTES "Client;Server"
)

View File

@ -0,0 +1,6 @@
xcode-file-attributes
---------------------
* A :prop_sf:`XCODE_FILE_ATTRIBUTES` source file property was
added to tell the :generator:`Xcode` generator to generate
custom content in the Xcode project attributes for the file.

View File

@ -689,7 +689,8 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
cmXCodeObject* fileRef = buildFile->GetObject("fileRef")->GetObject();
cmXCodeObject* settings = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP);
settings->AddAttribute("COMPILER_FLAGS", this->CreateString(flags));
settings->AddAttributeIfNotEmpty("COMPILER_FLAGS",
this->CreateString(flags));
// Is this a resource file in this target? Add it to the resources group...
//
@ -698,23 +699,37 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
gtgt->GetTargetSourceFileFlags(sf);
bool isResource = tsFlags.Type == cmGeneratorTarget::SourceFileTypeResource;
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
// Is this a "private" or "public" framework header file?
// Set the ATTRIBUTES attribute appropriately...
//
if (gtgt->IsFrameworkOnApple()) {
if (tsFlags.Type == cmGeneratorTarget::SourceFileTypePrivateHeader) {
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
attrs->AddObject(this->CreateString("Private"));
settings->AddAttribute("ATTRIBUTES", attrs);
isResource = true;
} else if (tsFlags.Type == cmGeneratorTarget::SourceFileTypePublicHeader) {
cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST);
attrs->AddObject(this->CreateString("Public"));
settings->AddAttribute("ATTRIBUTES", attrs);
isResource = true;
}
}
// Add user-specified file attributes.
const char* extraFileAttributes = sf->GetProperty("XCODE_FILE_ATTRIBUTES");
if (extraFileAttributes) {
// Expand the list of attributes.
std::vector<std::string> attributes;
cmSystemTools::ExpandListArgument(extraFileAttributes, attributes);
// Store the attributes.
for (std::vector<std::string>::const_iterator ai = attributes.begin();
ai != attributes.end(); ++ai) {
attrs->AddObject(this->CreateString(*ai));
}
}
settings->AddAttributeIfNotEmpty("ATTRIBUTES", attrs);
// Add the fileRef to the top level Resources group/folder if it is not
// already there.
//
@ -723,7 +738,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(
this->ResourcesGroupChildren->AddObject(fileRef);
}
buildFile->AddAttribute("settings", settings);
buildFile->AddAttributeIfNotEmpty("settings", settings);
return buildFile;
}
@ -772,6 +787,8 @@ std::string GetSourcecodeValueFromFileExtension(const std::string& _ext,
sourcecode += ".asm";
} else if (ext == "metal") {
sourcecode += ".metal";
} else if (ext == "mig") {
sourcecode += ".mig";
}
// else
// {

View File

@ -83,6 +83,22 @@ cmXCodeObject::cmXCodeObject(PBXType ptype, Type type)
}
}
bool cmXCodeObject::IsEmpty() const
{
switch (this->TypeValue) {
case OBJECT_LIST:
return this->List.empty();
case STRING:
return this->String.empty();
case ATTRIBUTE_GROUP:
return this->ObjectAttributes.empty();
case OBJECT_REF:
case OBJECT:
return this->Object == 0;
}
return true; // unreachable, but quiets warnings
}
void cmXCodeObject::Indent(int level, std::ostream& out)
{
while (level) {

View File

@ -59,21 +59,30 @@ public:
static const char* PBXTypeNames[];
virtual ~cmXCodeObject();
cmXCodeObject(PBXType ptype, Type type);
Type GetType() { return this->TypeValue; }
PBXType GetIsA() { return this->IsA; }
Type GetType() const { return this->TypeValue; }
PBXType GetIsA() const { return this->IsA; }
bool IsEmpty() const;
void SetString(const std::string& s);
const std::string& GetString() { return this->String; }
const std::string& GetString() const { return this->String; }
void AddAttribute(const std::string& name, cmXCodeObject* value)
{
this->ObjectAttributes[name] = value;
}
void AddAttributeIfNotEmpty(const std::string& name, cmXCodeObject* value)
{
if (value && !value->IsEmpty()) {
AddAttribute(name, value);
}
}
void SetObject(cmXCodeObject* value) { this->Object = value; }
cmXCodeObject* GetObject() { return this->Object; }
void AddObject(cmXCodeObject* value) { this->List.push_back(value); }
bool HasObject(cmXCodeObject* o)
bool HasObject(cmXCodeObject* o) const
{
return !(std::find(this->List.begin(), this->List.end(), o) ==
this->List.end());
@ -94,23 +103,25 @@ public:
virtual void PrintComment(std::ostream&) {}
static void PrintList(std::vector<cmXCodeObject*> const&, std::ostream& out);
const std::string& GetId() { return this->Id; }
const std::string& GetId() const { return this->Id; }
void SetId(const std::string& id) { this->Id = id; }
cmGeneratorTarget* GetTarget() { return this->Target; }
cmGeneratorTarget* GetTarget() const { return this->Target; }
void SetTarget(cmGeneratorTarget* t) { this->Target = t; }
const std::string& GetComment() { return this->Comment; }
bool HasComment() { return (!this->Comment.empty()); }
cmXCodeObject* GetObject(const char* name)
const std::string& GetComment() const { return this->Comment; }
bool HasComment() const { return (!this->Comment.empty()); }
cmXCodeObject* GetObject(const char* name) const
{
if (this->ObjectAttributes.count(name)) {
return this->ObjectAttributes[name];
std::map<std::string, cmXCodeObject*>::const_iterator i =
this->ObjectAttributes.find(name);
if (i != this->ObjectAttributes.end()) {
return i->second;
}
return 0;
}
// search the attribute list for an object of the specified type
cmXCodeObject* GetObject(cmXCodeObject::PBXType t)
cmXCodeObject* GetObject(cmXCodeObject::PBXType t) const
{
for (std::vector<cmXCodeObject*>::iterator i = this->List.begin();
for (std::vector<cmXCodeObject*>::const_iterator i = this->List.begin();
i != this->List.end(); ++i) {
cmXCodeObject* o = *i;
if (o->IsA == t) {
@ -126,7 +137,7 @@ public:
{
this->DependLibraries[configName].push_back(l);
}
std::map<std::string, StringVec> const& GetDependLibraries()
std::map<std::string, StringVec> const& GetDependLibraries() const
{
return this->DependLibraries;
}
@ -134,11 +145,14 @@ public:
{
this->DependTargets[configName].push_back(tName);
}
std::map<std::string, StringVec> const& GetDependTargets()
std::map<std::string, StringVec> const& GetDependTargets() const
{
return this->DependTargets;
}
std::vector<cmXCodeObject*> const& GetObjectList() { return this->List; }
std::vector<cmXCodeObject*> const& GetObjectList() const
{
return this->List;
}
void SetComment(const std::string& c) { this->Comment = c; }
static void PrintString(std::ostream& os, std::string String);