From 5d885db416a4cec236ba6422868dc3db3d766bc4 Mon Sep 17 00:00:00 2001
From: Nicolas Despres <nicolas.despres@gmail.com>
Date: Mon, 16 Jul 2012 17:34:22 +0200
Subject: Re-factor bundle content copying rules generation.

---
 Source/cmMakefileExecutableTargetGenerator.cxx |  5 +-
 Source/cmMakefileExecutableTargetGenerator.h   |  5 --
 Source/cmMakefileLibraryTargetGenerator.cxx    |  4 +-
 Source/cmMakefileLibraryTargetGenerator.h      |  5 --
 Source/cmMakefileTargetGenerator.cxx           | 72 +++++++++++++-------------
 Source/cmMakefileTargetGenerator.h             | 16 +++++-
 Source/cmMakefileUtilityTargetGenerator.cxx    |  6 +++
 Source/cmNinjaTargetGenerator.cxx              | 50 +++++++++---------
 Source/cmNinjaTargetGenerator.h                | 19 +++++--
 Source/cmOSXBundleGenerator.cxx                | 18 +++++++
 Source/cmOSXBundleGenerator.h                  | 11 ++++
 11 files changed, 127 insertions(+), 84 deletions(-)

diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index d9ab334..ab5150a 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -18,13 +18,11 @@
 #include "cmSourceFile.h"
 #include "cmTarget.h"
 #include "cmake.h"
-#include "cmOSXBundleGenerator.h"
 
 //----------------------------------------------------------------------------
 cmMakefileExecutableTargetGenerator
 ::cmMakefileExecutableTargetGenerator(cmTarget* target):
-  cmMakefileTargetGenerator(target),
-  OSXBundleGenerator(0)
+  cmMakefileTargetGenerator(target)
 {
   this->CustomCommandDriver = OnDepends;
   this->Target->GetExecutableNames(
@@ -34,6 +32,7 @@ cmMakefileExecutableTargetGenerator
   this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
                                                       this->TargetNameOut,
                                                       this->ConfigName);
+  this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
   this->MacContentDirectory =
     this->OSXBundleGenerator->GetMacContentDirectory();
 }
diff --git a/Source/cmMakefileExecutableTargetGenerator.h b/Source/cmMakefileExecutableTargetGenerator.h
index 26dc72f..3b18166 100644
--- a/Source/cmMakefileExecutableTargetGenerator.h
+++ b/Source/cmMakefileExecutableTargetGenerator.h
@@ -14,8 +14,6 @@
 
 #include "cmMakefileTargetGenerator.h"
 
-class cmOSXBundleGenerator;
-
 class cmMakefileExecutableTargetGenerator: public cmMakefileTargetGenerator
 {
 public:
@@ -28,9 +26,6 @@ public:
 
 protected:
   virtual void WriteExecutableRule(bool relink);
-
-private:
-  cmOSXBundleGenerator* OSXBundleGenerator;
 };
 
 #endif
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index a655504..577e5fd 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -18,15 +18,13 @@
 #include "cmSourceFile.h"
 #include "cmTarget.h"
 #include "cmake.h"
-#include "cmOSXBundleGenerator.h"
 
 #include <memory> // auto_ptr
 
 //----------------------------------------------------------------------------
 cmMakefileLibraryTargetGenerator
 ::cmMakefileLibraryTargetGenerator(cmTarget* target):
