From 10686a17f4457fd6032543992538850be5cc8d88 Mon Sep 17 00:00:00 2001 From: Nicolas Despres Date: Tue, 10 Jul 2012 20:13:01 +0200 Subject: [PATCH] Ninja: Copy resource files in the bundle. This patch fixes test BundleTest on Darwin. --- Source/cmGlobalNinjaGenerator.cxx | 47 +++++++++++++++++ Source/cmGlobalNinjaGenerator.h | 4 ++ Source/cmNinjaNormalTargetGenerator.cxx | 2 - Source/cmNinjaNormalTargetGenerator.h | 2 - Source/cmNinjaTargetGenerator.cxx | 67 ++++++++++++++++++++++++- Source/cmNinjaTargetGenerator.h | 11 ++++ 6 files changed, 128 insertions(+), 5 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 07cc75f39..1bf466e03 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -252,6 +252,48 @@ cmGlobalNinjaGenerator::WriteCustomCommandBuild(const std::string& command, vars); } +void +cmGlobalNinjaGenerator::AddMacOSXContentRule() +{ + cmLocalGenerator *lg = this->LocalGenerators[0]; + cmMakefile* mfRoot = lg->GetMakefile(); + + cmOStringStream cmd; + cmd << lg->ConvertToOutputFormat( + mfRoot->GetRequiredDefinition("CMAKE_COMMAND"), + cmLocalGenerator::SHELL) + << " -E copy $in $out"; + + this->AddRule("COPY_OSX_CONTENT", + cmd.str(), + "Copying OS X Content $out", + "Rule for copying OS X bundle content file." + /*depfile*/ "", + /*rspfile*/ ""); +} + +void +cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input, + const std::string& output) +{ + this->AddMacOSXContentRule(); + + cmNinjaDeps outputs; + outputs.push_back(output); + cmNinjaDeps deps; + deps.push_back(input); + cmNinjaVars vars; + + cmGlobalNinjaGenerator::WriteBuild(*this->BuildFileStream, + "", + "COPY_OSX_CONTENT", + outputs, + deps, + cmNinjaDeps(), + cmNinjaDeps(), + cmNinjaVars()); +} + void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, const std::string& name, const std::string& command, @@ -758,6 +800,11 @@ void cmGlobalNinjaGenerator::AddDependencyToAll(cmTarget* target) this->AppendTargetOutputs(target, this->AllDependencies); } +void cmGlobalNinjaGenerator::AddDependencyToAll(const std::string& input) +{ + this->AllDependencies.push_back(input); +} + void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies() { for (std::map >::iterator diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index ff4f85d10..61353c538 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -103,6 +103,8 @@ public: const cmNinjaDeps& outputs, const cmNinjaDeps& deps = cmNinjaDeps(), const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps()); + void WriteMacOSXContentBuild(const std::string& input, + const std::string& output); /** * Write a rule statement named @a name to @a os with the @a comment, @@ -242,6 +244,7 @@ public: bool HasRule(const std::string& name); void AddCustomCommandRule(); + void AddMacOSXContentRule(); protected: @@ -276,6 +279,7 @@ private: void WriteDisclaimer(std::ostream& os); void AddDependencyToAll(cmTarget* target); + void AddDependencyToAll(const std::string& input); void WriteAssumedSourceDependencies(); diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index fecce14e7..45a4f683f 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -35,8 +35,6 @@ cmNinjaNormalTargetGenerator(cmTarget* target) , TargetNameImport() , TargetNamePDB() , TargetLinkLanguage(0) - , OSXBundleGenerator(0) - , MacContentFolders() { this->TargetLinkLanguage = target->GetLinkerLanguage(this->GetConfigName()); if (target->GetType() == cmTarget::EXECUTABLE) diff --git a/Source/cmNinjaNormalTargetGenerator.h b/Source/cmNinjaNormalTargetGenerator.h index fb597c5a2..284804b08 100644 --- a/Source/cmNinjaNormalTargetGenerator.h +++ b/Source/cmNinjaNormalTargetGenerator.h @@ -47,8 +47,6 @@ private: std::string TargetNameImport; std::string TargetNamePDB; const char *TargetLinkLanguage; - cmOSXBundleGenerator* OSXBundleGenerator; - std::set MacContentFolders; }; #endif // ! cmNinjaNormalTargetGenerator_h diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 475898956..f71cc6034 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -22,6 +22,7 @@ #include "cmComputeLinkInformation.h" #include "cmSourceFile.h" #include "cmCustomCommandGenerator.h" +#include "cmOSXBundleGenerator.h" #include @@ -56,7 +57,10 @@ cmNinjaTargetGenerator::New(cmTarget* target) } cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target) - : Target(target), + : + OSXBundleGenerator(0), + MacContentFolders(), + Target(target), Makefile(target->GetMakefile()), LocalGenerator( static_cast(Makefile->GetLocalGenerator())), @@ -428,6 +432,9 @@ cmNinjaTargetGenerator cmCustomCommand const* cc = (*si)->GetCustomCommand(); this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget()); } + this->WriteMacOSXContentBuildStatements( + this->GeneratorTarget->HeaderSources); + this->WriteMacOSXContentBuildStatements(this->GeneratorTarget->ExtraSources); for(std::vector::const_iterator si = this->GeneratorTarget->ExternalObjects.begin(); si != this->GeneratorTarget->ExternalObjects.end(); ++si) @@ -634,3 +641,61 @@ cmNinjaTargetGenerator { EnsureDirectoryExists(cmSystemTools::GetParentDirectory(path.c_str())); } + +//---------------------------------------------------------------------------- +// TODO: Re-factor with cmMakefileTargetGenerator::WriteMacOSXContentRules +void cmNinjaTargetGenerator::WriteMacOSXContentBuildStatements( + std::vector const& sources) +{ + for(std::vector::const_iterator + si = sources.begin(); si != sources.end(); ++si) + { + cmTarget::SourceFileFlags tsFlags = + this->Target->GetTargetSourceFileFlags(*si); + if(tsFlags.Type != cmTarget::SourceFileTypeNormal) + { + this->WriteMacOSXContentBuildStatement(**si, tsFlags.MacFolder); + } + } +} + +//---------------------------------------------------------------------------- +// TODO: Re-factor with cmMakefileTargetGenerator::WriteMacOSXContentRules +void cmNinjaTargetGenerator::WriteMacOSXContentBuildStatement( + cmSourceFile& source, const char* pkgloc) +{ + // Skip OS X content when not building a Framework or Bundle. + if(this->OSXBundleGenerator->GetMacContentDirectory().empty()) + { + return; + } + + // Construct the full path to the content subdirectory. + std::string macdir = this->OSXBundleGenerator->GetMacContentDirectory(); + macdir += pkgloc; + cmSystemTools::MakeDirectory(macdir.c_str()); + + // Record use of this content location. Only the first level + // directory is needed. + { + std::string loc = pkgloc; + loc = loc.substr(0, loc.find('/')); + this->MacContentFolders.insert(loc); + } + + // Get the input file location. + std::string input = source.GetFullPath(); + input = this->GetLocalGenerator()->ConvertToNinjaPath(input.c_str()); + + // Get the output file location. + std::string output = macdir; + output += "/"; + output += cmSystemTools::GetFilenameName(input); + output = this->GetLocalGenerator()->ConvertToNinjaPath(output.c_str()); + + // Write a build statement to copy the content into the bundle. + this->GetGlobalGenerator()->WriteMacOSXContentBuild(input, output); + + // Add as a dependency of all target so that it gets called. + this->GetGlobalGenerator()->AddDependencyToAll(output); +} diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h index af43a8b38..49168c4f3 100644 --- a/Source/cmNinjaTargetGenerator.h +++ b/Source/cmNinjaTargetGenerator.h @@ -24,6 +24,7 @@ class cmGeneratorTarget; class cmMakefile; class cmSourceFile; class cmCustomCommand; +class cmOSXBundleGenerator; class cmNinjaTargetGenerator { @@ -114,6 +115,16 @@ protected: void EnsureDirectoryExists(const std::string& dir); void EnsureParentDirectoryExists(const std::string& path); + void WriteMacOSXContentBuildStatements( + std::vector const& sources); + void WriteMacOSXContentBuildStatement(cmSourceFile& source, + const char* pkgloc); + +protected: + // Properly initialized by sub-classes. + cmOSXBundleGenerator* OSXBundleGenerator; + std::set MacContentFolders; + private: cmTarget* Target; cmGeneratorTarget* GeneratorTarget;