summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmGlobalGenerator.h6
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx57
-rw-r--r--Source/cmGlobalXCodeGenerator.h2
3 files changed, 62 insertions, 3 deletions
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 0eb27e4..4df2d39 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -317,6 +317,9 @@ protected:
// This is computed just before local generators generate.
cmTargetManifest TargetManifest;
+ // All targets in the entire project.
+ std::map<cmStdString,cmTarget *> TotalTargets;
+
private:
float FirstTimeProgress;
// If you add a new map here, make sure it is copied
@@ -328,9 +331,6 @@ private:
std::map<cmStdString, cmStdString> ExtensionToLanguage;
std::map<cmStdString, int> LanguageToLinkerPreference;
- // this is used to improve performance
- std::map<cmStdString,cmTarget *> TotalTargets;
-
// Record hashes for rules and outputs.
struct RuleHash { char Data[32]; };
std::map<cmStdString, RuleHash> RuleHashes;
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 5f22946..353fa6e 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -239,6 +239,7 @@ void cmGlobalXCodeGenerator::Generate()
// add ALL_BUILD, INSTALL, etc
this->AddExtraTargets(root, it->second);
}
+ this->ForceLinkerLanguages();
this->cmGlobalGenerator::Generate();
for(it = this->ProjectMap.begin(); it!= this->ProjectMap.end(); ++it)
{
@@ -969,6 +970,62 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
}
//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::ForceLinkerLanguages()
+{
+ // This makes sure all targets link using the proper language.
+ for(std::map<cmStdString, cmTarget*>::const_iterator
+ ti = this->TotalTargets.begin(); ti != this->TotalTargets.end(); ++ti)
+ {
+ this->ForceLinkerLanguage(*ti->second);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget)
+{
+ // This matters only for targets that link.
+ if(cmtarget.GetType() != cmTarget::EXECUTABLE &&
+ cmtarget.GetType() != cmTarget::SHARED_LIBRARY &&
+ cmtarget.GetType() != cmTarget::MODULE_LIBRARY)
+ {
+ return;
+ }
+
+ const char* llang = cmtarget.GetLinkerLanguage("NOCONFIG");
+ if(!llang) { return; }
+
+ // If the language is compiled as a source trust Xcode to link with it.
+ cmTarget::LinkImplementation const* impl =
+ cmtarget.GetLinkImplementation("NOCONFIG");
+ for(std::vector<std::string>::const_iterator li = impl->Languages.begin();
+ li != impl->Languages.end(); ++li)
+ {
+ if(*li == llang) { return; }
+ }
+
+ // Add an empty source file to the target that compiles with the
+ // linker language. This should convince Xcode to choose the proper
+ // language.
+ cmMakefile* mf = cmtarget.GetMakefile();
+ std::string fname = mf->GetCurrentOutputDirectory();
+ fname += cmake::GetCMakeFilesDirectory();
+ fname += "/";
+ fname += cmtarget.GetName();
+ fname += "-CMakeForceLinker";
+ fname += ".";
+ fname += cmSystemTools::LowerCase(llang);
+ {
+ cmGeneratedFileStream fout(fname.c_str());
+ fout << "\n";
+ }
+ if(cmSourceFile* sf = mf->GetOrCreateSource(fname.c_str()))
+ {
+ sf->SetProperty("LANGUAGE", llang);
+ cmtarget.AddSourceFile(sf);
+ }
+}
+
+//----------------------------------------------------------------------------
bool cmGlobalXCodeGenerator::IsHeaderFile(cmSourceFile* sf)
{
const std::vector<std::string>& hdrExts =
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index ba1529d..e7bb20c 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -128,6 +128,8 @@ private:
cmXCodeObject* CreateObjectReference(cmXCodeObject*);
cmXCodeObject* CreateXCodeTarget(cmTarget& target,
cmXCodeObject* buildPhases);
+ void ForceLinkerLanguages();
+ void ForceLinkerLanguage(cmTarget& cmtarget);
const char* GetTargetFileType(cmTarget& cmtarget);
const char* GetTargetProductType(cmTarget& cmtarget);
std::string AddConfigurations(cmXCodeObject* target, cmTarget& cmtarget);