-  cmMakefileTargetGenerator(target),
-  OSXBundleGenerator(0)
+  cmMakefileTargetGenerator(target)
 {
   cmOSXBundleGenerator::PrepareTargetProperties(this->Target);
 
diff --git a/Source/cmMakefileLibraryTargetGenerator.h b/Source/cmMakefileLibraryTargetGenerator.h
index ee56f6c..07f828b 100644
--- a/Source/cmMakefileLibraryTargetGenerator.h
+++ b/Source/cmMakefileLibraryTargetGenerator.h
@@ -14,8 +14,6 @@
 
 #include "cmMakefileTargetGenerator.h"
 
-class cmOSXBundleGenerator;
-
 class cmMakefileLibraryTargetGenerator:
   public cmMakefileTargetGenerator
 {
@@ -42,9 +40,6 @@ protected:
 
   void AppendOSXVerFlag(std::string& flags, const char* lang,
                         const char* name, bool so);
-
-private:
-  cmOSXBundleGenerator* OSXBundleGenerator;
 };
 
 #endif
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 16e3e02..342fa49 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -28,6 +28,8 @@
 
 
 cmMakefileTargetGenerator::cmMakefileTargetGenerator(cmTarget* target)
+  : OSXBundleGenerator(0)
+  , MacOSXContentGenerator(this)
 {
   this->BuildFileStream = 0;
   this->InfoFileStream = 0;
@@ -153,8 +155,12 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
         }
       }
     }
-  this->WriteMacOSXContentRules(this->GeneratorTarget->HeaderSources);
-  this->WriteMacOSXContentRules(this->GeneratorTarget->ExtraSources);
+  this->OSXBundleGenerator->GenerateMacOSXContentStatements(
+    this->GeneratorTarget->HeaderSources,
+    &this->MacOSXContentGenerator);
+  this->OSXBundleGenerator->GenerateMacOSXContentStatements(
+    this->GeneratorTarget->ExtraSources,
+    &this->MacOSXContentGenerator);
   for(std::vector<cmSourceFile*>::const_iterator
         si = this->GeneratorTarget->ExternalObjects.begin();
       si != this->GeneratorTarget->ExternalObjects.end(); ++si)
@@ -173,7 +179,6 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
   this->GeneratorTarget->UseObjectLibraries(this->ExternalObjects);
 }
 
-
 //----------------------------------------------------------------------------
 void cmMakefileTargetGenerator::WriteCommonCodeRules()
 {
@@ -344,33 +349,26 @@ void cmMakefileTargetGenerator::WriteTargetLanguageFlags()
 }
 
 //----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::WriteMacOSXContentRules(
-  std::vector<cmSourceFile*> const& sources)
+cmMakefileTargetGenerator::MacOSXContentGeneratorType::
+MacOSXContentGeneratorType(cmMakefileTargetGenerator* generator)
+  : cmOSXBundleGenerator::MacOSXContentGeneratorType()
+  , Generator(generator)
 {
-  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->WriteMacOSXContentRules(**si, tsFlags.MacFolder);
-      }
-    }
 }
 
 //----------------------------------------------------------------------------
