summaryrefslogtreecommitdiffstats
path: root/Source/cmGlobalXCodeGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmGlobalXCodeGenerator.cxx')
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx213
1 files changed, 165 insertions, 48 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index dd771b1..42dd997 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -28,6 +28,7 @@
#include "cmTarget.h"
#include "cmXCode21Object.h"
#include "cmXCodeObject.h"
+#include "cmXCodeScheme.h"
#include "cm_auto_ptr.hxx"
#include "cmake.h"
@@ -423,14 +424,12 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
// Add XCODE depend helper
std::string dir = root->GetCurrentBinaryDirectory();
cmCustomCommandLine makeHelper;
- if (this->XcodeVersion < 50) {
- makeHelper.push_back("make");
- makeHelper.push_back("-C");
- makeHelper.push_back(dir);
- makeHelper.push_back("-f");
- makeHelper.push_back(this->CurrentXCodeHackMakefile);
- makeHelper.push_back(""); // placeholder, see below
- }
+ makeHelper.push_back("make");
+ makeHelper.push_back("-C");
+ makeHelper.push_back(dir);
+ makeHelper.push_back("-f");
+ makeHelper.push_back(this->CurrentXCodeHackMakefile);
+ makeHelper.push_back(""); // placeholder, see below
// Add ZERO_CHECK
bool regenerate = !mf->IsOn("CMAKE_SUPPRESS_REGENERATION");
@@ -475,13 +474,12 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
// run the depend check makefile as a post build rule
// this will make sure that when the next target is built
// things are up-to-date
- if (!makeHelper.empty() &&
- (target->GetType() == cmStateEnums::EXECUTABLE ||
- // Nope - no post-build for OBJECT_LIRBRARY
- // target->GetType() == cmStateEnums::OBJECT_LIBRARY ||
- target->GetType() == cmStateEnums::STATIC_LIBRARY ||
- target->GetType() == cmStateEnums::SHARED_LIBRARY ||
- target->GetType() == cmStateEnums::MODULE_LIBRARY)) {
+ if (target->GetType() == cmStateEnums::OBJECT_LIBRARY ||
+ (this->XcodeVersion < 50 &&
+ (target->GetType() == cmStateEnums::EXECUTABLE ||
+ target->GetType() == cmStateEnums::STATIC_LIBRARY ||
+ target->GetType() == cmStateEnums::SHARED_LIBRARY ||
+ target->GetType() == cmStateEnums::MODULE_LIBRARY))) {
makeHelper[makeHelper.size() - 1] = // fill placeholder
this->PostBuildMakeTarget(target->GetName(), "$(CONFIGURATION)");
cmCustomCommandLines commandLines;
@@ -489,7 +487,8 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
std::vector<std::string> no_byproducts;
lg->GetMakefile()->AddCustomCommandToTarget(
target->GetName(), no_byproducts, no_depends, commandLines,
- cmTarget::POST_BUILD, "Depend check for xcode", dir.c_str());
+ cmTarget::POST_BUILD, "Depend check for xcode", dir.c_str(), true,
+ false, "", false, cmMakefile::AcceptObjectLibraryCommands);
}
if (target->GetType() != cmStateEnums::INTERFACE_LIBRARY &&
@@ -1155,8 +1154,12 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
// dstPath in frameworks is relative to Versions/<version>
ostr << mit->first;
} else if (mit->first != "MacOS") {
- // dstPath in bundles is relative to Contents/MacOS
- ostr << "../" << mit->first.c_str();
+ if (gtgt->Target->GetMakefile()->PlatformIsAppleIos()) {
+ ostr << mit->first;
+ } else {
+ // dstPath in bundles is relative to Contents/MacOS
+ ostr << "../" << mit->first;
+ }
}
copyFilesBuildPhase->AddAttribute("dstPath",
this->CreateString(ostr.str()));
@@ -1174,6 +1177,45 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
}
}
+ // create vector of "resource content file" build phases - only for
+ // framework or bundle targets
+ if (isFrameworkTarget || isBundleTarget || isCFBundleTarget) {
+ typedef std::map<std::string, std::vector<cmSourceFile*> >
+ mapOfVectorOfSourceFiles;
+ mapOfVectorOfSourceFiles bundleFiles;
+ for (std::vector<cmSourceFile*>::const_iterator i = classes.begin();
+ i != classes.end(); ++i) {
+ cmGeneratorTarget::SourceFileFlags tsFlags =
+ gtgt->GetTargetSourceFileFlags(*i);
+ if (tsFlags.Type == cmGeneratorTarget::SourceFileTypeDeepResource) {
+ bundleFiles[tsFlags.MacFolder].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"));
+ copyFilesBuildPhase->AddAttribute("dstSubfolderSpec",
+ this->CreateString("7"));
+ copyFilesBuildPhase->AddAttribute("dstPath",
+ this->CreateString(mit->first));
+ 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, gtgt);
+ buildFiles->AddObject(xsf);
+ }
+ contentBuildPhases.push_back(copyFilesBuildPhase);
+ }
+ }
+
// create framework build phase
cmXCodeObject* frameworkBuildPhase = 0;
if (!externalObjFiles.empty()) {
@@ -3133,10 +3175,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeObjects(
cmXCodeObject* t = *i;
this->AddDependAndLinkInformation(t);
}
- if (this->XcodeVersion < 50) {
- // now create xcode depend hack makefile
- this->CreateXCodeDependHackTarget(targets);
- }
+ this->CreateXCodeDependHackTarget(targets);
// now add all targets to the root object
cmXCodeObject* allTargets = this->CreateObject(cmXCodeObject::OBJECT_LIST);
for (std::vector<cmXCodeObject*>::iterator i = targets.begin();
@@ -3187,29 +3226,9 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
"default:\n"
"\techo \"Do not invoke directly\"\n"
"\n";
- makefileStream
- << "# For each target create a dummy rule "
- "so the target does not have to exist\n";
/* clang-format on */
- std::set<std::string> emitted;
- for (std::vector<cmXCodeObject*>::iterator i = targets.begin();
- i != targets.end(); ++i) {
- cmXCodeObject* target = *i;
- std::map<std::string, cmXCodeObject::StringVec> const& deplibs =
- target->GetDependLibraries();
- for (std::map<std::string, cmXCodeObject::StringVec>::const_iterator ci =
- deplibs.begin();
- ci != deplibs.end(); ++ci) {
- for (cmXCodeObject::StringVec::const_iterator d = ci->second.begin();
- d != ci->second.end(); ++d) {
- if (emitted.insert(*d).second) {
- makefileStream << this->ConvertToRelativeForMake(d->c_str())
- << ":\n";
- }
- }
- }
- }
- makefileStream << "\n\n";
+
+ std::set<std::string> dummyRules;
// Write rules to help Xcode relink things at the right time.
/* clang-format off */
@@ -3228,8 +3247,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
cmGeneratorTarget* gt = target->GetTarget();
if (gt->GetType() == cmStateEnums::EXECUTABLE ||
- // Nope - no post-build for OBJECT_LIRBRARY
- // gt->GetType() == cmStateEnums::OBJECT_LIBRARY ||
+ gt->GetType() == cmStateEnums::OBJECT_LIBRARY ||
gt->GetType() == cmStateEnums::STATIC_LIBRARY ||
gt->GetType() == cmStateEnums::SHARED_LIBRARY ||
gt->GetType() == cmStateEnums::MODULE_LIBRARY) {
@@ -3239,6 +3257,7 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
}
if (gt->GetType() == cmStateEnums::EXECUTABLE ||
+ gt->GetType() == cmStateEnums::STATIC_LIBRARY ||
gt->GetType() == cmStateEnums::SHARED_LIBRARY ||
gt->GetType() == cmStateEnums::MODULE_LIBRARY) {
std::string tfull = gt->GetFullPath(configName);
@@ -3256,6 +3275,15 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
}
}
+ std::vector<cmGeneratorTarget*> objlibs;
+ gt->GetObjectLibrariesCMP0026(objlibs);
+ for (std::vector<cmGeneratorTarget*>::const_iterator it =
+ objlibs.begin();
+ it != objlibs.end(); ++it) {
+ makefileStream << this->PostBuildMakeTarget((*it)->GetName(), *ct)
+ << ": " << trel << "\n";
+ }
+
// Create a rule for this target.
makefileStream << trel << ":";
@@ -3266,10 +3294,28 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
std::vector<std::string> const& deplibs = x->second;
for (std::vector<std::string>::const_iterator d = deplibs.begin();
d != deplibs.end(); ++d) {
- makefileStream << "\\\n\t"
- << this->ConvertToRelativeForMake(d->c_str());
+ std::string file = this->ConvertToRelativeForMake(d->c_str());
+ makefileStream << "\\\n\t" << file;
+ dummyRules.insert(file);
}
}
+
+ for (std::vector<cmGeneratorTarget*>::const_iterator it =
+ objlibs.begin();
+ it != objlibs.end(); ++it) {
+
+ const std::string objLibName = (*it)->GetName();
+ std::string d = this->GetObjectsNormalDirectory(this->CurrentProject,
+ configName, *it);
+ d += "lib";
+ d += objLibName;
+ d += ".a";
+
+ std::string dependency = this->ConvertToRelativeForMake(d.c_str());
+ makefileStream << "\\\n\t" << dependency;
+ dummyRules.insert(dependency);
+ }
+
// Write the action to remove the target if it is out of date.
makefileStream << "\n";
makefileStream << "\t/bin/rm -f "
@@ -3297,6 +3343,14 @@ void cmGlobalXCodeGenerator::CreateXCodeDependHackTarget(
}
}
}
+
+ makefileStream << "\n\n"
+ << "# For each target create a dummy rule"
+ << "so the target does not have to exist\n";
+ for (std::set<std::string>::const_iterator it = dummyRules.begin();
+ it != dummyRules.end(); ++it) {
+ makefileStream << *it << ":\n";
+ }
}
void cmGlobalXCodeGenerator::OutputXCodeProject(
@@ -3331,6 +3385,15 @@ void cmGlobalXCodeGenerator::OutputXCodeProject(
return;
}
this->WriteXCodePBXProj(fout, root, generators);
+
+ // Since the lowest available Xcode version for testing was 7.0,
+ // I'm setting this as a limit then
+ if (root->GetMakefile()->IsOn("CMAKE_XCODE_GENERATE_SCHEME") &&
+ this->XcodeVersion >= 70) {
+ this->OutputXCodeSharedSchemes(xcodeDir);
+ this->OutputXCodeWorkspaceSettings(xcodeDir);
+ }
+
this->ClearXCodeObjects();
// Since this call may have created new cache entries, save the cache:
@@ -3339,6 +3402,54 @@ void cmGlobalXCodeGenerator::OutputXCodeProject(
root->GetBinaryDirectory());
}
+void cmGlobalXCodeGenerator::OutputXCodeSharedSchemes(
+ const std::string& xcProjDir)
+{
+ for (std::vector<cmXCodeObject*>::const_iterator i =
+ this->XCodeObjects.begin();
+ i != this->XCodeObjects.end(); ++i) {
+ cmXCodeObject* obj = *i;
+ if (obj->GetType() == cmXCodeObject::OBJECT &&
+ (obj->GetIsA() == cmXCodeObject::PBXNativeTarget ||
+ obj->GetIsA() == cmXCodeObject::PBXAggregateTarget)) {
+ cmXCodeScheme schm(obj, this->CurrentConfigurationTypes,
+ this->XcodeVersion);
+ schm.WriteXCodeSharedScheme(xcProjDir,
+ this->RelativeToSource(xcProjDir.c_str()));
+ }
+ }
+}
+
+void cmGlobalXCodeGenerator::OutputXCodeWorkspaceSettings(
+ const std::string& xcProjDir)
+{
+ std::string xcodeSharedDataDir = xcProjDir;
+ xcodeSharedDataDir += "/project.xcworkspace/xcshareddata";
+ cmSystemTools::MakeDirectory(xcodeSharedDataDir);
+
+ std::string workspaceSettingsFile = xcodeSharedDataDir;
+ workspaceSettingsFile += "/WorkspaceSettings.xcsettings";
+
+ cmGeneratedFileStream fout(workspaceSettingsFile.c_str());
+ fout.SetCopyIfDifferent(true);
+ if (!fout) {
+ return;
+ }
+
+ cmXMLWriter xout(fout);
+ xout.StartDocument();
+ xout.Doctype("plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\""
+ "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
+ xout.StartElement("plist");
+ xout.Attribute("version", "1.0");
+ xout.StartElement("dict");
+ xout.Element("key", "IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded");
+ xout.Element("false");
+ xout.EndElement(); // dict
+ xout.EndElement(); // plist
+ xout.EndDocument();
+}
+
void cmGlobalXCodeGenerator::WriteXCodePBXProj(std::ostream& fout,
cmLocalGenerator*,
std::vector<cmLocalGenerator*>&)
@@ -3593,6 +3704,12 @@ bool cmGlobalXCodeGenerator::UseEffectivePlatformName(cmMakefile* mf) const
return cmSystemTools::IsOn(epnValue);
}
+bool cmGlobalXCodeGenerator::ShouldStripResourcePath(cmMakefile*) const
+{
+ // Xcode determines Resource location itself
+ return true;
+}
+
void cmGlobalXCodeGenerator::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{