[Cmake-commits] CMake branch, next, updated. v3.2.1-1203-g0437c47

Brad King brad.king at kitware.com
Tue Mar 24 11:49:48 EDT 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  0437c473420f10b06488bf3d786c4c48b312d0f3 (commit)
       via  ed1ee3d43992ef0b1512dcca2beb5add480580c5 (commit)
       via  52a7d6a8b1923ce08472a4f6ad9c7640fe4554a9 (commit)
       via  3fbaa3720dd024e653b654cd0d081f76da95f4f7 (commit)
       via  ad69c815edf7f6b70b2e8a872d0968ec99aad988 (commit)
       via  590e0eb516f716a7e9beea17203fa462de6dfe5a (commit)
       via  1128a5f75d39fcf7c629d9367595e1812f7a1e75 (commit)
      from  febdd93da4e12087157861cbf74f929a714e0b46 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0437c473420f10b06488bf3d786c4c48b312d0f3
commit 0437c473420f10b06488bf3d786c4c48b312d0f3
Merge: febdd93 ed1ee3d
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Mar 24 11:49:47 2015 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue Mar 24 11:49:47 2015 -0400

    Merge topic 'add-GreenHills-MULTI-generator' into next
    
    ed1ee3d4 GHS: Drop unused method argument
    52a7d6a8 GHS: Cleanup file streams as soon as we are done with them
    3fbaa372 GHS: Fix global generator constructor
    ad69c815 GHS: Wrap long lines in source
    590e0eb5 Help: Revise CMAKE_MAKE_PROGRAM documentation for GHS
    1128a5f7 Add a 'Green Hills MULTI' generator


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ed1ee3d43992ef0b1512dcca2beb5add480580c5
commit ed1ee3d43992ef0b1512dcca2beb5add480580c5
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Mar 24 11:28:25 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Mar 24 11:31:38 2015 -0400

    GHS: Drop unused method argument

diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index d8cbb69..042339a 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -174,8 +174,7 @@ void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
   *filestream << "#!gbuild" << std::endl;
 }
 