-void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
-                                                        const char* pkgloc)
+void
+cmMakefileTargetGenerator::MacOSXContentGeneratorType::operator()
+  (cmSourceFile& source, const char* pkgloc)
 {
   // Skip OS X content when not building a Framework or Bundle.
-  if(this->MacContentDirectory.empty())
+  if(this->Generator->MacContentDirectory.empty())
     {
     return;
     }
 
   // Construct the full path to the content subdirectory.
-  std::string macdir = this->MacContentDirectory;
+  std::string macdir = this->Generator->MacContentDirectory;
   macdir += pkgloc;
   cmSystemTools::MakeDirectory(macdir.c_str());
 
@@ -379,7 +377,7 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
   {
   std::string loc = pkgloc;
   loc = loc.substr(0, loc.find('/'));
-  this->MacContentFolders.insert(loc);
+  this->Generator->MacContentFolders.insert(loc);
   }
 
   // Get the input file location.
@@ -389,9 +387,11 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
   std::string output = macdir;
   output += "/";
   output += cmSystemTools::GetFilenameName(input);
-  this->CleanFiles.push_back(this->Convert(output.c_str(),
-                                           cmLocalGenerator::START_OUTPUT));
-  output = this->Convert(output.c_str(), cmLocalGenerator::HOME_OUTPUT);
+  this->Generator->CleanFiles.push_back(
+    this->Generator->Convert(output.c_str(),
+                             cmLocalGenerator::START_OUTPUT));
+  output = this->Generator->Convert(output.c_str(),
+                                    cmLocalGenerator::HOME_OUTPUT);
 
   // Create a rule to copy the content into the bundle.
   std::vector<std::string> depends;
@@ -399,21 +399,23 @@ void cmMakefileTargetGenerator::WriteMacOSXContentRules(cmSourceFile& source,
   depends.push_back(input);
   std::string copyEcho = "Copying OS X content ";
   copyEcho += output;
-  this->LocalGenerator->AppendEcho(commands, copyEcho.c_str(),
-                                   cmLocalUnixMakefileGenerator3::EchoBuild);
+  this->Generator->LocalGenerator->AppendEcho(
+    commands, copyEcho.c_str(),
+    cmLocalUnixMakefileGenerator3::EchoBuild);
   std::string copyCommand = "$(CMAKE_COMMAND) -E copy ";
-  copyCommand += this->Convert(input.c_str(),
-                               cmLocalGenerator::NONE,
-                               cmLocalGenerator::SHELL);
+  copyCommand += this->Generator->Convert(input.c_str(),
+                                          cmLocalGenerator::NONE,
+                                          cmLocalGenerator::SHELL);
   copyCommand += " ";
-  copyCommand += this->Convert(output.c_str(),
-                               cmLocalGenerator::NONE,
-                               cmLocalGenerator::SHELL);
+  copyCommand += this->Generator->Convert(output.c_str(),
+                                          cmLocalGenerator::NONE,
+                                          cmLocalGenerator::SHELL);
   commands.push_back(copyCommand);
-  this->LocalGenerator->WriteMakeRule(*this->BuildFileStream, 0,
-                                      output.c_str(),
-                                      depends, commands, false);
-  this->ExtraFiles.insert(output);
+  this->Generator->LocalGenerator->WriteMakeRule(
+    *this->Generator->BuildFileStream, 0,
+    output.c_str(),
+    depends, commands, false);
+  this->Generator->ExtraFiles.insert(output);
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index 36a1f68..d5eb634 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -13,6 +13,7 @@
 #define cmMakefileTargetGenerator_h
 
 #include "cmLocalUnixMakefileGenerator3.h"
+#include "cmOSXBundleGenerator.h"
 
 class cmCustomCommand;
 class cmDependInformation;
@@ -73,8 +74,17 @@ protected:
   void WriteTargetDependRules();
 
   // write rules for Mac OS X Application Bundle content.
-  void WriteMacOSXContentRules(std::vector<cmSourceFile*> const& sources);
-  void WriteMacOSXContentRules(cmSourceFile& source, const char* pkgloc);
+  class MacOSXContentGeneratorType
+    : public cmOSXBundleGenerator::MacOSXContentGeneratorType
+  {
+  public:
+    MacOSXContentGeneratorType(cmMakefileTargetGenerator* Generator);
+    virtual void operator()(cmSourceFile& source, const char* pkgloc);
+
+  private:
+    cmMakefileTargetGenerator* Generator;
+  };
+  friend class MacOSXContentGeneratorType;
 
   // write the rules for an object
   void WriteObjectRuleFiles(cmSourceFile& source);
@@ -223,6 +233,8 @@ protected:
   // Mac OS X content info.
   std::string MacContentDirectory;
   std::set<cmStdString> MacContentFolders;
+  cmOSXBundleGenerator* OSXBundleGenerator;
+  MacOSXContentGeneratorType MacOSXContentGenerator;
 
   typedef std::map<cmStdString, cmStdString> ByLanguageMap;
   std::string GetFlags(const std::string &l);
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index a82c503..e8afd45 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -24,6 +24,12 @@ cmMakefileUtilityTargetGenerator
   cmMakefileTargetGenerator(target)
 {
   this->CustomCommandDriver = OnUtility;
+  this->OSXBundleGenerator = new cmOSXBundleGenerator(this->Target,
+                                                      this->TargetNameOut,
+                                                      this->ConfigName);
+  this->OSXBundleGenerator->SetMacContentFolders(&this->MacContentFolders);
+  this->MacContentDirectory =
+    this->OSXBundleGenerator->GetMacContentDirectory();
 }
 
 //----------------------------------------------------------------------------
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index f71cc60..2c7bffc 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -22,7 +22,6 @@
 #include "cmComputeLinkInformation.h"
 #include "cmSourceFile.h"
 #include "cmCustomCommandGenerator.h"
-#include "cmOSXBundleGenerator.h"
 
 #include <algorithm>
 
@@ -58,6 +57,7 @@ cmNinjaTargetGenerator::New(cmTarget* target)
 
 cmNinjaTargetGenerator::cmNinjaTargetGenerator(cmTarget* target)
   :
+    MacOSXContentGenerator(this),
     OSXBundleGenerator(0),
     MacContentFolders(),
     Target(target),
@@ -432,9 +432,12 @@ cmNinjaTargetGenerator
      cmCustomCommand const* cc = (*si)->GetCustomCommand();
      this->GetLocalGenerator()->AddCustomCommandTarget(cc, this->GetTarget());
      }
-  this->WriteMacOSXContentBuildStatements(
-    this->GeneratorTarget->HeaderSources);
-  this->WriteMacOSXContentBuildStatements(this->GeneratorTarget->ExtraSources);
+  this->OSXBundleGenerator->GenerateMacOSXContentStatements(
+    this->GeneratorTarget->HeaderSources,
+    &this->MacOSXContentGenerator);
+  this->OSXBundleGenerator->GenerateMacOSXContentStatements(
+    this->GeneratorTarget->ExtraSources,
+    &this->MacOSXContentGenerator);
   for(std::vector<cmSourceFile*>::const_iterator
         si = this->GeneratorTarget->ExternalObjects.begin();
       si != this->GeneratorTarget->ExternalObjects.end(); ++si)
@@ -643,35 +646,27 @@ cmNinjaTargetGenerator
 }
 
 //----------------------------------------------------------------------------
