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, master has been updated
       via  0793464d95c3dbbe9ed87bb5882d29efb7a8e3c3 (commit)
       via  e2128e11ac7ac38f33100f5277cb4ace8697bad8 (commit)
       via  6aab5e0ef9b95933495042f3e2dab64c3c002f37 (commit)
       via  a6bf68141faca9af22624c8d0e1603653a73fce4 (commit)
       via  032e969879f4362471eb4a952b28aae6fd5a8116 (commit)
       via  717e85418b068734dd9d8d0aa3063ec4e363fcbf (commit)
       via  9010f5c18a60ce034fb547d98a19585326aadba1 (commit)
       via  2bae6a1346cb95703a93dbf73c9689598c9056d1 (commit)
       via  3b415c60c1a02b9ac76089a44c28e70692dcdef1 (commit)
       via  83c47ef5b8a6b1a63edbd82092d8eae68da453d6 (commit)
       via  5d2e1404bdfa83eeae5b361bd7d8a882aadc7242 (commit)
       via  b6bfa7eeb29937fbed44153518abfa4f28b9aa62 (commit)
       via  39ee9718d9a56e7b8b15f63576f042415a2771f8 (commit)
       via  8d3dad9a76591ae0426335d039b8aaacb95862cd (commit)
       via  37acc9e2299713b9b23c767e72b0e0169697e510 (commit)
      from  ef9c38ccf8b6bf12e8d8b539a316a304076948c8 (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 -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0793464d95c3dbbe9ed87bb5882d29efb7a8e3c3
commit 0793464d95c3dbbe9ed87bb5882d29efb7a8e3c3
Merge: e2128e1 2bae6a1
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Mon Apr 15 14:52:11 2019 +0000
Commit:     Kitware Robot <kwro...@kitware.com>
CommitDate: Mon Apr 15 10:52:21 2019 -0400

    Merge topic 'ghs_custom'
    
    2bae6a1346 GHS: Update tests and notes
    3b415c60c1 GHS: Update ExternalProject for GHS tools
    83c47ef5b8 GHS: Update project layout to accommodate gbuild inconsistencies
    5d2e1404bd GHS: Update project layout to build targets correctly
    b6bfa7eeb2 GHS: Support add_dependencies() command
    39ee9718d9 GHS: Support add_custom_target() command
    8d3dad9a76 GHS: Support add_custom_command( OUTPUT ) signature
    37acc9e229 GHS: Update custom command build events
    
    Acked-by: Kitware Robot <kwro...@kitware.com>
    Acked-by: Narendhar Manimohan <narendha...@gmail.com>
    Merge-request: !3119


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e2128e11ac7ac38f33100f5277cb4ace8697bad8
commit e2128e11ac7ac38f33100f5277cb4ace8697bad8
Merge: 6aab5e0 a6bf681
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Mon Apr 15 10:51:08 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Mon Apr 15 10:51:08 2019 -0400

    Merge branch 'release-3.14'


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=6aab5e0ef9b95933495042f3e2dab64c3c002f37
commit 6aab5e0ef9b95933495042f3e2dab64c3c002f37
Merge: ef9c38c 032e969
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Mon Apr 15 14:49:46 2019 +0000
Commit:     Kitware Robot <kwro...@kitware.com>
CommitDate: Mon Apr 15 10:49:54 2019 -0400

    Merge topic 'FindBoost-msvc-toolset-14.2'
    
    032e969879 Merge branch 'backport-FindBoost-msvc-toolset-14.2'
    717e85418b FindBoost: Add support for MSVC toolset version 14.2
    9010f5c18a FindBoost: Add support for MSVC toolset version 14.2
    
    Acked-by: Kitware Robot <kwro...@kitware.com>
    Merge-request: !3221


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=032e969879f4362471eb4a952b28aae6fd5a8116
commit 032e969879f4362471eb4a952b28aae6fd5a8116
Merge: 717e854 9010f5c
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Fri Apr 12 11:37:51 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Fri Apr 12 11:37:51 2019 -0400

    Merge branch 'backport-FindBoost-msvc-toolset-14.2'


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=717e85418b068734dd9d8d0aa3063ec4e363fcbf
commit 717e85418b068734dd9d8d0aa3063ec4e363fcbf
Author:     Brad King <brad.k...@kitware.com>
AuthorDate: Fri Apr 12 09:48:20 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Fri Apr 12 11:35:19 2019 -0400

    FindBoost: Add support for MSVC toolset version 14.2
    
    Generalize the logic to express compatibility among 14.x versions.

diff --git a/Modules/FindBoost.cmake b/Modules/FindBoost.cmake
index 53be493..c30c6c8 100644
--- a/Modules/FindBoost.cmake
+++ b/Modules/FindBoost.cmake
@@ -466,8 +466,17 @@ function(_Boost_GUESS_COMPILER_PREFIX _ret)
   elseif (GHSMULTI)
     set(_boost_COMPILER "-ghs")
   elseif("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" OR 
"x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
-    if(MSVC_TOOLSET_VERSION GREATER_EQUAL 141)
-      set(_boost_COMPILER "-vc141;-vc140")
+    if(MSVC_TOOLSET_VERSION GREATER_EQUAL 150)
+      # Not yet known.
+      set(_boost_COMPILER "")
+    elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 140)
+      # MSVC toolset 14.x versions are forward compatible.
+      set(_boost_COMPILER "")
+      foreach(v 9 8 7 6 5 4 3 2 1 0)
+        if(MSVC_TOOLSET_VERSION GREATER_EQUAL 14${v})
+          list(APPEND _boost_COMPILER "-vc14${v}")
+        endif()
+      endforeach()
     elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80)
       set(_boost_COMPILER "-vc${MSVC_TOOLSET_VERSION}")
     elseif(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.10)
@@ -1083,9 +1092,15 @@ 
function(_Boost_UPDATE_WINDOWS_LIBRARY_SEARCH_DIRS_WITH_PREBUILT_PATHS component
     else()
       set(_arch_suffix 32)
     endif()
-    if(MSVC_TOOLSET_VERSION GREATER_EQUAL 141)
-      list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.1)
-      list(APPEND ${componentlibvar} ${basedir}/lib${_arch_suffix}-msvc-14.0)
+    if(MSVC_TOOLSET_VERSION GREATER_EQUAL 150)
+      # Not yet known.
+    elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 140)
+      # MSVC toolset 14.x versions are forward compatible.
+      foreach(v 9 8 7 6 5 4 3 2 1 0)
+        if(MSVC_TOOLSET_VERSION GREATER_EQUAL 14${v})
+          list(APPEND ${componentlibvar} 
${basedir}/lib${_arch_suffix}-msvc-14.${v})
+        endif()
+      endforeach()
     elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 80)
       math(EXPR _toolset_major_version "${MSVC_TOOLSET_VERSION} / 10")
       list(APPEND ${componentlibvar} 
${basedir}/lib${_arch_suffix}-msvc-${_toolset_major_version}.0)

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2bae6a1346cb95703a93dbf73c9689598c9056d1
commit 2bae6a1346cb95703a93dbf73c9689598c9056d1
Author:     Fred Baksik <froda...@gmail.com>
AuthorDate: Mon Apr 8 09:55:35 2019 -0400
Commit:     Fred Baksik <froda...@gmail.com>
CommitDate: Thu Apr 11 13:15:51 2019 -0400

    GHS: Update tests and notes
    
    -- add new tests for custom commands
    -- minor test cleanup
    
    Fixes #15995
    Fixes #18909
    Fixes #15902

diff --git a/Help/release/dev/ghs-custom-commands.rst 
b/Help/release/dev/ghs-custom-commands.rst
new file mode 100644
index 0000000..a29ef88
--- /dev/null
+++ b/Help/release/dev/ghs-custom-commands.rst
@@ -0,0 +1,5 @@
+ghs_custom_commands
+-------------------
+
+* The :generator:`Green Hills MULTI` generator now supports
+  :command:`add_custom_command` and :command:`add_custom_target`
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 2d9b806..2e0902c 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -2391,6 +2391,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P 
${CMake_SOURCE_DIR}/Utilities/Release
       add_test_GhsMulti(compiler_options_kernel GhsMultiCompilerOptions Kernel 
"-DRUN_TEST=KERNEL_FLAGS -DRUN_TEST_BUILD_TYPE=DEBUG")
       add_test_GhsMulti(try_compile_copy GhsMultiCopyFile "" "")
       add_test_GhsMulti(ghs_platform GhsMultiPlatform "" "")
+      add_test_GhsMulti(custom_target GhsMultiCustomTarget "" "")
+      add_test_GhsMulti(dep_order GhsMultiDepOrder "" "")
+      add_test_GhsMulti(external_project GhsMultiExternalProject "" "")
       list(APPEND TEST_BUILD_DIRS 
"${CMake_BINARY_DIR}/Tests/GhsMulti/${ghs_config_name}")
       #unset ghs config variables
       unset(ghs_config_name)
diff --git a/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt
new file mode 100644
index 0000000..93d668b
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt
@@ -0,0 +1,110 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
+
+project(test C)
+
+# Tests assume no previous builds in the build directory
+file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/build)
+
+macro (test_output)
+  if (BUILD_OUTPUT STREQUAL EXPECTED_LINES )
+    message("Build OK")
+  else()
+    message("BUILD_OUTPUT")
+    foreach(Line IN LISTS BUILD_OUTPUT)
+      message("${Line}")
+    endforeach()
+    message("EXPECTED_LINES")
+    foreach(Line IN LISTS EXPECTED_LINES)
+      message("${Line}")
+    endforeach()
+    message(SEND_ERROR "Build KO")
+  endif()
+endmacro()
+
+message("Copy project")
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt.in
+  ${CMAKE_CURRENT_BINARY_DIR}/src/CMakeLists.txt COPYONLY)
+
+file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/exe1.c
+          ${CMAKE_CURRENT_SOURCE_DIR}/lib1.c
+  DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/src
+)
+
+message("Building ALL target")
+try_compile(RESULT
+  ${CMAKE_CURRENT_BINARY_DIR}/build
+  ${CMAKE_CURRENT_BINARY_DIR}/src
+  test
+  CMAKE_FLAGS
+    -DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}
+  OUTPUT_VARIABLE BUILD_OUTPUT)
+
+message("Output from build:\n${BUILD_OUTPUT}")
+
+#filter outputs
+string(REPLACE "\r" "" BUILD_OUTPUT "${BUILD_OUTPUT}")
+string(REPLACE "\n" ";" BUILD_OUTPUT "${BUILD_OUTPUT}")
+list(FILTER BUILD_OUTPUT INCLUDE REGEX "^.*CT:")
+
+unset(EXPECTED_LINES)
+list(APPEND EXPECTED_LINES "CT: Processing target_empty_prebuild")
+list(APPEND EXPECTED_LINES "CT: Processing target_empty_postbuild")
+list(APPEND EXPECTED_LINES "CT: Processing target_cmd")
+list(APPEND EXPECTED_LINES "CT: Processing target_cmd_prebuild")
+list(APPEND EXPECTED_LINES "CT: Processing target_cmd_postbuild")
+
+test_output()
+
+message("Building target_update_files target")
+try_compile(RESULT
+  ${CMAKE_CURRENT_BINARY_DIR}/build
+  ${CMAKE_CURRENT_BINARY_DIR}/src
+  test target_update_files
+  CMAKE_FLAGS
+    -DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}
+  OUTPUT_VARIABLE BUILD_OUTPUT)
+
+message("Output from build:\n${BUILD_OUTPUT}")
+
+#filter outputs
+string(REPLACE "\r" "" BUILD_OUTPUT "${BUILD_OUTPUT}")
+string(REPLACE "\n" ";" BUILD_OUTPUT "${BUILD_OUTPUT}")
+list(FILTER BUILD_OUTPUT INCLUDE REGEX "^.*CT:")
+
+unset(EXPECTED_LINES)
+list(APPEND EXPECTED_LINES "CT: Processing target_empty_prebuild")
+list(APPEND EXPECTED_LINES "CT: Processing target_empty_postbuild")
+list(APPEND EXPECTED_LINES "CT: generate C file another_file")
+list(APPEND EXPECTED_LINES "CT: generate text file dependsA")
+list(APPEND EXPECTED_LINES "CT: generate text file out_of_order_dep")
+list(APPEND EXPECTED_LINES "CT: generate text files A, B, and C")
+list(APPEND EXPECTED_LINES "CT: Processing target_update_files")
+
+test_output()
+
+message("Rerun target_update_files target")
+try_compile(RESULT
+  ${CMAKE_CURRENT_BINARY_DIR}/build
+  ${CMAKE_CURRENT_BINARY_DIR}/src
+  test target_update_files
+  CMAKE_FLAGS
+    -DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}
+  OUTPUT_VARIABLE BUILD_OUTPUT)
+
+message("Output from build:\n${BUILD_OUTPUT}")
+
+#filter outputs
+string(REPLACE "\r" "" BUILD_OUTPUT "${BUILD_OUTPUT}")
+string(REPLACE "\n" ";" BUILD_OUTPUT "${BUILD_OUTPUT}")
+list(FILTER BUILD_OUTPUT INCLUDE REGEX "^.*CT:")
+
+unset(EXPECTED_LINES)
+list(APPEND EXPECTED_LINES "CT: Processing target_empty_prebuild")
+list(APPEND EXPECTED_LINES "CT: Processing target_empty_postbuild")
+list(APPEND EXPECTED_LINES "CT: generate text files A, B, and C")
+list(APPEND EXPECTED_LINES "CT: Processing target_update_files")
+
+test_output()
diff --git a/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt.in 
b/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt.in
new file mode 100644
index 0000000..fed946c
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt.in
@@ -0,0 +1,108 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
+
+project(test C)
+
+if(CMAKE_C_COMPILER_ID STREQUAL "GHS")
+  add_link_options("-non_shared")
+endif()
+
+add_library(lib1 lib1.c)
+
+set(TEST_MISSING_TARGET_SRC 0)
+set(TEST_MISSING_TARGET_DEP 0)
+set(TEST_MISSING_DEP 0)
+set(TEST_DEP_CYCLE 0)
+
+add_executable(exe1 exe1.c)
+target_link_libraries(exe1 lib1)
+
+add_custom_target(target_cmd ALL
+  COMMAND ${CMAKE_COMMAND} -E echo "target_cmd" > target_cmd
+  COMMAND ${CMAKE_COMMAND} -E echo "target_cmd_extra" > target_cmd_extra.txt
+  BYPRODUCTS target_cmd target_cmd_extra.txt
+  COMMENT "CT: Processing target_cmd")
+
+add_custom_command(TARGET target_cmd PRE_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo "target_cmd_prebuild" > 
target_cmd_prebuild.txt
+  BYPRODUCTS target_cmd_prebuild.txt
+  COMMENT "CT: Processing target_cmd_prebuild")
+#event does not run for custom targets
+add_custom_command(TARGET target_cmd PRE_LINK
+  COMMAND ${CMAKE_COMMAND} -E echo "executing target_cmd_prelink commands"
+  COMMAND ${CMAKE_COMMAND} -E echo "target_cmd_prelink" > 
target_cmd_prelink.txt
+  BYPRODUCTS target_cmd_prelink.txt
+  COMMENT "CT: Processing target_cmd_prelink")
+add_custom_command(TARGET target_cmd POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo "executing target_cmd_postbuild commands"
+  COMMAND ${CMAKE_COMMAND} -E echo "target_cmd_postbuild" > 
target_cmd_postbuild.txt
+  BYPRODUCTS target_cmd_postbuild.txt
+  COMMENT "CT: Processing target_cmd_postbuild")
+
+add_custom_target(target_empty ALL
+  COMMENT "CT: Processing target_empty")
+
+add_custom_command(TARGET target_empty PRE_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo "target_empty_prebuild" > 
target_empty_prebuild.txt
+  BYPRODUCTS target_empty_prebuild.txt
+  COMMENT "CT: Processing target_empty_prebuild")
+add_custom_command(TARGET target_empty POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E echo "target_empty_postbuild" > 
target_empty_postbuild.txt
+  BYPRODUCTS target_empty_postbuild.txt
+  COMMENT "CT: Processing target_empty_postbuild")
+
+add_dependencies(target_cmd target_empty)
+
+add_custom_command(
+  OUTPUT out_of_order_dep.txt
+  COMMAND ${CMAKE_COMMAND} -E echo "out_of_order_dep" > out_of_order_dep.txt
+  COMMENT "CT: generate text file out_of_order_dep"
+  DEPENDS dependsA.txt
+)
+
+if(TEST_MISSING_TARGET_SRC)
+  set(SRC_FILE does_not_exist)
+endif()
+if(TEST_MISSING_TARGET_DEP)
+  set(DEP_FILE does_not_exist)
+endif()
+
+add_custom_target(target_update_files
+  DEPENDS genc_do_not_list.txt ${DEP_FILE}
+  SOURCES gena.txt genb.txt another_file.c ${SRC_FILE}
+  BYPRODUCTS junkit.txt
+  COMMAND ${CMAKE_COMMAND} -E copy another_file.c junkit.txt
+  COMMENT "CT: Processing target_update_files")
+
+add_custom_command(
+  OUTPUT force_rebuild gena.txt genb.txt genc_do_not_list.txt
+  COMMAND ${CMAKE_COMMAND} -E copy dependsA.txt gena.txt
+  COMMAND ${CMAKE_COMMAND} -E echo "genb" > genb.txt
+  COMMAND ${CMAKE_COMMAND} -E echo "genc" > genc_do_not_list.txt
+  DEPENDS out_of_order_dep.txt dependsA.txt
+  COMMENT "CT: generate text files A, B, and C"
+)
+
+if(TEST_MISSING_DEP)
+  set(MISSING_DEP MISSING_DEP)
+endif()
+if(TEST_DEP_CYCLE)
+  set(DEP_CYCLE out_of_order_dep.txt)
+endif()
+
+add_custom_command(
+  OUTPUT dependsA.txt
+  COMMAND ${CMAKE_COMMAND} -E echo "dependsA" > dependsA.txt
+  DEPENDS ${MISSING_DEP} ${DEP_CYCLE} another_file.c
+  COMMENT "CT: generate text file dependsA"
+)
+
+add_custom_command(
+  OUTPUT another_file.c
+  COMMAND ${CMAKE_COMMAND} -E echo "//auto-gen file" > another_file.c
+  COMMENT "CT: generate C file another_file"
+)
+
+add_dependencies(target_update_files target_empty)
diff --git a/Tests/GhsMulti/GhsMultiCustomTarget/exe1.c 
b/Tests/GhsMulti/GhsMultiCustomTarget/exe1.c
new file mode 100644
index 0000000..29ad70a
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiCustomTarget/exe1.c
@@ -0,0 +1,5 @@
+extern int func(void);
+int main(void)
+{
+  return func();
+}
diff --git a/Tests/GhsMulti/GhsMultiCustomTarget/lib1.c 
b/Tests/GhsMulti/GhsMultiCustomTarget/lib1.c
new file mode 100644
index 0000000..b35e9cc
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiCustomTarget/lib1.c
@@ -0,0 +1,4 @@
+int func(void)
+{
+  return 2;
+}
diff --git a/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiDepOrder/CMakeLists.txt
similarity index 56%
copy from Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt
copy to Tests/GhsMulti/GhsMultiDepOrder/CMakeLists.txt
index ed3094b..2e2871b 100644
--- a/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt
+++ b/Tests/GhsMulti/GhsMultiDepOrder/CMakeLists.txt
@@ -5,8 +5,8 @@ cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
 
 project(test C)
 