-void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
-    cmMakefile *const makefile) {
+void cmGlobalGhsMultiGenerator::OpenBuildFileStream() {
   // Compute GHS MULTI's build file path.
   std::string buildFilePath =
       this->GetCMakeInstance()->GetHomeOutputDirectory();
@@ -238,8 +237,7 @@ void cmGlobalGhsMultiGenerator::Generate() {
   this->cmGlobalGenerator::Generate();
 
   if (this->LocalGenerators.size() > 0) {
-    cmLocalGenerator *sampLG = this->LocalGenerators[0];
-    this->OpenBuildFileStream(sampLG->GetMakefile());
+    this->OpenBuildFileStream();
 
     // Build all the folder build files
     for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index 9aff8e7..78a7736 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -93,7 +93,7 @@ private:
   std::string GetCompRoot();
   std::vector<std::string> GetCompRootHardPaths();
   std::vector<std::string> GetCompRootRegistry();
-  void OpenBuildFileStream(cmMakefile *makefile);
+  void OpenBuildFileStream();
 
   void WriteMacros();
   void WriteHighLevelDirectives();

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=52a7d6a8b1923ce08472a4f6ad9c7640fe4554a9
commit 52a7d6a8b1923ce08472a4f6ad9c7640fe4554a9
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Mar 24 10:54:50 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Mar 24 10:57:00 2015 -0400

    GHS: Cleanup file streams as soon as we are done with them

diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 85b3aaf..d8cbb69 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -249,6 +249,9 @@ void cmGlobalGhsMultiGenerator::Generate() {
       UpdateBuildFiles(tgts);
     }
   }
+
+  cmDeleteAll(TargetFolderBuildStreams);
+  this->TargetFolderBuildStreams.clear();
 }
 
 void cmGlobalGhsMultiGenerator::GenerateBuildCommand(

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3fbaa3720dd024e653b654cd0d081f76da95f4f7
commit 3fbaa3720dd024e653b654cd0d081f76da95f4f7
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Mar 24 10:51:12 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Mar 24 10:56:59 2015 -0400

    GHS: Fix global generator constructor
    
    We have no module to find the make program.
    
    Add missing member initializer.

diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index 2410d76..85b3aaf 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -21,7 +21,7 @@
 const char *cmGlobalGhsMultiGenerator::FILE_EXTENSION = ".gpj";
 
 cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator() : OSDirRelative(false) {
-  this->FindMakeProgramFile = "CMakeGreenHillsFindMake.cmake";
+  this->GhsBuildCommandInitialized = false;
 }
 
 cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator() {

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ad69c815edf7f6b70b2e8a872d0968ec99aad988
commit ad69c815edf7f6b70b2e8a872d0968ec99aad988
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Mar 24 10:50:51 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Mar 24 10:56:59 2015 -0400

    GHS: Wrap long lines in source

diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index e242cc0..648751f 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -354,7 +354,8 @@ void cmGhsMultiTargetGenerator::WriteObjectDir(
 }
 
 std::string
-cmGhsMultiTargetGenerator::GetOutputDirectory(const std::string &config) const {
+cmGhsMultiTargetGenerator
+::GetOutputDirectory(const std::string &config) const {
   std::string outputDir(AbsBuildFilePath);
 
   const char *runtimeOutputProp =
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
index 7822fab..0e61193 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -38,7 +38,7 @@ public:
   const char *GetAbsBuildFilePath() const { return AbsBuildFilePath.c_str(); }
   const char *GetRelBuildFileName() const { return RelBuildFileName.c_str(); }
   const char *GetAbsBuildFileName() const { return AbsBuildFileName.c_str(); }
-  const char *GetAbsOutputFileName() const { return AbsOutputFileName.c_str(); }
+  const char *GetAbsOutputFileName() const {return AbsOutputFileName.c_str();}
 
 private:
   cmGlobalGhsMultiGenerator *GetGlobalGenerator() const;
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index d66d0d7..2410d76 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -78,7 +78,8 @@ void cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile *mf) {
   // directly instead of needing a helper module to do it, so we
   // do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
   if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
-    mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetGhsBuildCommand().c_str());
+    mf->AddDefinition("CMAKE_MAKE_PROGRAM",
+                      this->GetGhsBuildCommand().c_str());
   }
 }
 
@@ -101,7 +102,8 @@ std::string cmGlobalGhsMultiGenerator::FindGhsBuildCommand() {
 std::string cmGlobalGhsMultiGenerator::GetCompRoot() {
   std::string output;
 
-  const std::vector<std::string> potentialDirsHardPaths(GetCompRootHardPaths());
+  const std::vector<std::string>
+    potentialDirsHardPaths(GetCompRootHardPaths());
   const std::vector<std::string> potentialDirsRegistry(GetCompRootRegistry());
 
   std::vector<std::string> potentialDirsComplete;
@@ -143,14 +145,14 @@ std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootRegistry() {
   std::vector<std::string> output(2);
   cmsys::SystemTools::ReadRegistryValue(
       "HKEY_LOCAL_"
-      "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Unin"
-      "stall\\"
+      "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
+      "Windows\\CurrentVersion\\Uninstall\\"
       "GreenHillsSoftwared771f1b4;InstallLocation",
       output[0]);
   cmsys::SystemTools::ReadRegistryValue(
       "HKEY_LOCAL_"
-      "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Unin"
-      "stall\\"
+      "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
+      "Windows\\CurrentVersion\\Uninstall\\"
       "GreenHillsSoftware9881cef6;InstallLocation",
       output[1]);
   return output;
@@ -257,7 +259,8 @@ void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
     std::vector<std::string> const &makeOptions) {
   makeCommand.push_back(this->SelectMakeProgram(makeProgram));
 
-  makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeOptions.end());
+  makeCommand.insert(makeCommand.end(),
+                     makeOptions.begin(), makeOptions.end());
   if (!targetName.empty()) {
     if (targetName == "clean") {
       makeCommand.push_back("-clean");
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
index c7b5196..9aff8e7 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -82,9 +82,10 @@ protected:
   virtual void GenerateBuildCommand(
       std::vector<std::string> &makeCommand, const std::string &makeProgram,
       const std::string &projectName, const std::string &projectDir,
-      const std::string &targetName, const std::string &config, bool fast,
-      bool verbose,
-      std::vector<std::string> const &makeOptions = std::vector<std::string>());
+      const std::string &targetName, const std::string &config,
+      bool fast, bool verbose,
+      std::vector<std::string> const &makeOptions =
+      std::vector<std::string>());
 
 private:
   std::string const &GetGhsBuildCommand();

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=590e0eb516f716a7e9beea17203fa462de6dfe5a
commit 590e0eb516f716a7e9beea17203fa462de6dfe5a
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue Mar 24 10:50:16 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Mar 24 10:56:59 2015 -0400

    Help: Revise CMAKE_MAKE_PROGRAM documentation for GHS

diff --git a/Help/variable/CMAKE_MAKE_PROGRAM.rst b/Help/variable/CMAKE_MAKE_PROGRAM.rst
index 1cc22b5..85b098b 100644
--- a/Help/variable/CMAKE_MAKE_PROGRAM.rst
+++ b/Help/variable/CMAKE_MAKE_PROGRAM.rst
@@ -8,8 +8,6 @@ name if it is expected to be in the ``PATH``.
 The tool selected depends on the :variable:`CMAKE_GENERATOR` used
 to configure the project:
 
-* The Green Hills MULTI generator sets this to ``GHS-MULTI``
-
 * The Makefile generators set this to ``make``, ``gmake``, or
   a generator-specific tool (e.g. ``nmake`` for "NMake Makefiles").
 
@@ -58,6 +56,10 @@ to configure the project:
   the CMake cache then CMake will use the specified value if
   possible.
 
+* The :generator:`Green Hills MULTI` generator sets this to ``gbuild``.
+  If a user or project explicitly adds ``CMAKE_MAKE_PROGRAM`` to
+  the CMake cache then CMake will use the specified value.
+
 The ``CMAKE_MAKE_PROGRAM`` variable is set for use by project code.
 The value is also used by the :manual:`cmake(1)` ``--build`` and
 :manual:`ctest(1)` ``--build-and-test`` tools to launch the native

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1128a5f75d39fcf7c629d9367595e1812f7a1e75
commit 1128a5f75d39fcf7c629d9367595e1812f7a1e75
Author:     Geoff Viola <geoffrey.viola at asirobots.com>
AuthorDate: Mon Mar 23 23:12:55 2015 -0600
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue Mar 24 10:56:59 2015 -0400

    Add a 'Green Hills MULTI' generator

diff --git a/Help/generator/Green Hills MULTI.rst b/Help/generator/Green Hills MULTI.rst
new file mode 100644
index 0000000..79695f1
--- /dev/null
+++ b/Help/generator/Green Hills MULTI.rst	
@@ -0,0 +1,11 @@
+Green Hills MULTI
+-----------------
+
+Generates Green Hills MULTI project files.
+
+Customizations are available through the following cache variables:
+
+* ``GHS_BSP_NAME``
+* ``GHS_CUSTOMIZATION``
+* ``GHS_GPJ_MACROS``
+* ``GHS_OS_DIR``
diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst
index 804229b..ce9f5c8 100644
--- a/Help/manual/cmake-generators.7.rst
+++ b/Help/manual/cmake-generators.7.rst
@@ -56,6 +56,7 @@ one may launch CMake from any environment.
 .. toctree::
    :maxdepth: 1
 
+   /generator/Green Hills MULTI
    /generator/Visual Studio 6
    /generator/Visual Studio 7
    /generator/Visual Studio 7 .NET 2003
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index c342dbe..5282872 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -181,6 +181,7 @@ Variables that Describe the System
    /variable/CMAKE_SYSTEM_VERSION
    /variable/CYGWIN
    /variable/ENV
+   /variable/GHS-MULTI
    /variable/MINGW
    /variable/MSVC10
    /variable/MSVC11
diff --git a/Help/variable/CMAKE_MAKE_PROGRAM.rst b/Help/variable/CMAKE_MAKE_PROGRAM.rst
index f1d88a5..1cc22b5 100644
--- a/Help/variable/CMAKE_MAKE_PROGRAM.rst
+++ b/Help/variable/CMAKE_MAKE_PROGRAM.rst
@@ -8,6 +8,8 @@ name if it is expected to be in the ``PATH``.
 The tool selected depends on the :variable:`CMAKE_GENERATOR` used
 to configure the project:
 
+* The Green Hills MULTI generator sets this to ``GHS-MULTI``
+
 * The Makefile generators set this to ``make``, ``gmake``, or
   a generator-specific tool (e.g. ``nmake`` for "NMake Makefiles").
 
diff --git a/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst b/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst
index 8ad89f1..2f5313b 100644
--- a/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst
+++ b/Help/variable/CMAKE_SYSTEM_PROCESSOR.rst
@@ -6,3 +6,5 @@ The name of the CPU CMake is building for.
 This variable is the same as :variable:`CMAKE_HOST_SYSTEM_PROCESSOR` if
 you build for the host system instead of the target system when
 cross compiling.
+
+* The Green Hills MULTI generator sets this to ``ARM`` by default
diff --git a/Help/variable/GHS-MULTI.rst b/Help/variable/GHS-MULTI.rst
new file mode 100644
index 0000000..0f91be8
--- /dev/null
+++ b/Help/variable/GHS-MULTI.rst
@@ -0,0 +1,4 @@
+GHS-MULTI
+---------
+
+True when using Green Hills MULTI
diff --git a/Modules/Compiler/GHS-DetermineCompiler.cmake b/Modules/Compiler/GHS-DetermineCompiler.cmake
new file mode 100644
index 0000000..56d24e2
--- /dev/null
+++ b/Modules/Compiler/GHS-DetermineCompiler.cmake
@@ -0,0 +1,6 @@
+set(_compiler_id_pp_test "defined(__INTEGRITY)")
+
+set(_compiler_id_version_compute "
+# define @PREFIX at COMPILER_VERSION_MAJOR @MACRO_DEC@(__INTEGRITY_MAJOR_VERSION)
+# define @PREFIX at COMPILER_VERSION_MINOR @MACRO_DEC@(__INTEGRITY_MINOR_VERSION)
+# define @PREFIX at COMPILER_VERSION_PATCH @MACRO_DEC@(__INTEGRITY_PATCH_VERSION)")
diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 466090b..c844aed 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -405,6 +405,8 @@ function(_Boost_GUESS_COMPILER_PREFIX _ret)
     else()
       set (_boost_COMPILER "-il")
     endif()
+  elseif (GHSMULTI)
+    set(_boost_COMPILER "-ghs")
   elseif (MSVC14)
     set(_boost_COMPILER "-vc140")
   elseif (MSVC12)
@@ -777,7 +779,8 @@ endif()
 # ------------------------------------------------------------------------
 
 set(Boost_LIB_PREFIX "")
-if ( WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN)
+if ( (GHSMULTI AND Boost_USE_STATIC_LIBS) OR
+    (WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN) )
   set(Boost_LIB_PREFIX "lib")
 endif()
 
diff --git a/Modules/Platform/GHS-MULTI-Initialize.cmake b/Modules/Platform/GHS-MULTI-Initialize.cmake
new file mode 100644
index 0000000..342ad21
--- /dev/null
+++ b/Modules/Platform/GHS-MULTI-Initialize.cmake
@@ -0,0 +1,29 @@
+
+#=============================================================================
+# Copyright 2015 Geoffrey Viola <geoffrey.viola at asirobots.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+#Setup Greenhills MULTI specific compilation information
+find_path(GHS_INT_DIRECTORY INTEGRITY.ld PATHS
+  "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\GreenHillsSoftware6433c345;InstallLocation]" #int1122
+  "C:/ghs/int1122"
+  "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\GreenHillsSoftware289b6625;InstallLocation]" #int1104
+  "C:/ghs/int1104"
+  DOC "Path to integrity directory"
+  )
+set(GHS_OS_DIR ${GHS_INT_DIRECTORY} CACHE PATH "OS directory")
+set(GHS_PRIMARY_TARGET "arm_integrity.tgt" CACHE STRING "target for compilation")
+set(GHS_BSP_NAME "simarm" CACHE STRING "BSP name")
+set(GHS_CUSTOMIZATION "" CACHE FILEPATH "optional GHS customization")
+mark_as_advanced(GHS_CUSTOMIZATION)
+set(GHS_GPJ_MACROS "" CACHE STRING "optional GHS macros generated in the .gpjs for legacy reasons")
+mark_as_advanced(GHS_GPJ_MACROS)
diff --git a/Modules/Platform/GHS-MULTI.cmake b/Modules/Platform/GHS-MULTI.cmake
new file mode 100644
index 0000000..211cf3e
--- /dev/null
+++ b/Modules/Platform/GHS-MULTI.cmake
@@ -0,0 +1,27 @@
+
+#=============================================================================
+# Copyright 2015 Geoffrey Viola <geoffrey.viola at asirobots.com>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# This module is shared by multiple languages; use include blocker.
+
+if(__GHSMULTI)
+  return()
+endif()
+set(__GHSMULTI 1)
+
+set(GHSMULTI 1)
+
+set(CMAKE_FIND_LIBRARY_PREFIXES "")
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
+
+include(Platform/WindowsPaths)
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 04f6a81..064b827 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -472,6 +472,14 @@ if (WIN32)
       cmVisualStudioSlnParser.cxx
       cmVisualStudioWCEPlatformParser.h
       cmVisualStudioWCEPlatformParser.cxx
+      cmGlobalGhsMultiGenerator.cxx
+      cmGlobalGhsMultiGenerator.h
+      cmLocalGhsMultiGenerator.cxx
+      cmLocalGhsMultiGenerator.h
+      cmGhsMultiTargetGenerator.cxx
+      cmGhsMultiTargetGenerator.h
+      cmGhsMultiGpj.cxx
+      cmGhsMultiGpj.h
       )
   endif()
 endif ()
@@ -499,6 +507,7 @@ set(SRCS ${SRCS}
   cmNinjaUtilityTargetGenerator.cxx
   cmNinjaUtilityTargetGenerator.h
   )
+
 if(WIN32 AND NOT CYGWIN)
   set_source_files_properties(cmcldeps.cxx PROPERTIES COMPILE_DEFINITIONS _WIN32_WINNT=0x0501)
   add_executable(cmcldeps cmcldeps.cxx)
diff --git a/Source/cmGhsMultiGpj.cxx b/Source/cmGhsMultiGpj.cxx
new file mode 100644
index 0000000..d630faa
--- /dev/null
+++ b/Source/cmGhsMultiGpj.cxx
@@ -0,0 +1,39 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Geoffrey Viola <geoffrey.viola at asirobots.com>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmGhsMultiGpj.h"
+
+#include "cmGeneratedFileStream.h"
+
+void GhsMultiGpj::WriteGpjTag(Types const gpjType,
+                              cmGeneratedFileStream *const filestream) {
+  char const *tag;
+  switch (gpjType) {
+  case INTERGRITY_APPLICATION:
+    tag = "INTEGRITY Application";
+    break;
+  case PROJECT:
+    tag = "Project";
+    break;
+  case PROGRAM:
+    tag = "Program";
+    break;
+  case REFERENCE:
+    tag = "Reference";
+    break;
+  case SUBPROJECT:
+    tag = "Subproject";
+    break;
+  default:
+    tag = "";
+  }
+  *filestream << "[" << tag << "]" << std::endl;
+}
diff --git a/Source/cmGhsMultiGpj.h b/Source/cmGhsMultiGpj.h
new file mode 100644
index 0000000..225ec47
--- /dev/null
+++ b/Source/cmGhsMultiGpj.h
@@ -0,0 +1,31 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Geoffrey Viola <geoffrey.viola at asirobots.com>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmGhsMultiGpj_h
+#define cmGhsMultiGpj_h
+
+class cmGeneratedFileStream;
+
+class GhsMultiGpj {
+public:
+  enum Types {
+    INTERGRITY_APPLICATION,
+    PROJECT,
+    PROGRAM,
+    REFERENCE,
+    SUBPROJECT
+  };
+
+  static void WriteGpjTag(Types const gpjType,
+                          cmGeneratedFileStream *filestream);
+};
+
+#endif // ! cmGhsMultiGpjType_h
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
new file mode 100644
index 0000000..e242cc0
--- /dev/null
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -0,0 +1,435 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Geoffrey Viola <geoffrey.viola at asirobots.com>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmGhsMultiTargetGenerator.h"
+#include "cmGlobalGhsMultiGenerator.h"
+#include "cmLocalGhsMultiGenerator.h"
+#include "cmMakefile.h"
+#include "cmTarget.h"
+#include "cmGeneratedFileStream.h"
+#include "cmSourceFile.h"
+#include <assert.h>
+#include <cmAlgorithms.h>
+
+std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
+
+cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmTarget const *target)
+    : Target(target), LocalGenerator(static_cast<cmLocalGhsMultiGenerator *>(
+                          target->GetMakefile()->GetLocalGenerator())),
+      Makefile(target->GetMakefile()), TargetGroup(DetermineIfTargetGroup()),
+      DynamicDownload(false) {
+  std::string BuildFileName;
+  BuildFileName = this->Target->GetName();
+  BuildFileName += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
+
+  char const *folderProp = this->Target->GetProperty("FOLDER");
+  RelBuildFilePath = NULL == folderProp ? "" : folderProp;
+  if (RelBuildFilePath.size() > 0 && '/' != RelBuildFilePath.back()) {
+    RelBuildFilePath += "/";
+  }
+  RelBuildFilePath += Target->GetName() + "/";
+
+  RelOutputFileName = RelBuildFilePath + Target->GetName() + ".a";
+
+  RelBuildFileName = RelBuildFilePath;
+  if (RelBuildFileName.size() > 0 && '/' != RelBuildFileName.back()) {
+    RelBuildFileName += "/";
+  }
+  RelBuildFileName += BuildFileName;
+
+  std::string absPathToRoot(this->Makefile->GetHomeOutputDirectory());
+  if (absPathToRoot.size() > 0 && '/' != absPathToRoot.back()) {
+    absPathToRoot += "/";
+  }
+  AbsBuildFilePath = absPathToRoot + RelBuildFilePath;
+  AbsBuildFileName = absPathToRoot + RelBuildFileName;
+  AbsOutputFileName = absPathToRoot + RelOutputFileName;
+}
+
+cmGhsMultiTargetGenerator::~cmGhsMultiTargetGenerator()
+{
+  cmDeleteAll(FolderBuildStreams);
+}
+
+void cmGhsMultiTargetGenerator::Generate() {
+  std::vector<cmSourceFile *> objectSources = GetSources();
+  if (objectSources.size() > 0 && IncludeThisTarget()) {
+    if (!cmSystemTools::FileExists(AbsBuildFilePath.c_str())) {
+      cmSystemTools::MakeDirectory(AbsBuildFilePath.c_str());
+    }
+    cmGlobalGhsMultiGenerator::Open(std::string(""), this->AbsBuildFileName,
+                                    &FolderBuildStreams);
+    cmGlobalGhsMultiGenerator::OpenBuildFileStream(GetFolderBuildStreams());
+    std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+    if (0 == config.length()) {
+      config = "RELEASE";
+    }
+    const std::string language(this->Target->GetLinkerLanguage(config));
+    config = cmSystemTools::UpperCase(config);
+    DynamicDownload = DetermineIfDynamicDownload(config, language);
+    if (DynamicDownload) {
+      *this->GetFolderBuildStreams() << "#component integrity_dynamic_download"
+                                     << std::endl;
+    }
+    GhsMultiGpj::WriteGpjTag(GetGpjTag(), this->GetFolderBuildStreams());
+    cmGlobalGhsMultiGenerator::WriteDisclaimer(GetFolderBuildStreams());
+
+    bool const notKernel = IsNotKernel(config, language);
+    WriteTypeSpecifics(config, notKernel);
+    WriteDebugOptions(config, notKernel);
+    WriteCompilerOptions(config, language);
+    WriteCompilerFlags();
+    WriteCompilerDefinitions(config, language);
+    WriteIncludes(config, language);
+    WriteTargetLinkLibraries();
+    WriteCustomCommands();
+    if (DynamicDownload) {
+      *this->GetFolderBuildStreams() << "    " << DDOption << std::endl;
+    }
+
+    WriteSources(objectSources);
+  }
+}
+
+bool cmGhsMultiTargetGenerator::IncludeThisTarget() {
+  bool output = true;
+  char const *excludeFromAll = this->Target->GetProperty("EXCLUDE_FROM_ALL");
+  if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
+      '\0' == excludeFromAll[1]) {
+    output = false;
+  }
+  return output;
+}
+
+std::vector<cmSourceFile *> cmGhsMultiTargetGenerator::GetSources() const {
+  std::vector<cmSourceFile *> output;
+  std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+  this->Target->GetSourceFiles(output, config);
+  return output;
+}
+
+GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag() const {
+  GhsMultiGpj::Types output;
+  if (IsTargetGroup()) {
+    output = GhsMultiGpj::Types::INTERGRITY_APPLICATION;
+  } else {
+    output = GhsMultiGpj::Types::PROGRAM;
+  }
+  return output;
+}
+
+cmGlobalGhsMultiGenerator *
+cmGhsMultiTargetGenerator::GetGlobalGenerator() const {
+  return static_cast<cmGlobalGhsMultiGenerator *>(
+      LocalGenerator->GetGlobalGenerator());
+}
+
+void cmGhsMultiTargetGenerator::WriteTypeSpecifics(const std::string &config,
+                                                   bool const notKernel) {
+  std::string outputDir(GetOutputDirectory(config));
+  std::string outputFilename(GetOutputFilename(config));
+
+  if (Target->GetType() == cmTarget::TargetType::STATIC_LIBRARY) {
+    *GetFolderBuildStreams() << "    -relobj" << std::endl;
+    *GetFolderBuildStreams() << "    {optgroup=GhsCommonOptions} -o \""
+                             << outputDir << outputFilename << ".a\""
+                             << std::endl;
+  } else if (Target->GetType() == cmTarget::TargetType::EXECUTABLE) {
+    if (notKernel && !IsTargetGroup()) {
+      *GetFolderBuildStreams() << "    -relprog" << std::endl;
+    }
+    if (IsTargetGroup()) {
+      *GetFolderBuildStreams() << "    -non_shared" << std::endl;
+      *GetFolderBuildStreams() << "    -o \"" << outputDir << outputFilename
+                               << ".elf\"" << std::endl;
+    } else {
+      *GetFolderBuildStreams() << "    {optgroup=GhsCommonOptions} -o \""
+                               << outputDir << outputFilename << ".as\""
+                               << std::endl;
+    }
+  }
+}
+
+void cmGhsMultiTargetGenerator::WriteDebugOptions(std::string const &config,
+                                                  bool const notKernel) {
+  if ("DEBUG" == config) {
+    if (notKernel) {
+      *GetFolderBuildStreams() << "    -G" << std::endl;
+      *GetFolderBuildStreams() << "    -Onone" << std::endl;
+    } else {
+      *GetFolderBuildStreams() << "    -ldebug" << std::endl;
+    }
+  } else if (notKernel) {
+    *GetFolderBuildStreams() << "    -O" << std::endl;
+  }
+}
+
+void cmGhsMultiTargetGenerator::WriteCompilerOptions(
+    std::string const &config, const std::string &language) {
+  std::vector<std::string> options;
+  Target->GetCompileOptions(options, config, language);
+  bool hasStartfileDirProp = false;
+  std::string const startFilePropName("-startfile_dir=");
+  for (std::vector<std::string>::const_iterator options_i = options.begin();
+       options_i != options.end(); ++options_i) {
+    std::string option = *options_i;
+    if (DDOption != option) {
+      if (option.length() >= startFilePropName.length() &&
+          startFilePropName == option.substr(0, startFilePropName.length())) {
+        hasStartfileDirProp = true;
+      }
+      cmSystemTools::ConvertToUnixSlashes(option);
+      *this->GetFolderBuildStreams() << "    " << option << std::endl;
+    }
+  }
+
+  // If this property is relative, make it relative to the root lists file
+  if (!hasStartfileDirProp && GetGlobalGenerator()->IsOSDirRelative()) {
+    *this->GetFolderBuildStreams() << "    " << startFilePropName << "\""
+                                   << this->Makefile->GetHomeOutputDirectory()
+                                   << "/$(__LIBS_DIR_BASE)/$(__BSP_NAME)\""
+                                   << std::endl;
+  }
+}
+
+void cmGhsMultiTargetGenerator::WriteCompilerFlags() {
+  char const *const compileFlags = Target->GetProperty("COMPILE_FLAGS");
+  if (NULL != compileFlags) {
+    *this->GetFolderBuildStreams() << "    " << compileFlags << std::endl;
+  }
+}
+
+void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
+    const std::string &config, const std::string &language) {
+  std::vector<std::string> compileDefinitions;
+  this->Target->GetCompileDefinitions(compileDefinitions, config, language);
+  for (std::vector<std::string>::const_iterator cdI =
+           compileDefinitions.begin();
+       cdI != compileDefinitions.end(); ++cdI) {
+    *this->GetFolderBuildStreams() << "    -D" << (*cdI) << std::endl;
+  }
+}
+
+void cmGhsMultiTargetGenerator::WriteIncludes(const std::string &config,
+                                              const std::string &language) {
+  std::vector<std::string> includes =
+      Target->GetIncludeDirectories(config, language);
+  for (std::vector<std::string>::const_iterator includes_i = includes.begin();
+       includes_i != includes.end(); ++includes_i) {
+    *this->GetFolderBuildStreams() << "    -I\"" << *includes_i << "\""
+                                   << std::endl;
+  }
+}
+
+void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries() {
+  // library directories
+  cmTargetDependSet tds =
+      GetGlobalGenerator()->GetTargetDirectDepends(*this->Target);
+  for (cmTargetDependSet::iterator tdsI = tds.begin(); tdsI != tds.end();
+       ++tdsI) {
+    cmTarget const *tg(*tdsI);
+    cmGhsMultiTargetGenerator gmtg(tg);
+    *this->GetFolderBuildStreams() << "    -L\"" << gmtg.GetAbsBuildFilePath()
+                                   << "\"" << std::endl;
+  }
+  // library targets
+  cmTarget::LinkLibraryVectorType llv =
+      this->Target->GetOriginalLinkLibraries();
+  for (cmTarget::LinkLibraryVectorType::const_iterator llvI = llv.begin();
+       llvI != llv.end(); ++llvI) {
+    std::string libName = llvI->first;
+    // if it is a user defined target get the full path to the lib
+    cmTarget *tg(GetGlobalGenerator()->FindTarget(libName));
+    if (NULL != tg) {
+      cmGhsMultiTargetGenerator gmtg(tg);
+      libName = tg->GetName() + ".a";
+    }
+    *this->GetFolderBuildStreams() << "    -l\"" << libName << "\""
+                                   << std::endl;
+  }
+}
+
+void cmGhsMultiTargetGenerator::WriteCustomCommands() {
+  WriteCustomCommandsHelper(this->Target->GetPreBuildCommands(),
+                            cmTarget::CustomCommandType::PRE_BUILD);
+  WriteCustomCommandsHelper(this->Target->GetPostBuildCommands(),
+                            cmTarget::CustomCommandType::POST_BUILD);
+}
+
+void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
+    std::vector<cmCustomCommand> const &commandsSet,
+    cmTarget::CustomCommandType const commandType) {
+  for (std::vector<cmCustomCommand>::const_iterator commandsSetI =
+           commandsSet.begin();
+       commandsSetI != commandsSet.end(); ++commandsSetI) {
+    cmCustomCommandLines const &commands = commandsSetI->GetCommandLines();
+    for (cmCustomCommandLines::const_iterator commandI = commands.begin();
+         commandI != commands.end(); ++commandI) {
+      switch (commandType) {
+      case cmTarget::CustomCommandType::PRE_BUILD:
+        *GetFolderBuildStreams() << "    :preexecShellSafe=";
+        break;
+      case cmTarget::CustomCommandType::POST_BUILD:
+        *GetFolderBuildStreams() << "    :postexecShellSafe=";
+        break;
+      default:
+        assert("Only pre and post are supported");
+      }
+      cmCustomCommandLine const &command = *commandI;
+      for (cmCustomCommandLine::const_iterator commandLineI = command.begin();
+           commandLineI != command.end(); ++commandLineI) {
+        if (command.size() > 0) {
+          *GetFolderBuildStreams()
+              << (command.begin() == commandLineI ? "'" : " ");
+        }
+        *GetFolderBuildStreams() << *commandLineI;
+      }
+      if (command.size() > 0) {
+        *GetFolderBuildStreams() << "'" << std::endl;
+      }
+    }
+  }
+}
+
+void cmGhsMultiTargetGenerator::WriteSources(
+    std::vector<cmSourceFile *> const &objectSources) {
+  for (std::vector<cmSourceFile *>::const_iterator si = objectSources.begin();
+       si != objectSources.end(); ++si) {
+    std::vector<cmSourceGroup> sourceGroups(this->Makefile->GetSourceGroups());
+    char const *sourceFullPath = (*si)->GetFullPath().c_str();
+    cmSourceGroup *sourceGroup =
+        this->Makefile->FindSourceGroup(sourceFullPath, sourceGroups);
+    std::string sgPath(sourceGroup->GetFullName());
+    cmSystemTools::ConvertToUnixSlashes(sgPath);
+    cmGlobalGhsMultiGenerator::AddFilesUpToPath(
+        GetFolderBuildStreams(), &FolderBuildStreams,
+        this->Makefile->GetHomeOutputDirectory(), sgPath,
+        GhsMultiGpj::Types::SUBPROJECT, RelBuildFilePath);
+
+    if ((*si)->GetExtension() == ".int") {
+      *this->FolderBuildStreams[sgPath] << "\"" << (*si)->GetFullPath() << "\""
+                                        << std::endl;
+    } else {
+      *this->FolderBuildStreams[sgPath] << (*si)->GetFullPath() << std::endl;
+    }
+
+    if ("ld" != (*si)->GetExtension() && "int" != (*si)->GetExtension() &&
+        "bsp" != (*si)->GetExtension()) {
+      WriteObjectLangOverride(this->FolderBuildStreams[sgPath], (*si));
+
+      WriteObjectDir(this->FolderBuildStreams[sgPath],
+                     AbsBuildFilePath + sgPath);
+    }
+  }
+}
+
+void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
+    cmGeneratedFileStream *fileStream, cmSourceFile *sourceFile) {
+  const char *rawLangProp = sourceFile->GetProperty("LANGUAGE");
+  if (NULL != rawLangProp) {
+    std::string sourceLangProp(rawLangProp);
+    std::string extension(sourceFile->GetExtension());
+    if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
+      *fileStream << "    -dotciscxx" << std::endl;
+    }
+  }
+}
+
+void cmGhsMultiTargetGenerator::WriteObjectDir(
+    cmGeneratedFileStream *fileStream, std::string const &dir) {
+  std::string workingDir(dir);
+  if (workingDir.size() > 0 && '/' != workingDir.back()) {
+    workingDir += "/";
+  }
+  workingDir += "Objs";
+  *fileStream << "    -object_dir=\"" << workingDir << "\"" << std::endl;
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetOutputDirectory(const std::string &config) const {
+  std::string outputDir(AbsBuildFilePath);
+
+  const char *runtimeOutputProp =
+      Target->GetProperty("RUNTIME_OUTPUT_DIRECTORY");
+  if (NULL != runtimeOutputProp) {
+    outputDir = runtimeOutputProp;
+  }
+
+  std::string configCapped(cmSystemTools::UpperCase(config));
+  const char *runtimeOutputSProp =
+      Target->GetProperty("RUNTIME_OUTPUT_DIRECTORY_" + configCapped);
+  if (NULL != runtimeOutputSProp) {
+    outputDir = runtimeOutputSProp;
+  }
+  cmSystemTools::ConvertToUnixSlashes(outputDir);
+
+  if (outputDir.length() > 0 && ('/' != (*outputDir.rbegin()))) {
+    outputDir += "/";
+  }
+
+  return outputDir;
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetOutputFilename(const std::string &config) const {
+  std::string outputFilename(Target->GetName());
+
+  const char *outputNameProp = Target->GetProperty("OUTPUT_NAME");
+  if (NULL != outputNameProp) {
+    outputFilename = outputNameProp;
+  }
+
+  std::string configCapped(cmSystemTools::UpperCase(config));
+  const char *outputNameSProp =
+      Target->GetProperty(configCapped + "_OUTPUT_NAME");
+  if (NULL != outputNameSProp) {
+    outputFilename = outputNameSProp;
+  }
+
+  return outputFilename;
+}
+
+bool cmGhsMultiTargetGenerator::IsNotKernel(std::string const &config,
+                                            const std::string &language) {
+  bool output;
+  std::vector<std::string> options;
+  Target->GetCompileOptions(options, config, language);
+  output =
+      options.end() == std::find(options.begin(), options.end(), "-kernel");
+  return output;
+}
+
+bool cmGhsMultiTargetGenerator::DetermineIfTargetGroup() {
+  bool output = false;
+  std::vector<cmSourceFile *> sources = GetSources();
+  for (std::vector<cmSourceFile *>::const_iterator sources_i = sources.begin();
+       sources.end() != sources_i; ++sources_i) {
+    if ("int" == (*sources_i)->GetExtension()) {
+      output = true;
+    }
+  }
+  return output;
+}
+
+bool cmGhsMultiTargetGenerator::DetermineIfDynamicDownload(
+    std::string const &config, const std::string &language) {
+  std::vector<std::string> options;
+  bool output = false;
+  Target->GetCompileOptions(options, config, language);
+  for (std::vector<std::string>::const_iterator options_i = options.begin();
+       options_i != options.end(); ++options_i) {
+    std::string option = *options_i;
+    if (DDOption == option) {
+      output = true;
+    }
+  }
+  return output;
+}
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
new file mode 100644
index 0000000..7822fab
--- /dev/null
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -0,0 +1,92 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Geoffrey Viola <geoffrey.viola at asirobots.com>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmGhsMultiTargetGenerator_h
+#define cmGhsMultiTargetGenerator_h
+
+#include "cmStandardIncludes.h"
+#include "cmTarget.h"
+#include "cmGhsMultiGpj.h"
+
+class cmGeneratedFileStream;
+class cmGlobalGhsMultiGenerator;
+class cmLocalGhsMultiGenerator;
+class cmMakefile;
+class cmSourceFile;
+class cmGeneratedFileStream;
+class cmCustomCommand;
+
+class cmGhsMultiTargetGenerator {
+public:
+  cmGhsMultiTargetGenerator(cmTarget const *target);
+
+  virtual ~cmGhsMultiTargetGenerator();
+
+  virtual void Generate();
+
+  bool IncludeThisTarget();
+  std::vector<cmSourceFile *> GetSources() const;
+  GhsMultiGpj::Types GetGpjTag() const;
+  const char *GetAbsBuildFilePath() const { return AbsBuildFilePath.c_str(); }
+  const char *GetRelBuildFileName() const { return RelBuildFileName.c_str(); }
+  const char *GetAbsBuildFileName() const { return AbsBuildFileName.c_str(); }
+  const char *GetAbsOutputFileName() const { return AbsOutputFileName.c_str(); }
+
+private:
+  cmGlobalGhsMultiGenerator *GetGlobalGenerator() const;
+  cmGeneratedFileStream *GetFolderBuildStreams() {
+    return FolderBuildStreams[""];
+  };
+  bool IsTargetGroup() const { return TargetGroup; }
+
+  void WriteTypeSpecifics(const std::string &config, bool notKernel);
+  void WriteDebugOptions(std::string const &config, bool notKernel);
+  void WriteCompilerOptions(const std::string &config,
+                            const std::string &language);
+  void WriteCompilerFlags();
+  void WriteCompilerDefinitions(const std::string &config,
+                                const std::string &language);
+  void WriteIncludes(const std::string &config, const std::string &language);
+  void WriteTargetLinkLibraries();
+  void WriteCustomCommands();
+  void
+  WriteCustomCommandsHelper(std::vector<cmCustomCommand> const &commandsSet,
+                            cmTarget::CustomCommandType commandType);
+  void WriteSources(std::vector<cmSourceFile *> const &objectSources);
+  static void WriteObjectLangOverride(cmGeneratedFileStream *fileStream,
+                                      cmSourceFile *sourceFile);
+  static void WriteObjectDir(cmGeneratedFileStream *fileStream,
+                             std::string const &dir);
+  std::string GetOutputDirectory(const std::string &config) const;
+  std::string GetOutputFilename(const std::string &config) const;
+
+  bool IsNotKernel(std::string const &config, const std::string &language);
+  bool DetermineIfTargetGroup();
+  bool DetermineIfDynamicDownload(std::string const &config,
+                                  const std::string &language);
+
+  cmTarget const *Target;
+  cmLocalGhsMultiGenerator *LocalGenerator;
+  cmMakefile *Makefile;
+  std::string AbsBuildFilePath;
+  std::string RelBuildFilePath;
+  std::string AbsBuildFileName;
+  std::string RelBuildFileName;
+  std::string RelOutputFileName;
+  std::string AbsOutputFileName;
+  std::map<std::string, cmGeneratedFileStream*>
+      FolderBuildStreams;
+  bool TargetGroup;
+  bool DynamicDownload;
+  static std::string const DDOption;
+};
+
+#endif // ! cmGhsMultiTargetGenerator_h
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
new file mode 100644
index 0000000..d66d0d7
--- /dev/null
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -0,0 +1,448 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Geoffrey Viola <geoffrey.viola at asirobots.com>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmGlobalGhsMultiGenerator.h"
+#include "cmLocalGhsMultiGenerator.h"
+#include "cmMakefile.h"
+#include "cmVersion.h"
+#include "cmGeneratedFileStream.h"
+#include "cmGhsMultiTargetGenerator.h"
+#include <cmsys/SystemTools.hxx>
+#include <cmAlgorithms.h>
+
+const char *cmGlobalGhsMultiGenerator::FILE_EXTENSION = ".gpj";
+
+cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator() : OSDirRelative(false) {
+  this->FindMakeProgramFile = "CMakeGreenHillsFindMake.cmake";
+}
+
+cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator() {
+  cmDeleteAll(TargetFolderBuildStreams);
+}
+
+cmLocalGenerator *cmGlobalGhsMultiGenerator::CreateLocalGenerator() {
+  cmLocalGenerator *lg = new cmLocalGhsMultiGenerator;
+  lg->SetGlobalGenerator(this);
+  this->SetCurrentLocalGenerator(lg);
+  return lg;
+}
+
+void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry &entry) {
+  entry.Name = GetActualName();
+  entry.Brief = "Generates Green Hills MULTI files (experimental).";
+}
+
+void cmGlobalGhsMultiGenerator::EnableLanguage(
+    std::vector<std::string> const &l, cmMakefile *mf, bool optional) {
+  mf->AddDefinition("CMAKE_SYSTEM_NAME", "GHS-MULTI");
+  mf->AddDefinition("CMAKE_SYSTEM_PROCESSOR", "ARM");
+
+  const std::string ghsCompRoot(GetCompRoot());
+  mf->AddDefinition("GHS_COMP_ROOT", ghsCompRoot.c_str());
+  std::string ghsCompRootStart =
+      0 == ghsCompRootStart.size() ? "" : ghsCompRoot + "/";
+  mf->AddDefinition("CMAKE_C_COMPILER",
+                    std::string(ghsCompRootStart + "ccarm.exe").c_str());
+  mf->AddDefinition("CMAKE_C_COMPILER_ID_RUN", "TRUE");
+  mf->AddDefinition("CMAKE_C_COMPILER_ID", "GHSC");
+  mf->AddDefinition("CMAKE_C_COMPILER_FORCED", "TRUE");
+
+  mf->AddDefinition("CMAKE_CXX_COMPILER",
+                    std::string(ghsCompRootStart + "cxarm.exe").c_str());
+  mf->AddDefinition("CMAKE_CXX_COMPILER_ID_RUN", "TRUE");
+  mf->AddDefinition("CMAKE_CXX_COMPILER_ID", "GHSCXX");
+  mf->AddDefinition("CMAKE_CXX_COMPILER_FORCED", "TRUE");
+
+  if (ghsCompRoot.length() > 0) {
+    static const char *compPreFix = "comp_";
+    std::string compFilename =
+        cmsys::SystemTools::FindLastString(ghsCompRoot.c_str(), compPreFix);
+    cmsys::SystemTools::ReplaceString(compFilename, compPreFix, "");
+    mf->AddDefinition("CMAKE_SYSTEM_VERSION", compFilename.c_str());
+  }
+
+  mf->AddDefinition("GHSMULTI", "1"); // identifier for user CMake files
+  this->cmGlobalGenerator::EnableLanguage(l, mf, optional);
+}
+
+void cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile *mf) {
+  // The GHS generator knows how to lookup its build tool
+  // directly instead of needing a helper module to do it, so we
+  // do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
+  if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
+    mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetGhsBuildCommand().c_str());
+  }
+}
+
+std::string const &cmGlobalGhsMultiGenerator::GetGhsBuildCommand() {
+  if (!this->GhsBuildCommandInitialized) {
+    this->GhsBuildCommandInitialized = true;
+    this->GhsBuildCommand = this->FindGhsBuildCommand();
+  }
+  return this->GhsBuildCommand;
+}
+
+std::string cmGlobalGhsMultiGenerator::FindGhsBuildCommand() {
+  std::string makeProgram = cmSystemTools::FindProgram("gbuild");
+  if (makeProgram.empty()) {
+    makeProgram = "gbuild";
+  }
+  return makeProgram;
+}
+
+std::string cmGlobalGhsMultiGenerator::GetCompRoot() {
+  std::string output;
+
+  const std::vector<std::string> potentialDirsHardPaths(GetCompRootHardPaths());
+  const std::vector<std::string> potentialDirsRegistry(GetCompRootRegistry());
+
+  std::vector<std::string> potentialDirsComplete;
+  potentialDirsComplete.insert(potentialDirsComplete.end(),
+                               potentialDirsHardPaths.begin(),
+                               potentialDirsHardPaths.end());
+  potentialDirsComplete.insert(potentialDirsComplete.end(),
+                               potentialDirsRegistry.begin(),
+                               potentialDirsRegistry.end());
+
+  // Use latest version
+  std::string outputDirName;
+  for (std::vector<std::string>::const_iterator potentialDirsCompleteIt =
+           potentialDirsComplete.begin();
+       potentialDirsCompleteIt != potentialDirsComplete.end();
+       ++potentialDirsCompleteIt) {
+    const std::string dirName(
+        cmsys::SystemTools::GetFilenameName(*potentialDirsCompleteIt));
+    if (dirName.compare(outputDirName) > 0) {
+      output = *potentialDirsCompleteIt;
+      outputDirName = dirName;
+    }
+  }
+
+  return output;
+}
+
+std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootHardPaths() {
+  std::vector<std::string> output;
+  cmSystemTools::Glob("C:/ghs", "comp_[^;]+", output);
+  for (std::vector<std::string>::iterator outputIt = output.begin();
+       outputIt != output.end(); ++outputIt) {
+    *outputIt = "C:/ghs/" + *outputIt;
+  }
+  return output;
+}
+
+std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootRegistry() {
+  std::vector<std::string> output(2);
+  cmsys::SystemTools::ReadRegistryValue(
+      "HKEY_LOCAL_"
+      "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Unin"
+      "stall\\"
+      "GreenHillsSoftwared771f1b4;InstallLocation",
+      output[0]);
+  cmsys::SystemTools::ReadRegistryValue(
+      "HKEY_LOCAL_"
+      "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Unin"
+      "stall\\"
+      "GreenHillsSoftware9881cef6;InstallLocation",
+      output[1]);
+  return output;
+}
+
+void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
+    std::string const &filepath, cmGeneratedFileStream **filestream) {
+  // Get a stream where to generate things.
+  if (NULL == *filestream) {
+    *filestream = new cmGeneratedFileStream(filepath.c_str());
+    if (NULL != *filestream) {
+      OpenBuildFileStream(*filestream);
+    }
+  }
+}
+
+void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
+    cmGeneratedFileStream *filestream) {
+  *filestream << "#!gbuild" << std::endl;
+}
+
+void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
+    cmMakefile *const makefile) {
+  // Compute GHS MULTI's build file path.
+  std::string buildFilePath =
+      this->GetCMakeInstance()->GetHomeOutputDirectory();
+  buildFilePath += "/";
+  buildFilePath += "default";
+  buildFilePath += FILE_EXTENSION;
+
+  Open(std::string(""), buildFilePath, &TargetFolderBuildStreams);
+  OpenBuildFileStream(GetBuildFileStream());
+
+  char const *osDir =
+      this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR");
+  if (NULL == osDir) {
+    osDir = "";
+    cmSystemTools::Error("GHS_OS_DIR cache variable must be set");
+  } else {
+    this->GetCMakeInstance()->MarkCliAsUsed("GHS_OS_DIR");
+  }
+  std::string fOSDir(trimQuotes(osDir));
+  cmSystemTools::ReplaceString(fOSDir, "\\", "/");
+  if (fOSDir.length() > 0 && ('c' == fOSDir[0] || 'C' == fOSDir[0])) {
+    OSDirRelative = false;
+  } else {
+    OSDirRelative = true;
+  }
+
+  char const *bspName =
+      this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME");
+  if (NULL == bspName) {
+    bspName = "";
+    cmSystemTools::Error("GHS_BSP_NAME cache variable must be set");
+  } else {
+    this->GetCMakeInstance()->MarkCliAsUsed("GHS_BSP_NAME");
+  }
+  std::string fBspName(trimQuotes(bspName));
+  cmSystemTools::ReplaceString(fBspName, "\\", "/");
+  WriteMacros();
+  WriteHighLevelDirectives();
+
+  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::Types::PROJECT, GetBuildFileStream());
+  WriteDisclaimer(GetBuildFileStream());
+  *GetBuildFileStream() << "# Top Level Project File" << std::endl;
+  if (fBspName.length() > 0) {
+    *GetBuildFileStream() << "    -bsp " << fBspName << std::endl;
+  }
+  WriteCompilerOptions(fOSDir);
+}
+
+void cmGlobalGhsMultiGenerator::CloseBuildFileStream(
+    cmGeneratedFileStream **filestream) {
+  if (filestream) {
+    delete *filestream;
+    *filestream = NULL;
+  } else {
+    cmSystemTools::Error("Build file stream was not open.");
+  }
+}
+
+void cmGlobalGhsMultiGenerator::Generate() {
+  this->cmGlobalGenerator::Generate();
+
+  if (this->LocalGenerators.size() > 0) {
+    cmLocalGenerator *sampLG = this->LocalGenerators[0];
+    this->OpenBuildFileStream(sampLG->GetMakefile());
+
+    // Build all the folder build files
+    for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
+      cmLocalGhsMultiGenerator *lg =
+          static_cast<cmLocalGhsMultiGenerator *>(this->LocalGenerators[i]);
+      cmGeneratorTargetsType tgts = lg->GetMakefile()->GetGeneratorTargets();
+      UpdateBuildFiles(tgts);
+    }
+  }
+}
+
+void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
+    std::vector<std::string> &makeCommand, const std::string &makeProgram,
+    const std::string & /*projectName*/, const std::string & /*projectDir*/,
+    const std::string &targetName, const std::string & /*config*/,
+    bool /*fast*/, bool /*verbose*/,
+    std::vector<std::string> const &makeOptions) {
+  makeCommand.push_back(this->SelectMakeProgram(makeProgram));
+
+  makeCommand.insert(makeCommand.end(), makeOptions.begin(), makeOptions.end());
+  if (!targetName.empty()) {
+    if (targetName == "clean") {
+      makeCommand.push_back("-clean");
+    } else {
+      makeCommand.push_back(targetName);
+    }
+  }
+}
+
+void cmGlobalGhsMultiGenerator::WriteMacros() {
+  char const *ghsGpjMacros =
+      this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
+  if (NULL != ghsGpjMacros) {
+    std::vector<std::string> expandedList;
+    cmSystemTools::ExpandListArgument(std::string(ghsGpjMacros), expandedList);
+    for (std::vector<std::string>::const_iterator expandedListI =
+             expandedList.begin();
+         expandedListI != expandedList.end(); ++expandedListI) {
+      *GetBuildFileStream() << "macro " << *expandedListI << std::endl;
+    }
+  }
+}
+
+void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives() {
+  *GetBuildFileStream() << "primaryTarget=arm_integrity.tgt" << std::endl;
+  char const *const customization =
+      this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
+  if (NULL != customization && strlen(customization) > 0) {
+    *GetBuildFileStream() << "customization=" << trimQuotes(customization)
+                          << std::endl;
+    this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
+  }
+}
+
+void cmGlobalGhsMultiGenerator::WriteCompilerOptions(
+    std::string const &fOSDir) {
+  *GetBuildFileStream() << "    -os_dir=\"" << fOSDir << "\"" << std::endl;
+  *GetBuildFileStream() << "    --link_once_templates" << std::endl;
+}
+
+void cmGlobalGhsMultiGenerator::WriteDisclaimer(std::ostream *os) {
+  (*os) << "#" << std::endl
+        << "# CMAKE generated file: DO NOT EDIT!" << std::endl
+        << "# Generated by \"" << GetActualName() << "\""
+        << " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
+        << cmVersion::GetMinorVersion() << std::endl
+        << "#" << std::endl;
+}
+
+void cmGlobalGhsMultiGenerator::AddFilesUpToPath(
+    cmGeneratedFileStream *mainBuildFile,
+    std::map<std::string, cmGeneratedFileStream*> *
+        targetFolderBuildStreams,
+    char const *homeOutputDirectory, std::string const &path,
+    GhsMultiGpj::Types projType, std::string const &relPath) {
+  std::string workingPath(path);
+  cmSystemTools::ConvertToUnixSlashes(workingPath);
+  std::vector<cmsys::String> splitPath =
+      cmSystemTools::SplitString(workingPath);
+  std::string workingRelPath(relPath);
+  if (relPath.size() > 0 && '/' != relPath.back()) {
+    workingRelPath += "/";
+  }
+  std::string pathUpTo;
+  for (std::vector<cmsys::String>::const_iterator splitPathI =
+           splitPath.begin();
+       splitPath.end() != splitPathI; ++splitPathI) {
+    pathUpTo += *splitPathI;
+    if (targetFolderBuildStreams->end() ==
+        targetFolderBuildStreams->find(pathUpTo)) {
+      AddFilesUpToPathNewBuildFile(
+          mainBuildFile, targetFolderBuildStreams, homeOutputDirectory,
+          pathUpTo, splitPath.begin() == splitPathI, workingRelPath, projType);
+    }
+    AddFilesUpToPathAppendNextFile(targetFolderBuildStreams, pathUpTo,
+                                   splitPathI, splitPath.end(), projType);
+    pathUpTo += "/";
+  }
+}
+
+void cmGlobalGhsMultiGenerator::Open(
+    std::string const &mapKeyName, std::string const &fileName,
+    std::map<std::string, cmGeneratedFileStream*> *fileMap) {
+  if (fileMap->end() == fileMap->find(fileName)) {
+    cmGeneratedFileStream* temp(new cmGeneratedFileStream);
+    temp->open(fileName.c_str());
+    (*fileMap)[mapKeyName] = temp;
+  }
+}
+
+void cmGlobalGhsMultiGenerator::AddFilesUpToPathNewBuildFile(
+    cmGeneratedFileStream *mainBuildFile,
+    std::map<std::string, cmGeneratedFileStream*> *
+        targetFolderBuildStreams,
+    char const *homeOutputDirectory, std::string const &pathUpTo,
+    bool const isFirst, std::string const &relPath,
+    GhsMultiGpj::Types const projType) {
+  // create folders up to file path
+  std::string absPath = std::string(homeOutputDirectory) + "/" + relPath;
+  std::string newPath = absPath + pathUpTo;
+  if (!cmSystemTools::FileExists(newPath.c_str())) {
+    cmSystemTools::MakeDirectory(newPath.c_str());
+  }
+
+  // Write out to filename for first time
+  std::string relFilename(GetFileNameFromPath(pathUpTo));
+  std::string absFilename = absPath + relFilename;
+  Open(pathUpTo, absFilename, targetFolderBuildStreams);
+  OpenBuildFileStream((*targetFolderBuildStreams)[pathUpTo]);
+  GhsMultiGpj::WriteGpjTag(projType,
+                           (*targetFolderBuildStreams)[pathUpTo]);
+  WriteDisclaimer((*targetFolderBuildStreams)[pathUpTo]);
+
+  // Add to main build file
+  if (isFirst) {
+    *mainBuildFile << relFilename << " ";
+    GhsMultiGpj::WriteGpjTag(projType, mainBuildFile);
+  }
+}
+
+void cmGlobalGhsMultiGenerator::AddFilesUpToPathAppendNextFile(
+    std::map<std::string, cmGeneratedFileStream*> *
+        targetFolderBuildStreams,
+    std::string const &pathUpTo,
+    std::vector<cmsys::String>::const_iterator splitPathI,
+    std::vector<cmsys::String>::const_iterator end,
+    GhsMultiGpj::Types const projType) {
+  std::vector<cmsys::String>::const_iterator splitPathNextI = splitPathI + 1;
+  if (end != splitPathNextI &&
+      targetFolderBuildStreams->end() ==
+          targetFolderBuildStreams->find(pathUpTo + "/" + *splitPathNextI)) {
+    std::string nextFilename(*splitPathNextI);
+    nextFilename = GetFileNameFromPath(nextFilename);
+    *(*targetFolderBuildStreams)[pathUpTo] << nextFilename << " ";
+    GhsMultiGpj::WriteGpjTag(projType,
+                             (*targetFolderBuildStreams)[pathUpTo]);
+  }
+}
+
+std::string
+cmGlobalGhsMultiGenerator::GetFileNameFromPath(std::string const &path) {
+  std::string output(path);
+  if (path.length() > 0) {
+    cmSystemTools::ConvertToUnixSlashes(output);
+    std::vector<cmsys::String> splitPath = cmSystemTools::SplitString(output);
+    output += "/" + splitPath.back() + FILE_EXTENSION;
+  }
+  return output;
+}
+
+void cmGlobalGhsMultiGenerator::UpdateBuildFiles(
+    cmGeneratorTargetsType const &tgts) {
+  for (cmGeneratorTargetsType::const_iterator tgtsI = tgts.begin();
+       tgtsI != tgts.end(); ++tgtsI) {
+    cmGhsMultiTargetGenerator gmtg(tgtsI->first);
+    if (gmtg.GetSources().size() > 0 && gmtg.IncludeThisTarget()) {
+      char const *rawFolderName = tgtsI->first->GetProperty("FOLDER");
+      if (NULL == rawFolderName) {
+        rawFolderName = "";
+      }
+      std::string folderName(rawFolderName);
+      if (TargetFolderBuildStreams.end() ==
+          TargetFolderBuildStreams.find(folderName)) {
+        AddFilesUpToPath(GetBuildFileStream(), &TargetFolderBuildStreams,
+                         this->GetCMakeInstance()->GetHomeOutputDirectory(),
+                         folderName, GhsMultiGpj::Types::PROJECT);
+      }
+      std::vector<cmsys::String> splitPath =
+          cmSystemTools::SplitString(gmtg.GetRelBuildFileName());
+      std::string foldNameRelBuildFile(*(splitPath.end() - 2) + "/" +
+                                       splitPath.back());
+      *TargetFolderBuildStreams[folderName] << foldNameRelBuildFile << " ";
+      GhsMultiGpj::WriteGpjTag(gmtg.GetGpjTag(),
+                               TargetFolderBuildStreams[folderName]);
+    }
+  }
+}
+
+std::string cmGlobalGhsMultiGenerator::trimQuotes(std::string const &str) {
+  std::string result;
+  result.reserve(str.size());
+  for (const char *ch = str.c_str(); *ch != '\0'; ++ch) {
+    if (*ch != '"') {
+      result += *ch;
+    }
+  }
+  return result;
+}
diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h
new file mode 100644
index 0000000..c7b5196
--- /dev/null
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -0,0 +1,128 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Geoffrey Viola <geoffrey.viola at asirobots.com>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmGhsMultiGenerator_h
+#define cmGhsMultiGenerator_h
+
+#include "cmGlobalGeneratorFactory.h"
+#include "cmGlobalGenerator.h"
+#include "cmGhsMultiGpj.h"
+
+class cmGeneratedFileStream;
+
+class cmGlobalGhsMultiGenerator : public cmGlobalGenerator {
+public:
+  /// The default name of GHS MULTI's build file. Typically: monolith.gpj.
+  static const char *FILE_EXTENSION;
+
+  cmGlobalGhsMultiGenerator();
+  ~cmGlobalGhsMultiGenerator();
+
+  static cmGlobalGeneratorFactory *NewFactory() {
+    return new cmGlobalGeneratorSimpleFactory<cmGlobalGhsMultiGenerator>();
+  }
+
+  ///! create the correct local generator
+  virtual cmLocalGenerator *CreateLocalGenerator();
+
+  /// @return the name of this generator.
+  static std::string GetActualName() { return "Green Hills MULTI"; }
+  ///! Get the name for this generator
+  virtual std::string GetName() const { return GetActualName(); }
+
+  /// Overloaded methods. @see cmGlobalGenerator::GetDocumentation()
+  static void GetDocumentation(cmDocumentationEntry &entry);
+
+  /**
+  * Try to determine system information such as shared library
+  * extension, pthreads, byte order etc.
+  */
+  virtual void EnableLanguage(std::vector<std::string> const &languages,
+                              cmMakefile *, bool optional);
+  /*
+  * Determine what program to use for building the project.
+  */
+  virtual void FindMakeProgram(cmMakefile *);
+
+  cmGeneratedFileStream *GetBuildFileStream() {
+    return TargetFolderBuildStreams[""];
+  }
+
+  static void OpenBuildFileStream(std::string const &filepath,
+                                  cmGeneratedFileStream **filestream);
+  static void OpenBuildFileStream(cmGeneratedFileStream *filestream);
+  static void CloseBuildFileStream(cmGeneratedFileStream **filestream);
+  /// Write the common disclaimer text at the top of each build file.
+  static void WriteDisclaimer(std::ostream *os);
+  std::vector<std::string> GetLibDirs() { return LibDirs; }
+
+  static void AddFilesUpToPath(
+      cmGeneratedFileStream *mainBuildFile,
+      std::map<std::string, cmGeneratedFileStream*> *
+          targetFolderBuildStreams,
+      char const *homeOutputDirectory, std::string const &path,
+      GhsMultiGpj::Types projType, std::string const &relPath = "");
+  static void
+  Open(std::string const &mapKeyName, std::string const &fileName,
+       std::map<std::string, cmGeneratedFileStream*> *fileMap);
+
+  static std::string trimQuotes(std::string const &str);
+  inline bool IsOSDirRelative() { return OSDirRelative; }
+
+protected:
+  virtual void Generate();
+  virtual void GenerateBuildCommand(
+      std::vector<std::string> &makeCommand, const std::string &makeProgram,
+      const std::string &projectName, const std::string &projectDir,
+      const std::string &targetName, const std::string &config, bool fast,
+      bool verbose,
+      std::vector<std::string> const &makeOptions = std::vector<std::string>());
+
+private:
+  std::string const &GetGhsBuildCommand();
+  std::string FindGhsBuildCommand();
+  std::string GetCompRoot();
+  std::vector<std::string> GetCompRootHardPaths();
+  std::vector<std::string> GetCompRootRegistry();
+  void OpenBuildFileStream(cmMakefile *makefile);
+
+  void WriteMacros();
+  void WriteHighLevelDirectives();
+  void WriteCompilerOptions(std::string const &fOSDir);
+
+  static void AddFilesUpToPathNewBuildFile(
+      cmGeneratedFileStream *mainBuildFile,
+      std::map<std::string, cmGeneratedFileStream*> *
+          targetFolderBuildStreams,
+      char const *homeOutputDirectory, std::string const &pathUpTo,
+      bool isFirst, std::string const &relPath, GhsMultiGpj::Types projType);
+  static void AddFilesUpToPathAppendNextFile(
+      std::map<std::string, cmGeneratedFileStream*> *
+          targetFolderBuildStreams,
+      std::string const &pathUpTo,
+      std::vector<cmsys::String>::const_iterator splitPathI,
+      std::vector<cmsys::String>::const_iterator end,
+      GhsMultiGpj::Types projType);
+  static std::string GetFileNameFromPath(std::string const &path);
+  void UpdateBuildFiles(cmGeneratorTargetsType const &tgts);
+
+  std::vector<cmGeneratedFileStream *> TargetSubProjects;
+  std::map<std::string, cmGeneratedFileStream*>
+      TargetFolderBuildStreams;
+
+  std::vector<std::string> LibDirs;
+
+  bool OSDirRelative;
+  bool GhsBuildCommandInitialized;
+  std::string GhsBuildCommand;
+};
+
+#endif
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index f74f1e0..2ade825 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -576,6 +576,7 @@ bool cmGlobalNinjaGenerator::UsingMinGW = false;
 
 // Implemented by:
 //   cmGlobalUnixMakefileGenerator3
