Browse Source

GHS: Add Compiler ID detection

-- Detect GHS compiler and version
   Detect ARCHITECTURE_ID for PPC / ARM / 86 targets
   Detect PLATFORM_ID for Integrity and Integrity178 platforms
   Using defines specified in the documents for the compilers: 201416 PPC / 201754 ARM / 201714 86
-- Fallback C/CXX compiler ID to GHS if not otherwise detected and using GHS MULTI generator
   Works around issue with some GHS compilers not setting __ghs__ compiler define
-- Tweak Compiler ID checking so major id of 002017 is not replaced with 217
-- Prefer try_compile() library targets when testing for working GHS compilers
-- Avoid CMake errors if reading past end of file for checking if file is PE executable
Fred Baksik 7 years ago
parent
commit
72e0c115b7

+ 1 - 0
Help/variable/CMAKE_LANG_COMPILER_ID.rst

@@ -19,6 +19,7 @@ include:
   Embarcadero, Borland = Embarcadero (embarcadero.com)
   G95 = G95 Fortran (g95.org)
   GNU = GNU Compiler Collection (gcc.gnu.org)
+  GHS = Green Hills Software (www.ghs.com)
   HP = Hewlett-Packard Compiler (hp.com)
   IAR = IAR Systems (iar.com)
   Intel = Intel Compiler (intel.com)

+ 1 - 0
Modules/CMakeCompilerIdDetection.cmake

@@ -63,6 +63,7 @@ function(compiler_id_detection outvar lang)
       Cray
       TI
       Fujitsu