-add_custom_target(testTarget ALL echo this is a test)
-
-add_library(sharedLib SHARED file.c)
-
-add_library(moduleLib MODULE file.c)
+#set_property( GLOBAL PROPERTY GLOBAL_DEPENDS_DEBUG_MODE 1)
+add_subdirectory(exec)
+add_subdirectory(lib)
+add_subdirectory(protolib)
+add_dependencies(lib1 proto)
diff --git a/Tests/GhsMulti/GhsMultiDepOrder/exec/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiDepOrder/exec/CMakeLists.txt
new file mode 100644
index 0000000..85ee805
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiDepOrder/exec/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
+
+add_executable(exe1 exe1.c)
+target_link_libraries(exe1 lib1)
+target_include_directories(exe1 PRIVATE "${test_BINARY_DIR}")
+if(CMAKE_C_COMPILER_ID STREQUAL "GHS")
+  target_link_options(exe1 PRIVATE "-non_shared")
+endif()
diff --git a/Tests/GhsMulti/GhsMultiDepOrder/exec/exe1.c 
b/Tests/GhsMulti/GhsMultiDepOrder/exec/exe1.c
new file mode 100644
index 0000000..fbf4ed4
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiDepOrder/exec/exe1.c
@@ -0,0 +1,8 @@
+#include "lib1.h"
+#include "p.h"
+
+int main(void)
+{
+  return func1() + func2() + func3() + func1p() + func2p() + func3p() +
+    PROTO1 + PROTO2 + PROTO3;
+}
diff --git a/Tests/GhsMulti/GhsMultiDepOrder/lib/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiDepOrder/lib/CMakeLists.txt
new file mode 100644
index 0000000..ae30fa2
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiDepOrder/lib/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+add_library(lib1 STATIC
+  func1.c lib1.h
+  "${test_BINARY_DIR}/protolib/proto1.c"
+  "${test_BINARY_DIR}/protolib/proto1.h")
+set_source_files_properties(
+  "${test_BINARY_DIR}/protolib/proto1.c"
+  "${test_BINARY_DIR}/protolib/proto1.h"
+  PROPERTIES GENERATED 1)
+target_include_directories(lib1 PRIVATE "${test_BINARY_DIR}/protolib"
+  PUBLIC .)
+add_custom_command( TARGET lib1 POST_BUILD
+  COMMAND ${CMAKE_COMMAND} -E copy "${test_BINARY_DIR}/protolib/proto1.h" 
"${test_BINARY_DIR}/p.h"
+  COMMENT "Copy ${test_BINARY_DIR}/protolib/proto1.h ${test_BINARY_DIR}/p.h"
+  BYPRODUCTS "${test_BINARY_DIR}/p.h")
diff --git a/Tests/GhsMulti/GhsMultiDepOrder/lib/func1.c 
b/Tests/GhsMulti/GhsMultiDepOrder/lib/func1.c
new file mode 100644
index 0000000..53334fe
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiDepOrder/lib/func1.c
@@ -0,0 +1,17 @@
+#include "lib1.h"
+#include "proto1.h"
+
+int func1(void)
+{
+  return 1 + PROTO1;
+}
+
+int func2(void)
+{
+  return 2 + PROTO2;
+}
+
+int func3(void)
+{
+  return 3 + PROTO3;
+}
diff --git a/Tests/GhsMulti/GhsMultiDepOrder/lib/lib1.h 
b/Tests/GhsMulti/GhsMultiDepOrder/lib/lib1.h
new file mode 100644
index 0000000..5e99f02
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiDepOrder/lib/lib1.h
@@ -0,0 +1,3 @@
+extern int func1(void);
+extern int func2(void);
+extern int func3(void);
diff --git a/Tests/GhsMulti/GhsMultiDepOrder/protolib/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiDepOrder/protolib/CMakeLists.txt
new file mode 100644
index 0000000..8cb6869
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiDepOrder/protolib/CMakeLists.txt
@@ -0,0 +1,28 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
+
+add_custom_target(proto ALL
+  DEPENDS proto1.c
+          proto1.h
+  SOURCES
+          ${test_SOURCE_DIR}/protolib/proto1.c.in
+          ${test_SOURCE_DIR}/protolib/proto1.h.in
+  COMMENT "Creating proto files")
+
+add_custom_command(
+  OUTPUT proto1.c
+  COMMAND ${CMAKE_COMMAND} -E copy
+    ${test_SOURCE_DIR}/protolib/proto1.c.in proto1.c
+  DEPENDS ${test_SOURCE_DIR}/protolib/proto1.c.in
+  COMMENT "generate proto C files"
+)
+
+add_custom_command(
+  OUTPUT proto1.h
+  COMMAND ${CMAKE_COMMAND} -E copy
+    ${test_SOURCE_DIR}/protolib/proto1.h.in proto1.h
+  DEPENDS ${test_SOURCE_DIR}/protolib/proto1.h.in
+  COMMENT "generate proto H files"
+)
diff --git a/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.c.in 
b/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.c.in
new file mode 100644
index 0000000..0efb1bd
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.c.in
@@ -0,0 +1,16 @@
+#include "proto1.h"
+
+int func1p(void)
+{
+  return 1;
+}
+
+int func2p(void)
+{
+  return 2;
+}
+
+int func3p(void)
+{
+  return 3;
+}
diff --git a/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.h.in 
b/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.h.in
new file mode 100644
index 0000000..f2f93af
--- /dev/null
+++ b/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.h.in
@@ -0,0 +1,7 @@
+extern int func1p(void);
+extern int func2p(void);
+extern int func3p(void);
+
+#define PROTO1 0x1
+#define PROTO2 0x2
+#define PROTO3 0x3
diff --git a/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiExternalProject/CMakeLists.txt
similarity index 54%
copy from Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt
copy to Tests/GhsMulti/GhsMultiExternalProject/CMakeLists.txt
index ed3094b..24126c8 100644
--- a/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt
+++ b/Tests/GhsMulti/GhsMultiExternalProject/CMakeLists.txt
@@ -4,9 +4,11 @@
 cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
 
 project(test C)
-
-add_custom_target(testTarget ALL echo this is a test)
-
-add_library(sharedLib SHARED file.c)
-
-add_library(moduleLib MODULE file.c)
+include(ExternalProject)
+
+ExternalProject_Add(another_project
+  SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/empty
+  BINARY_DIR empty_build
+  INSTALL_COMMAND ""
+  TEST_COMMAND ""
+  )
diff --git a/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiExternalProject/empty/CMakeLists.txt
similarity index 57%
copy from Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt
copy to Tests/GhsMulti/GhsMultiExternalProject/empty/CMakeLists.txt
index ed3094b..6846a98 100644
--- a/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt
+++ b/Tests/GhsMulti/GhsMultiExternalProject/empty/CMakeLists.txt
@@ -3,10 +3,6 @@
 
 cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
 
-project(test C)
+project(empty NONE)
 
-add_custom_target(testTarget ALL echo this is a test)
-
-add_library(sharedLib SHARED file.c)
-
-add_library(moduleLib MODULE file.c)
+message("EMPTY PROJECT")
diff --git 
a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/App/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/App/CMakeLists.txt
index e431217..3837b5a 100644
--- a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/App/CMakeLists.txt
+++ b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/App/CMakeLists.txt
@@ -1,4 +1,3 @@
 add_executable(App Main.c)
-target_include_directories(App PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../Lib)
 target_link_libraries(App Lib)
 target_compile_options(App PUBLIC "-non_shared")
diff --git 
a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/Lib/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/Lib/CMakeLists.txt
index 00e0f59..bb9849a 100644
--- a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/Lib/CMakeLists.txt
+++ b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/Lib/CMakeLists.txt
@@ -1 +1,2 @@
 add_library(Lib HelperFun.c HelperFun.h)
+target_include_directories(Lib PUBLIC .)
diff --git 
a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityMonolith/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityMonolith/CMakeLists.txt
index c5db155..3f2f0eb 100644
--- a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityMonolith/CMakeLists.txt
+++ b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityMonolith/CMakeLists.txt
@@ -18,3 +18,4 @@ target_link_options(kernel PRIVATE -kernel)
 
 # create monolith INTEGRITY application
 add_executable(monolith test.int)
+add_dependencies(monolith vas)
diff --git a/Tests/GhsMulti/GhsMultiPlatform/file1.c 
b/Tests/GhsMulti/GhsMultiPlatform/file1.c
deleted file mode 100644
index 4132aa4..0000000
--- a/Tests/GhsMulti/GhsMultiPlatform/file1.c
+++ /dev/null
@@ -1,4 +0,0 @@
-int main(void)
-{
-  return -42;
-}
diff --git a/Tests/GhsMulti/GhsMultiRenameInstall/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiRenameInstall/CMakeLists.txt
index f5792b4..b2540d9 100644
--- a/Tests/GhsMulti/GhsMultiRenameInstall/CMakeLists.txt
+++ b/Tests/GhsMulti/GhsMultiRenameInstall/CMakeLists.txt
@@ -13,7 +13,7 @@ endif()
 
 if(RUN_TEST STREQUAL "SINGLE_EXEC")
   add_executable(exe1 exe.c)
-  set(targets_to_install ${targets_to_install} exe1)
+  set(targets_to_install exe1)
 endif()
 
 if(RUN_TEST STREQUAL "SINGLE_EXEC_RENAMED")
@@ -22,7 +22,7 @@ if(RUN_TEST STREQUAL "SINGLE_EXEC_RENAMED")
   set_property(TARGET exe1 PROPERTY RUNTIME_OUTPUT_DIRECTORY 
${name}_bin_$<CONFIG>)
   set_property(TARGET exe1 PROPERTY OUTPUT_NAME ${name}_$<CONFIG>)
   set_property(TARGET exe1 PROPERTY SUFFIX .bin)
-  set(targets_to_install ${targets_to_install} exe1)
+  set(targets_to_install exe1)
 endif()
 
 if(RUN_TEST STREQUAL "EXEC_AND_LIB")
@@ -33,7 +33,7 @@ if(RUN_TEST STREQUAL "EXEC_AND_LIB")
 
  add_executable(exe1 exe1.c)
  target_link_libraries(exe1 lib1)
- set(targets_to_install ${targets_to_install} exe1 lib1)
+ set(targets_to_install exe1 lib1)
 endif()
 
 install(TARGETS ${targets_to_install}
diff --git a/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt 
b/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt
index ed3094b..f5f3c55 100644
--- a/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt
+++ b/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt
@@ -5,8 +5,6 @@ cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
 
 project(test C)
 
-add_custom_target(testTarget ALL echo this is a test)
-
 add_library(sharedLib SHARED file.c)
 
 add_library(moduleLib MODULE file.c)

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=3b415c60c1a02b9ac76089a44c28e70692dcdef1
commit 3b415c60c1a02b9ac76089a44c28e70692dcdef1
Author:     Fred Baksik <froda...@gmail.com>
AuthorDate: Mon Apr 8 09:55:35 2019 -0400
Commit:     Fred Baksik <froda...@gmail.com>
CommitDate: Thu Apr 11 13:15:51 2019 -0400

    GHS: Update ExternalProject for GHS tools
    
    -- When using default values for the external project forward GHS platform
       variables so that the external project builds with the same tools as
       the original project.
    
    -- Fix issue with bad top level project when GHS_PRIMARY_TARGET is set but 
has
       no value.  In this case treat it as unset and use default value.

diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 948b921..104ef9f 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -421,6 +421,10 @@ External Project Definition
       different behavior depending on whether the build starts from a fresh
       build directory or re-uses previous build contents.
 
+      If the CMake generator is the ``Green Hills MULTI`` and not overridden 
then
+      the orginal projects settings for the GHS toolset and target system
+      customization cache variables are propagated into the external project.
+
     ``SOURCE_SUBDIR <dir>``
       When no ``CONFIGURE_COMMAND`` option is specified, the configure step
       assumes the external project has a ``CMakeLists.txt`` file at the top of
@@ -2849,18 +2853,6 @@ function(_ep_extract_configure_command var name)
       set(has_cmake_cache_default_args 1)
     endif()
 
-    if(has_cmake_cache_args OR has_cmake_cache_default_args)
-      set(_ep_cache_args_script "<TMP_DIR>/${name}-cache-$<CONFIG>.cmake")
-      if(has_cmake_cache_args)
-        _ep_command_line_to_initial_cache(script_initial_cache_force 
"${cmake_cache_args}" 1)
-      endif()
-      if(has_cmake_cache_default_args)
-        _ep_command_line_to_initial_cache(script_initial_cache_default 
"${cmake_cache_default_args}" 0)
-      endif()
-      _ep_write_initial_cache(${name} "${_ep_cache_args_script}" 
"${script_initial_cache_force}${script_initial_cache_default}")
-      list(APPEND cmd "-C${_ep_cache_args_script}")
-    endif()
-
     get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR)
     get_target_property(cmake_generator_instance ${name} 
_EP_CMAKE_GENERATOR_INSTANCE)
     get_target_property(cmake_generator_platform ${name} 
_EP_CMAKE_GENERATOR_PLATFORM)
@@ -2881,6 +2873,16 @@ function(_ep_extract_configure_command var name)
         list(APPEND cmd "-G${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}")
       else()
         list(APPEND cmd "-G${CMAKE_GENERATOR}")