+//   cmGlobalGhsMultiGenerator
 //   cmGlobalVisualStudio10Generator
 //   cmGlobalVisualStudio6Generator
 //   cmGlobalVisualStudio7Generator
diff --git a/Source/cmLocalGhsMultiGenerator.cxx b/Source/cmLocalGhsMultiGenerator.cxx
new file mode 100644
index 0000000..b700143
--- /dev/null
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -0,0 +1,48 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Geoffrey Viola <geoffrey.viola at asirobots.com>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#include "cmLocalGhsMultiGenerator.h"
+#include "cmGlobalGhsMultiGenerator.h"
+#include "cmGeneratorTarget.h"
+#include "cmMakefile.h"
+#include "cmGhsMultiTargetGenerator.h"
+#include "cmGeneratedFileStream.h"
+
+cmLocalGhsMultiGenerator::cmLocalGhsMultiGenerator() {}
+
+cmLocalGhsMultiGenerator::~cmLocalGhsMultiGenerator() {}
+
+void cmLocalGhsMultiGenerator::Generate() {
+  cmGeneratorTargetsType tgts = this->GetMakefile()->GetGeneratorTargets();
+  if (tgts.size() > 0) {
+    for (cmGeneratorTargetsType::iterator l = tgts.begin(); l != tgts.end();
+         ++l) {
+      cmGhsMultiTargetGenerator tg(l->second->Target);
+      tg.Generate();
+    }
+  }
+}
+
+// Implemented in:
+//   cmLocalGenerator.
+// Used in:
+//   Source/cmMakefile.cxx
+//   Source/cmGlobalGenerator.cxx
+void cmLocalGhsMultiGenerator::Configure() {
+  // Compute the path to use when referencing the current output
+  // directory from the top output directory.
+  this->HomeRelativeOutputPath =
+      this->Convert(this->Makefile->GetStartOutputDirectory(), HOME_OUTPUT);
+  if (this->HomeRelativeOutputPath == ".") {
+    this->HomeRelativeOutputPath = "";
+  }
+  this->cmLocalGenerator::Configure();
+}
diff --git a/Source/cmLocalGhsMultiGenerator.h b/Source/cmLocalGhsMultiGenerator.h
new file mode 100644
index 0000000..c97b03f
--- /dev/null
+++ b/Source/cmLocalGhsMultiGenerator.h
@@ -0,0 +1,54 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Geoffrey Viola <geoffrey.viola at asirobots.com>
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+#ifndef cmLocalGhsMultiGenerator_h
+#define cmLocalGhsMultiGenerator_h
+
+#include "cmLocalGenerator.h"
+
+class cmGeneratedFileStream;
+
+/** \class cmLocalGhsMultiGenerator
+ * \brief Write Green Hills MULTI project files.
+ *
+ * cmLocalGhsMultiGenerator produces a set of .gpj
+ * file for each target in its mirrored directory.
+ */
+class cmLocalGhsMultiGenerator : public cmLocalGenerator {
+public:
+  cmLocalGhsMultiGenerator();
+
+  virtual ~cmLocalGhsMultiGenerator();
+
+  /// @returns the relative path between the HomeOutputDirectory and this
+  /// local generators StartOutputDirectory.
+  std::string GetHomeRelativeOutputPath() const {
+    return this->HomeRelativeOutputPath;
+  }
+
+  /**
+   * Generate the makefile for this directory.
+   */
+  virtual void Generate();
+
+  /// Overloaded methods. @see cmLocalGenerator::Configure()
+  virtual void Configure();
+  const char *GetBuildFileName() { return BuildFileName.c_str(); }
+
+protected:
+  virtual bool CustomCommandUseLocal() const { return true; }
+
+private:
+  std::string BuildFileName;
+  std::string HomeRelativeOutputPath;
+};
+
+#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 51df7f2..631397b 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -63,6 +63,7 @@
 #    include "cmGlobalBorlandMakefileGenerator.h"
 #    include "cmGlobalNMakeMakefileGenerator.h"
 #    include "cmGlobalJOMMakefileGenerator.h"