+      GHS
     )
     if (lang STREQUAL C)
       list(APPEND ordered_compilers

+ 1 - 0
Modules/CMakeDetermineCCompiler.cmake

@@ -31,6 +31,7 @@ if(NOT CMAKE_C_COMPILER_NAMES)
 endif()
 
 if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+elseif("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
 elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
   set(CMAKE_C_COMPILER_XCODE_TYPE sourcecode.c.c)
   _cmake_find_compiler_path(C)

+ 1 - 0
Modules/CMakeDetermineCXXCompiler.cmake

@@ -30,6 +30,7 @@ if(NOT CMAKE_CXX_COMPILER_NAMES)
 endif()
 
 if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+elseif("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
 elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
   set(CMAKE_CXX_COMPILER_XCODE_TYPE sourcecode.cpp.cpp)
   _cmake_find_compiler_path(CXX)

+ 2 - 0
Modules/CMakeDetermineCompilerABI.cmake

@@ -7,6 +7,7 @@
 # code.
 
 include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
+include(CMakeTestCompilerCommon)
 
 function(CMAKE_DETERMINE_COMPILER_ABI lang src)
   if(NOT DEFINED CMAKE_${lang}_ABI_COMPILED)
@@ -23,6 +24,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
       # from which we might detect implicit link libraries.
       list(APPEND CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD_LIBRARIES=")
     endif()
+    __TestCompiler_setTryCompileTargetType()
     try_compile(CMAKE_${lang}_ABI_COMPILED
       ${CMAKE_BINARY_DIR} ${src}
       CMAKE_FLAGS ${CMAKE_FLAGS}

+ 64 - 21
Modules/CMakeDetermineCompilerId.cmake

@@ -52,6 +52,13 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
     endforeach()
   endif()
 
+  # If the compiler is still unknown, fallback to GHS
+  if(NOT CMAKE_${lang}_COMPILER_ID  AND "${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
+    set(CMAKE_${lang}_COMPILER_ID GHS)
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "The ${lang} compiler identification is falling back to GHS.\n\n")
+  endif()
+
   # CUDA < 7.5 is missing version macros
   if(lang STREQUAL "CUDA"
      AND CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA"
@@ -391,6 +398,40 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
       separate_arguments(CMAKE_${lang}_XCODE_ARCHS)
       set(CMAKE_${lang}_XCODE_ARCHS "${CMAKE_${lang}_XCODE_ARCHS}" PARENT_SCOPE)
     endif()
+  elseif("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
+    set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
+    set(id_src "${src}")
+    if (GHS_PRIMARY_TARGET)
+      set(ghs_primary_target "${GHS_PRIMARY_TARGET}")
+    else()
+      set(ghs_primary_target "${CMAKE_GENERATOR_PLATFORM}_${GHS_TARGET_PLATFORM}.tgt")
+    endif()
+    if ("${GHS_TARGET_PLATFORM}" MATCHES "integrity")
+        set(bsp_name "macro GHS_BSP=${GHS_BSP_NAME}")
+        set(os_dir "macro GHS_OS=${GHS_OS_DIR}")
+    endif()
+    set(command "${CMAKE_MAKE_PROGRAM}" "-commands" "-top" "GHS_default.gpj")
+    configure_file(${CMAKE_ROOT}/Modules/CompilerId/GHS_default.gpj.in
+      ${id_dir}/GHS_default.gpj @ONLY)
+    configure_file(${CMAKE_ROOT}/Modules/CompilerId/GHS_lib.gpj.in
+      ${id_dir}/GHS_lib.gpj @ONLY)
+    execute_process(COMMAND ${command}
+      WORKING_DIRECTORY ${id_dir}
+      OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
+      ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
+      RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
+      )
+    # Match the compiler location line printed out.
+    set(ghs_toolpath "${CMAKE_MAKE_PROGRAM}")
+    string(REPLACE "/gbuild.exe" "/" ghs_toolpath ${ghs_toolpath})
+    string(REPLACE / "\\\\" ghs_toolpath ${ghs_toolpath})
+    if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "(${ghs_toolpath}[^ ]*)")
+      set(_comp "${CMAKE_MATCH_1}.exe")
+      if(EXISTS "${_comp}")
+        file(TO_CMAKE_PATH "${_comp}" _comp)
+        set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE)
+      endif()
+    endif()
   else()
     execute_process(
       COMMAND "${CMAKE_${lang}_COMPILER}"
@@ -550,7 +591,7 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
         set(ARCHITECTURE_ID "${CMAKE_MATCH_1}")
       endif()
       if("${info}" MATCHES "INFO:compiler_version\\[([^]\"]*)\\]")
-        string(REGEX REPLACE "^0+([0-9])" "\\1" COMPILER_VERSION "${CMAKE_MATCH_1}")
+        string(REGEX REPLACE "^0+([0-9]+)" "\\1" COMPILER_VERSION "${CMAKE_MATCH_1}")
         string(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION "${COMPILER_VERSION}")
       endif()
       if("${info}" MATCHES "INFO:compiler_version_internal\\[([^]\"]*)\\]")
@@ -602,26 +643,28 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
     if(WIN32)
       # The offset to the PE signature is stored at 0x3c.
       file(READ ${file} peoffsethex LIMIT 1 OFFSET 60 HEX)
-      string(SUBSTRING "${peoffsethex}" 0 1 peoffsethex1)
-      string(SUBSTRING "${peoffsethex}" 1 1 peoffsethex2)
-      set(peoffsetexpression "${peoffsethex1} * 16 + ${peoffsethex2}")
-      string(REPLACE "a" "10" peoffsetexpression "${peoffsetexpression}")
-      string(REPLACE "b" "11" peoffsetexpression "${peoffsetexpression}")
-      string(REPLACE "c" "12" peoffsetexpression "${peoffsetexpression}")
-      string(REPLACE "d" "13" peoffsetexpression "${peoffsetexpression}")
-      string(REPLACE "e" "14" peoffsetexpression "${peoffsetexpression}")
-      string(REPLACE "f" "15" peoffsetexpression "${peoffsetexpression}")
-      math(EXPR peoffset "${peoffsetexpression}")
-
-      file(READ ${file} peheader LIMIT 6 OFFSET ${peoffset} HEX)
-      if(peheader STREQUAL "50450000a201")
-        set(ARCHITECTURE_ID "SH3")
-      elseif(peheader STREQUAL "50450000a301")
-        set(ARCHITECTURE_ID "SH3DSP")
-      elseif(peheader STREQUAL "50450000a601")
-        set(ARCHITECTURE_ID "SH4")
-      elseif(peheader STREQUAL "50450000a801")
-        set(ARCHITECTURE_ID "SH5")
+      if(NOT peoffsethex STREQUAL "")
+        string(SUBSTRING "${peoffsethex}" 0 1 peoffsethex1)
+        string(SUBSTRING "${peoffsethex}" 1 1 peoffsethex2)
+        set(peoffsetexpression "${peoffsethex1} * 16 + ${peoffsethex2}")
+        string(REPLACE "a" "10" peoffsetexpression "${peoffsetexpression}")
+        string(REPLACE "b" "11" peoffsetexpression "${peoffsetexpression}")
+        string(REPLACE "c" "12" peoffsetexpression "${peoffsetexpression}")
+        string(REPLACE "d" "13" peoffsetexpression "${peoffsetexpression}")
+        string(REPLACE "e" "14" peoffsetexpression "${peoffsetexpression}")
+        string(REPLACE "f" "15" peoffsetexpression "${peoffsetexpression}")
+        math(EXPR peoffset "${peoffsetexpression}")
+
+        file(READ ${file} peheader LIMIT 6 OFFSET ${peoffset} HEX)
+        if(peheader STREQUAL "50450000a201")
+          set(ARCHITECTURE_ID "SH3")
+        elseif(peheader STREQUAL "50450000a301")
+          set(ARCHITECTURE_ID "SH3DSP")
+        elseif(peheader STREQUAL "50450000a601")
+          set(ARCHITECTURE_ID "SH4")
+        elseif(peheader STREQUAL "50450000a801")
+          set(ARCHITECTURE_ID "SH5")
+        endif()
       endif()
     endif()
 

+ 28 - 0
Modules/CMakePlatformId.h.in

@@ -91,6 +91,14 @@
 #  define PLATFORM_ID
 # endif
 
+#elif defined(__INTEGRITY)
+# if defined(INT_178B)
+#  define PLATFORM_ID "Integrity178"
+
+# else /* regular Integrity */
+#  define PLATFORM_ID "Integrity"
+# endif
+
 #else /* unknown platform */
 # define PLATFORM_ID
 
@@ -151,6 +159,26 @@
 # elif defined(__ICCAVR__)
 #  define ARCHITECTURE_ID "AVR"
 
+# else /* unknown architecture */
+#  define ARCHITECTURE_ID ""
+# endif
+
+#elif defined(__ghs__)
+# if defined(__PPC64__)
+#  define ARCHITECTURE_ID "PPC64"
+
+# elif defined(__ppc__)
+#  define ARCHITECTURE_ID "PPC"
+
+# elif defined(__ARM__)
+#  define ARCHITECTURE_ID "ARM"
+
+# elif defined(__x86_64__)
+#  define ARCHITECTURE_ID "x64"
+
+# elif defined(__i386__)
+#  define ARCHITECTURE_ID "X86"
+
 # else /* unknown architecture */
 #  define ARCHITECTURE_ID ""
 # endif

+ 2 - 0
Modules/CMakeTestCCompiler.cmake

@@ -22,6 +22,7 @@ unset(CMAKE_C_COMPILER_WORKS CACHE)
 # any makefiles or projects.
 if(NOT CMAKE_C_COMPILER_WORKS)
   PrintTestCompilerStatus("C" "")
+  __TestCompiler_setTryCompileTargetType()
   file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCCompiler.c
     "#ifdef __cplusplus\n"
     "# error \"The CMAKE_C_COMPILER is set to a C++ compiler\"\n"
@@ -41,6 +42,7 @@ if(NOT CMAKE_C_COMPILER_WORKS)
   set(CMAKE_C_COMPILER_WORKS ${CMAKE_C_COMPILER_WORKS})
   unset(CMAKE_C_COMPILER_WORKS CACHE)
   set(C_TEST_WAS_RUN 1)
+  __TestCompiler_restoreTryCompileTargetType()
 endif()
 
 if(NOT CMAKE_C_COMPILER_WORKS)

+ 2 - 0
Modules/CMakeTestCXXCompiler.cmake

@@ -22,6 +22,7 @@ unset(CMAKE_CXX_COMPILER_WORKS CACHE)
 # any makefiles or projects.
 if(NOT CMAKE_CXX_COMPILER_WORKS)
   PrintTestCompilerStatus("CXX" "")
+  __TestCompiler_setTryCompileTargetType()
   file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testCXXCompiler.cxx
     "#ifndef __cplusplus\n"
     "# error \"The CMAKE_CXX_COMPILER is set to a C compiler\"\n"
@@ -34,6 +35,7 @@ if(NOT CMAKE_CXX_COMPILER_WORKS)
   set(CMAKE_CXX_COMPILER_WORKS ${CMAKE_CXX_COMPILER_WORKS})
   unset(CMAKE_CXX_COMPILER_WORKS CACHE)
   set(CXX_TEST_WAS_RUN 1)
+  __TestCompiler_restoreTryCompileTargetType()
 endif()
 
 if(NOT CMAKE_CXX_COMPILER_WORKS)

+ 20 - 0
Modules/CMakeTestCompilerCommon.cmake

@@ -5,3 +5,23 @@
 function(PrintTestCompilerStatus LANG MSG)
   message(STATUS "Check for working ${LANG} compiler: ${CMAKE_${LANG}_COMPILER}${MSG}")
 endfunction()
+
+# if required set the target type if not already explicitly set
+macro(__TestCompiler_setTryCompileTargetType)
+  if(NOT CMAKE_TRY_COMPILE_TARGET_TYPE)
+    if("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
+      #prefer static libraries to avoid linking issues
+      set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+      set(__CMAKE_TEST_COMPILER_TARGET_TYPE_RESTORE 1)
+    endif()
+  endif()
+endmacro()
+
+# restore the original value
+# -- not necessary if __TestCompiler_setTryCompileTargetType() was used in function scope
+macro(__TestCompiler_restoreTryCompileTargetType)
+  if(__CMAKE_TEST_COMPILER_TARGET_TYPE_RESTORE)
+    unset(CMAKE_TRY_COMPILE_TARGET_TYPE)
+    unset(__CMAKE_TEST_COMPILER_TARGET_TYPE_RESTORE)
+  endif()
+endmacro()

+ 7 - 4
Modules/Compiler/GHS-DetermineCompiler.cmake

@@ -1,6 +1,9 @@
-set(_compiler_id_pp_test "defined(__INTEGRITY)")
+set(_compiler_id_pp_test "defined(__ghs__)")
 
 set(_compiler_id_version_compute "
-# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__INTEGRITY_MAJOR_VERSION)
-# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__INTEGRITY_MINOR_VERSION)
-# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__INTEGRITY_PATCH_VERSION)")
+/* __GHS_VERSION_NUMBER = VVVVRP */
+# ifdef __GHS_VERSION_NUMBER
+# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__GHS_VERSION_NUMBER / 100)
+# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__GHS_VERSION_NUMBER / 10 % 10)
+# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__GHS_VERSION_NUMBER      % 10)
+# endif")

+ 8 - 0
Modules/CompilerId/GHS_default.gpj.in

@@ -0,0 +1,8 @@
+#!gbuild
+@bsp_name@
+@os_dir@
+primaryTarget=@ghs_primary_target@
+[Project]
+     {isdefined(GHS_BSP)} -bsp $GHS_BSP
+     {isdefined(GHS_OS)} -os_dir $GHS_OS
+GHS_lib.gpj [Library]

+ 3 - 0
Modules/CompilerId/GHS_lib.gpj.in

@@ -0,0 +1,3 @@
+#!gbuild
+[Library]
+@id_src@

+ 0 - 18
Source/cmGlobalGhsMultiGenerator.cxx

@@ -104,24 +104,6 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
 
   mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp.c_str());
 
-  // FIXME: compiler detection not implemented
-  // gbuild uses the primaryTarget setting in the top-level project
-  // file to determine which compiler to use. Because compiler
-  // detection is not implemented these variables must be
-  // set to skip past these tests. However cmake will verify that
-  // the executable pointed to by CMAKE_<LANG>_COMPILER exists.
-  // To pass this additional check gbuild is used as a place holder for the
-  // actual compiler.
-  mf->AddDefinition("CMAKE_C_COMPILER", gbuild.c_str());
-  mf->AddDefinition("CMAKE_C_COMPILER_ID_RUN", "TRUE");
-  mf->AddDefinition("CMAKE_C_COMPILER_ID", "GHS");
-  mf->AddDefinition("CMAKE_C_COMPILER_FORCED", "TRUE");
-
-  mf->AddDefinition("CMAKE_CXX_COMPILER", gbuild.c_str());
-  mf->AddDefinition("CMAKE_CXX_COMPILER_ID_RUN", "TRUE");
-  mf->AddDefinition("CMAKE_CXX_COMPILER_ID", "GHS");
-  mf->AddDefinition("CMAKE_CXX_COMPILER_FORCED", "TRUE");
-
   return true;
 }
 

+ 1 - 0
Tests/CMakeLists.txt

@@ -2317,6 +2317,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
       add_test_GhsMulti(compiler_options_none GhsMultiCompilerOptions None "-DRUN_TEST=RELEASE_FLAGS -DRUN_TEST_BUILD_TYPE=\"\"" "")
       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 "" "" "")
       list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/GhsMulti/${ghs_config_name}")
       #unset ghs config variables
       unset(ghs_config_name)

+ 30 - 0
Tests/GhsMulti/GhsMultiPlatform/CMakeLists.txt

@@ -0,0 +1,30 @@
+# 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)
+
+message("CMAKE_C_COMPILER = ${CMAKE_C_COMPILER}")
+message("CMAKE_C_COMPILER_ID = ${CMAKE_C_COMPILER_ID}")
+message("CMAKE_C_COMPILER_VERSION = ${CMAKE_C_COMPILER_VERSION}")
+message("CMAKE_C_PLATFORM_ID = ${CMAKE_C_PLATFORM_ID}")
+message("CMAKE_C_COMPILER_ARCHITECTURE_ID = ${CMAKE_C_COMPILER_ARCHITECTURE_ID}")
+message("CMAKE_C_COMPILER_ABI = ${CMAKE_C_COMPILER_ABI}")
+message("CMAKE_C_STANDARD_COMPUTED_DEFAULT = ${CMAKE_C_STANDARD_COMPUTED_DEFAULT}")
+
+message("CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}")
+message("CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}")
+message("CMAKE_CXX_COMPILER_VERSION = ${CMAKE_CXX_COMPILER_VERSION}")
+message("CMAKE_CXX_PLATFORM_ID = ${CMAKE_CXX_PLATFORM_ID}")
+message("CMAKE_CXX_COMPILER_ARCHITECTURE_ID = ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}")
+message("CMAKE_CXX_COMPILER_ABI = ${CMAKE_CXX_COMPILER_ABI}")
+message("CMAKE_CXX_STANDARD_COMPUTED_DEFAULT = ${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT}")
+
+if(CMAKE_C_COMPILER AND NOT CMAKE_C_COMPILER_ID STREQUAL "GHS")
+  message(FATAL_ERROR "CMAKE_C_COMPILER_ID != GHS")
+endif()
+
+if(CMAKE_CXX_COMPILER AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "GHS")
+  message(FATAL_ERROR "CMAKE_CXX_COMPILER_ID != GHS")
+endif()

+ 6 - 0
Tests/GhsMulti/GhsMultiPlatform/file1.c

@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main(void)
+{
+  printf("Testing...\n");
+}