+        if("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
+          set(has_cmake_cache_default_args 1)
+          set(cmake_cache_default_args ${cmake_cache_default_args}
+            "-DGHS_TARGET_PLATFORM:STRING=${GHS_TARGET_PLATFORM}"
+            "-DGHS_PRIMARY_TARGET:STRING=${GHS_PRIMARY_TARGET}"
+            "-DGHS_TOOLSET_ROOT:STRING=${GHS_TOOLSET_ROOT}"
+            "-DGHS_OS_ROOT:STRING=${GHS_OS_ROOT}"
+            "-DGHS_OS_DIR:STRING=${GHS_OS_DIR}"
+            "-DGHS_BSP_NAME:STRING=${GHS_BSP_NAME}")
+        endif()
       endif()
       if(cmake_generator_platform)
         message(FATAL_ERROR "Option CMAKE_GENERATOR_PLATFORM not allowed 
without CMAKE_GENERATOR.")
@@ -2902,6 +2904,18 @@ function(_ep_extract_configure_command var name)
       endif()
     endif()
 
+    if(has_cmake_cache_args OR has_cmake_cache_default_args)
+      set(_ep_cache_args_script "<TMP_DIR>/${name}-cache-$<CONFIG>.cmake")
+      if(has_cmake_cache_args)
+        _ep_command_line_to_initial_cache(script_initial_cache_force 
"${cmake_cache_args}" 1)
+      endif()
+      if(has_cmake_cache_default_args)
+        _ep_command_line_to_initial_cache(script_initial_cache_default 
"${cmake_cache_default_args}" 0)
+      endif()
+      _ep_write_initial_cache(${name} "${_ep_cache_args_script}" 
"${script_initial_cache_force}${script_initial_cache_default}")
+      list(APPEND cmd "-C${_ep_cache_args_script}")
+    endif()
+
     list(APPEND cmd "<SOURCE_DIR><SOURCE_SUBDIR>")
   endif()
 
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx 
b/Source/cmGlobalGhsMultiGenerator.cxx
index f9d7e75..b69dea0 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -638,7 +638,7 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(
   std::string tgt;
   const char* t =
     this->GetCMakeInstance()->GetCacheDefinition("GHS_PRIMARY_TARGET");
-  if (t) {
+  if (t && *t != '\0') {
     tgt = t;
     this->GetCMakeInstance()->MarkCliAsUsed("GHS_PRIMARY_TARGET");
   } else {

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=83c47ef5b8a6b1a63edbd82092d8eae68da453d6
commit 83c47ef5b8a6b1a63edbd82092d8eae68da453d6
Author:     Fred Baksik <froda...@gmail.com>
AuthorDate: Mon Apr 8 09:55:35 2019 -0400
Commit:     Fred Baksik <froda...@gmail.com>
CommitDate: Thu Apr 11 13:15:51 2019 -0400

    GHS: Update project layout to accommodate gbuild inconsistencies
    
    -- Do not use reference projects, use build hierarchy instead.
       gbuild has three parallel levels:
       * low -- Parallelizes compiling source files within a single project 
(.gpj)
         file when safe to do so.
       * medium -- Parallelizes processing files within a single linked output 
when
         safe to do so.
       * high [default] -- Parallelizes processing files whenever safe to do so,
         including linking task.
    
       Testing showed that for some combinations of gbuild / MULTI there are 
issues
       with building a project that uses references to target project files 
along with
       using {nobuild} option.
    
       Sometimes the archiving of a library and linking of an executable were
       happening in parallel and the build would fail when linking because the
       archive wasn't complete.
    
       This behavior was also inconsistent when running the build from MULTI and
       from the command line with gbuild. In some cases MULTI did not 
parallelize
       archiving and linking, but gbuild performed these actions in parallel.
    
       The parallel build issue was not seen when using a build hierarchy where 
the
       project listed the project files normally instead of using a reference 
link.
    
       The other option was to add the -parallel_level=medium to the command 
line
       when using "cmake --build" but this wouldn't fix the issue if gbuild 
itself
       was used to and the user might not be aware of the extra option used by 
cmake.

diff --git a/Source/cmGhsMultiTargetGenerator.cxx 
b/Source/cmGhsMultiTargetGenerator.cxx
index f59d410..b80da72 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -143,8 +143,6 @@ void cmGhsMultiTargetGenerator::GenerateTarget()
   }
   this->WriteSources(fout);
   fout.Close();
-
-  this->WriteReferenceFile(fproj);
 }
 
 cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator()
@@ -735,27 +733,6 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
   }
 }
 
-void cmGhsMultiTargetGenerator::WriteReferenceFile(std::string fproj)
-{
-  // Open the target ref file in copy-if-different mode.
-  std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
-  fname += "/";
-  fname += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
-  fname += "/";
-  fname += this->Name + "_REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION;
-  cmGeneratedFileStream fref(fname);
-  fref.SetCopyIfDifferent(true);
-  this->GetGlobalGenerator()->WriteFileHeader(fref);
-  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
-  fref << "    :reference=CMakeFiles/${PROJ_NAME}.project.gpj;" << fproj
-       << std::endl;
-  fref.Close();
-
-  // Store location of the reference file
-  this->GeneratorTarget->Target->SetProperty("GHS_REFERENCE_PROJECT",
-                                             fname.c_str());
-}
-
 bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
 {
   const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
diff --git a/Source/cmGhsMultiTargetGenerator.h 
b/Source/cmGhsMultiTargetGenerator.h
index 9a41c92..a131567 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -66,7 +66,6 @@ private:
   void WriteSourceProperty(std::ostream& fout, const cmSourceFile* sf,
                            std::string const& propName,
                            std::string const& propFlag);
-  void WriteReferenceFile(std::string fproj);
   static void WriteObjectLangOverride(std::ostream& fout,
                                       const cmSourceFile* sourceFile);
 
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx 
b/Source/cmGlobalGhsMultiGenerator.cxx
index 7cf0664..f9d7e75 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -352,66 +352,24 @@ void 
cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout,
     }
     fout << "\"" << this->OsDir << "\"" << std::endl;
   }
-
-  this->WriteSubProjects(fout, root);
 }
 
 void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
-                                                 cmLocalGenerator* root)
-{
-  fout << "CMakeFiles/" << root->GetProjectName() << this->GetAllTargetName()
-       << "_REF" << FILE_EXTENSION << " [Reference]" << std::endl;
-  fout << "{nobuild} CMakeFiles/" << root->GetProjectName() << ".target"
-       << FILE_EXTENSION << " [Project]" << std::endl;
-  fout << "{nobuild} CMakeFiles/" << root->GetProjectName() << ".project"
-       << FILE_EXTENSION << " [Project]" << std::endl;
-}
-
-void cmGlobalGhsMultiGenerator::WriteProjectRefLine(
-  std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
-  std::string& rootBinaryDir)
-{
-  const char* projRef = target->GetProperty("GHS_REFERENCE_PROJECT");
-  if (projRef) {
-    std::string projFile = projRef;
-    projFile = root->MaybeConvertToRelativePath(rootBinaryDir, projFile);
-    fout << projFile << " [Reference]\n";
-  } else {
-    /* Should never happen */
-    std::string message = "The project file reference for target [" +
-      target->GetName() + "] is missing.\n";
-    cmSystemTools::Error(message);
-    fout << "{comment} " << target->GetName() << " [missing reference file]\n";
-  }
-}
-
-void cmGlobalGhsMultiGenerator::WriteProjects(cmLocalGenerator* root)
+                                                 std::string& all_target)
 {
-  std::string fname = root->GetCurrentBinaryDirectory();
-  fname += "/CMakeFiles/";
-  fname += root->GetProjectName();
-  fname += ".project";
-  fname += FILE_EXTENSION;
-  cmGeneratedFileStream pf(fname);
-  pf.SetCopyIfDifferent(true);
-  this->WriteFileHeader(pf);
-  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, pf);
-
-  std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
-  rootBinaryDir += "/CMakeFiles";
-
+  fout << "CMakeFiles/" << all_target << " [Project]" << std::endl;
+  // All known targets
   for (cmGeneratorTarget const* target : this->ProjectTargets) {
     if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
         target->GetType() == cmStateEnums::MODULE_LIBRARY ||
         target->GetType() == cmStateEnums::SHARED_LIBRARY ||
         (target->GetType() == cmStateEnums::GLOBAL_TARGET &&
-         target->GetName() != this->GetInstallTargetName())) {
+         target->GetName() != GetInstallTargetName())) {
       continue;
     }
-    this->WriteProjectLine(pf, target, root, rootBinaryDir);
+    fout << "CMakeFiles/" << target->GetName() + ".tgt" + FILE_EXTENSION
+         << " [Project]" << std::endl;
   }
-
-  pf.Close();
 }
 
 void cmGlobalGhsMultiGenerator::WriteProjectLine(
@@ -446,25 +404,10 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
 
 void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
 {
-  std::string fname = root->GetCurrentBinaryDirectory();
-  fname += "/CMakeFiles/";
-  fname += root->GetProjectName();
-  fname += ".target";
-  fname += FILE_EXTENSION;
-  cmGeneratedFileStream tf(fname);
-  tf.SetCopyIfDifferent(true);
-  WriteFileHeader(tf);
-  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, tf);
-
   std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
   rootBinaryDir += "/CMakeFiles";
 
-  // ALL target
-  tf << root->GetProjectName() + "." + this->GetAllTargetName() +
-      FILE_EXTENSION
-     << " [Project]" << std::endl;
-
-  // All other targets
+  // All known targets
   for (cmGeneratorTarget const* target : this->ProjectTargets) {
     if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
         target->GetType() == cmStateEnums::MODULE_LIBRARY ||
@@ -475,8 +418,8 @@ void 
cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
     }
 
     // create target build file
-    fname = root->GetCurrentBinaryDirectory() + "/CMakeFiles/" +
-      target->GetName() + FILE_EXTENSION;
+    std::string name = target->GetName() + ".tgt" + FILE_EXTENSION;
+    std::string fname = rootBinaryDir + "/" + name;
     cmGeneratedFileStream fbld(fname);
     fbld.SetCopyIfDifferent(true);
     this->WriteFileHeader(fbld);
@@ -488,24 +431,24 @@ void 
cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
       cmSystemTools::Error(message);
     } else {
       for (auto& tgt : build) {
-        this->WriteProjectRefLine(fbld, tgt, root, rootBinaryDir);
+        WriteProjectLine(fbld, tgt, root, rootBinaryDir);
       }
     }
     fbld.Close();
-
-    tf << target->GetName() << FILE_EXTENSION << " [Project]" << std::endl;
   }
-  tf.Close();
 }
 
 void cmGlobalGhsMultiGenerator::WriteAllTarget(
-  cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
+  cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators,
+  std::string& all_target)
 {
   this->ProjectTargets.clear();
 
   // create target build file
-  std::string fname = root->GetCurrentBinaryDirectory() + "/CMakeFiles/" +
-    root->GetProjectName() + "." + this->GetAllTargetName() + FILE_EXTENSION;
+  all_target = root->GetProjectName() + "." + this->GetAllTargetName() +
+    ".tgt" + FILE_EXTENSION;
+  std::string fname =
+    root->GetCurrentBinaryDirectory() + "/CMakeFiles/" + all_target;
   cmGeneratedFileStream fbld(fname);
   fbld.SetCopyIfDifferent(true);
   this->WriteFileHeader(fbld);
@@ -513,12 +456,6 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget(
 
   // Collect all targets under this root generator and the transitive
   // closure of their dependencies.
-  /* NOTE: GetTargetSets() returns the set in a different order
-   * every time it is run even though nothing has changed.  To avoid
-   * creating a different build order sort the targets by name so that
-   * the inputs of calculating build order are the same (otherwise the
-   * build order will be different every time).
-   */
   TargetDependSet projectTargets;
   TargetDependSet originalTargets;
   this->GetTargetSets(projectTargets, originalTargets, root, generators);
@@ -551,22 +488,10 @@ void cmGlobalGhsMultiGenerator::WriteAllTarget(
           target->GetType() == cmStateEnums::SHARED_LIBRARY) {
         continue;
       }
-      this->WriteProjectRefLine(fbld, target, root, rootBinaryDir);
+      this->WriteProjectLine(fbld, target, root, rootBinaryDir);
     }
   }
   fbld.Close();
-
-  // Open the target ref file in copy-if-different mode.
-  std::string frn = root->GetCurrentBinaryDirectory() + "/CMakeFiles/" +
-    root->GetProjectName() + this->GetAllTargetName() + "_REF" +
-    FILE_EXTENSION;
-  cmGeneratedFileStream fref(frn);
-  fref.SetCopyIfDifferent(true);
-  this->WriteFileHeader(fref);
-  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
-  fref << "    :reference=CMakeFiles/${PROJ_NAME}.target.gpj;" << fname
-       << std::endl;
-  fref.Close();
 }
 
 void cmGlobalGhsMultiGenerator::Generate()
@@ -604,6 +529,7 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
   cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
 {
   std::string fname;
+  std::string all_target;
 
   if (generators.empty()) {
     return;
@@ -622,11 +548,12 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
   cmGeneratedFileStream top(fname);
   top.SetCopyIfDifferent(true);
   this->WriteTopLevelProject(top, root);
-  top.Close();
 
-  this->WriteAllTarget(root, generators);
+  this->WriteAllTarget(root, generators, all_target);
   this->WriteTargets(root);
-  this->WriteProjects(root);
+
+  this->WriteSubProjects(top, all_target);
+  top.Close();
 }
 
 std::vector<cmGlobalGenerator::GeneratedMakeCommand>
@@ -655,10 +582,12 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
 
   /* determine which top-project file to use */
   std::string proj = projectName + ".top" + FILE_EXTENSION;
-  std::string target = projectName + ".target" + FILE_EXTENSION;
   std::vector<std::string> files;
   cmSystemTools::Glob(projectDir, ".*\\.top\\.gpj", files);
   if (!files.empty()) {
+    /* if multiple top-projects are found in build directory
+     * then prefer projectName top-project.
+     */
     auto p = std::find(files.begin(), files.end(), proj);
     if (p == files.end()) {
       proj = files.at(0);
@@ -671,21 +600,18 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
         targetNames.end()) {
       makeCommand.Add("-clean");
     } else {
-      bool print_within = true;
       for (const auto& tname : targetNames) {
         if (!tname.empty()) {
-          if (print_within) {
-            makeCommand.Add("-within", target);
-            print_within = false;
-          }
-          if (tname.compare(tname.size() - 4, 4, ".gpj") == 0) {
-            makeCommand.Add(tname);
-          } else {
-            makeCommand.Add(tname + ".gpj");
-          }
+          makeCommand.Add(tname + ".tgt.gpj");
         }
       }
     }
+  } else {
+    /* transform name to default build */;
+    std::string all = proj;
+    all.replace(all.end() - 7, all.end(),
+                std::string(this->GetAllTargetName()) + ".tgt.gpj");
+    makeCommand.Add(all);
   }
   return { makeCommand };
 }
diff --git a/Source/cmGlobalGhsMultiGenerator.h 
b/Source/cmGlobalGhsMultiGenerator.h
index a964af8..98358c7 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -98,17 +98,15 @@ private:
   void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root);
   void WriteMacros(std::ostream& fout, cmLocalGenerator* root);
   void WriteHighLevelDirectives(cmLocalGenerator* root, std::ostream& fout);
-  void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root);
+  void WriteSubProjects(std::ostream& fout, std::string& all_target);
   void WriteTargets(cmLocalGenerator* root);
-  void WriteProjects(cmLocalGenerator* root);
   void WriteProjectLine(std::ostream& fout, cmGeneratorTarget const* target,
                         cmLocalGenerator* root, std::string& rootBinaryDir);
-  void WriteProjectRefLine(std::ostream& fout, cmGeneratorTarget const* target,
-                           cmLocalGenerator* root, std::string& rootBinaryDir);
   void WriteCustomRuleBOD(std::ostream& fout);
   void WriteCustomTargetBOD(std::ostream& fout);
   void WriteAllTarget(cmLocalGenerator* root,
-                      std::vector<cmLocalGenerator*>& generators);
+                      std::vector<cmLocalGenerator*>& generators,
+                      std::string& all_target);
 
   std::string TrimQuotes(std::string const& str);
 

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5d2e1404bdfa83eeae5b361bd7d8a882aadc7242
commit 5d2e1404bdfa83eeae5b361bd7d8a882aadc7242
Author:     Fred Baksik <froda...@gmail.com>
AuthorDate: Mon Apr 8 09:55:34 2019 -0400
Commit:     Fred Baksik <froda...@gmail.com>
CommitDate: Thu Apr 11 13:15:50 2019 -0400

    GHS: Update project layout to build targets correctly
    
    -- Restructure projects and files to support proper building of targets
       Build order is determined by hierarchy of project files and folders
       Custom targets may have been run multiple times in the original file / 
folder structure
    -- Default to build targets that are part of ALL target
    -- List all known targets for this project
       Includes global targets for ALL_BUILD and INSTALL
    -- Compute build order for building targets

diff --git a/Source/cmGhsMultiTargetGenerator.cxx 
b/Source/cmGhsMultiTargetGenerator.cxx
index 51d08cb..f59d410 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -13,13 +13,13 @@
 #include "cmMakefile.h"
 #include "cmOutputConverter.h"
 #include "cmSourceFile.h"
+#include "cmSourceFileLocation.h"
 #include "cmSourceGroup.h"
 #include "cmStateDirectory.h"
 #include "cmStateSnapshot.h"
 #include "cmStateTypes.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
-#include "cmTargetDepend.h"
 
 #include <algorithm>
 #include <ostream>
@@ -94,6 +94,16 @@ void cmGhsMultiTargetGenerator::Generate()
       this->TagType = GhsMultiGpj::CUSTOM_TARGET;
       break;
     }
+    case cmStateEnums::GLOBAL_TARGET: {
+      this->TargetNameReal = this->GeneratorTarget->GetName();
+      if (this->TargetNameReal ==
+          this->GetGlobalGenerator()->GetInstallTargetName()) {
+        this->TagType = GhsMultiGpj::CUSTOM_TARGET;
+      } else {
+        return;
+      }
+      break;
+    }
     default:
       return;
   }
@@ -120,10 +130,9 @@ void cmGhsMultiTargetGenerator::GenerateTarget()
   this->GetGlobalGenerator()->WriteFileHeader(fout);
   GhsMultiGpj::WriteGpjTag(this->TagType, fout);
 
