diff options
-rw-r--r-- | Source/cmGlobalGenerator.h | 6 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.cxx | 57 | ||||
-rw-r--r-- | Source/cmGlobalXCodeGenerator.h | 2 |
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); |