-// TODO: Re-factor with cmMakefileTargetGenerator::WriteMacOSXContentRules
-void cmNinjaTargetGenerator::WriteMacOSXContentBuildStatements(
-  std::vector<cmSourceFile*> const& sources)
+cmNinjaTargetGenerator::MacOSXContentGeneratorType::
+MacOSXContentGeneratorType(cmNinjaTargetGenerator* generator)
+  : cmOSXBundleGenerator::MacOSXContentGeneratorType()
+  , Generator(generator)
 {
-  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(
+void
+cmNinjaTargetGenerator::MacOSXContentGeneratorType::operator()(
   cmSourceFile& source, const char* pkgloc)
 {
   // Skip OS X content when not building a Framework or Bundle.
-  if(this->OSXBundleGenerator->GetMacContentDirectory().empty())
+  if(this->Generator->OSXBundleGenerator->GetMacContentDirectory().empty())
     {
     return;
     }
 
   // Construct the full path to the content subdirectory.
-  std::string macdir = this->OSXBundleGenerator->GetMacContentDirectory();
+  std::string macdir =
+    this->Generator->OSXBundleGenerator->GetMacContentDirectory();
   macdir += pkgloc;
   cmSystemTools::MakeDirectory(macdir.c_str());
 
@@ -680,22 +675,25 @@ void cmNinjaTargetGenerator::WriteMacOSXContentBuildStatement(
   {
   std::string loc = pkgloc;
   loc = loc.substr(0, loc.find('/'));
-  this->MacContentFolders.insert(loc);
+  this->Generator->MacContentFolders.insert(loc);
   }
 
   // Get the input file location.
   std::string input = source.GetFullPath();
-  input = this->GetLocalGenerator()->ConvertToNinjaPath(input.c_str());
+  input =
+    this->Generator->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());
+  output =
+    this->Generator->GetLocalGenerator()->ConvertToNinjaPath(output.c_str());
 
   // Write a build statement to copy the content into the bundle.
-  this->GetGlobalGenerator()->WriteMacOSXContentBuild(input, output);
+  this->Generator->GetGlobalGenerator()->WriteMacOSXContentBuild(input,
+                                                                 output);
 
   // Add as a dependency of all target so that it gets called.
-  this->GetGlobalGenerator()->AddDependencyToAll(output);
+  this->Generator->GetGlobalGenerator()->AddDependencyToAll(output);
 }
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 49168c4..0a3329f 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -16,6 +16,7 @@
 #include "cmStandardIncludes.h"
 #include "cmNinjaTypes.h"
 #include "cmLocalNinjaGenerator.h"
+#include "cmOSXBundleGenerator.h"
 
 class cmTarget;
 class cmGlobalNinjaGenerator;
@@ -24,7 +25,6 @@ class cmGeneratorTarget;
 class cmMakefile;
 class cmSourceFile;
 class cmCustomCommand;
-class cmOSXBundleGenerator;
 
 class cmNinjaTargetGenerator
 {
@@ -115,12 +115,21 @@ 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);
+  // write rules for Mac OS X Application Bundle content.
+  class MacOSXContentGeneratorType
+    : public cmOSXBundleGenerator::MacOSXContentGeneratorType
+  {
+  public:
+    MacOSXContentGeneratorType(cmNinjaTargetGenerator* Generator);
+    virtual void operator()(cmSourceFile& source, const char* pkgloc);
+
+  private:
+    cmNinjaTargetGenerator* Generator;
+  };
+  friend class MacOSXContentGeneratorType;
 
 protected:
+  MacOSXContentGeneratorType MacOSXContentGenerator;
   // Properly initialized by sub-classes.
   cmOSXBundleGenerator* OSXBundleGenerator;
   std::set<cmStdString> MacContentFolders;
diff --git a/Source/cmOSXBundleGenerator.cxx b/Source/cmOSXBundleGenerator.cxx
index b3210eb..8788d42 100644
--- a/Source/cmOSXBundleGenerator.cxx
+++ b/Source/cmOSXBundleGenerator.cxx
@@ -200,3 +200,21 @@ void cmOSXBundleGenerator::CreateCFBundle(std::string& targetName,
                                                plist.c_str());
   this->Makefile->AddCMakeOutputFile(plist.c_str());
 }
+
+//----------------------------------------------------------------------------
+void
+cmOSXBundleGenerator::
+GenerateMacOSXContentStatements(std::vector<cmSourceFile*> const& sources,
+                                MacOSXContentGeneratorType* generator)
+{
+  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)
+      {
+      (*generator)(**si, tsFlags.MacFolder);
+      }
+    }
+}
diff --git a/Source/cmOSXBundleGenerator.h b/Source/cmOSXBundleGenerator.h
index 38092b9..dc6a8ae 100644
--- a/Source/cmOSXBundleGenerator.h
+++ b/Source/cmOSXBundleGenerator.h
@@ -13,6 +13,7 @@
 #define cmOSXBundleGenerator_h
 
 #include "cmStandardIncludes.h"
+#include "cmSourceFile.h"
 
 #include <string>
 #include <set>
@@ -34,6 +35,16 @@ public:
   void CreateFramework(std::string const& targetName);
   void CreateCFBundle(std::string& targetName, std::string& outpath);
 
+  class MacOSXContentGeneratorType
+  {
+  public:
+    virtual void operator()(cmSourceFile& source, const char* pkgloc) = 0;
+  };
+
+  void GenerateMacOSXContentStatements(
+    std::vector<cmSourceFile*> const& sources,
+    MacOSXContentGeneratorType* generator);
+
   std::string GetMacContentDirectory() const
   { return this->MacContentDirectory; }
   std::string GetFrameworkVersion() const
-- 
cgit v0.12