-  const std::string language(
-    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName));
-
   if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
+    const std::string language(
+      this->GeneratorTarget->GetLinkerLanguage(this->ConfigName));
     this->WriteTargetSpecifics(fout, this->ConfigName);
     this->SetCompilerFlags(this->ConfigName, language);
     this->WriteCompilerFlags(fout, this->ConfigName, language);
@@ -132,23 +141,10 @@ void cmGhsMultiTargetGenerator::GenerateTarget()
     this->WriteTargetLinkLine(fout, this->ConfigName);
     this->WriteBuildEvents(fout);
   }
-  this->WriteReferences(fout);
   this->WriteSources(fout);
-
   fout.Close();
 
-  // Open the target ref file in copy-if-different mode.
-  std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
-  fname += "/";
-  fname += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
-  fname += "/";
-  fname += this->Name + "_REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION;
-  cmGeneratedFileStream fref(fname);
-  fref.SetCopyIfDifferent(true);
-  this->GetGlobalGenerator()->WriteFileHeader(fref);
-  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
-  fref << "    :reference=" << fproj << std::endl;
-  fref.Close();
+  this->WriteReferenceFile(fproj);
 }
 
 cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator()
@@ -739,27 +735,25 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
   }
 }
 
-void cmGhsMultiTargetGenerator::WriteReferences(std::ostream& fout)
+void cmGhsMultiTargetGenerator::WriteReferenceFile(std::string fproj)
 {
-  // FIXME - compare unordered to ordered projects
-  //         also needs transitive build order deps!
-  // Get the targets that this one depends upon
-  cmTargetDependSet unordered =
-    this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
-  cmGlobalGhsMultiGenerator::OrderedTargetDependSet ordered(unordered,
-                                                            this->Name);
-  for (auto& t : ordered) {
-    std::string tname = t->GetName();
-    std::string tpath = t->LocalGenerator->GetCurrentBinaryDirectory();
-    std::string rootpath = this->LocalGenerator->GetCurrentBinaryDirectory();
-    std::string outpath =
-      this->LocalGenerator->MaybeConvertToRelativePath(rootpath, tpath) + "/" +
-      tname + "REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION;
-
-    fout << outpath;
-    fout << "    ";
-    GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fout);
-  }
+  // Open the target ref file in copy-if-different mode.
+  std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
+  fname += "/";
+  fname += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+  fname += "/";
+  fname += this->Name + "_REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION;
+  cmGeneratedFileStream fref(fname);
+  fref.SetCopyIfDifferent(true);
+  this->GetGlobalGenerator()->WriteFileHeader(fref);
+  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
+  fref << "    :reference=CMakeFiles/${PROJ_NAME}.project.gpj;" << fproj
+       << std::endl;
+  fref.Close();
+
+  // Store location of the reference file
+  this->GeneratorTarget->Target->SetProperty("GHS_REFERENCE_PROJECT",
+                                             fname.c_str());
 }
 
 bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
diff --git a/Source/cmGhsMultiTargetGenerator.h 
b/Source/cmGhsMultiTargetGenerator.h
index 3ba3884..9a41c92 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -66,7 +66,7 @@ private:
   void WriteSourceProperty(std::ostream& fout, const cmSourceFile* sf,
                            std::string const& propName,
                            std::string const& propFlag);
-  void WriteReferences(std::ostream& fout);
+  void WriteReferenceFile(std::string fproj);
   static void WriteObjectLangOverride(std::ostream& fout,
                                       const cmSourceFile* sourceFile);
 
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx 
b/Source/cmGlobalGhsMultiGenerator.cxx
index f212efc..7cf0664 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -321,13 +321,11 @@ void 
cmGlobalGhsMultiGenerator::WriteCustomTargetBOD(std::ostream& fout)
           "}\n";
 }
 
-void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
-  std::ostream& fout, cmLocalGenerator* root,
-  std::vector<cmLocalGenerator*>& generators)
+void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout,
+                                                     cmLocalGenerator* root)
 {
-  WriteFileHeader(fout);
-
-  this->WriteMacros(fout);
+  this->WriteFileHeader(fout);
+  this->WriteMacros(fout, root);
   this->WriteHighLevelDirectives(root, fout);
   GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
 
@@ -355,73 +353,70 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
     fout << "\"" << this->OsDir << "\"" << std::endl;
   }
 
-  WriteSubProjects(fout, root, generators);
+  this->WriteSubProjects(fout, root);
 }
 
-void cmGlobalGhsMultiGenerator::WriteSubProjects(
-  std::ostream& fout, cmLocalGenerator* root,
-  std::vector<cmLocalGenerator*>& generators)
+void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout,
+                                                 cmLocalGenerator* root)
 {
-  this->DefaultTargets.clear();
-  this->ProjectTargets.clear();
-
-  // Collect all targets under this root generator and the transitive
-  // closure of their dependencies.
-  // FIXME -- what is correct list or is it build order
-  TargetDependSet projectTargets;
-  TargetDependSet originalTargets;
-  this->GetTargetSets(projectTargets, originalTargets, root, generators);
-  OrderedTargetDependSet orderedProjectTargets(projectTargets, "");
-
-  // determine the targets for ALL target
-  std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
-  for (cmGeneratorTarget const* target : orderedProjectTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-      continue;
-    }
-    this->ProjectTargets.push_back(target);
-    if (!cmSystemTools::IsOn(target->GetProperty("EXCLUDE_FROM_ALL"))) {
-      this->DefaultTargets.push_back(target);
-    }
-  }
-
-  fout << root->GetProjectName() << ".default" << FILE_EXTENSION
-       << " [Project]" << std::endl;
-  fout << "{nobuild} " << root->GetProjectName() << ".target" << FILE_EXTENSION
-       << " [Project]" << std::endl;
-  fout << "{nobuild} " << root->GetProjectName() << ".project"
+  fout << "CMakeFiles/" << root->GetProjectName() << this->GetAllTargetName()
+       << "_REF" << FILE_EXTENSION << " [Reference]" << std::endl;
+  fout << "{nobuild} CMakeFiles/" << root->GetProjectName() << ".target"
+       << FILE_EXTENSION << " [Project]" << std::endl;
+  fout << "{nobuild} CMakeFiles/" << root->GetProjectName() << ".project"
        << FILE_EXTENSION << " [Project]" << std::endl;
 }
 
-void cmGlobalGhsMultiGenerator::WriteDefaultProject(
-  std::ostream& fout, cmLocalGenerator* root,
-  std::vector<cmLocalGenerator*>& generators)
+void cmGlobalGhsMultiGenerator::WriteProjectRefLine(
+  std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
+  std::string& rootBinaryDir)
 {
-  // write out all the targets for this project
-  WriteFileHeader(fout);
-  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
-  std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
-  for (cmGeneratorTarget const* target : this->DefaultTargets) {
-    this->WriteProjectLine(fout, target, root, rootBinaryDir, false);
+  const char* projRef = target->GetProperty("GHS_REFERENCE_PROJECT");
+  if (projRef) {
+    std::string projFile = projRef;
+    projFile = root->MaybeConvertToRelativePath(rootBinaryDir, projFile);
+    fout << projFile << " [Reference]\n";
+  } else {
+    /* Should never happen */
+    std::string message = "The project file reference for target [" +
+      target->GetName() + "] is missing.\n";
+    cmSystemTools::Error(message);
+    fout << "{comment} " << target->GetName() << " [missing reference file]\n";
   }
 }
 
-void cmGlobalGhsMultiGenerator::WriteTargetProjects(
-  std::ostream& fout, cmLocalGenerator* root,
-  std::vector<cmLocalGenerator*>& generators, bool proj)
+void cmGlobalGhsMultiGenerator::WriteProjects(cmLocalGenerator* root)
 {
-  // write out all the targets for this project
-  WriteFileHeader(fout);
-  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
+  std::string fname = root->GetCurrentBinaryDirectory();
+  fname += "/CMakeFiles/";
+  fname += root->GetProjectName();
+  fname += ".project";
+  fname += FILE_EXTENSION;
+  cmGeneratedFileStream pf(fname);
+  pf.SetCopyIfDifferent(true);
+  this->WriteFileHeader(pf);
+  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, pf);
+
   std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
+  rootBinaryDir += "/CMakeFiles";
+
   for (cmGeneratorTarget const* target : this->ProjectTargets) {
-    this->WriteProjectLine(fout, target, root, rootBinaryDir, proj);
+    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
+        target->GetType() == cmStateEnums::MODULE_LIBRARY ||
+        target->GetType() == cmStateEnums::SHARED_LIBRARY ||
+        (target->GetType() == cmStateEnums::GLOBAL_TARGET &&
+         target->GetName() != this->GetInstallTargetName())) {
+      continue;
+    }
+    this->WriteProjectLine(pf, target, root, rootBinaryDir);
   }
+
+  pf.Close();
 }
 
 void cmGlobalGhsMultiGenerator::WriteProjectLine(
   std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
-  std::string& rootBinaryDir, bool proj)
+  std::string& rootBinaryDir)
 {
   const char* projName = target->GetProperty("GENERATOR_FILE_NAME");
   const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
@@ -440,7 +435,138 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
     std::string projFile = dir + projName + FILE_EXTENSION;
     fout << projFile;
     fout << " " << projType << std::endl;
+  } else {
+    /* Should never happen */
+    std::string message =
+      "The project file for target [" + target->GetName() + "] is missing.\n";
+    cmSystemTools::Error(message);
+    fout << "{comment} " << target->GetName() << " [missing project file]\n";
+  }
+}
+
+void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root)
+{
+  std::string fname = root->GetCurrentBinaryDirectory();
+  fname += "/CMakeFiles/";
+  fname += root->GetProjectName();
+  fname += ".target";
+  fname += FILE_EXTENSION;
+  cmGeneratedFileStream tf(fname);
+  tf.SetCopyIfDifferent(true);
+  WriteFileHeader(tf);
+  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, tf);
+
+  std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
+  rootBinaryDir += "/CMakeFiles";
+
+  // ALL target
+  tf << root->GetProjectName() + "." + this->GetAllTargetName() +
+      FILE_EXTENSION
+     << " [Project]" << std::endl;
+
+  // All other targets
+  for (cmGeneratorTarget const* target : this->ProjectTargets) {
+    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
+        target->GetType() == cmStateEnums::MODULE_LIBRARY ||
+        target->GetType() == cmStateEnums::SHARED_LIBRARY ||
+        (target->GetType() == cmStateEnums::GLOBAL_TARGET &&
+         target->GetName() != GetInstallTargetName())) {
+      continue;
+    }
+
+    // create target build file
+    fname = root->GetCurrentBinaryDirectory() + "/CMakeFiles/" +
+      target->GetName() + FILE_EXTENSION;
+    cmGeneratedFileStream fbld(fname);
+    fbld.SetCopyIfDifferent(true);
+    this->WriteFileHeader(fbld);
+    GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld);
+    std::vector<cmGeneratorTarget const*> build;
+    if (ComputeTargetBuildOrder(target, build)) {
+      std::string message = "The inter-target dependency graph for target [" +
+        target->GetName() + "] had a cycle.\n";
+      cmSystemTools::Error(message);
+    } else {
+      for (auto& tgt : build) {
+        this->WriteProjectRefLine(fbld, tgt, root, rootBinaryDir);
+      }
+    }
+    fbld.Close();
+
+    tf << target->GetName() << FILE_EXTENSION << " [Project]" << std::endl;
   }
+  tf.Close();
+}
+
+void cmGlobalGhsMultiGenerator::WriteAllTarget(
+  cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
+{
+  this->ProjectTargets.clear();
+
+  // create target build file
+  std::string fname = root->GetCurrentBinaryDirectory() + "/CMakeFiles/" +
+    root->GetProjectName() + "." + this->GetAllTargetName() + FILE_EXTENSION;
+  cmGeneratedFileStream fbld(fname);
+  fbld.SetCopyIfDifferent(true);
+  this->WriteFileHeader(fbld);
+  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld);
+
+  // Collect all targets under this root generator and the transitive
+  // closure of their dependencies.
+  /* NOTE: GetTargetSets() returns the set in a different order
+   * every time it is run even though nothing has changed.  To avoid
+   * creating a different build order sort the targets by name so that
+   * the inputs of calculating build order are the same (otherwise the
+   * build order will be different every time).
+   */
+  TargetDependSet projectTargets;
+  TargetDependSet originalTargets;
+  this->GetTargetSets(projectTargets, originalTargets, root, generators);
+  OrderedTargetDependSet sortedProjectTargets(projectTargets, "");
+  std::vector<cmGeneratorTarget const*> defaultTargets;
+  for (cmGeneratorTarget const* t : sortedProjectTargets) {
+    /* save list of all targets in sorted order */
+    this->ProjectTargets.push_back(t);
+  }
+  for (cmGeneratorTarget const* t : sortedProjectTargets) {
+    if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      continue;
+    }
+    if (!cmSystemTools::IsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) {
+      defaultTargets.push_back(t);
+    }
+  }
+  std::vector<cmGeneratorTarget const*> build;
+  if (ComputeTargetBuildOrder(defaultTargets, build)) {
+    std::string message = "The inter-target dependency graph for project [" +
+      root->GetProjectName() + "] had a cycle.\n";
+    cmSystemTools::Error(message);
+  } else {
+    // determine the targets for ALL target
+    std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
+    rootBinaryDir += "/CMakeFiles";
+    for (cmGeneratorTarget const* target : build) {
+      if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
+          target->GetType() == cmStateEnums::MODULE_LIBRARY ||
+          target->GetType() == cmStateEnums::SHARED_LIBRARY) {
+        continue;
+      }
+      this->WriteProjectRefLine(fbld, target, root, rootBinaryDir);
+    }
+  }
+  fbld.Close();
+
+  // Open the target ref file in copy-if-different mode.
+  std::string frn = root->GetCurrentBinaryDirectory() + "/CMakeFiles/" +
+    root->GetProjectName() + this->GetAllTargetName() + "_REF" +
+    FILE_EXTENSION;
+  cmGeneratedFileStream fref(frn);
+  fref.SetCopyIfDifferent(true);
+  this->WriteFileHeader(fref);
+  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
+  fref << "    :reference=CMakeFiles/${PROJ_NAME}.target.gpj;" << fname
+       << std::endl;
+  fref.Close();
 }
 
 void cmGlobalGhsMultiGenerator::Generate()
@@ -495,35 +621,12 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
 
   cmGeneratedFileStream top(fname);
   top.SetCopyIfDifferent(true);
-  this->WriteTopLevelProject(top, root, generators);
+  this->WriteTopLevelProject(top, root);
   top.Close();
 
-  fname = root->GetCurrentBinaryDirectory() + "/";
-  fname += root->GetProjectName();
-  fname += ".target";
-  fname += FILE_EXTENSION;
-  cmGeneratedFileStream target(fname);
-  target.SetCopyIfDifferent(true);
-  this->WriteTargetProjects(target, root, generators, false);
-  target.Close();
-
-  fname = root->GetCurrentBinaryDirectory() + "/";
-  fname += root->GetProjectName();
-  fname += ".project";
-  fname += FILE_EXTENSION;
-  cmGeneratedFileStream project(fname);
-  project.SetCopyIfDifferent(true);
-  this->WriteTargetProjects(project, root, generators, true);
-  project.Close();
-
-  fname = root->GetCurrentBinaryDirectory() + "/";
-  fname += root->GetProjectName();
-  fname += ".default";
-  fname += FILE_EXTENSION;
-  cmGeneratedFileStream default_targets(fname);
-  default_targets.SetCopyIfDifferent(true);
-  this->WriteDefaultProject(default_targets, root, generators);
-  default_targets.Close();
+  this->WriteAllTarget(root, generators);
+  this->WriteTargets(root);
+  this->WriteProjects(root);
 }
 
 std::vector<cmGlobalGenerator::GeneratedMakeCommand>
@@ -552,6 +655,7 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
 
   /* determine which top-project file to use */
   std::string proj = projectName + ".top" + FILE_EXTENSION;