+#    include "cmGlobalGhsMultiGenerator.h"
 #    define CMAKE_HAVE_VS_GENERATORS
 #  endif
 #  include "cmGlobalMSYSMakefileGenerator.h"
@@ -1841,6 +1842,8 @@ void cmake::AddDefaultGenerators()
     cmGlobalNMakeMakefileGenerator::NewFactory());
   this->Generators.push_back(
     cmGlobalJOMMakefileGenerator::NewFactory());
+  this->Generators.push_back(
+    cmGlobalGhsMultiGenerator::NewFactory());
 # endif
   this->Generators.push_back(
     cmGlobalMSYSMakefileGenerator::NewFactory());
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 49fd02b..87727c7 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1938,6 +1938,23 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     endif()
   endif()
 
+  if (CMake_TEST_GreenHillsMULTI)
+    macro(add_test_GhsMulti name primaryTarget bspName)
+      add_test(NAME GhsMulti.${name} COMMAND ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/GhsMulti"
+        "${CMake_BINARY_DIR}/Tests/GhsMulti/${name}"
+        --build-generator "Green Hills MULTI"
+        --build-project ReturnNum
+        --build-config $<CONFIGURATION>
+        --build-options -DGHS_PRIMARY_TARGET=${primaryTarget}
+        -DGHS_BSP_NAME=${bspName}
+        )
+    endmacro ()
+    add_test_GhsMulti("arm_integrity_simarm" "arm_integrity.tgt" "simarm")
+    add_test_GhsMulti("arm64_integrity_simarm" "arm64_integrity.tgt" "simarm")
+  endif ()
+
   if(tegra AND NOT "${CMake_SOURCE_DIR};${CMake_BINARY_DIR}" MATCHES " ")
     macro(add_test_VSNsightTegra name generator)
       add_test(NAME VSNsightTegra.${name} COMMAND ${CMAKE_CTEST_COMMAND}
diff --git a/Tests/GhsMulti/CMakeLists.txt b/Tests/GhsMulti/CMakeLists.txt
new file mode 100644
index 0000000..6e15ba9
--- /dev/null
+++ b/Tests/GhsMulti/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 3.1)
+project(ReturnNum)
+
+add_subdirectory(ReturnNum)
diff --git a/Tests/GhsMulti/ReturnNum/App/CMakeLists.txt b/Tests/GhsMulti/ReturnNum/App/CMakeLists.txt
new file mode 100644
index 0000000..2adbd4e
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/App/CMakeLists.txt
@@ -0,0 +1,4 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../Lib)
+add_executable(App Main.c)
+target_link_libraries(App Lib)
+target_compile_options(App PUBLIC "-non_shared")
diff --git a/Tests/GhsMulti/ReturnNum/App/Main.c b/Tests/GhsMulti/ReturnNum/App/Main.c
new file mode 100644
index 0000000..1133834
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/App/Main.c
@@ -0,0 +1,8 @@
+#include "HelperFun.h"
+
+int main(int argc, const char* argv[])
+{
+    int out;
+    out = giveNum();
+    return out;
+}
diff --git a/Tests/GhsMulti/ReturnNum/CMakeLists.txt b/Tests/GhsMulti/ReturnNum/CMakeLists.txt
new file mode 100644
index 0000000..7bcc5f9
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(App)
+add_subdirectory(Int)
+add_subdirectory(Lib)
diff --git a/Tests/GhsMulti/ReturnNum/Int/AppDD.int b/Tests/GhsMulti/ReturnNum/Int/AppDD.int
new file mode 100644
index 0000000..9e22b5e
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Int/AppDD.int
@@ -0,0 +1,12 @@
+# Input File for the Integrate utility for use with the INTEGRITY real-time
+#  operating system by Green Hills Software.
+# Before editing this file, refer to the Integrate Reference Manual.
+
+Kernel
+    Filename    DynamicDownload
+EndKernel
+
+AddressSpace        App
+  Filename      "App/App.as"
+  Language C
+EndAddressSpace
diff --git a/Tests/GhsMulti/ReturnNum/Int/CMakeLists.txt b/Tests/GhsMulti/ReturnNum/Int/CMakeLists.txt
new file mode 100644
index 0000000..44c5de1
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Int/CMakeLists.txt
@@ -0,0 +1 @@
+add_executable(AppDD AppDD.int Default.bsp)
diff --git a/Tests/GhsMulti/ReturnNum/Int/Default.bsp b/Tests/GhsMulti/ReturnNum/Int/Default.bsp
new file mode 100644
index 0000000..224ec29
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Int/Default.bsp
@@ -0,0 +1,35 @@
+# Target description File for the Integrate utility for use with the
+# INTEGRITY real-time operating system by Green Hills Software.
+# Before editing this file, refer to your Integrate documentation.
+# default.bsp is appropriate for INTEGRITY applications which are
+# fully linked with the kernel (for RAM or ROM) or dynamically downloaded.
+#
+# MinimumAddress must match the value of .ramend in the linker directives
+# file used for the KernelSpace program - see default.ld for more info.
+# The MaximumAddress used here allows memory mappings to be specified
+# for up to the 16 MB mark in RAM.   Intex will not permit programs
+# that require more memory for its mappings.    If the board has less
+# memory,  this number can be reduced by the user.
+
+Target
+	MinimumAddress				.ramend
+	MaximumAddress				.ramlimit
+	Clock					StandardTick
+	EndClock
+        Clock                                   HighResTimer
+        EndClock
+	IODevice				"SerialDev0"
+	InitialKernelObjects 			200
+	DefaultStartIt				false
+	DefaultMaxPriority			255
+	DefaultPriority				127
+	DefaultWeight				1
+	DefaultMaxWeight			255
+	DefaultHeapSize				0x10000
+	LastVirtualAddress			0x3fffffff
+	PageSize				0x1000
+	ArchitectedPageSize			0x1000
+	ArchitectedPageSize			0x10000
+	ArchitectedPageSize			0x100000
+	DefaultMemoryRegionSize			0x20000
+EndTarget
diff --git a/Tests/GhsMulti/ReturnNum/Lib/CMakeLists.txt b/Tests/GhsMulti/ReturnNum/Lib/CMakeLists.txt
new file mode 100644
index 0000000..9c822da
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Lib/CMakeLists.txt
@@ -0,0 +1 @@
+add_library(Lib HelperFun.c HelperFun.h)
\ No newline at end of file
diff --git a/Tests/GhsMulti/ReturnNum/Lib/HelperFun.c b/Tests/GhsMulti/ReturnNum/Lib/HelperFun.c
new file mode 100644
index 0000000..d7515d7
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Lib/HelperFun.c
@@ -0,0 +1,4 @@
+int giveNum(void)
+{
+    return 1;
+}
diff --git a/Tests/GhsMulti/ReturnNum/Lib/HelperFun.h b/Tests/GhsMulti/ReturnNum/Lib/HelperFun.h
new file mode 100644
index 0000000..00971b0
--- /dev/null
+++ b/Tests/GhsMulti/ReturnNum/Lib/HelperFun.h
@@ -0,0 +1 @@
+int giveNum(void);

