Browse Source

Ninja: Copy resource files in the bundle.

This patch fixes test BundleTest on Darwin.
Nicolas Despres 13 years ago
parent
commit
10686a17f4

+ 47 - 0
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<std::string, std::set<std::string> >::iterator

+ 4 - 0
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();
 

+ 0 - 2
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)

+ 0 - 2
Source/cmNinjaNormalTargetGenerator.h

@@ -47,8 +47,6 @@ private:
   std::string TargetNameImport;
   std::string TargetNamePDB;
   const char *TargetLinkLanguage;
-  cmOSXBundleGenerator* OSXBundleGenerator;
-  std::set<cmStdString> MacContentFolders;
 };
 
 #endif // ! cmNinjaNormalTargetGenerator_h

+ 66 - 1
Source/cmNinjaTargetGenerator.cxx

@@ -22,6 +22,7 @@
 #include "cmComputeLinkInformation.h"
 #include "cmSourceFile.h"
 #include "cmCustomCommandGenerator.h"
+#include "cmOSXBundleGenerator.h"
 
 #include <algorithm>
 
@@ -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<cmLocalNinjaGenerator*>(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<cmSourceFile*>::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<cmSourceFile*> const& sources)
+{
+  for(std::vector<cmSourceFile*>::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);
+}

+ 11 - 0
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<cmSourceFile*> const& sources);
+  void WriteMacOSXContentBuildStatement(cmSourceFile& source,
+                                        const char* pkgloc);
+
+protected:
+  // Properly initialized by sub-classes.
+  cmOSXBundleGenerator* OSXBundleGenerator;
+  std::set<cmStdString> MacContentFolders;
+
 private:
   cmTarget* Target;
   cmGeneratorTarget* GeneratorTarget;