+  std::string target = projectName + ".target" + FILE_EXTENSION;
   std::vector<std::string> files;
   cmSystemTools::Glob(projectDir, ".*\\.top\\.gpj", files);
   if (!files.empty()) {
@@ -567,8 +671,13 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
         targetNames.end()) {
       makeCommand.Add("-clean");
     } else {
+      bool print_within = true;
       for (const auto& tname : targetNames) {
         if (!tname.empty()) {
+          if (print_within) {
+            makeCommand.Add("-within", target);
+            print_within = false;
+          }
           if (tname.compare(tname.size() - 4, 4, ".gpj") == 0) {
             makeCommand.Add(tname);
           } else {
@@ -581,8 +690,10 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand(
   return { makeCommand };
 }
 
-void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout)
+void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout,
+                                            cmLocalGenerator* root)
 {
+  fout << "macro PROJ_NAME=" << root->GetProjectName() << std::endl;
   char const* ghsGpjMacros =
     this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
   if (nullptr != ghsGpjMacros) {
@@ -624,12 +735,12 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(
   char const* const customization =
     this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
   if (nullptr != customization && strlen(customization) > 0) {
-    fout << "customization=" << trimQuotes(customization) << std::endl;
+    fout << "customization=" << this->TrimQuotes(customization) << std::endl;
     this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
   }
 }
 
-std::string cmGlobalGhsMultiGenerator::trimQuotes(std::string const& str)
+std::string cmGlobalGhsMultiGenerator::TrimQuotes(std::string const& str)
 {
   std::string result;
   result.reserve(str.size());
@@ -662,3 +773,56 @@ 
cmGlobalGhsMultiGenerator::OrderedTargetDependSet::OrderedTargetDependSet(
 {
   this->insert(targets.begin(), targets.end());
 }
+
+bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder(
+  cmGeneratorTarget const* tgt, std::vector<cmGeneratorTarget const*>& build)
+{
+  std::vector<cmGeneratorTarget const*> t{ tgt };
+  return ComputeTargetBuildOrder(t, build);
+}
+
+bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder(
+  std::vector<cmGeneratorTarget const*>& tgt,
+  std::vector<cmGeneratorTarget const*>& build)
+{
+  std::set<cmGeneratorTarget const*> temp;
+  std::set<cmGeneratorTarget const*> perm;
+
+  for (auto ti : tgt) {
+    bool r = VisitTarget(temp, perm, build, ti);
+    if (r) {
+      return r;
+    }
+  }
+  return false;
+}
+
+bool cmGlobalGhsMultiGenerator::VisitTarget(
+  std::set<cmGeneratorTarget const*>& temp,
+  std::set<cmGeneratorTarget const*>& perm,
+  std::vector<cmGeneratorTarget const*>& order, cmGeneratorTarget const* ti)
+{
+  /* check if permanent mark is set*/
+  if (perm.find(ti) == perm.end()) {
+    /* set temporary mark; check if revisit*/
+    if (temp.insert(ti).second) {
+      /* sort targets lexicographically to ensure that nodes are always visited
+       * in the same order */
+      OrderedTargetDependSet sortedTargets(this->GetTargetDirectDepends(ti),
+                                           "");
+      for (auto& di : sortedTargets) {
+        if (this->VisitTarget(temp, perm, order, di)) {
+          return true;
+        }
+      }
+      /* mark as complete; insert into beginning of list*/
+      perm.insert(ti);
+      order.push_back(ti);
+      return false;
+    }
+    /* revisiting item - not a DAG */
+    return true;
+  }
+  /* already complete */
+  return false;
+}
diff --git a/Source/cmGlobalGhsMultiGenerator.h 
b/Source/cmGlobalGhsMultiGenerator.h
index 5027a7c..a964af8 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -78,23 +78,7 @@ public:
   // Write the common disclaimer text at the top of each build file.
   void WriteFileHeader(std::ostream& fout);
 
-  // Target dependency sorting
-  class TargetSet : public std::set<cmGeneratorTarget const*>
-  {
-  };
-  class TargetCompare
-  {
-    std::string First;
-
-  public:
-    TargetCompare(std::string first)
-      : First(std::move(first))
-    {
-    }
-    bool operator()(cmGeneratorTarget const* l,
-                    cmGeneratorTarget const* r) const;
-  };
-  class OrderedTargetDependSet;
+  const char* GetInstallTargetName() const override { return "install"; }
 
 protected:
   void Generate() override;
@@ -111,30 +95,55 @@ private:
   /* top-level project */
   void OutputTopLevelProject(cmLocalGenerator* root,
                              std::vector<cmLocalGenerator*>& generators);
-  void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root,
-                            std::vector<cmLocalGenerator*>& generators);
-  void WriteMacros(std::ostream& fout);
+  void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root);
+  void WriteMacros(std::ostream& fout, cmLocalGenerator* root);
   void WriteHighLevelDirectives(cmLocalGenerator* root, std::ostream& fout);
-  void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root,
-                        std::vector<cmLocalGenerator*>& generators);
-  void WriteTargetProjects(std::ostream& fout, cmLocalGenerator* root,
-                           std::vector<cmLocalGenerator*>& generators,
-                           bool proj);
-  void WriteDefaultProject(std::ostream& fout, cmLocalGenerator* root,
-                           std::vector<cmLocalGenerator*>& generators);
+  void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root);
+  void WriteTargets(cmLocalGenerator* root);
+  void WriteProjects(cmLocalGenerator* root);
   void WriteProjectLine(std::ostream& fout, cmGeneratorTarget const* target,
-                        cmLocalGenerator* root, std::string& rootBinaryDir,
-                        bool proj);
+                        cmLocalGenerator* root, std::string& rootBinaryDir);
+  void WriteProjectRefLine(std::ostream& fout, cmGeneratorTarget const* target,
+                           cmLocalGenerator* root, std::string& rootBinaryDir);
   void WriteCustomRuleBOD(std::ostream& fout);
   void WriteCustomTargetBOD(std::ostream& fout);
+  void WriteAllTarget(cmLocalGenerator* root,
+                      std::vector<cmLocalGenerator*>& generators);
 
-  std::string trimQuotes(std::string const& str);
+  std::string TrimQuotes(std::string const& str);
 
   std::string OsDir;
   static const char* DEFAULT_BUILD_PROGRAM;
   static const char* DEFAULT_TOOLSET_ROOT;
-  std::vector<cmGeneratorTarget const*> DefaultTargets;
+
+  bool ComputeTargetBuildOrder(cmGeneratorTarget const* tgt,
+                               std::vector<cmGeneratorTarget const*>& build);
+  bool ComputeTargetBuildOrder(std::vector<cmGeneratorTarget const*>& tgt,
+                               std::vector<cmGeneratorTarget const*>& build);
+  bool VisitTarget(std::set<cmGeneratorTarget const*>& temp,
+                   std::set<cmGeneratorTarget const*>& perm,
+                   std::vector<cmGeneratorTarget const*>& order,
+                   cmGeneratorTarget const* ti);
+
   std::vector<cmGeneratorTarget const*> ProjectTargets;
+
+  // Target sorting
+  class TargetSet : public std::set<cmGeneratorTarget const*>
+  {
+  };
+  class TargetCompare
+  {
+    std::string First;
+
+  public:
+    TargetCompare(std::string first)
+      : First(std::move(first))
+    {
+    }
+    bool operator()(cmGeneratorTarget const* l,
+                    cmGeneratorTarget const* r) const;
+  };
+  class OrderedTargetDependSet;
 };
 
 class cmGlobalGhsMultiGenerator::OrderedTargetDependSet
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 3746965..2d9b806 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -2336,7 +2336,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P 
${CMake_SOURCE_DIR}/Utilities/Release
     endmacro()
     macro(add_test_GhsMulti_rename_install test_name)
       add_test_GhsMulti( ${test_name} GhsMultiRenameInstall ${test_name}
-        "-DCMAKE_INSTALL_PREFIX=. -DRUN_TEST=${test_name}" 
${CMAKE_CMAKE_COMMAND} -P ./cmake_install.cmake)
+        "-DCMAKE_INSTALL_PREFIX=. -DRUN_TEST=${test_name}" 
${CMAKE_CMAKE_COMMAND} --build . --target install)
     endmacro()
     #unset ghs config variables
     unset(ghs_config_name)

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b6bfa7eeb29937fbed44153518abfa4f28b9aa62
commit b6bfa7eeb29937fbed44153518abfa4f28b9aa62
Author:     Fred Baksik <froda...@gmail.com>
AuthorDate: Mon Apr 8 09:55:34 2019 -0400
Commit:     Fred Baksik <froda...@gmail.com>
CommitDate: Thu Apr 11 13:15:50 2019 -0400

    GHS: Support add_dependencies() command
    
    -- use references to list target dependencies

diff --git a/Source/cmGhsMultiTargetGenerator.cxx 
b/Source/cmGhsMultiTargetGenerator.cxx
index 725c4b4..51d08cb 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -109,12 +109,12 @@ void cmGhsMultiTargetGenerator::Generate()
 
 void cmGhsMultiTargetGenerator::GenerateTarget()
 {
-  // Open the filestream in copy-if-different mode.
-  std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
-  fname += "/";
-  fname += this->Name;
-  fname += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
-  cmGeneratedFileStream fout(fname);
+  // Open the target file in copy-if-different mode.
+  std::string fproj = this->LocalGenerator->GetCurrentBinaryDirectory();
+  fproj += "/";
+  fproj += this->Name;
+  fproj += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
+  cmGeneratedFileStream fout(fproj);
   fout.SetCopyIfDifferent(true);
 
   this->GetGlobalGenerator()->WriteFileHeader(fout);
@@ -132,9 +132,23 @@ void cmGhsMultiTargetGenerator::GenerateTarget()
     this->WriteTargetLinkLine(fout, this->ConfigName);
     this->WriteBuildEvents(fout);
   }
-  this->WriteSources(fout);
   this->WriteReferences(fout);
+  this->WriteSources(fout);
+
   fout.Close();
+
+  // Open the target ref file in copy-if-different mode.
+  std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
+  fname += "/";
+  fname += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+  fname += "/";
+  fname += this->Name + "_REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION;
+  cmGeneratedFileStream fref(fname);
+  fref.SetCopyIfDifferent(true);
+  this->GetGlobalGenerator()->WriteFileHeader(fref);
+  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
+  fref << "    :reference=" << fproj << std::endl;
+  fref.Close();
 }
 
 cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator()
@@ -489,7 +503,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& 
fout_proj)
 
   /* list of known groups and the order they are displayed in a project file */
   const std::vector<std::string> standardGroups = {
-    "Header Files", "Source Files",     "CMake Rules",
+    "CMake Rules",  "Header Files",     "Source Files",
     "Object Files", "Object Libraries", "Resources"
   };
 
@@ -667,7 +681,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& 
fout_proj)
           fname += std::to_string(cmdcount++) + "_";
           fname += (sf->GetLocation()).GetName();
           fname += this->CmdWindowsShell ? ".bat" : ".sh";
-          cmGeneratedFileStream f(fname.c_str());
+          cmGeneratedFileStream f(fname);
           f.SetCopyIfDifferent(true);
           this->WriteCustomCommandsHelper(f, ccg);
           f.Close();
@@ -727,11 +741,8 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
 
 void cmGhsMultiTargetGenerator::WriteReferences(std::ostream& fout)
 {
-  // This only applies to INTEGRITY Applications
-  if (this->TagType != GhsMultiGpj::INTERGRITY_APPLICATION) {
-    return;
-  }
-
+  // FIXME - compare unordered to ordered projects
+  //         also needs transitive build order deps!
   // Get the targets that this one depends upon
   cmTargetDependSet unordered =
     this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
@@ -748,9 +759,6 @@ void 
cmGhsMultiTargetGenerator::WriteReferences(std::ostream& fout)
     fout << outpath;
     fout << "    ";
     GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fout);
-
-    // Tell the global generator that a reference project needs to be created
-    t->Target->SetProperty("GHS_REFERENCE_PROJECT", "ON");
   }
 }
 
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx 
b/Source/cmGlobalGhsMultiGenerator.cxx
index 2180770..f212efc 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -322,7 +322,7 @@ void 
cmGlobalGhsMultiGenerator::WriteCustomTargetBOD(std::ostream& fout)
 }
 
 void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
-  std::ostream& fout, std::string& ename, cmLocalGenerator* root,
+  std::ostream& fout, cmLocalGenerator* root,
   std::vector<cmLocalGenerator*>& generators)
 {
   WriteFileHeader(fout);
@@ -355,64 +355,80 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
     fout << "\"" << this->OsDir << "\"" << std::endl;
   }
 
-  WriteSubProjects(fout, ename, root, generators);
+  WriteSubProjects(fout, root, generators);
 }
 
 void cmGlobalGhsMultiGenerator::WriteSubProjects(
-  std::ostream& fout, std::string& ename, cmLocalGenerator* root,
+  std::ostream& fout, cmLocalGenerator* root,
   std::vector<cmLocalGenerator*>& generators)
 {
-  this->ExcludedTargets.clear();
+  this->DefaultTargets.clear();
+  this->ProjectTargets.clear();
 
   // Collect all targets under this root generator and the transitive
   // closure of their dependencies.
+  // FIXME -- what is correct list or is it build order
   TargetDependSet projectTargets;
   TargetDependSet originalTargets;
   this->GetTargetSets(projectTargets, originalTargets, root, generators);
   OrderedTargetDependSet orderedProjectTargets(projectTargets, "");
 
-  // write out all the targets for ALL target
+  // determine the targets for ALL target
   std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
   for (cmGeneratorTarget const* target : orderedProjectTargets) {
     if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       continue;
     }
-    if (cmSystemTools::IsOn(target->GetProperty("EXCLUDE_FROM_ALL"))) {
-      this->ExcludedTargets.push_back(target);
-      continue;
+    this->ProjectTargets.push_back(target);
+    if (!cmSystemTools::IsOn(target->GetProperty("EXCLUDE_FROM_ALL"))) {
+      this->DefaultTargets.push_back(target);
     }
-    this->WriteProjectLine(fout, target, root, rootBinaryDir);
-  }
-  if (!this->ExcludedTargets.empty()) {
-    fout << "{nobuild} " << ename << " [Project]" << std::endl;
   }
+
+  fout << root->GetProjectName() << ".default" << FILE_EXTENSION
+       << " [Project]" << std::endl;
+  fout << "{nobuild} " << root->GetProjectName() << ".target" << FILE_EXTENSION
+       << " [Project]" << std::endl;
+  fout << "{nobuild} " << root->GetProjectName() << ".project"
+       << FILE_EXTENSION << " [Project]" << std::endl;
 }
 
-void cmGlobalGhsMultiGenerator::WriteExcludedProjects(
+void cmGlobalGhsMultiGenerator::WriteDefaultProject(
   std::ostream& fout, cmLocalGenerator* root,
   std::vector<cmLocalGenerator*>& generators)
 {
-  // write out all the excluded targets
+  // write out all the targets for this project
+  WriteFileHeader(fout);
+  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
   std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
-  for (cmGeneratorTarget const* target : this->ExcludedTargets) {
-    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-      continue;
-    }
-    this->WriteProjectLine(fout, target, root, rootBinaryDir);
+  for (cmGeneratorTarget const* target : this->DefaultTargets) {
+    this->WriteProjectLine(fout, target, root, rootBinaryDir, false);
+  }
+}
+
+void cmGlobalGhsMultiGenerator::WriteTargetProjects(
+  std::ostream& fout, cmLocalGenerator* root,
+  std::vector<cmLocalGenerator*>& generators, bool proj)
+{
+  // write out all the targets for this project
+  WriteFileHeader(fout);
+  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
+  std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
+  for (cmGeneratorTarget const* target : this->ProjectTargets) {
+    this->WriteProjectLine(fout, target, root, rootBinaryDir, proj);
   }
-  this->ExcludedTargets.clear();
 }
 
 void cmGlobalGhsMultiGenerator::WriteProjectLine(
   std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
-  std::string& rootBinaryDir)
+  std::string& rootBinaryDir, bool proj)
 {
   const char* projName = target->GetProperty("GENERATOR_FILE_NAME");
   const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
   if (projName && projType) {
     cmLocalGenerator* lg = target->GetLocalGenerator();
     std::string dir = lg->GetCurrentBinaryDirectory();
-    dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir.c_str());
+    dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir);
     if (dir == ".") {
       dir.clear();
     } else {
@@ -424,23 +440,6 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine(
     std::string projFile = dir + projName + FILE_EXTENSION;
     fout << projFile;
     fout << " " << projType << std::endl;
-
-    if (cmSystemTools::IsOn(target->GetProperty("GHS_REFERENCE_PROJECT"))) {
-      // create reference project
-      std::string fname = dir;
-      fname += target->GetName();
-      fname += "REF";
-      fname += FILE_EXTENSION;
-
-      cmGeneratedFileStream fref(fname);
-      fref.SetCopyIfDifferent(true);
-
-      this->WriteFileHeader(fref);
-      GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
-      fref << "    :reference=" << projFile << std::endl;
-
-      fref.Close();
-    }
   }
 }
 
@@ -468,7 +467,7 @@ void cmGlobalGhsMultiGenerator::Generate()
   // create custom target BOD file
   fname = this->GetCMakeInstance()->GetHomeOutputDirectory() +
     "/CMakeFiles/custom_target.bod";
-  cmGeneratedFileStream ftarget(fname.c_str());
+  cmGeneratedFileStream ftarget(fname);
   ftarget.SetCopyIfDifferent(true);
   this->WriteFileHeader(ftarget);
   this->WriteCustomTargetBOD(ftarget);
