[Cmake-commits] CMake branch, next, updated. v3.2.2-1949-g68ce6cc

Brad King brad.king at kitware.com
Mon Apr 20 13:56:09 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  68ce6ccb4bd50a3f7e20bfcfa2d9699a941bf23b (commit)
       via  66b641f443a1d3fc8b5f74233307ba9b0929d340 (commit)
       via  48004d9dbeb2af20d3a8df66670323d924a3f4c6 (commit)
      from  6f1bb33e01a036534582b6923bfff60883f6359d (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=68ce6ccb4bd50a3f7e20bfcfa2d9699a941bf23b
commit 68ce6ccb4bd50a3f7e20bfcfa2d9699a941bf23b
Merge: 6f1bb33 66b641f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Apr 20 13:56:07 2015 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Mon Apr 20 13:56:07 2015 -0400

    Merge topic 'add-GreenHills-MULTI-generator' into next
    
    66b641f4 Help: Add notes for topic 'add-GreenHills-MULTI-generator'
    48004d9d Add a 'Green Hills MULTI' generator on Windows


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=66b641f443a1d3fc8b5f74233307ba9b0929d340
commit 66b641f443a1d3fc8b5f74233307ba9b0929d340
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon Apr 13 09:51:46 2015 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon Apr 20 13:55:40 2015 -0400

    Help: Add notes for topic 'add-GreenHills-MULTI-generator'

diff --git a/Help/release/dev/add-GreenHills-MULTI-generator.rst b/Help/release/dev/add-GreenHills-MULTI-generator.rst
new file mode 100644
index 0000000..b4c5c5a
--- /dev/null
+++ b/Help/release/dev/add-GreenHills-MULTI-generator.rst
@@ -0,0 +1,8 @@
+add-GreenHills-MULTI-generator
+------------------------------
+
+* A new experimental :generator:`Green Hills MULTI` generator was
+  added on Windows.  `Green Hills MULTI`_ is an IDE for embedded
+  real-time systems.
+
+.. _`Green Hills MULTI`: http://www.ghs.com/products/MULTI_IDE.html

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=48004d9dbeb2af20d3a8df66670323d924a3f4c6
commit 48004d9dbeb2af20d3a8df66670323d924a3f4c6
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: Mon Apr 20 13:55:40 2015 -0400

    Add a 'Green Hills MULTI' generator on Windows
    
    Green Hills MULTI is an IDE for embedded real-time systems.  The IDE's
    product page can be found here:
    
     http://www.ghs.com/products/MULTI_IDE.html
    
    It supports cross compiling on ARM, Intel x86, and other architectures
    with various operating systems.  The IDE exists on Linux and Windows
    host systems, but CMake will currently only generate the project files
    on Windows host systems.

diff --git a/Help/generator/Green Hills MULTI.rst b/Help/generator/Green Hills MULTI.rst
new file mode 100644
index 0000000..4d31690
--- /dev/null
+++ b/Help/generator/Green Hills MULTI.rst	
@@ -0,0 +1,16 @@
+Green Hills MULTI
+-----------------
+
+Generates Green Hills MULTI project files (experimental, work-in-progress).
+
+Customizations are available through the following cache variables:
+
+* ``GHS_BSP_NAME``
+* ``GHS_CUSTOMIZATION``
+* ``GHS_GPJ_MACROS``
+* ``GHS_OS_DIR``
+
+.. note::
+  This generator is deemed experimental as of CMake |release|
+  and is still a work in progress.  Future versions of CMake
+  may make breaking changes as the generator matures.
diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst
index 6f76fb1..723c308 100644
--- a/Help/manual/cmake-generators.7.rst
+++ b/Help/manual/cmake-generators.7.rst
@@ -73,6 +73,7 @@ Visual Studio Generators
 .. 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 63f704d..865e1ef 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -182,6 +182,7 @@ Variables that Describe the System
    /variable/CMAKE_SYSTEM_VERSION
    /variable/CYGWIN
    /variable/ENV
+   /variable/GHS-MULTI
    /variable/MINGW
    /variable/MSVC10
    /variable/MSVC11
@@ -307,6 +308,10 @@ Variables for Languages
    /variable/CMAKE_LANG_FLAGS_RELEASE
    /variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO
    /variable/CMAKE_LANG_FLAGS
+   /variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG
+   /variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL
+   /variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE
+   /variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO
    /variable/CMAKE_LANG_IGNORE_EXTENSIONS
    /variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES
    /variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst
new file mode 100644
index 0000000..c5915c3
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_GHS_KERNEL_FLAGS_DEBUG
+-----------------------------------
+
+GHS kernel flags for Debug build type or configuration.
+
+<LANG> flags used when CMAKE_BUILD_TYPE is Debug.
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst
new file mode 100644
index 0000000..f80e785
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_GHS_KERNEL_FLAGS_MINSIZEREL
+----------------------------------------
+
+GHS kernel flags for MinSizeRel build type or configuration.
+
+<LANG> flags used when CMAKE_BUILD_TYPE is MinSizeRel.Short for
+minimum size release.
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst
new file mode 100644
index 0000000..fe02bc3
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE.rst
@@ -0,0 +1,6 @@
+CMAKE_<LANG>_GHS_KERNEL_FLAGS_RELEASE
+-------------------------------------
+
+GHS kernel flags for Release build type or configuration.
+
+<LANG> flags used when CMAKE_BUILD_TYPE is Release
diff --git a/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst
new file mode 100644
index 0000000..220f7f9
--- /dev/null
+++ b/Help/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO.rst
@@ -0,0 +1,7 @@
+CMAKE_<LANG>_GHS_KERNEL_FLAGS_RELWITHDEBINFO
+--------------------------------------------
+
+GHS kernel flags for RelWithDebInfo type or configuration.
+
+<LANG> flags used when CMAKE_BUILD_TYPE is RelWithDebInfo.  Short for
+Release With Debug Information.
diff --git a/Help/variable/CMAKE_MAKE_PROGRAM.rst b/Help/variable/CMAKE_MAKE_PROGRAM.rst
index f1d88a5..85b098b 100644
--- a/Help/variable/CMAKE_MAKE_PROGRAM.rst
+++ b/Help/variable/CMAKE_MAKE_PROGRAM.rst
@@ -56,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
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-C.cmake b/Modules/Compiler/GHS-C.cmake
new file mode 100644
index 0000000..e97d62c
--- /dev/null
+++ b/Modules/Compiler/GHS-C.cmake
@@ -0,0 +1,27 @@
+set(CMAKE_C_VERBOSE_FLAG "-v")
+
+set(CMAKE_C_FLAGS_INIT "")
+set(CMAKE_C_FLAGS_DEBUG_INIT "-Odebug -g")
+set(CMAKE_C_FLAGS_MINSIZEREL_INIT "-Ospace")
+set(CMAKE_C_FLAGS_RELEASE_INIT "-O")
+set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "-O -g")
+
+set(CMAKE_C_GHS_KERNEL_FLAGS_DEBUG_INIT "-ldebug ${CMAKE_C_FLAGS_DEBUG_INIT}")
+set(CMAKE_C_GHS_KERNEL_FLAGS_MINSIZEREL_INIT "${CMAKE_C_FLAGS_MINSIZEREL_INIT}")
+set(CMAKE_C_GHS_KERNEL_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS_RELEASE_INIT}")
+set(CMAKE_C_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT
+  "-ldebug ${CMAKE_C_FLAGS_RELWITHDEBINFO_INIT}")
+
+if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+  set (CMAKE_C_GHS_KERNEL_FLAGS_DEBUG "${CMAKE_C_GHS_KERNEL_FLAGS_DEBUG_INIT}"
+    CACHE STRING "Kernel flags used by the compiler during debug builds.")
+  set (CMAKE_C_GHS_KERNEL_FLAGS_MINSIZEREL
+    "${CMAKE_C_GHS_KERNEL_FLAGS_MINSIZEREL_INIT}" CACHE STRING
+    "Kernel flags used by the compiler during release builds for minimum size.")
+  set (CMAKE_C_GHS_KERNEL_FLAGS_RELEASE
+    "${CMAKE_C_GHS_KERNEL_FLAGS_RELEASE_INIT}"
+    CACHE STRING "Kernel flags used by the compiler during release builds.")
+  set (CMAKE_C_GHS_KERNEL_FLAGS_RELWITHDEBINFO
+    "${CMAKE_C_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
+    "Kernel flags used by the compiler during release builds with debug info.")
+endif()
diff --git a/Modules/Compiler/GHS-CXX.cmake b/Modules/Compiler/GHS-CXX.cmake
new file mode 100644
index 0000000..71a0dec
--- /dev/null
+++ b/Modules/Compiler/GHS-CXX.cmake
@@ -0,0 +1,31 @@
+set(CMAKE_CXX_VERBOSE_FLAG "-v")
+
+set(CMAKE_CXX_FLAGS_INIT "")
+set(CMAKE_CXX_FLAGS_DEBUG_INIT "-Odebug -g")
+set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "-Ospace")
+set(CMAKE_CXX_FLAGS_RELEASE_INIT "-O")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "-O -g")
+
+set(CMAKE_CXX_GHS_KERNEL_FLAGS_DEBUG_INIT
+  "-ldebug ${CMAKE_CXX_FLAGS_DEBUG_INIT}")
+set(CMAKE_CXX_GHS_KERNEL_FLAGS_MINSIZEREL_INIT
+  "${CMAKE_CXX_FLAGS_MINSIZEREL_INIT}")
+set(CMAKE_CXX_GHS_KERNEL_FLAGS_RELEASE_INIT
+  "${CMAKE_CXX_FLAGS_RELEASE_INIT}")
+set(CMAKE_CXX_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT
+  "-ldebug ${CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT}")
+
+if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
+  set (CMAKE_CXX_GHS_KERNEL_FLAGS_DEBUG
+    "${CMAKE_CXX_GHS_KERNEL_FLAGS_DEBUG_INIT}"
+    CACHE STRING "Kernel flags used by the compiler during debug builds.")
+  set (CMAKE_CXX_GHS_KERNEL_FLAGS_MINSIZEREL
+    "${CMAKE_CXX_GHS_KERNEL_FLAGS_MINSIZEREL_INIT}" CACHE STRING
+    "Kernel flags used by the compiler during release builds for minimum size.")
+  set (CMAKE_CXX_GHS_KERNEL_FLAGS_RELEASE
+    "${CMAKE_CXX_GHS_KERNEL_FLAGS_RELEASE_INIT}"
+    CACHE STRING "Kernel flags used by the compiler during release builds.")
+  set (CMAKE_CXX_GHS_KERNEL_FLAGS_RELWITHDEBINFO
+    "${CMAKE_CXX_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
+    "Kernel flags used by the compiler during release builds with debug info.")
+endif()
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..e1dce52
--- /dev/null
+++ b/Source/cmGhsMultiGpj.cxx
@@ -0,0 +1,44 @@
+/*============================================================================
+  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 LIBRARY:
+      tag = "Library";
+      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..91ff0f4
--- /dev/null
+++ b/Source/cmGhsMultiGpj.h
@@ -0,0 +1,34 @@
+/*============================================================================
+  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,
+    LIBRARY,
+    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..01e2011
--- /dev/null
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -0,0 +1,600 @@
+/*============================================================================
+  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 *target)
+  : Target(target)
+  , LocalGenerator(static_cast<cmLocalGhsMultiGenerator *>(
+                     target->GetMakefile()->GetLocalGenerator()))
+  , Makefile(target->GetMakefile())
+  , TargetGroup(DetermineIfTargetGroup(target))
+  , DynamicDownload(false)
+{
+  this->RelBuildFilePath = this->GetRelBuildFilePath(target);
+
+  this->RelOutputFileName =
+    this->RelBuildFilePath + this->Target->GetName() + ".a";
+
+  this->RelBuildFileName = this->RelBuildFilePath;
+  this->RelBuildFileName += this->GetBuildFileName(target);
+
+  std::string absPathToRoot = this->GetAbsPathToRoot(target);
+  absPathToRoot = this->AddSlashIfNeededToPath(absPathToRoot);
+  this->AbsBuildFilePath = absPathToRoot + this->RelBuildFilePath;
+  this->AbsBuildFileName = absPathToRoot + this->RelBuildFileName;
+  this->AbsOutputFileName = absPathToRoot + this->RelOutputFileName;
+}
+
+cmGhsMultiTargetGenerator::~cmGhsMultiTargetGenerator()
+{
+  cmDeleteAll(this->FolderBuildStreams);
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetRelBuildFilePath(const cmTarget *target)
+{
+  std::string output;
+  char const *folderProp = target->GetProperty("FOLDER");
+  output = NULL == folderProp ? "" : folderProp;
+  cmSystemTools::ConvertToUnixSlashes(output);
+  if (!output.empty())
+  {
+    output += "/";
+  }
+  output += target->GetName() + "/";
+  return output;
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetAbsPathToRoot(const cmTarget *target)
+{
+  return target->GetMakefile()->GetHomeOutputDirectory();
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetAbsBuildFilePath(const cmTarget *target)
+{
+  std::string output;
+  output = cmGhsMultiTargetGenerator::GetAbsPathToRoot(target);
+  output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
+  output += cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
+  return  output;
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetRelBuildFileName(const cmTarget *target)
+{
+  std::string output;
+  output = cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
+  output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
+  output += cmGhsMultiTargetGenerator::GetBuildFileName(target);
+  return  output;
+}
+
+std::string cmGhsMultiTargetGenerator::GetBuildFileName(const cmTarget *target)
+{
+  std::string output;
+  output = target->GetName();
+  output += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
+  return output;
+}
+
+std::string
+cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(std::string const &input)
+{
+  std::string output(input);
+  if (!cmHasLiteralSuffix(output, "/"))
+    {
+    output += "/";
+    }
+  return output;
+}
+
+void cmGhsMultiTargetGenerator::Generate()
+{
+  const std::vector<cmSourceFile *> objectSources = this->GetSources();
+  if (!objectSources.empty() && this->IncludeThisTarget())
+    {
+    if (!cmSystemTools::FileExists(this->AbsBuildFilePath.c_str()))
+      {
+      cmSystemTools::MakeDirectory(this->AbsBuildFilePath.c_str());
+      }
+    cmGlobalGhsMultiGenerator::Open(std::string(""), this->AbsBuildFileName,
+                                    &this->FolderBuildStreams);
+    cmGlobalGhsMultiGenerator::OpenBuildFileStream(
+      this->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);
+    this->DynamicDownload = this->DetermineIfDynamicDownload(config, language);
+    if (this->DynamicDownload)
+      {
+      *this->GetFolderBuildStreams() << "#component integrity_dynamic_download"
+                                     << std::endl;
+      }
+    GhsMultiGpj::WriteGpjTag(this->GetGpjTag(), this->GetFolderBuildStreams());
+    cmGlobalGhsMultiGenerator::WriteDisclaimer(this->GetFolderBuildStreams());
+
+    bool const notKernel = this->IsNotKernel(config, language);
+    this->WriteTypeSpecifics(config, notKernel);
+    this->SetCompilerFlags(config, language, notKernel);
+    this->WriteCompilerFlags(config, language);
+    this->WriteCompilerDefinitions(config, language);
+    this->WriteIncludes(config, language);
+    if (this->Target->GetType() == cmTarget::EXECUTABLE)
+      {
+      this->WriteTargetLinkLibraries();
+      }
+    this->WriteCustomCommands();
+    if (this->DynamicDownload)
+      {
+      *this->GetFolderBuildStreams() << "    " << this->DDOption << std::endl;
+      }
+
+    this->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
+{
+  return cmGhsMultiTargetGenerator::GetGpjTag(this->Target);
+}
+
+GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag(const cmTarget *target)
+{
+  GhsMultiGpj::Types output;
+  if (cmGhsMultiTargetGenerator::DetermineIfTargetGroup(target))
+    {
+    output = GhsMultiGpj::INTERGRITY_APPLICATION;
+    }
+  else if (target->GetType() == cmTarget::STATIC_LIBRARY)
+    {
+    output = GhsMultiGpj::LIBRARY;
+    }
+  else
+    {
+    output = GhsMultiGpj::PROGRAM;
+    }
+  return output;
+}
+
+cmGlobalGhsMultiGenerator*
+cmGhsMultiTargetGenerator::GetGlobalGenerator() const
+{
+  return static_cast<cmGlobalGhsMultiGenerator *>(
+    this->LocalGenerator->GetGlobalGenerator());
+}
+
+void cmGhsMultiTargetGenerator::WriteTypeSpecifics(const std::string &config,
+                                                   bool const notKernel)
+{
+  std::string outputDir(this->GetOutputDirectory(config));
+  std::string outputFilename(this->GetOutputFilename(config));
+
+  if (this->Target->GetType() == cmTarget::STATIC_LIBRARY)
+    {
+    *this->GetFolderBuildStreams() << "    {optgroup=GhsCommonOptions} -o \""
+                                   << outputDir << outputFilename << ".a\""
+                                   << std::endl;
+    }
+  else if (this->Target->GetType() == cmTarget::EXECUTABLE)
+    {
+    if (notKernel && !this->IsTargetGroup())
+      {
+      *this->GetFolderBuildStreams() << "    -relprog" << std::endl;
+      }
+    if (this->IsTargetGroup())
+      {
+      *this->GetFolderBuildStreams() << "    -non_shared" << std::endl;
+      *this->GetFolderBuildStreams() << "    -o \"" << outputDir
+                                     << outputFilename << ".elf\""
+                                     << std::endl;
+      }
+    else
+      {
+      *this->GetFolderBuildStreams() << "    {optgroup=GhsCommonOptions} -o \""
+                                     << outputDir << outputFilename << ".as\""
+                                     << std::endl;
+      }
+    }
+}
+
+void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const &config,
+                                                 const std::string &language,
+                                                 bool const notKernel)
+{
+  std::map<std::string, std::string>::iterator i =
+    this->FlagsByLanguage.find(language);
+  if (i == this->FlagsByLanguage.end())
+    {
+    std::string flags;
+    const char *lang = language.c_str();
+
+    if (notKernel)
+      {
+      this->LocalGenerator->AddLanguageFlags(flags, lang, config);
+      }
+    else
+      {
+        this->LocalGenerator->AddLanguageFlags(
+            flags, lang + std::string("_GHS_KERNEL"), config);
+      }
+    this->LocalGenerator->AddCMP0018Flags(flags, this->Target, lang, config);
+    this->LocalGenerator->AddVisibilityPresetFlags(flags, this->Target, lang);
+
+    // Append old-style preprocessor definition flags.
+    if (std::string(" ") != std::string(this->Makefile->GetDefineFlags()))
+      {
+      this->LocalGenerator->AppendFlags(flags,
+                                      this->Makefile->GetDefineFlags());
+      }
+
+    // Add target-specific flags.
+    this->LocalGenerator->AddCompileOptions(flags, this->Target, lang, config);
+
+    std::map<std::string, std::string>::value_type entry(language, flags);
+    i = this->FlagsByLanguage.insert(entry).first;
+    }
+}
+
+std::string cmGhsMultiTargetGenerator::GetDefines(const std::string &language,
+                                                  std::string const &config)
+{
+  std::map<std::string, std::string>::iterator i =
+    this->DefinesByLanguage.find(language);
+  if (i == this->DefinesByLanguage.end())
+    {
+    std::set<std::string> defines;
+    const char *lang = language.c_str();
+    // Add the export symbol definition for shared library objects.
+    if (const char *exportMacro = this->Target->GetExportMacro())
+      {
+      this->LocalGenerator->AppendDefines(defines, exportMacro);
+      }
+
+    // Add preprocessor definitions for this target and configuration.
+    this->LocalGenerator->AddCompileDefinitions(defines, this->Target, config,
+                                                language);
+
+    std::string definesString;
+    this->LocalGenerator->JoinDefines(defines, definesString, lang);
+
+    std::map<std::string, std::string>::value_type entry(language,
+                                                          definesString);
+    i = this->DefinesByLanguage.insert(entry).first;
+    }
+  return i->second;
+}
+
+void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::string const &,
+                                                   const std::string &language)
+{
+  std::map<std::string, std::string>::iterator flagsByLangI =
+      this->FlagsByLanguage.find(language);
+  if (flagsByLangI != this->FlagsByLanguage.end())
+    {
+    if (!flagsByLangI->second.empty())
+      {
+      *this->GetFolderBuildStreams() << "    " << flagsByLangI->second
+        << 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 =
+    this->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 =
+    this->GetGlobalGenerator()->GetTargetDirectDepends(*this->Target);
+  for (cmTargetDependSet::iterator tdsI = tds.begin(); tdsI != tds.end();
+       ++tdsI)
+    {
+    const cmTarget *tg(*tdsI);
+    *this->GetFolderBuildStreams() << "    -L\"" << GetAbsBuildFilePath(tg)
+                                   << "\"" << 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::PRE_BUILD);
+  WriteCustomCommandsHelper(this->Target->GetPostBuildCommands(),
+                            cmTarget::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::PRE_BUILD:
+          *this->GetFolderBuildStreams() << "    :preexecShellSafe=";
+          break;
+        case cmTarget::POST_BUILD:
+          *this->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)
+        {
+        std::string subCommandE =
+            this->LocalGenerator->EscapeForShell(*commandLineI, true);
+        if (!command.empty())
+          {
+          *this->GetFolderBuildStreams()
+            << (command.begin() == commandLineI ? "'" : " ");
+          //Need to double escape backslashes
+          cmSystemTools::ReplaceString(subCommandE, "\\", "\\\\");
+          }
+        *this->GetFolderBuildStreams() << subCommandE;
+        }
+      if (!command.empty())
+        {
+        *this->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(
+      this->GetFolderBuildStreams(), &this->FolderBuildStreams,
+      this->Makefile->GetHomeOutputDirectory(), sgPath,
+      GhsMultiGpj::SUBPROJECT, this->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())
+      {
+      this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], (*si));
+
+      this->WriteObjectDir(this->FolderBuildStreams[sgPath],
+                           this->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);
+  cmSystemTools::ConvertToUnixSlashes(workingDir);
+  if (!workingDir.empty())
+    {
+    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 =
+    this->Target->GetProperty("RUNTIME_OUTPUT_DIRECTORY");
+  if (NULL != runtimeOutputProp)
+    {
+    outputDir = runtimeOutputProp;
+    }
+
+  std::string configCapped(cmSystemTools::UpperCase(config));
+  const char *runtimeOutputSProp =
+    this->Target->GetProperty("RUNTIME_OUTPUT_DIRECTORY_" + configCapped);
+  if (NULL != runtimeOutputSProp)
+    {
+    outputDir = runtimeOutputSProp;
+    }
+  cmSystemTools::ConvertToUnixSlashes(outputDir);
+
+  if (!outputDir.empty())
+    {
+    outputDir += "/";
+    }
+
+  return outputDir;
+}
+
+std::string
+cmGhsMultiTargetGenerator::GetOutputFilename(const std::string &config) const
+{
+  std::string outputFilename(this->Target->GetName());
+
+  const char *outputNameProp = this->Target->GetProperty("OUTPUT_NAME");
+  if (NULL != outputNameProp)
+    {
+    outputFilename = outputNameProp;
+    }
+
+  std::string configCapped(cmSystemTools::UpperCase(config));
+  const char *outputNameSProp =
+    this->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;
+  this->Target->GetCompileOptions(options, config, language);
+  output =
+    options.end() == std::find(options.begin(), options.end(), "-kernel");
+  return output;
+}
+
+bool cmGhsMultiTargetGenerator::DetermineIfTargetGroup(const cmTarget *target)
+{
+  bool output = false;
+  std::vector<cmSourceFile *> sources;
+  std::string config =
+      target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
+  target->GetSourceFiles(sources, config);
+  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;
+  this->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 (this->DDOption == option)
+      {
+      output = true;
+      }
+    }
+  return output;
+}
diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h
new file mode 100644
index 0000000..8e81db8
--- /dev/null
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -0,0 +1,119 @@
+/*============================================================================
+  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 *target);
+
+  virtual ~cmGhsMultiTargetGenerator();
+
+  virtual void Generate();
+
+  bool IncludeThisTarget();
+  std::vector<cmSourceFile *> GetSources() const;
+  GhsMultiGpj::Types GetGpjTag() const;
+  static GhsMultiGpj::Types GetGpjTag(const cmTarget *target);
+  const char *GetAbsBuildFilePath() const
+  {
+    return this->AbsBuildFilePath.c_str();
+  }
+  const char *GetRelBuildFileName() const
+  {
+    return this->RelBuildFileName.c_str();
+  }
+  const char *GetAbsBuildFileName() const
+  {
+    return this->AbsBuildFileName.c_str();
+  }
+  const char *GetAbsOutputFileName() const
+  {
+    return this->AbsOutputFileName.c_str();
+  }
+
+  static std::string GetRelBuildFilePath(const cmTarget *target);
+  static std::string GetAbsPathToRoot(const cmTarget *target);
+  static std::string GetAbsBuildFilePath(const cmTarget *target);
+  static std::string GetRelBuildFileName(const cmTarget *target);
+  static std::string GetBuildFileName(const cmTarget *target);
+  static std::string AddSlashIfNeededToPath(std::string const &input);
+
+private:
+  cmGlobalGhsMultiGenerator *GetGlobalGenerator() const;
+  cmGeneratedFileStream *GetFolderBuildStreams()
+  {
+    return this->FolderBuildStreams[""];
+  };
+  bool IsTargetGroup() const { return this->TargetGroup; }
+
+  void WriteTypeSpecifics(const std::string &config, bool notKernel);
+  void WriteCompilerFlags(const std::string &config,
+    const std::string &language);
+  void WriteCompilerDefinitions(const std::string &config,
+                                const std::string &language);
+
+  void SetCompilerFlags(std::string const &config, const std::string &language,
+                        bool const notKernel);
+  std::string GetDefines(const std::string &langugae,
+                         std::string const &config);
+
+  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);
+  static bool DetermineIfTargetGroup(const cmTarget *target);
+  bool DetermineIfDynamicDownload(std::string const &config,
+                                  const std::string &language);
+
+  cmTarget *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;
+  std::map<std::string, std::string> FlagsByLanguage;
+  std::map<std::string, std::string> DefinesByLanguage;
+};
+
+#endif // ! cmGhsMultiTargetGenerator_h
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
new file mode 100644
index 0000000..bba29b1
--- /dev/null
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -0,0 +1,548 @@
+/*============================================================================
+  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";
+const char *cmGlobalGhsMultiGenerator::DEFAULT_MAKE_PROGRAM = "gbuild";
+
+cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator()
+  : OSDirRelative(false)
+{
+  this->GhsBuildCommandInitialized = false;
+}
+
+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, work-in-progress).";
+}
+
+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", "GHS");
+  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", "GHS");
+  mf->AddDefinition("CMAKE_CXX_COMPILER_FORCED", "TRUE");
+
+  if (!ghsCompRoot.empty())
+    {
+    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::vector<std::string> userPaths;
+  userPaths.push_back(this->GetCompRoot());
+  std::string makeProgram =
+    cmSystemTools::FindProgram(DEFAULT_MAKE_PROGRAM, userPaths);
+  if (makeProgram.empty())
+    {
+    makeProgram = DEFAULT_MAKE_PROGRAM;
+    }
+  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\\Uninstall\\"
+    "GreenHillsSoftwared771f1b4;InstallLocation",
+    output[0]);
+  cmsys::SystemTools::ReadRegistryValue(
+    "HKEY_LOCAL_"
+    "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
+    "Windows\\CurrentVersion\\Uninstall\\"
+    "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()
+{
+  // Compute GHS MULTI's build file path.
+  std::string buildFilePath =
+    this->GetCMakeInstance()->GetHomeOutputDirectory();
+  buildFilePath += "/";
+  buildFilePath += "default";
+  buildFilePath += FILE_EXTENSION;
+
+  this->Open(std::string(""), buildFilePath, &this->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(this->trimQuotes(osDir));
+  cmSystemTools::ReplaceString(fOSDir, "\\", "/");
+  if (!fOSDir.empty() && ('c' == fOSDir[0] || 'C' == fOSDir[0]))
+    {
+    this->OSDirRelative = false;
+    }
+  else
+    {
+    this->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(this->trimQuotes(bspName));
+  cmSystemTools::ReplaceString(fBspName, "\\", "/");
+  this->WriteMacros();
+  this->WriteHighLevelDirectives();
+
+  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, this->GetBuildFileStream());
+  this->WriteDisclaimer(this->GetBuildFileStream());
+  *this->GetBuildFileStream() << "# Top Level Project File" << std::endl;
+  if (!fBspName.empty())
+    {
+    *this->GetBuildFileStream() << "    -bsp " << fBspName << std::endl;
+    }
+  this->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.empty())
+    {
+    this->OpenBuildFileStream();
+
+    // 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();
+      this->UpdateBuildFiles(&tgts);
+      }
+    }
+
+  cmDeleteAll(TargetFolderBuildStreams);
+  this->TargetFolderBuildStreams.clear();
+}
+
+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, this->GetGhsBuildCommand())
+    );
+
+  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)
+      {
+      *this->GetBuildFileStream() << "macro " << *expandedListI << std::endl;
+      }
+    }
+}
+
+void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives()
+{
+  *this->GetBuildFileStream() << "primaryTarget=arm_integrity.tgt"
+                              << std::endl;
+  char const *const customization =
+    this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
+  if (NULL != customization && strlen(customization) > 0)
+    {
+    *this->GetBuildFileStream() << "customization="
+                                << trimQuotes(customization)
+                                << std::endl;
+    this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
+    }
+}
+
+void cmGlobalGhsMultiGenerator::WriteCompilerOptions(std::string const &fOSDir)
+{
+  *this->GetBuildFileStream() << "    -os_dir=\"" << fOSDir << "\""
+                              << 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);
+  cmSystemTools::ConvertToUnixSlashes(workingRelPath);
+  if (!workingRelPath.empty())
+    {
+    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.empty())
+    {
+    cmSystemTools::ConvertToUnixSlashes(output);
+    std::vector<cmsys::String> splitPath = cmSystemTools::SplitString(output);
+    output += "/" + splitPath.back() + FILE_EXTENSION;
+    }
+  return output;
+}
+
+void cmGlobalGhsMultiGenerator::UpdateBuildFiles(
+  cmGeneratorTargetsType *tgts)
+{
+  for (cmGeneratorTargetsType::iterator tgtsI = tgts->begin();
+       tgtsI != tgts->end(); ++tgtsI)
+    {
+    const cmTarget *tgt(tgtsI->first);
+    if (IsTgtForBuild(tgt))
+      {
+      char const *rawFolderName = tgtsI->first->GetProperty("FOLDER");
+      if (NULL == rawFolderName)
+        {
+        rawFolderName = "";
+        }
+      std::string folderName(rawFolderName);
+      if (this->TargetFolderBuildStreams.end() ==
+          this->TargetFolderBuildStreams.find(folderName))
+        {
+        this->AddFilesUpToPath(
+          GetBuildFileStream(), &this->TargetFolderBuildStreams,
+          this->GetCMakeInstance()->GetHomeOutputDirectory(), folderName,
+          GhsMultiGpj::PROJECT);
+        }
+      std::vector<cmsys::String> splitPath = cmSystemTools::SplitString(
+            cmGhsMultiTargetGenerator::GetRelBuildFileName(tgt));
+      std::string foldNameRelBuildFile(*(splitPath.end() - 2) + "/" +
+                                       splitPath.back());
+      *this->TargetFolderBuildStreams[folderName] << foldNameRelBuildFile
+                                                  << " ";
+      GhsMultiGpj::WriteGpjTag(cmGhsMultiTargetGenerator::GetGpjTag(tgt),
+                               this->TargetFolderBuildStreams[folderName]);
+      }
+    }
+}
+
+bool cmGlobalGhsMultiGenerator::IsTgtForBuild(const cmTarget *tgt)
+{
+  const std::string config =
+    tgt->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
+  std::vector<cmSourceFile *> tgtSources;
+  tgt->GetSourceFiles(tgtSources, config);
+  bool tgtInBuild = true;
+  char const *excludeFromAll = tgt->GetProperty("EXCLUDE_FROM_ALL");
+  if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
+    '\0' == excludeFromAll[1])
+  {
+    tgtInBuild = false;
+  }
+  return !tgtSources.empty() && tgtInBuild;
+}
+
+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..b934c3a
--- /dev/null
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -0,0 +1,127 @@
+/*============================================================================
+  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 this->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 this->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 this->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 this->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();
+
+  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 *tgts);
+  bool IsTgtForBuild(const cmTarget *tgt);
+
+  std::vector<cmGeneratedFileStream *> TargetSubProjects;
+  std::map<std::string, cmGeneratedFileStream *> TargetFolderBuildStreams;
+
+  std::vector<std::string> LibDirs;
+
+  bool OSDirRelative;
+  bool GhsBuildCommandInitialized;
+  std::string GhsBuildCommand;
+  static const char *DEFAULT_MAKE_PROGRAM;
+};
+
+#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..782fec4
--- /dev/null
+++ b/Source/cmLocalGhsMultiGenerator.cxx
@@ -0,0 +1,55 @@
+/*============================================================================
+  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.empty())
+    {
+    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..a8df3e7
--- /dev/null
+++ b/Source/cmLocalGhsMultiGenerator.h
@@ -0,0 +1,56 @@
+/*============================================================================
+  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 this->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 5c52a1a..bfe9aea 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"
@@ -1840,6 +1841,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 f80191b..83c919d 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1978,6 +1978,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:


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list