diff options
Diffstat (limited to 'Source/cmGlobalXCodeGenerator.cxx')
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 527 |
1 files changed, 324 insertions, 203 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index f4c6411..d872637 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -25,6 +25,7 @@ PURPOSE. See the above copyright notices for more information. #include "cmSourceFile.h" #include "cmOrderLinkDirectories.h" +//---------------------------------------------------------------------------- #if defined(CMAKE_BUILD_WITH_CMAKE) #include "cmXMLParser.h" @@ -61,7 +62,6 @@ public: }; #endif - //---------------------------------------------------------------------------- cmGlobalXCodeGenerator::cmGlobalXCodeGenerator() { @@ -69,6 +69,7 @@ cmGlobalXCodeGenerator::cmGlobalXCodeGenerator() this->RootObject = 0; this->MainGroupChildren = 0; this->SourcesGroupChildren = 0; + this->ResourcesGroupChildren = 0; this->CurrentMakefile = 0; this->CurrentLocalGenerator = 0; this->XcodeVersion = 15; @@ -266,6 +267,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& gens) { cmMakefile* mf = root->GetMakefile(); + // Add ALL_BUILD const char* no_working_directory = 0; std::vector<std::string> no_depends; @@ -273,7 +275,7 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root, no_working_directory, "echo", "Build all projects"); cmTarget* allbuild = mf->FindTarget("ALL_BUILD", false); - + // Add XCODE depend helper std::string dir = mf->GetCurrentOutputDirectory(); cmCustomCommandLine makecommand; @@ -326,7 +328,6 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root, } } - //---------------------------------------------------------------------------- void cmGlobalXCodeGenerator::CreateReRunCMakeFile(cmLocalGenerator* root) { @@ -373,6 +374,7 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects() this->GroupMap.clear(); this->GroupNameMap.clear(); this->TargetGroup.clear(); + this->FileRefs.clear(); } //---------------------------------------------------------------------------- @@ -420,37 +422,109 @@ cmXCodeObject* cmGlobalXCodeGenerator } //---------------------------------------------------------------------------- +bool IsResource(cmSourceFile* sf) +{ + const char* location = sf->GetProperty("MACOSX_PACKAGE_LOCATION"); + + bool isResource = + (sf->GetPropertyAsBool("FRAMEWORK_RESOURCE") || + (location && cmStdString(location) == "Resources")); + + return isResource; +} + +//---------------------------------------------------------------------------- +cmStdString GetGroupMapKey(cmTarget& cmtarget, cmSourceFile* sf) +{ + cmStdString key(cmtarget.GetName()); + key += "-"; + key += sf->GetFullPath(); + return key; +} + +//---------------------------------------------------------------------------- cmXCodeObject* cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg, cmSourceFile* sf, cmTarget& cmtarget) { + // Add flags from target and source file properties. std::string flags; - // Add flags from source file properties. if(cmtarget.GetProperty("COMPILE_FLAGS")) { lg->AppendFlags(flags, cmtarget.GetProperty("COMPILE_FLAGS")); } lg->AppendFlags(flags, sf->GetProperty("COMPILE_FLAGS")); cmSystemTools::ReplaceString(flags, "\"", "\\\""); - cmXCodeObject* fileRef = - this->CreateObject(cmXCodeObject::PBXFileReference); - cmXCodeObject* group = this->GroupMap[sf]; + // Using a map and the full path guarantees that we will always get the same + // fileRef object for any given full path. + // + std::string fname = sf->GetFullPath(); + cmXCodeObject* fileRef = this->FileRefs[fname]; + if(!fileRef) + { + fileRef = this->CreateObject(cmXCodeObject::PBXFileReference); + std::string comment = fname; + comment += " in "; + //std::string gname = group->GetObject("name")->GetString(); + //comment += gname.substr(1, gname.size()-2); + fileRef->SetComment(fname.c_str()); + + this->FileRefs[fname] = fileRef; + } + + cmStdString key = GetGroupMapKey(cmtarget, sf); + cmXCodeObject* group = this->GroupMap[key]; cmXCodeObject* children = group->GetObject("children"); - children->AddObject(fileRef); + if (!children->HasObject(fileRef)) + { + children->AddObject(fileRef); + } + cmXCodeObject* buildFile = this->CreateObject(cmXCodeObject::PBXBuildFile); - std::string fname = sf->GetFullPath(); - std::string comment = fname; - comment += " in "; - std::string gname = group->GetObject("name")->GetString(); - comment += gname.substr(1, gname.size()-2); - buildFile->SetComment(comment.c_str()); - fileRef->SetComment(fname.c_str()); + buildFile->SetComment(fileRef->GetComment()); buildFile->AddAttribute("fileRef", this->CreateObjectReference(fileRef)); + cmXCodeObject* settings = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP); settings->AddAttribute("COMPILER_FLAGS", this->CreateString(flags.c_str())); + + // Is this a resource file in this target? Add it to the resources group... + // + bool isResource = IsResource(sf); + + // Is this a "private" or "public" framework header file? + // Set the ATTRIBUTES attribute appropriately... + // + if(cmtarget.GetType() == cmTarget::SHARED_LIBRARY && + cmtarget.GetPropertyAsBool("FRAMEWORK")) + { + if(sf->GetPropertyAsBool("FRAMEWORK_PRIVATE_HEADER")) + { + cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST); + attrs->AddObject(this->CreateString("Private")); + settings->AddAttribute("ATTRIBUTES", attrs); + isResource = true; + } + else if(sf->GetPropertyAsBool("FRAMEWORK_PUBLIC_HEADER")) + { + cmXCodeObject* attrs = this->CreateObject(cmXCodeObject::OBJECT_LIST); + attrs->AddObject(this->CreateString("Public")); + settings->AddAttribute("ATTRIBUTES", attrs); + isResource = true; + } + } + + // Add the fileRef to the top level Resources group/folder if it is not + // already there. + // + if(isResource && this->ResourcesGroupChildren && + !this->ResourcesGroupChildren->HasObject(fileRef)) + { + this->ResourcesGroupChildren->AddObject(fileRef); + } + buildFile->AddAttribute("settings", settings); fileRef->AddAttribute("fileEncoding", this->CreateString("4")); const char* lang = @@ -524,7 +598,7 @@ cmGlobalXCodeGenerator::CreateXCodeSourceFile(cmLocalGenerator* lg, bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname) { if(tname == "ALL_BUILD" || tname == "XCODE_DEPEND_HELPER" || - tname == "install" || tname == "RUN_TESTS" ) + tname == "install" || tname == "package" || tname == "RUN_TESTS" ) { if(this->TargetDoneSet.find(tname) != this->TargetDoneSet.end()) { @@ -536,7 +610,7 @@ bool cmGlobalXCodeGenerator::SpecialTargetEmitted(std::string const& tname) return false; } - +//---------------------------------------------------------------------------- void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen) { this->CurrentLocalGenerator = gen; @@ -572,18 +646,18 @@ void cmGlobalXCodeGenerator::SetCurrentLocalGenerator(cmLocalGenerator* gen) } } - //---------------------------------------------------------------------------- -void +void cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, - std::vector<cmXCodeObject*>& + std::vector<cmXCodeObject*>& targets) { this->SetCurrentLocalGenerator(gen); cmTargets &tgts = this->CurrentMakefile->GetTargets(); for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) - { + { cmTarget& cmtarget = l->second; + // make sure ALL_BUILD, INSTALL, etc are only done once if(this->SpecialTargetEmitted(l->first.c_str())) { @@ -597,31 +671,22 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, continue; } - // create source build phase - cmXCodeObject* sourceBuildPhase = - this->CreateObject(cmXCodeObject::PBXSourcesBuildPhase); - sourceBuildPhase->AddAttribute("buildActionMask", - this->CreateString("2147483647")); - sourceBuildPhase->SetComment("Sources"); - cmXCodeObject* buildFiles = - this->CreateObject(cmXCodeObject::OBJECT_LIST); - sourceBuildPhase->AddAttribute("files", buildFiles); - sourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", - this->CreateString("0")); - std::vector<cmSourceFile*> const &classes = l->second.GetSourceFiles(); - // add all the sources + // organize the sources + std::vector<cmSourceFile*> const &classes = cmtarget.GetSourceFiles(); std::vector<cmXCodeObject*> externalObjFiles; std::vector<cmXCodeObject*> headerFiles; - std::vector<cmXCodeObject*> specialBundleFiles; - for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); + std::vector<cmXCodeObject*> resourceFiles; + std::vector<cmXCodeObject*> sourceFiles; + for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); i != classes.end(); ++i) { cmXCodeObject* xsf = - this->CreateXCodeSourceFile(this->CurrentLocalGenerator, + this->CreateXCodeSourceFile(this->CurrentLocalGenerator, *i, cmtarget); cmXCodeObject* fr = xsf->GetObject("fileRef"); cmXCodeObject* filetype = fr->GetObject()->GetObject("lastKnownFileType"); + if(strcmp(filetype->GetString(), "\"compiled.mach-o.objfile\"") == 0) { externalObjFiles.push_back(xsf); @@ -630,76 +695,106 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, { headerFiles.push_back(xsf); } + else if(IsResource(*i)) + { + resourceFiles.push_back(xsf); + } else { - buildFiles->AddObject(xsf); + sourceFiles.push_back(xsf); } } - // create header build phase - cmXCodeObject* headerBuildPhase = - this->CreateObject(cmXCodeObject::PBXHeadersBuildPhase); - headerBuildPhase->SetComment("Headers"); - headerBuildPhase->AddAttribute("buildActionMask", - this->CreateString("2147483647")); - buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); - for(std::vector<cmXCodeObject*>::iterator i = headerFiles.begin(); - i != headerFiles.end(); ++i) - { - buildFiles->AddObject(*i); - } - headerBuildPhase->AddAttribute("files", buildFiles); - headerBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", - this->CreateString("0")); - - // create framework build phase - cmXCodeObject* frameworkBuildPhase = - this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase); - frameworkBuildPhase->SetComment("Frameworks"); - frameworkBuildPhase->AddAttribute("buildActionMask", - this->CreateString("2147483647")); - buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); - frameworkBuildPhase->AddAttribute("files", buildFiles); - for(std::vector<cmXCodeObject*>::iterator i = externalObjFiles.begin(); - i != externalObjFiles.end(); ++i) - { - buildFiles->AddObject(*i); - } - frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", - this->CreateString("0")); - cmXCodeObject* buildPhases = - this->CreateObject(cmXCodeObject::OBJECT_LIST); - this->CreateCustomCommands(buildPhases, sourceBuildPhase, - headerBuildPhase, frameworkBuildPhase, - cmtarget); - targets.push_back(this->CreateXCodeTarget(l->second, buildPhases)); - - // copy files build phase - typedef std::map<cmStdString, std::vector<cmSourceFile*> > - mapOfVectorOfSourceFiles; - mapOfVectorOfSourceFiles bundleFiles; - for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); - i != classes.end(); ++i) + + // some build phases only apply to bundles and/or frameworks + bool isFrameworkTarget = cmtarget.GetType() == cmTarget::SHARED_LIBRARY && + cmtarget.GetPropertyAsBool("FRAMEWORK"); + bool isBundleTarget = cmtarget.GetPropertyAsBool("MACOSX_BUNDLE"); + + cmXCodeObject* buildFiles = 0; + + // create source build phase + cmXCodeObject* sourceBuildPhase = 0; + if (!sourceFiles.empty()) + { + sourceBuildPhase = + this->CreateObject(cmXCodeObject::PBXSourcesBuildPhase); + sourceBuildPhase->SetComment("Sources"); + sourceBuildPhase->AddAttribute("buildActionMask", + this->CreateString("2147483647")); + buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); + for(std::vector<cmXCodeObject*>::iterator i = sourceFiles.begin(); + i != sourceFiles.end(); ++i) + { + buildFiles->AddObject(*i); + } + sourceBuildPhase->AddAttribute("files", buildFiles); + sourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); + } + + // create header build phase - only for framework targets + cmXCodeObject* headerBuildPhase = 0; + if (!headerFiles.empty() && isFrameworkTarget) { - const char* resLoc = (*i)->GetProperty("MACOSX_PACKAGE_LOCATION"); - if ( !resLoc ) + headerBuildPhase = + this->CreateObject(cmXCodeObject::PBXHeadersBuildPhase); + headerBuildPhase->SetComment("Headers"); + headerBuildPhase->AddAttribute("buildActionMask", + this->CreateString("2147483647")); + buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); + for(std::vector<cmXCodeObject*>::iterator i = headerFiles.begin(); + i != headerFiles.end(); ++i) { - continue; + buildFiles->AddObject(*i); } - bundleFiles[resLoc].push_back(*i); + headerBuildPhase->AddAttribute("files", buildFiles); + headerBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); } - mapOfVectorOfSourceFiles::iterator mit; - for ( mit = bundleFiles.begin(); mit != bundleFiles.end(); ++ mit ) + + // create resource build phase - only for framework or bundle targets + cmXCodeObject* resourceBuildPhase = 0; + if (!resourceFiles.empty() && (isFrameworkTarget || isBundleTarget)) { - cmXCodeObject* copyFilesBuildPhase; - if ( mit->first == "Resources" ) + resourceBuildPhase = + this->CreateObject(cmXCodeObject::PBXResourcesBuildPhase); + resourceBuildPhase->SetComment("Resources"); + resourceBuildPhase->AddAttribute("buildActionMask", + this->CreateString("2147483647")); + buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); + for(std::vector<cmXCodeObject*>::iterator i = resourceFiles.begin(); + i != resourceFiles.end(); ++i) { - copyFilesBuildPhase - = this->CreateObject(cmXCodeObject::PBXResourcesBuildPhase); + buildFiles->AddObject(*i); } - else + resourceBuildPhase->AddAttribute("files", buildFiles); + resourceBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); + } + + // create vector of "non-resource content file" build phases - only for + // framework or bundle targets + std::vector<cmXCodeObject*> contentBuildPhases; + if (isFrameworkTarget || isBundleTarget) + { + typedef std::map<cmStdString, std::vector<cmSourceFile*> > + mapOfVectorOfSourceFiles; + mapOfVectorOfSourceFiles bundleFiles; + for(std::vector<cmSourceFile*>::const_iterator i = classes.begin(); + i != classes.end(); ++i) { - copyFilesBuildPhase - = this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); + const char* contentLoc = (*i)->GetProperty("MACOSX_PACKAGE_LOCATION"); + if ( !contentLoc || cmStdString(contentLoc) == "Resources" ) + { + continue; + } + bundleFiles[contentLoc].push_back(*i); + } + mapOfVectorOfSourceFiles::iterator mit; + for ( mit = bundleFiles.begin(); mit != bundleFiles.end(); ++ mit ) + { + cmXCodeObject* copyFilesBuildPhase = + this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); copyFilesBuildPhase->SetComment("Copy files"); copyFilesBuildPhase->AddAttribute("buildActionMask", this->CreateString("2147483647")); @@ -712,73 +807,58 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen, } copyFilesBuildPhase->AddAttribute("dstPath", this->CreateString(ostr.str().c_str())); + copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); + buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); + copyFilesBuildPhase->AddAttribute("files", buildFiles); + std::vector<cmSourceFile*>::iterator sfIt; + for ( sfIt = mit->second.begin(); sfIt != mit->second.end(); ++ sfIt ) + { + cmXCodeObject* xsf = + this->CreateXCodeSourceFile(this->CurrentLocalGenerator, + *sfIt, cmtarget); + buildFiles->AddObject(xsf); + } + contentBuildPhases.push_back(copyFilesBuildPhase); } - copyFilesBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", - this->CreateString("0")); - buildPhases->AddObject(copyFilesBuildPhase); + } + + // create framework build phase + cmXCodeObject* frameworkBuildPhase = 0; + if (!externalObjFiles.empty()) + { + frameworkBuildPhase = + this->CreateObject(cmXCodeObject::PBXFrameworksBuildPhase); + frameworkBuildPhase->SetComment("Frameworks"); + frameworkBuildPhase->AddAttribute("buildActionMask", + this->CreateString("2147483647")); buildFiles = this->CreateObject(cmXCodeObject::OBJECT_LIST); - copyFilesBuildPhase->AddAttribute("files", buildFiles); - std::vector<cmSourceFile*>::iterator sfIt; - for ( sfIt = mit->second.begin(); sfIt != mit->second.end(); ++ sfIt ) + frameworkBuildPhase->AddAttribute("files", buildFiles); + for(std::vector<cmXCodeObject*>::iterator i = externalObjFiles.begin(); + i != externalObjFiles.end(); ++i) { - cmXCodeObject* xsf = - this->CreateXCodeSourceFile(this->CurrentLocalGenerator, - *sfIt, cmtarget); - buildFiles->AddObject(xsf); + buildFiles->AddObject(*i); } + frameworkBuildPhase->AddAttribute("runOnlyForDeploymentPostprocessing", + this->CreateString("0")); } - if (cmtarget.GetType() == cmTarget::SHARED_LIBRARY && - cmtarget.GetPropertyAsBool("FRAMEWORK")) - { - this->AddFrameworkPhases(&cmtarget, buildPhases); - } - } -} -//---------------------------------------------------------------------------- -void cmGlobalXCodeGenerator::AddFrameworkPhases(cmTarget* target, - cmXCodeObject* buildPhases) -{ - const char* headers = target->GetProperty("FRAMEWORK_PUBLIC_HEADERS"); - if(!headers) - { - return; - } - - cmXCodeObject* copyHeaders = - this->CreateObject(cmXCodeObject::PBXCopyFilesBuildPhase); - copyHeaders->SetComment("Copy files"); - copyHeaders->AddAttribute("buildActionMask", - this->CreateString("2147483647")); - copyHeaders->AddAttribute("dstSubfolderSpec", - this->CreateString("6")); - copyHeaders->AddAttribute("dstPath", - this->CreateString("Headers")); - buildPhases->AddObject(copyHeaders); - cmXCodeObject* headersToCopy = - this->CreateObject(cmXCodeObject::OBJECT_LIST); - copyHeaders->AddAttribute("files", headersToCopy); - std::vector<std::string> headersVec; - cmSystemTools::ExpandListArgument(headers, - headersVec); - cmCustomCommandLines commandLines; - std::vector<std::string> depends; - for(std::vector<std::string>::iterator i = headersVec.begin(); - i != headersVec.end(); ++i) - { - cmCustomCommandLine line; - cmSourceFile* sf = this->CurrentMakefile->GetOrCreateSource(i->c_str()); - cmXCodeObject* xsf = - this->CreateXCodeSourceFile(this->CurrentLocalGenerator, - sf, *target); - //std::cerr << "copy header " << sf->GetFullPath() << "\n"; - headersToCopy->AddObject(xsf); + // create list of build phases and create the XCode target + cmXCodeObject* buildPhases = + this->CreateObject(cmXCodeObject::OBJECT_LIST); + + this->CreateCustomCommands(buildPhases, sourceBuildPhase, + headerBuildPhase, resourceBuildPhase, + contentBuildPhases, + frameworkBuildPhase, cmtarget); + + targets.push_back(this->CreateXCodeTarget(cmtarget, buildPhases)); } } //---------------------------------------------------------------------------- cmXCodeObject* -cmGlobalXCodeGenerator::CreateBuildPhase(const char* name, +cmGlobalXCodeGenerator::CreateBuildPhase(const char* name, const char* name2, cmTarget& cmtarget, const std::vector<cmCustomCommand>& @@ -812,6 +892,10 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases, cmXCodeObject* headerBuildPhase, cmXCodeObject* + resourceBuildPhase, + std::vector<cmXCodeObject*> + contentBuildPhases, + cmXCodeObject* frameworkBuildPhase, cmTarget& cmtarget) { @@ -846,15 +930,19 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases, cmXCodeObject* preBuildPhase = this->CreateBuildPhase("CMake PreBuild Rules", "preBuildCommands", cmtarget, prebuild); - // create prebuild phase + // create prelink phase cmXCodeObject* preLinkPhase = this->CreateBuildPhase("CMake PreLink Rules", "preLinkCommands", cmtarget, prelink); - // create prebuild phase + // create postbuild phase cmXCodeObject* postBuildPhase = this->CreateBuildPhase("CMake PostBuild Rules", "postBuildPhase", cmtarget, postbuild); - // the order here is the order they will be built in + + // The order here is the order they will be built in. + // The order "headers, resources, sources" mimics a native project generated + // from an xcode template... + // if(preBuildPhase) { buildPhases->AddObject(preBuildPhase); @@ -863,14 +951,23 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases, { buildPhases->AddObject(cmakeRulesBuildPhase); } - if(sourceBuildPhase) - { - buildPhases->AddObject(sourceBuildPhase); - } if(headerBuildPhase) { buildPhases->AddObject(headerBuildPhase); } + if(resourceBuildPhase) + { + buildPhases->AddObject(resourceBuildPhase); + } + std::vector<cmXCodeObject*>::iterator cit; + for (cit = contentBuildPhases.begin(); cit != contentBuildPhases.end(); ++cit) + { + buildPhases->AddObject(*cit); + } + if(sourceBuildPhase) + { + buildPhases->AddObject(sourceBuildPhase); + } if(preLinkPhase) { buildPhases->AddObject(preLinkPhase); @@ -1312,27 +1409,33 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, { fileType = "wrapper.framework"; productType = "com.apple.product-type.framework"; - break; + + const char* version = target.GetProperty("FRAMEWORK_VERSION"); + buildSettings->AddAttribute("FRAMEWORK_VERSION", + this->CreateString(version)); } - fileType = "compiled.mach-o.dylib"; - productType = "com.apple.product-type.library.dynamic"; + else + { + fileType = "compiled.mach-o.dylib"; + productType = "com.apple.product-type.library.dynamic"; - buildSettings->AddAttribute("LIBRARY_STYLE", + // Add the flags to create a shared library. + std::string createFlags = + this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", lang, "_FLAGS", + "-dynamiclib"); + if(!createFlags.empty()) + { + extraLinkOptions += " "; + extraLinkOptions += createFlags; + } + } + + buildSettings->AddAttribute("LIBRARY_STYLE", this->CreateString("DYNAMIC")); - buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION", + buildSettings->AddAttribute("DYLIB_COMPATIBILITY_VERSION", this->CreateString("1")); - buildSettings->AddAttribute("DYLIB_CURRENT_VERSION", + buildSettings->AddAttribute("DYLIB_CURRENT_VERSION", this->CreateString("1")); - - // Add the flags to create a shared library. - std::string createFlags = - this->LookupFlags("CMAKE_SHARED_LIBRARY_CREATE_", lang, "_FLAGS", - "-dynamiclib"); - if(!createFlags.empty()) - { - extraLinkOptions += " "; - extraLinkOptions += createFlags; - } break; } case cmTarget::EXECUTABLE: @@ -1577,7 +1680,8 @@ cmGlobalXCodeGenerator::CreateUtilityTarget(cmTarget& cmtarget) target->SetComment(cmtarget.GetName()); cmXCodeObject* buildPhases = this->CreateObject(cmXCodeObject::OBJECT_LIST); - this->CreateCustomCommands(buildPhases, 0, 0, 0, cmtarget); + std::vector<cmXCodeObject*> emptyContentVector; + this->CreateCustomCommands(buildPhases, 0, 0, 0, emptyContentVector, 0, cmtarget); target->AddAttribute("buildPhases", buildPhases); cmXCodeObject* buildSettings = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP); @@ -1785,7 +1889,6 @@ void cmGlobalXCodeGenerator::AddDependTarget(cmXCodeObject* target, } } - //---------------------------------------------------------------------------- void cmGlobalXCodeGenerator::AppendOrAddBuildSetting(cmXCodeObject* settings, const char* attribute, @@ -2042,6 +2145,17 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root, for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) { cmTarget& cmtarget = l->second; + + // Same skipping logic here as in CreateXCodeTargets so that we do not + // end up with (empty anyhow) ALL_BUILD and XCODE_DEPEND_HELPER source + // groups: + // + if(cmtarget.GetType() == cmTarget::UTILITY || + cmtarget.GetType() == cmTarget::GLOBAL_TARGET) + { + continue; + } + // add the soon to be generated Info.plist file as a source for a // MACOSX_BUNDLE file if(cmtarget.GetPropertyAsBool("MACOSX_BUNDLE")) @@ -2053,29 +2167,9 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root, this->CurrentMakefile->GetOrCreateSource(plistFile.c_str(), true); cmtarget.AddSourceFile(sf); } + std::vector<cmSourceFile*> classes = cmtarget.GetSourceFiles(); - // add framework copy headers - if (cmtarget.GetType() == cmTarget::SHARED_LIBRARY && - cmtarget.GetPropertyAsBool("FRAMEWORK")) - { - const char* headers = cmtarget.GetProperty("FRAMEWORK_PUBLIC_HEADERS"); - if(!headers) - { - return; - } - std::vector<std::string> headersVec; - cmSystemTools::ExpandListArgument(headers, - headersVec); - cmCustomCommandLines commandLines; - std::vector<std::string> depends; - for(std::vector<std::string>::iterator h = headersVec.begin(); - h != headersVec.end(); ++h) - { - cmSourceFile* sf - = this->CurrentMakefile->GetOrCreateSource(h->c_str()); - classes.push_back(sf); - } - } + for(std::vector<cmSourceFile*>::const_iterator s = classes.begin(); s != classes.end(); s++) { @@ -2086,11 +2180,13 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root, mf->FindSourceGroup(source.c_str(), sourceGroups); cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(cmtarget, &sourceGroup); - this->GroupMap[sf] = pbxgroup; + cmStdString key = GetGroupMapKey(cmtarget, sf); + this->GroupMap[key] = pbxgroup; } } } } + //---------------------------------------------------------------------------- cmXCodeObject* cmGlobalXCodeGenerator ::CreateOrGetPBXGroup(cmTarget& cmtarget, cmSourceGroup* sg) @@ -2098,7 +2194,7 @@ cmXCodeObject* cmGlobalXCodeGenerator cmStdString s = cmtarget.GetName(); s += "/"; s += sg->GetName(); - std::map<cmStdString, cmXCodeObject* >::iterator i = + std::map<cmStdString, cmXCodeObject* >::iterator i = this->GroupNameMap.find(s); if(i != this->GroupNameMap.end()) { @@ -2125,7 +2221,16 @@ cmXCodeObject* cmGlobalXCodeGenerator tgroup->AddAttribute("sourceTree", this->CreateString("<group>")); this->SourcesGroupChildren->AddObject(tgroup); } - + + // If it's the default source group (empty name) then put the source file + // directly in the tgroup... + // + if (cmStdString(sg->GetName()) == "") + { + this->GroupNameMap[s] = tgroup; + return tgroup; + } + cmXCodeObject* tgroupChildren = tgroup->GetObject("children"); cmXCodeObject* group = this->CreateObject(cmXCodeObject::PBXGroup); cmXCodeObject* groupChildren = @@ -2151,6 +2256,7 @@ void cmGlobalXCodeGenerator this->ClearXCodeObjects(); this->RootObject = 0; this->SourcesGroupChildren = 0; + this->ResourcesGroupChildren = 0; this->MainGroupChildren = 0; cmXCodeObject* group = this->CreateObject(cmXCodeObject::ATTRIBUTE_GROUP); group->AddAttribute("COPY_PHASE_STRIP", this->CreateString("NO")); @@ -2209,9 +2315,22 @@ void cmGlobalXCodeGenerator } sourcesGroup->AddAttribute("sourceTree", this->CreateString("<group>")); this->MainGroupChildren->AddObject(sourcesGroup); + + cmXCodeObject* resourcesGroup = this->CreateObject(cmXCodeObject::PBXGroup); + this->ResourcesGroupChildren = + this->CreateObject(cmXCodeObject::OBJECT_LIST); + resourcesGroup->AddAttribute("name", this->CreateString("Resources")); + resourcesGroup->AddAttribute("children", this->ResourcesGroupChildren); + if(this->XcodeVersion == 15) + { + resourcesGroup->AddAttribute("refType", this->CreateString("4")); + } + resourcesGroup->AddAttribute("sourceTree", this->CreateString("<group>")); + this->MainGroupChildren->AddObject(resourcesGroup); + // now create the cmake groups this->CreateGroups(root, generators); - + cmXCodeObject* productGroup = this->CreateObject(cmXCodeObject::PBXGroup); productGroup->AddAttribute("name", this->CreateString("Products")); if(this->XcodeVersion == 15) @@ -2533,7 +2652,7 @@ cmGlobalXCodeGenerator::OutputXCodeProject(cmLocalGenerator* root, if(this->XcodeVersion > 20) { xcodeDir += "proj"; - } + } cmSystemTools::MakeDirectory(xcodeDir.c_str()); std::string xcodeProjFile = xcodeDir + "/project.pbxproj"; cmGeneratedFileStream fout(xcodeProjFile.c_str()); @@ -2609,6 +2728,7 @@ std::string cmGlobalXCodeGenerator::ConvertToRelativeForXCode(const char* p) } } +//---------------------------------------------------------------------------- std::string cmGlobalXCodeGenerator::XCodeEscapePath(const char* p) { std::string ret = p; @@ -2622,6 +2742,7 @@ std::string cmGlobalXCodeGenerator::XCodeEscapePath(const char* p) return ret; } +//---------------------------------------------------------------------------- void cmGlobalXCodeGenerator:: GetTargetObjectFileDirectories(cmTarget* target, std::vector<std::string>& |