@@ -479,7 +478,6 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
   cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
 {
   std::string fname;
-  std::string ename;
 
   if (generators.empty()) {
     return;
@@ -495,24 +493,37 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
   fname += ".top";
   fname += FILE_EXTENSION;
 
-  ename = root->GetProjectName();
-  ename += ".nobuild";
-  ename += FILE_EXTENSION;
-
   cmGeneratedFileStream top(fname);
   top.SetCopyIfDifferent(true);
-  this->WriteTopLevelProject(top, ename, root, generators);
+  this->WriteTopLevelProject(top, root, generators);
   top.Close();
 
-  if (!this->ExcludedTargets.empty()) {
-    ename = root->GetCurrentBinaryDirectory() + "/" + ename;
-    cmGeneratedFileStream exclude(ename);
-    exclude.SetCopyIfDifferent(true);
-    WriteFileHeader(exclude);
-    GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, exclude);
-    this->WriteExcludedProjects(exclude, root, generators);
-    exclude.Close();
-  }
+  fname = root->GetCurrentBinaryDirectory() + "/";
+  fname += root->GetProjectName();
+  fname += ".target";
+  fname += FILE_EXTENSION;
+  cmGeneratedFileStream target(fname);
+  target.SetCopyIfDifferent(true);
+  this->WriteTargetProjects(target, root, generators, false);
+  target.Close();
+
+  fname = root->GetCurrentBinaryDirectory() + "/";
+  fname += root->GetProjectName();
+  fname += ".project";
+  fname += FILE_EXTENSION;
+  cmGeneratedFileStream project(fname);
+  project.SetCopyIfDifferent(true);
+  this->WriteTargetProjects(project, root, generators, true);
+  project.Close();
+
+  fname = root->GetCurrentBinaryDirectory() + "/";
+  fname += root->GetProjectName();
+  fname += ".default";
+  fname += FILE_EXTENSION;
+  cmGeneratedFileStream default_targets(fname);
+  default_targets.SetCopyIfDifferent(true);
+  this->WriteDefaultProject(default_targets, root, generators);
+  default_targets.Close();
 }
 
 std::vector<cmGlobalGenerator::GeneratedMakeCommand>
diff --git a/Source/cmGlobalGhsMultiGenerator.h 
b/Source/cmGlobalGhsMultiGenerator.h
index a987205..5027a7c 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -111,18 +111,20 @@ private:
   /* top-level project */
   void OutputTopLevelProject(cmLocalGenerator* root,
                              std::vector<cmLocalGenerator*>& generators);
-  void WriteTopLevelProject(std::ostream& fout, std::string& ename,
-                            cmLocalGenerator* root,
+  void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root,
                             std::vector<cmLocalGenerator*>& generators);
   void WriteMacros(std::ostream& fout);
   void WriteHighLevelDirectives(cmLocalGenerator* root, std::ostream& fout);
-  void WriteSubProjects(std::ostream& fout, std::string& ename,
-                        cmLocalGenerator* root,
+  void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root,
                         std::vector<cmLocalGenerator*>& generators);
-  void WriteExcludedProjects(std::ostream& fout, cmLocalGenerator* root,
-                             std::vector<cmLocalGenerator*>& generators);
+  void WriteTargetProjects(std::ostream& fout, cmLocalGenerator* root,
+                           std::vector<cmLocalGenerator*>& generators,
+                           bool proj);
+  void WriteDefaultProject(std::ostream& fout, cmLocalGenerator* root,
+                           std::vector<cmLocalGenerator*>& generators);
   void WriteProjectLine(std::ostream& fout, cmGeneratorTarget const* target,
-                        cmLocalGenerator* root, std::string& rootBinaryDir);
+                        cmLocalGenerator* root, std::string& rootBinaryDir,
+                        bool proj);
   void WriteCustomRuleBOD(std::ostream& fout);
   void WriteCustomTargetBOD(std::ostream& fout);
 
@@ -131,7 +133,8 @@ private:
   std::string OsDir;
   static const char* DEFAULT_BUILD_PROGRAM;
   static const char* DEFAULT_TOOLSET_ROOT;
-  std::vector<cmGeneratorTarget const*> ExcludedTargets;
+  std::vector<cmGeneratorTarget const*> DefaultTargets;
+  std::vector<cmGeneratorTarget const*> ProjectTargets;
 };
 
 class cmGlobalGhsMultiGenerator::OrderedTargetDependSet

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=39ee9718d9a56e7b8b15f63576f042415a2771f8
commit 39ee9718d9a56e7b8b15f63576f042415a2771f8
Author:     Fred Baksik <froda...@gmail.com>
AuthorDate: Mon Apr 8 09:55:34 2019 -0400
Commit:     Fred Baksik <froda...@gmail.com>
CommitDate: Thu Apr 11 13:15:50 2019 -0400

    GHS: Support add_custom_target() command
    
    -- add new project type that runs shell scripts in proper order

diff --git a/Source/cmGhsMultiGpj.cxx b/Source/cmGhsMultiGpj.cxx
index 8b69b51..da27971 100644
--- a/Source/cmGhsMultiGpj.cxx
+++ b/Source/cmGhsMultiGpj.cxx
@@ -9,7 +9,8 @@ static const char* GHS_TAG[] = { "[INTEGRITY Application]",
                                  "[Project]",
                                  "[Program]",
                                  "[Reference]",
-                                 "[Subproject]" };
+                                 "[Subproject]",
+                                 "[Custom Target]" };
 
 const char* GhsMultiGpj::GetGpjTag(Types gpjType)
 {
@@ -21,6 +22,7 @@ const char* GhsMultiGpj::GetGpjTag(Types gpjType)
     case PROGRAM:
     case REFERENCE:
     case SUBPROJECT:
+    case CUSTOM_TARGET:
       tag = GHS_TAG[gpjType];
       break;
     default:
diff --git a/Source/cmGhsMultiGpj.h b/Source/cmGhsMultiGpj.h
index 420eab1..e588150 100644
--- a/Source/cmGhsMultiGpj.h
+++ b/Source/cmGhsMultiGpj.h
@@ -16,7 +16,8 @@ public:
     PROJECT,
     PROGRAM,
     REFERENCE,
-    SUBPROJECT
+    SUBPROJECT,
+    CUSTOM_TARGET
   };
 
   static void WriteGpjTag(Types gpjType, std::ostream& fout);
diff --git a/Source/cmGhsMultiTargetGenerator.cxx 
b/Source/cmGhsMultiTargetGenerator.cxx
index 9d0d195..725c4b4 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -90,10 +90,9 @@ void cmGhsMultiTargetGenerator::Generate()
       return;
     }
     case cmStateEnums::UTILITY: {
-      std::string msg = "add_custom_target(<name> ...) not supported: ";
-      msg += this->Name;
-      cmSystemTools::Message(msg);
-      return;
+      this->TargetNameReal = this->GeneratorTarget->GetName();
+      this->TagType = GhsMultiGpj::CUSTOM_TARGET;
+      break;
     }
     default:
       return;
@@ -124,13 +123,15 @@ void cmGhsMultiTargetGenerator::GenerateTarget()
   const std::string language(
     this->GeneratorTarget->GetLinkerLanguage(this->ConfigName));
 
-  this->WriteTargetSpecifics(fout, this->ConfigName);
-  this->SetCompilerFlags(this->ConfigName, language);
-  this->WriteCompilerFlags(fout, this->ConfigName, language);
-  this->WriteCompilerDefinitions(fout, this->ConfigName, language);
-  this->WriteIncludes(fout, this->ConfigName, language);
-  this->WriteTargetLinkLine(fout, this->ConfigName);
-  this->WriteBuildEvents(fout);
+  if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
+    this->WriteTargetSpecifics(fout, this->ConfigName);
+    this->SetCompilerFlags(this->ConfigName, language);
+    this->WriteCompilerFlags(fout, this->ConfigName, language);
+    this->WriteCompilerDefinitions(fout, this->ConfigName, language);
+    this->WriteIncludes(fout, this->ConfigName, language);
+    this->WriteTargetLinkLine(fout, this->ConfigName);
+    this->WriteBuildEvents(fout);
+  }
   this->WriteSources(fout);
   this->WriteReferences(fout);
   fout.Close();
@@ -315,9 +316,11 @@ void 
cmGhsMultiTargetGenerator::WriteBuildEvents(std::ostream& fout)
     fout, this->GeneratorTarget->GetPreBuildCommands(),
     std::string("prebuild"), std::string("preexecShell"));
 
-  this->WriteBuildEventsHelper(
-    fout, this->GeneratorTarget->GetPreLinkCommands(), std::string("prelink"),
-    std::string("preexecShell"));
+  if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
+    this->WriteBuildEventsHelper(
+      fout, this->GeneratorTarget->GetPreLinkCommands(),
+      std::string("prelink"), std::string("preexecShell"));
+  }
 
   this->WriteBuildEventsHelper(
     fout, this->GeneratorTarget->GetPostBuildCommands(),
@@ -343,7 +346,12 @@ void cmGhsMultiTargetGenerator::WriteBuildEventsHelper(
     f.SetCopyIfDifferent(true);
     this->WriteCustomCommandsHelper(f, ccg);
     f.Close();
-    fout << "    :" << cmd << "=\"" << fname << "\"" << std::endl;
+    if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
+      fout << "    :" << cmd << "=\"" << fname << "\"" << std::endl;
+    } else {
+      fout << fname << std::endl;
+      fout << "    :outputName=\"" << fname << ".rule\"" << std::endl;
+    }
     for (auto& byp : ccg.GetByproducts()) {
       fout << "    :extraOutputFile=\"" << byp << "\"" << std::endl;
     }
@@ -499,6 +507,14 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& 
fout_proj)
       groupFilesList[i] = *n;
       i += 1;
       groupNames.erase(gn);
+    } else if (this->TagType == GhsMultiGpj::CUSTOM_TARGET &&
+               gn == "CMake Rules") {
+      /* make sure that rules folder always exists in case of custom targets
+       * that have no custom commands except for pre or post build events.
+       */
+      groupFilesList.resize(groupFilesList.size() + 1);
+      groupFilesList[i] = gn;
+      i += 1;
     }
   }
 
@@ -575,37 +591,46 @@ void 
cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
     if (sg != "CMake Rules") {
       /* output rule for each source file */
       for (const cmSourceFile* si : groupFiles[sg]) {
-
+        bool compile = true;
         // Convert filename to native system
         // WORKAROUND: GHS MULTI 6.1.4 and 6.1.6 are known to need backslash on
         // windows when opening some files from the search window.
         std::string fname(si->GetFullPath());
         cmSystemTools::ConvertToOutputSlashes(fname);
 
-        /* Comment out any custom command dependencies to prevent from
-         * being considered part of the build.
+        /* For custom targets list any associated sources,
+         * comment out source code to prevent it from being
+         * compiled when processing this target.
+         * Otherwise, comment out any custom command (main) dependencies that
+         * are listed as source files to prevent them from being considered
+         * part of the build.
          */
         std::string comment;
-        if (si->GetCustomCommand()) {
+        if ((this->TagType == GhsMultiGpj::CUSTOM_TARGET &&
+             !si->GetLanguage().empty()) ||
+            si->GetCustomCommand()) {
           comment = "{comment} ";
+          compile = false;
         }
-        *fout << comment << fname << std::endl;
 
-        if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
-            "bsp" != si->GetExtension()) {
-          WriteObjectLangOverride(*fout, si);
-        }
+        *fout << comment << fname << std::endl;
+        if (compile) {
+          if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
+              "bsp" != si->GetExtension()) {
+            WriteObjectLangOverride(*fout, si);
+          }
 
-        this->WriteSourceProperty(*fout, si, "INCLUDE_DIRECTORIES", "-I");
-        this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D");
-        this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", "");
+          this->WriteSourceProperty(*fout, si, "INCLUDE_DIRECTORIES", "-I");
+          this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D");
+          this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", "");
 
-        /* to avoid clutter in the gui only print out the objectName if it has
-         * been renamed */
-        std::string objectName = this->GeneratorTarget->GetObjectName(si);
-        if (!objectName.empty() &&
-            this->GeneratorTarget->HasExplicitObjectName(si)) {
-          *fout << "    -o " << objectName << std::endl;
+          /* to avoid clutter in the GUI only print out the objectName if it
+           * has been renamed */
+          std::string objectName = this->GeneratorTarget->GetObjectName(si);
+          if (!objectName.empty() &&
+              this->GeneratorTarget->HasExplicitObjectName(si)) {
+            *fout << "    -o " << objectName << std::endl;
+          }
         }
       }
     } else {
@@ -649,6 +674,9 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& 
fout_proj)
           this->WriteCustomCommandLine(*fout, fname, ccg);
         }
       }
+      if (this->TagType == GhsMultiGpj::CUSTOM_TARGET) {
+        this->WriteBuildEvents(*fout);
+      }
     }
   }
 
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx 
b/Source/cmGlobalGhsMultiGenerator.cxx
index a2138d1..2180770 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -308,8 +308,21 @@ void 
cmGlobalGhsMultiGenerator::WriteCustomRuleBOD(std::ostream& fout)
           "}\n";
 }
 
+void cmGlobalGhsMultiGenerator::WriteCustomTargetBOD(std::ostream& fout)
+{
+  fout << "FileTypes {\n"
+          "  CmakeTarget {\n"
+          "    name = \"Custom Target\"\n"
+          "    action = \"&Execute\"\n"
+          "    grepable = false\n"
+          "    outputType = \"None\"\n"
+          "    color = \"#800080\"\n"
+          "  }\n"
+          "}\n";
+}
+
 void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
-  std::ostream& fout, cmLocalGenerator* root,
+  std::ostream& fout, std::string& ename, cmLocalGenerator* root,
   std::vector<cmLocalGenerator*>& generators)
 {
   WriteFileHeader(fout);
@@ -342,13 +355,15 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
     fout << "\"" << this->OsDir << "\"" << std::endl;
   }
 
-  WriteSubProjects(fout, root, generators);
+  WriteSubProjects(fout, ename, root, generators);
 }
 
 void cmGlobalGhsMultiGenerator::WriteSubProjects(
-  std::ostream& fout, cmLocalGenerator* root,
+  std::ostream& fout, std::string& ename, cmLocalGenerator* root,
   std::vector<cmLocalGenerator*>& generators)
 {
+  this->ExcludedTargets.clear();
+
   // Collect all targets under this root generator and the transitive
   // closure of their dependencies.
   TargetDependSet projectTargets;
@@ -356,50 +371,75 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(
   this->GetTargetSets(projectTargets, originalTargets, root, generators);
   OrderedTargetDependSet orderedProjectTargets(projectTargets, "");
 
-  // write out all the sub-projects
+  // write out all the targets for ALL target
   std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
   for (cmGeneratorTarget const* target : orderedProjectTargets) {
     if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
       continue;
     }
+    if (cmSystemTools::IsOn(target->GetProperty("EXCLUDE_FROM_ALL"))) {
+      this->ExcludedTargets.push_back(target);
+      continue;
+    }
+    this->WriteProjectLine(fout, target, root, rootBinaryDir);
+  }
+  if (!this->ExcludedTargets.empty()) {
+    fout << "{nobuild} " << ename << " [Project]" << std::endl;
+  }
+}
 
-    const char* projName = target->GetProperty("GENERATOR_FILE_NAME");
-    const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
-    if (projName && projType) {
-      cmLocalGenerator* lg = target->GetLocalGenerator();
-      std::string dir = lg->GetCurrentBinaryDirectory();
-      dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir);
-      if (dir == ".") {
-        dir.clear();
-      } else {
-        if (dir.back() != '/') {
-          dir += "/";
-        }
-      }
+void cmGlobalGhsMultiGenerator::WriteExcludedProjects(
+  std::ostream& fout, cmLocalGenerator* root,
+  std::vector<cmLocalGenerator*>& generators)
+{
+  // write out all the excluded targets
+  std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
+  for (cmGeneratorTarget const* target : this->ExcludedTargets) {
+    if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
+      continue;
+    }
+    this->WriteProjectLine(fout, target, root, rootBinaryDir);
+  }
+  this->ExcludedTargets.clear();
+}
 
-      if (cmSystemTools::IsOn(target->GetProperty("EXCLUDE_FROM_ALL"))) {
-        fout << "{comment} ";
+void cmGlobalGhsMultiGenerator::WriteProjectLine(
+  std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
+  std::string& rootBinaryDir)
+{
+  const char* projName = target->GetProperty("GENERATOR_FILE_NAME");
+  const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
+  if (projName && projType) {
+    cmLocalGenerator* lg = target->GetLocalGenerator();
+    std::string dir = lg->GetCurrentBinaryDirectory();
+    dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir.c_str());
+    if (dir == ".") {
+      dir.clear();
+    } else {
+      if (dir.back() != '/') {
+        dir += "/";
       }
-      std::string projFile = dir + projName + FILE_EXTENSION;
-      fout << projFile;
-      fout << " " << projType << std::endl;
+    }
 
-      if (cmSystemTools::IsOn(target->GetProperty("GHS_REFERENCE_PROJECT"))) {
-        // create reference project
-        std::string fname = dir;
-        fname += target->GetName();
-        fname += "REF";
-        fname += FILE_EXTENSION;
+    std::string projFile = dir + projName + FILE_EXTENSION;
+    fout << projFile;
+    fout << " " << projType << std::endl;
 
-        cmGeneratedFileStream fref(fname);
-        fref.SetCopyIfDifferent(true);
+    if (cmSystemTools::IsOn(target->GetProperty("GHS_REFERENCE_PROJECT"))) {
+      // create reference project
+      std::string fname = dir;
+      fname += target->GetName();
+      fname += "REF";
+      fname += FILE_EXTENSION;
 
-        this->WriteFileHeader(fref);
-        GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
-        fref << "    :reference=" << projFile << std::endl;
+      cmGeneratedFileStream fref(fname);
+      fref.SetCopyIfDifferent(true);
 
-        fref.Close();
-      }
+      this->WriteFileHeader(fref);
+      GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
+      fref << "    :reference=" << projFile << std::endl;
+
+      fref.Close();
     }
   }
 }