-----------------------------------------------------------------------

Summary of changes:
 Help/generator/Green Hills MULTI.rst         |   11 +
 Help/manual/cmake-generators.7.rst           |    1 +
 Help/manual/cmake-variables.7.rst            |    1 +
 Help/variable/CMAKE_MAKE_PROGRAM.rst         |    4 +
 Help/variable/CMAKE_SYSTEM_PROCESSOR.rst     |    2 +
 Help/variable/GHS-MULTI.rst                  |    4 +
 Modules/Compiler/GHS-DetermineCompiler.cmake |    6 +
 Modules/FindBoost.cmake                      |    5 +-
 Modules/Platform/GHS-MULTI-Initialize.cmake  |   29 ++
 Modules/Platform/GHS-MULTI.cmake             |   27 ++
 Source/CMakeLists.txt                        |    9 +
 Source/cmGhsMultiGpj.cxx                     |   39 +++
 Source/cmGhsMultiGpj.h                       |   31 ++
 Source/cmGhsMultiTargetGenerator.cxx         |  436 +++++++++++++++++++++++++
 Source/cmGhsMultiTargetGenerator.h           |   92 ++++++
 Source/cmGlobalGhsMultiGenerator.cxx         |  452 ++++++++++++++++++++++++++
 Source/cmGlobalGhsMultiGenerator.h           |  129 ++++++++
 Source/cmGlobalNinjaGenerator.cxx            |    1 +
 Source/cmLocalGhsMultiGenerator.cxx          |   48 +++
 Source/cmLocalGhsMultiGenerator.h            |   54 +++
 Source/cmake.cxx                             |    3 +
 Tests/CMakeLists.txt                         |   17 +
 Tests/GhsMulti/CMakeLists.txt                |    4 +
 Tests/GhsMulti/ReturnNum/App/CMakeLists.txt  |    4 +
 Tests/GhsMulti/ReturnNum/App/Main.c          |    8 +
 Tests/GhsMulti/ReturnNum/CMakeLists.txt      |    3 +
 Tests/GhsMulti/ReturnNum/Int/AppDD.int       |   12 +
 Tests/GhsMulti/ReturnNum/Int/CMakeLists.txt  |    1 +
 Tests/GhsMulti/ReturnNum/Int/Default.bsp     |   35 ++
 Tests/GhsMulti/ReturnNum/Lib/CMakeLists.txt  |    1 +
 Tests/GhsMulti/ReturnNum/Lib/HelperFun.c     |    4 +
 Tests/GhsMulti/ReturnNum/Lib/HelperFun.h     |    1 +
 32 files changed, 1473 insertions(+), 1 deletion(-)
 create mode 100644 Help/generator/Green Hills MULTI.rst
 create mode 100644 Help/variable/GHS-MULTI.rst
 create mode 100644 Modules/Compiler/GHS-DetermineCompiler.cmake
 create mode 100644 Modules/Platform/GHS-MULTI-Initialize.cmake
 create mode 100644 Modules/Platform/GHS-MULTI.cmake
 create mode 100644 Source/cmGhsMultiGpj.cxx
 create mode 100644 Source/cmGhsMultiGpj.h
 create mode 100644 Source/cmGhsMultiTargetGenerator.cxx
 create mode 100644 Source/cmGhsMultiTargetGenerator.h
 create mode 100644 Source/cmGlobalGhsMultiGenerator.cxx
 create mode 100644 Source/cmGlobalGhsMultiGenerator.h
 create mode 100644 Source/cmLocalGhsMultiGenerator.cxx
 create mode 100644 Source/cmLocalGhsMultiGenerator.h
 create mode 100644 Tests/GhsMulti/CMakeLists.txt
 create mode 100644 Tests/GhsMulti/ReturnNum/App/CMakeLists.txt
 create mode 100644 Tests/GhsMulti/ReturnNum/App/Main.c
 create mode 100644 Tests/GhsMulti/ReturnNum/CMakeLists.txt
 create mode 100644 Tests/GhsMulti/ReturnNum/Int/AppDD.int
 create mode 100644 Tests/GhsMulti/ReturnNum/Int/CMakeLists.txt
 create mode 100644 Tests/GhsMulti/ReturnNum/Int/Default.bsp
 create mode 100644 Tests/GhsMulti/ReturnNum/Lib/CMakeLists.txt
 create mode 100644 Tests/GhsMulti/ReturnNum/Lib/HelperFun.c
 create mode 100644 Tests/GhsMulti/ReturnNum/Lib/HelperFun.h


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list