@@ -424,11 +464,23 @@ void cmGlobalGhsMultiGenerator::Generate()
   this->WriteFileHeader(frule);
   this->WriteCustomRuleBOD(frule);
   frule.Close();
+
+  // create custom target BOD file
+  fname = this->GetCMakeInstance()->GetHomeOutputDirectory() +
+    "/CMakeFiles/custom_target.bod";
+  cmGeneratedFileStream ftarget(fname.c_str());
+  ftarget.SetCopyIfDifferent(true);
+  this->WriteFileHeader(ftarget);
+  this->WriteCustomTargetBOD(ftarget);
+  ftarget.Close();
 }
 
 void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
   cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
 {
+  std::string fname;
+  std::string ename;
+
   if (generators.empty()) {
     return;
   }
@@ -437,18 +489,30 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
    * with target projects.  This avoid the issue where the project has
    * the same name as the executable target.
    */
-  std::string fname = root->GetCurrentBinaryDirectory();
+  fname = root->GetCurrentBinaryDirectory();
   fname += "/";
   fname += root->GetProjectName();
   fname += ".top";
   fname += FILE_EXTENSION;
 
-  cmGeneratedFileStream fout(fname);
-  fout.SetCopyIfDifferent(true);
-
-  this->WriteTopLevelProject(fout, root, generators);
-
-  fout.Close();
+  ename = root->GetProjectName();
+  ename += ".nobuild";
+  ename += FILE_EXTENSION;
+
+  cmGeneratedFileStream top(fname);
+  top.SetCopyIfDifferent(true);
+  this->WriteTopLevelProject(top, ename, root, generators);
+  top.Close();
+
+  if (!this->ExcludedTargets.empty()) {
+    ename = root->GetCurrentBinaryDirectory() + "/" + ename;
+    cmGeneratedFileStream exclude(ename);
+    exclude.SetCopyIfDifferent(true);
+    WriteFileHeader(exclude);
+    GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, exclude);
+    this->WriteExcludedProjects(exclude, root, generators);
+    exclude.Close();
+  }
 }
 
 std::vector<cmGlobalGenerator::GeneratedMakeCommand>
@@ -543,6 +607,8 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(
   fout << "primaryTarget=" << tgt << std::endl;
   fout << "customization=" << root->GetBinaryDirectory()
        << "/CMakeFiles/custom_rule.bod" << std::endl;
+  fout << "customization=" << root->GetBinaryDirectory()
+       << "/CMakeFiles/custom_target.bod" << std::endl;
 
   char const* const customization =
     this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
diff --git a/Source/cmGlobalGhsMultiGenerator.h 
b/Source/cmGlobalGhsMultiGenerator.h
index 1dd951a..a987205 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -111,19 +111,27 @@ private:
   /* top-level project */
   void OutputTopLevelProject(cmLocalGenerator* root,
                              std::vector<cmLocalGenerator*>& generators);
-  void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root,
+  void WriteTopLevelProject(std::ostream& fout, std::string& ename,
+                            cmLocalGenerator* root,
                             std::vector<cmLocalGenerator*>& generators);
   void WriteMacros(std::ostream& fout);
   void WriteHighLevelDirectives(cmLocalGenerator* root, std::ostream& fout);
-  void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root,
+  void WriteSubProjects(std::ostream& fout, std::string& ename,
+                        cmLocalGenerator* root,
                         std::vector<cmLocalGenerator*>& generators);
+  void WriteExcludedProjects(std::ostream& fout, cmLocalGenerator* root,
+                             std::vector<cmLocalGenerator*>& generators);
+  void WriteProjectLine(std::ostream& fout, cmGeneratorTarget const* target,
+                        cmLocalGenerator* root, std::string& rootBinaryDir);
   void WriteCustomRuleBOD(std::ostream& fout);
+  void WriteCustomTargetBOD(std::ostream& fout);
 
   std::string trimQuotes(std::string const& str);
 
   std::string OsDir;
   static const char* DEFAULT_BUILD_PROGRAM;
   static const char* DEFAULT_TOOLSET_ROOT;
+  std::vector<cmGeneratorTarget const*> ExcludedTargets;
 };
 
 class cmGlobalGhsMultiGenerator::OrderedTargetDependSet

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8d3dad9a76591ae0426335d039b8aaacb95862cd
commit 8d3dad9a76591ae0426335d039b8aaacb95862cd
Author:     Fred Baksik <froda...@gmail.com>
AuthorDate: Mon Apr 8 09:55:34 2019 -0400
Commit:     Fred Baksik <froda...@gmail.com>
CommitDate: Thu Apr 11 13:15:50 2019 -0400

    GHS: Support add_custom_command( OUTPUT ) signature
    
    -- add new file type to run a shell script
    -- gbuild does not compute interfile dependencies like other build tools.
       Therefore calculate the required build order of custom commands and
       list all of them in the CMake Rules subproject.

diff --git a/Source/cmGhsMultiTargetGenerator.cxx 
b/Source/cmGhsMultiTargetGenerator.cxx
index 9f9ef18..9d0d195 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -572,31 +572,82 @@ void 
cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
       *fout << "{comment} Others" << std::endl;
     }
 
-    /* output rule for each source file */
-    for (const cmSourceFile* si : groupFiles[sg]) {
-
-      // Convert filename to native system
-      // WORKAROUND: GHS MULTI 6.1.4 and 6.1.6 are known to need backslash on
-      // windows when opening some files from the search window.
-      std::string fname(si->GetFullPath());
-      cmSystemTools::ConvertToOutputSlashes(fname);
-      *fout << fname << std::endl;
-
-      if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
-          "bsp" != si->GetExtension()) {
-        WriteObjectLangOverride(*fout, si);
-      }
+    if (sg != "CMake Rules") {
+      /* output rule for each source file */
+      for (const cmSourceFile* si : groupFiles[sg]) {
+
+        // Convert filename to native system
+        // WORKAROUND: GHS MULTI 6.1.4 and 6.1.6 are known to need backslash on
+        // windows when opening some files from the search window.
+        std::string fname(si->GetFullPath());
+        cmSystemTools::ConvertToOutputSlashes(fname);
+
+        /* Comment out any custom command dependencies to prevent from
+         * being considered part of the build.
+         */
+        std::string comment;
+        if (si->GetCustomCommand()) {
+          comment = "{comment} ";
+        }
+        *fout << comment << fname << std::endl;
 
-      this->WriteSourceProperty(*fout, si, "INCLUDE_DIRECTORIES", "-I");
-      this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D");
-      this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", "");
+        if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
+            "bsp" != si->GetExtension()) {
+          WriteObjectLangOverride(*fout, si);
+        }
 
-      /* to avoid clutter in the gui only print out the objectName if it has
-       * been renamed */
-      std::string objectName = this->GeneratorTarget->GetObjectName(si);
-      if (!objectName.empty() &&
-          this->GeneratorTarget->HasExplicitObjectName(si)) {
-        *fout << "    -o " << objectName << std::endl;
+        this->WriteSourceProperty(*fout, si, "INCLUDE_DIRECTORIES", "-I");
+        this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D");
+        this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", "");
+
+        /* to avoid clutter in the gui only print out the objectName if it has
+         * been renamed */
+        std::string objectName = this->GeneratorTarget->GetObjectName(si);
+        if (!objectName.empty() &&
+            this->GeneratorTarget->HasExplicitObjectName(si)) {
+          *fout << "    -o " << objectName << std::endl;
+        }
+      }
+    } else {
+      std::vector<cmSourceFile const*> customCommands;
+      if (ComputeCustomCommandOrder(customCommands)) {
+        std::string message = "The custom commands for target [" +
+          this->GeneratorTarget->GetName() + "] had a cycle.\n";
+        cmSystemTools::Error(message);
+      } else {
+        /* Custom targets do not have a dependency on SOURCES files.
+         * Therefore the dependency list may include SOURCES files after the
+         * custom target. Because nothing can depend on the custom target just
+         * move it to the last item.
+         */
+        for (auto sf = customCommands.begin(); sf != customCommands.end();
+             ++sf) {
+          if (((*sf)->GetLocation()).GetName() == this->Name + ".rule") {
+            std::rotate(sf, sf + 1, customCommands.end());
+            break;
+          }
+        }
+        int cmdcount = 0;
+        for (auto& sf : customCommands) {
+          const cmCustomCommand* cc = sf->GetCustomCommand();
+          cmCustomCommandGenerator ccg(*cc, this->ConfigName,
+                                       this->LocalGenerator);
+
+          // Open the filestream for this custom command
+          std::string fname =
+            this->LocalGenerator->GetCurrentBinaryDirectory();
+          fname += "/" +
+            this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+          fname += "/" + this->Name + "_cc";
+          fname += std::to_string(cmdcount++) + "_";
+          fname += (sf->GetLocation()).GetName();
+          fname += this->CmdWindowsShell ? ".bat" : ".sh";
+          cmGeneratedFileStream f(fname.c_str());
+          f.SetCopyIfDifferent(true);
+          this->WriteCustomCommandsHelper(f, ccg);
+          f.Close();
+          this->WriteCustomCommandLine(*fout, fname, ccg);
+        }
       }
     }
   }
@@ -606,6 +657,33 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& 
fout_proj)
   }
 }
 
+void cmGhsMultiTargetGenerator::WriteCustomCommandLine(
+  std::ostream& fout, std::string& fname, cmCustomCommandGenerator const& ccg)
+{
+  /* NOTE: Customization Files are not well documented.  Testing showed
+   * that ":outputName=file" can only be used once per script.  The
+   * script will only run if ":outputName=file" is missing or just run
+   * once if ":outputName=file" is not specified.  If there are
+   * multiple outputs then the script needs to be listed multiple times
+   * for each output.  Otherwise it won't rerun the script if one of
+   * the outputs is manually deleted.
+   */
+  bool specifyExtra = true;
+  for (auto& out : ccg.GetOutputs()) {
+    fout << fname << std::endl;
+    fout << "    :outputName=\"" << out << "\"" << std::endl;
+    if (specifyExtra) {
+      for (auto& byp : ccg.GetByproducts()) {
+        fout << "    :extraOutputFile=\"" << byp << "\"" << std::endl;
+      }
+      for (auto& dep : ccg.GetDepends()) {
+        fout << "    :depends=\"" << dep << "\"" << std::endl;
+      }
+      specifyExtra = false;
+    }
+  }
+}
+
 void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
   std::ostream& fout, const cmSourceFile* sourceFile)
 {
@@ -643,7 +721,7 @@ void 
cmGhsMultiTargetGenerator::WriteReferences(std::ostream& fout)
     fout << "    ";
     GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fout);
 
-    // Tell the global generator that a refernce project needs to be created
+    // Tell the global generator that a reference project needs to be created
     t->Target->SetProperty("GHS_REFERENCE_PROJECT", "ON");
   }
 }
@@ -664,3 +742,51 @@ bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()
   }
   return false;
 }
+
+bool cmGhsMultiTargetGenerator::ComputeCustomCommandOrder(
+  std::vector<cmSourceFile const*>& order)
+{
+  std::set<cmSourceFile const*> temp;
+  std::set<cmSourceFile const*> perm;
+
+  // Collect all custom commands for this target
+  std::vector<cmSourceFile const*> customCommands;
+  this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName);
+
+  for (cmSourceFile const* si : customCommands) {
+    bool r = VisitCustomCommand(temp, perm, order, si);
+    if (r) {
+      return r;
+    }
+  }
+  return false;
+}
+
+bool cmGhsMultiTargetGenerator::VisitCustomCommand(
+  std::set<cmSourceFile const*>& temp, std::set<cmSourceFile const*>& perm,
+  std::vector<cmSourceFile const*>& order, cmSourceFile const* si)
+{
+  /* check if permanent mark is set*/
+  if (perm.find(si) == perm.end()) {
+    /* set temporary mark; check if revisit*/
+    if (temp.insert(si).second) {
+      for (auto& di : si->GetCustomCommand()->GetDepends()) {
+        cmSourceFile const* sf = this->GeneratorTarget->GetLocalGenerator()
+                                   ->GetMakefile()
+                                   ->GetSourceFileWithOutput(di);
+        /* if sf exists then visit */
+        if (sf && this->VisitCustomCommand(temp, perm, order, sf)) {
+          return true;
+        }
+      }
+      /* mark as complete; insert into beginning of list*/
+      perm.insert(si);
+      order.push_back(si);
+      return false;
+    }
+    /* revisiting item - not a DAG */
+    return true;
+  }
+  /* already complete */
+  return false;
+}
diff --git a/Source/cmGhsMultiTargetGenerator.h 
b/Source/cmGhsMultiTargetGenerator.h
index fa251b0..3ba3884 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -7,6 +7,7 @@
 
 #include <iosfwd>
 #include <map>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -54,6 +55,13 @@ private:
                               std::string const& name, std::string const& cmd);
   void WriteCustomCommandsHelper(std::ostream& fout,
                                  cmCustomCommandGenerator const& ccg);
+  void WriteCustomCommandLine(std::ostream& fout, std::string& fname,
+                              cmCustomCommandGenerator const& ccg);
+  bool ComputeCustomCommandOrder(std::vector<cmSourceFile const*>& order);
+  bool VisitCustomCommand(std::set<cmSourceFile const*>& temp,
+                          std::set<cmSourceFile const*>& perm,
+                          std::vector<cmSourceFile const*>& order,
+                          cmSourceFile const* sf);
   void WriteSources(std::ostream& fout_proj);
   void WriteSourceProperty(std::ostream& fout, const cmSourceFile* sf,
                            std::string const& propName,
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx 
b/Source/cmGlobalGhsMultiGenerator.cxx
index 9f361f6..a2138d1 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -265,6 +265,49 @@ void 
cmGlobalGhsMultiGenerator::WriteFileHeader(std::ostream& fout)
        << std::endl;
 }
 
+void cmGlobalGhsMultiGenerator::WriteCustomRuleBOD(std::ostream& fout)
+{
+  fout << "Commands {\n"
+          "  Custom_Rule_Command {\n"
+          "    name = \"Custom Rule Command\"\n"
+          "    exec = \"";
+#ifdef _WIN32
+  fout << "cmd.exe";
+#else
+  fout << "/bin/sh";
+#endif
+  fout << "\"\n"
+          "    options = {\"SpecialOptions\"}\n"
+          "  }\n"
+          "}\n";
+
+  fout << "\n\n";
+  fout << "FileTypes {\n"
+          "  CmakeRule {\n"
+          "    name = \"Custom Rule\"\n"
+          "    action = \"&Run\"\n"
+          "    extensions = {\"";
+#ifdef _WIN32
+  fout << "bat";
+#else
+  fout << "sh";
+#endif
+  fout << "\"}\n"
+          "    grepable = false\n"
+          "    command = \"Custom Rule Command\"\n"
+          "    commandLine = \"$COMMAND ";
+#ifdef _WIN32
+  fout << "/c";
+#endif
+  fout << " $INPUTFILE\"\n"
+          "    progress = \"Processing Custom Rule\"\n"
+          "    promoteToFirstPass = true\n"
+          "    outputType = \"None\"\n"
+          "    color = \"#800080\"\n"
+          "  }\n"
+          "}\n";
+}
+
 void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
   std::ostream& fout, cmLocalGenerator* root,
   std::vector<cmLocalGenerator*>& generators)
@@ -272,7 +315,7 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
   WriteFileHeader(fout);
 
   this->WriteMacros(fout);
-  this->WriteHighLevelDirectives(fout);
+  this->WriteHighLevelDirectives(root, fout);
   GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
 
   fout << "# Top Level Project File" << std::endl;
@@ -363,6 +406,8 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(
 
 void cmGlobalGhsMultiGenerator::Generate()
 {
+  std::string fname;
+
   // first do the superclass method
   this->cmGlobalGenerator::Generate();
 
@@ -370,6 +415,15 @@ void cmGlobalGhsMultiGenerator::Generate()
   for (auto& it : this->ProjectMap) {
     this->OutputTopLevelProject(it.second[0], it.second);
   }
+
+  // create custom rule BOD file
+  fname = this->GetCMakeInstance()->GetHomeOutputDirectory() +
+    "/CMakeFiles/custom_rule.bod";
+  cmGeneratedFileStream frule(fname);
+  frule.SetCopyIfDifferent(true);
+  this->WriteFileHeader(frule);
+  this->WriteCustomRuleBOD(frule);
+  frule.Close();
 }
 
 void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
@@ -465,7 +519,8 @@ void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& 
fout)
   }
 }
 
-void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(std::ostream& fout)
+void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(
+  cmLocalGenerator* root, std::ostream& fout)
 {
   /* set primary target */
   std::string tgt;
@@ -486,6 +541,8 @@ void 
cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(std::ostream& fout)
   }
 
   fout << "primaryTarget=" << tgt << std::endl;
+  fout << "customization=" << root->GetBinaryDirectory()
+       << "/CMakeFiles/custom_rule.bod" << std::endl;
 
   char const* const customization =
     this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
diff --git a/Source/cmGlobalGhsMultiGenerator.h 
b/Source/cmGlobalGhsMultiGenerator.h
index 1aeb1dc..1dd951a 100644
--- a/Source/cmGlobalGhsMultiGenerator.h
+++ b/Source/cmGlobalGhsMultiGenerator.h
@@ -114,9 +114,10 @@ private:
   void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root,
                             std::vector<cmLocalGenerator*>& generators);
   void WriteMacros(std::ostream& fout);
-  void WriteHighLevelDirectives(std::ostream& fout);
+  void WriteHighLevelDirectives(cmLocalGenerator* root, std::ostream& fout);
   void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root,
                         std::vector<cmLocalGenerator*>& generators);
+  void WriteCustomRuleBOD(std::ostream& fout);
 
   std::string trimQuotes(std::string const& str);
 

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=37acc9e2299713b9b23c767e72b0e0169697e510
commit 37acc9e2299713b9b23c767e72b0e0169697e510
Author:     Fred Baksik <froda...@gmail.com>
AuthorDate: Mon Apr 8 09:55:34 2019 -0400
Commit:     Brad King <brad.k...@kitware.com>
CommitDate: Wed Apr 10 11:54:56 2019 -0400

    GHS: Update custom command build events
    
    -- Fixes issue where commands run out of order; Run commands as single 
script
       Do not allow build events to run in parallel
    -- Use command generator to parse the commands
    -- Support pre-link build events
    -- Support more options: COMMENT, BYPRODUCTS, WORKING_DIRECTORY

diff --git a/Source/cmGhsMultiTargetGenerator.cxx 
b/Source/cmGhsMultiTargetGenerator.cxx
index 668bcbd..9f9ef18 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -3,7 +3,7 @@
 #include "cmGhsMultiTargetGenerator.h"
 
 #include "cmCustomCommand.h"
-#include "cmCustomCommandLines.h"
+#include "cmCustomCommandGenerator.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGhsMultiGenerator.h"
@@ -11,6 +11,7 @@
 #include "cmLocalGenerator.h"
 #include "cmLocalGhsMultiGenerator.h"
 #include "cmMakefile.h"
+#include "cmOutputConverter.h"
 #include "cmSourceFile.h"
 #include "cmSourceGroup.h"
 #include "cmStateDirectory.h"
@@ -21,7 +22,6 @@
 #include "cmTargetDepend.h"
 
 #include <algorithm>
-#include <assert.h>
 #include <ostream>
 #include <set>
 #include <utility>
@@ -32,6 +32,11 @@ 
cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target)
       static_cast<cmLocalGhsMultiGenerator*>(target->GetLocalGenerator()))
   , Makefile(target->Target->GetMakefile())
   , Name(target->GetName())
+#ifdef _WIN32
+  , CmdWindowsShell(true)
+#else
+  , CmdWindowsShell(false)
+#endif
 {
   // Store the configuration name that is being used
   if (const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) {
@@ -125,7 +130,7 @@ void cmGhsMultiTargetGenerator::GenerateTarget()
   this->WriteCompilerDefinitions(fout, this->ConfigName, language);
   this->WriteIncludes(fout, this->ConfigName, language);
   this->WriteTargetLinkLine(fout, this->ConfigName);
-  this->WriteCustomCommands(fout);
+  this->WriteBuildEvents(fout);
   this->WriteSources(fout);
   this->WriteReferences(fout);
   fout.Close();
@@ -304,47 +309,138 @@ void 
cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
   }
 }
 
-void cmGhsMultiTargetGenerator::WriteCustomCommands(std::ostream& fout)
+void cmGhsMultiTargetGenerator::WriteBuildEvents(std::ostream& fout)
 {
-  WriteCustomCommandsHelper(fout, this->GeneratorTarget->GetPreBuildCommands(),
-                            cmTarget::PRE_BUILD);
-  WriteCustomCommandsHelper(
-    fout, this->GeneratorTarget->GetPostBuildCommands(), cmTarget::POST_BUILD);
+  this->WriteBuildEventsHelper(
+    fout, this->GeneratorTarget->GetPreBuildCommands(),
+    std::string("prebuild"), std::string("preexecShell"));
+
+  this->WriteBuildEventsHelper(
+    fout, this->GeneratorTarget->GetPreLinkCommands(), std::string("prelink"),
+    std::string("preexecShell"));
+
+  this->WriteBuildEventsHelper(
+    fout, this->GeneratorTarget->GetPostBuildCommands(),
+    std::string("postbuild"), std::string("postexecShell"));
+}
+
+void cmGhsMultiTargetGenerator::WriteBuildEventsHelper(
+  std::ostream& fout, const std::vector<cmCustomCommand>& ccv,
+  std::string const& name, std::string const& cmd)
+{
+  int cmdcount = 0;
+
+  for (cmCustomCommand const& cc : ccv) {
+    cmCustomCommandGenerator ccg(cc, this->ConfigName, this->LocalGenerator);
+    // Open the filestream for this custom command
+    std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
+    fname +=
+      "/" + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
+    fname += "/" + this->Name + "_" + name;
+    fname += std::to_string(cmdcount++);
+    fname += this->CmdWindowsShell ? ".bat" : ".sh";
+    cmGeneratedFileStream f(fname);
+    f.SetCopyIfDifferent(true);
+    this->WriteCustomCommandsHelper(f, ccg);
+    f.Close();
+    fout << "    :" << cmd << "=\"" << fname << "\"" << std::endl;
+    for (auto& byp : ccg.GetByproducts()) {
+      fout << "    :extraOutputFile=\"" << byp << "\"" << std::endl;
+    }
+  }
 }
 
 void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
-  std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet,
-  cmTarget::CustomCommandType const commandType)
+  std::ostream& fout, cmCustomCommandGenerator const& ccg)
 {
-  for (cmCustomCommand const& customCommand : commandsSet) {
-    cmCustomCommandLines const& commandLines = customCommand.GetCommandLines();
-    for (cmCustomCommandLine const& command : commandLines) {
-      switch (commandType) {
-        case cmTarget::PRE_BUILD:
-          fout << "    :preexecShellSafe=";
-          break;
-        case cmTarget::POST_BUILD:
-          fout << "    :postexecShellSafe=";
-          break;
-        default:
-          assert("Only pre and post are supported");
+  std::vector<std::string> cmdLines;
+
+  // if the command specified a working directory use it.
+  std::string dir = this->LocalGenerator->GetCurrentBinaryDirectory();
+  std::string currentBinDir = dir;
+  std::string workingDir = ccg.GetWorkingDirectory();
+  if (!workingDir.empty()) {
+    dir = workingDir;
+  }
+
+  // Line to check for error between commands.
+#ifdef _WIN32
+  std::string check_error = "if %errorlevel% neq 0 exit /b %errorlevel%";
+#else
+  std::string check_error = "if [[ $? -ne 0 ]]; then exit 1; fi";
+#endif
+
+#ifdef _WIN32
+  cmdLines.push_back("@echo off");
+#endif
+  // Echo the custom command's comment text.
+  const char* comment = ccg.GetComment();
+  if (comment && *comment) {
+    std::string echocmd = "echo ";
+    echocmd += comment;
+    cmdLines.push_back(std::move(echocmd));
+  }
+
+  // Switch to working directory
+  std::string cdCmd;
+#ifdef _WIN32
+  std::string cdStr = "cd /D ";
+#else
+  std::string cdStr = "cd ";
+#endif
+  cdCmd = cdStr +
+    this->LocalGenerator->ConvertToOutputFormat(dir, cmOutputConverter::SHELL);
+  cmdLines.push_back(std::move(cdCmd));
+
+  for (unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) {
+    // Build the command line in a single string.
+    std::string cmd = ccg.GetCommand(c);
+    if (!cmd.empty()) {
+      // Use "call " before any invocations of .bat or .cmd files
+      // invoked as custom commands in the WindowsShell.
+      //
+      bool useCall = false;
+
+      if (this->CmdWindowsShell) {
+        std::string suffix;
+        if (cmd.size() > 4) {
+          suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size() - 4));
+          if (suffix == ".bat" || suffix == ".cmd") {
+            useCall = true;
+          }
+        }
       }
 
-      bool firstIteration = true;
-      for (std::string const& commandLine : command) {
-        std::string subCommandE =
-          this->LocalGenerator->EscapeForShell(commandLine, true);
-        fout << (firstIteration ? "'" : " ");
-        // Need to double escape backslashes
-        cmSystemTools::ReplaceString(subCommandE, "\\", "\\\\");
-        fout << subCommandE;
-        firstIteration = false;
+      cmSystemTools::ReplaceString(cmd, "/./", "/");
+      // Convert the command to a relative path only if the current
+      // working directory will be the start-output directory.
+      bool had_slash = cmd.find('/') != std::string::npos;
+      if (workingDir.empty()) {
+        cmd =
+          this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, cmd);
       }
-      if (!command.empty()) {
-        fout << "'" << std::endl;
+      bool has_slash = cmd.find('/') != std::string::npos;
+      if (had_slash && !has_slash) {
+        // This command was specified as a path to a file in the
+        // current directory.  Add a leading "./" so it can run
+        // without the current directory being in the search path.
+        cmd = "./" + cmd;
       }
+      cmd = this->LocalGenerator->ConvertToOutputFormat(
+        cmd, cmOutputConverter::SHELL);
+      if (useCall) {
+        cmd = "call " + cmd;
+      }
+      ccg.AppendArguments(c, cmd);
+      cmdLines.push_back(std::move(cmd));
     }
   }
+
+  // push back the custom commands
+  for (auto const& c : cmdLines) {
+    fout << c << std::endl;
+    fout << check_error << std::endl;
+  }
 }
 
 void cmGhsMultiTargetGenerator::WriteSourceProperty(
@@ -433,7 +529,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& 
fout_proj)
 
   /* write files into the proper project file
    * -- groups go into main project file
-   *    unless FOLDER property or variable is set.
+   *    unless NO_SOURCE_GROUP_FILE property or variable is set.
    */
   for (auto& sg : groupFilesList) {
     std::ostream* fout;
@@ -472,6 +568,8 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& 
fout_proj)
       } else {
         *fout << "{comment} " << sg << std::endl;
       }
+    } else if (sg.empty()) {
+      *fout << "{comment} Others" << std::endl;
     }
 
     /* output rule for each source file */
diff --git a/Source/cmGhsMultiTargetGenerator.h 
b/Source/cmGhsMultiTargetGenerator.h
index a4e23d9..fa251b0 100644
--- a/Source/cmGhsMultiTargetGenerator.h
+++ b/Source/cmGhsMultiTargetGenerator.h
@@ -5,14 +5,13 @@
 
 #include "cmGhsMultiGpj.h"
 
-#include "cmTarget.h"
-
 #include <iosfwd>
 #include <map>
 #include <string>
 #include <vector>
 
 class cmCustomCommand;
+class cmCustomCommandGenerator;
 class cmGeneratorTarget;
 class cmGlobalGhsMultiGenerator;
 class cmLocalGhsMultiGenerator;
@@ -49,10 +48,12 @@ private:
   void WriteIncludes(std::ostream& fout, const std::string& config,
                      const std::string& language);
   void WriteTargetLinkLine(std::ostream& fout, std::string const& config);
-  void WriteCustomCommands(std::ostream& fout);
-  void WriteCustomCommandsHelper(
-    std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet,
-    cmTarget::CustomCommandType commandType);
+  void WriteBuildEvents(std::ostream& fout);
+  void WriteBuildEventsHelper(std::ostream& fout,
+                              const std::vector<cmCustomCommand>& ccv,
+                              std::string const& name, std::string const& cmd);
+  void WriteCustomCommandsHelper(std::ostream& fout,
+                                 cmCustomCommandGenerator const& ccg);
   void WriteSources(std::ostream& fout_proj);
   void WriteSourceProperty(std::ostream& fout, const cmSourceFile* sf,
                            std::string const& propName,
@@ -71,7 +72,8 @@ private:
   std::string TargetNameReal;
   GhsMultiGpj::Types TagType;
   std::string const Name;
-  std::string ConfigName; /* CMAKE_BUILD_TYPE */
+  std::string ConfigName;     /* CMAKE_BUILD_TYPE */
+  bool const CmdWindowsShell; /* custom commands run in cmd.exe or /bin/sh */
 };
 
 #endif // ! cmGhsMultiTargetGenerator_h

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

Summary of changes:
 Help/release/dev/ghs-custom-commands.rst           |   5 +
 Modules/ExternalProject.cmake                      |  38 +-
 Modules/FindBoost.cmake                            |  25 +-
 Source/cmGhsMultiGpj.cxx                           |   4 +-
 Source/cmGhsMultiGpj.h                             |   3 +-
 Source/cmGhsMultiTargetGenerator.cxx               | 449 ++++++++++++++++-----
 Source/cmGhsMultiTargetGenerator.h                 |  25 +-
 Source/cmGlobalGhsMultiGenerator.cxx               | 358 +++++++++++++---
 Source/cmGlobalGhsMultiGenerator.h                 |  69 ++--
 Tests/CMakeLists.txt                               |   5 +-
 Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt | 110 +++++
 .../GhsMultiCustomTarget/CMakeLists.txt.in         | 108 +++++
 .../exe1.c                                         |   0
 .../lib1.c                                         |   0
 .../CMakeLists.txt                                 |  10 +-
 .../GhsMulti/GhsMultiDepOrder/exec/CMakeLists.txt  |  11 +
 Tests/GhsMulti/GhsMultiDepOrder/exec/exe1.c        |   8 +
 Tests/GhsMulti/GhsMultiDepOrder/lib/CMakeLists.txt |  17 +
 Tests/GhsMulti/GhsMultiDepOrder/lib/func1.c        |  17 +
 Tests/GhsMulti/GhsMultiDepOrder/lib/lib1.h         |   3 +
 .../GhsMultiDepOrder/protolib/CMakeLists.txt       |  28 ++
 .../GhsMulti/GhsMultiDepOrder/protolib/proto1.c.in |  16 +
 .../GhsMulti/GhsMultiDepOrder/protolib/proto1.h.in |   7 +
 .../CMakeLists.txt                                 |  14 +-
 .../empty}/CMakeLists.txt                          |   8 +-
 .../GhsMultiIntegrityDDInt/App/CMakeLists.txt      |   1 -
 .../GhsMultiIntegrityDDInt/Lib/CMakeLists.txt      |   1 +
 .../GhsMultiIntegrityMonolith/CMakeLists.txt       |   1 +
 Tests/GhsMulti/GhsMultiPlatform/file1.c            |   4 -
 .../GhsMulti/GhsMultiRenameInstall/CMakeLists.txt  |   6 +-
 .../GhsMultiUnsupportedTargets/CMakeLists.txt      |   2 -
 31 files changed, 1097 insertions(+), 256 deletions(-)
 create mode 100644 Help/release/dev/ghs-custom-commands.rst
 create mode 100644 Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt
 create mode 100644 Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt.in
 copy Tests/GhsMulti/{GhsMultiRenameInstall => GhsMultiCustomTarget}/exe1.c 
(100%)
 copy Tests/GhsMulti/{GhsMultiRenameInstall => GhsMultiCustomTarget}/lib1.c 
(100%)
 copy Tests/GhsMulti/{GhsMultiUnsupportedTargets => 
GhsMultiDepOrder}/CMakeLists.txt (56%)
 create mode 100644 Tests/GhsMulti/GhsMultiDepOrder/exec/CMakeLists.txt
 create mode 100644 Tests/GhsMulti/GhsMultiDepOrder/exec/exe1.c
 create mode 100644 Tests/GhsMulti/GhsMultiDepOrder/lib/CMakeLists.txt
 create mode 100644 Tests/GhsMulti/GhsMultiDepOrder/lib/func1.c
 create mode 100644 Tests/GhsMulti/GhsMultiDepOrder/lib/lib1.h
 create mode 100644 Tests/GhsMulti/GhsMultiDepOrder/protolib/CMakeLists.txt
 create mode 100644 Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.c.in
 create mode 100644 Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.h.in
 copy Tests/GhsMulti/{GhsMultiUnsupportedTargets => 
GhsMultiExternalProject}/CMakeLists.txt (54%)
 copy Tests/GhsMulti/{GhsMultiUnsupportedTargets => 
GhsMultiExternalProject/empty}/CMakeLists.txt (57%)
 delete mode 100644 Tests/GhsMulti/GhsMultiPlatform/file1.c


hooks/post-receive
-- 
CMake
_______________________________________________
Cmake-commits mailing list
Cmake-commits@cmake.org
https://cmake.org/mailman/listinfo/cmake-commits

Reply via email to