Merge topic 'GHS_updates'

21ab58d3f8 GHS: Update test suite
72e0c115b7 GHS: Add Compiler ID detection
436cc5e991 GHS: try_compile() now uses GHS platform variables
4a1ec0de3d GHS: Fix toolset selection
1a66acdef2 GHS: Append ".gpj" to target name when generating build command
0c9e47d7cd GHS: Integrity Application updates
8044318431 GHS: Add support for some of the source file properties
73092b2213 GHS: Add support for object libraries
...

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2231
This commit is contained in:
Brad King
2019-01-18 11:58:23 +00:00
committed by Kitware Robot
148 changed files with 2080 additions and 1042 deletions

View File

@@ -168,3 +168,6 @@ then the language standard variables are honored:
Their values are used to set the corresponding target properties in
the generated project (unless overridden by an explicit option).
For the :generator:`Green Hills MULTI` generator the GHS toolset and target
system customization cache variables are also propagated into the test project.

View File

@@ -3,49 +3,63 @@ Green Hills MULTI
Generates Green Hills MULTI project files (experimental, work-in-progress).
The buildsystem has predetermined build-configuration settings that can be controlled
via the :variable:`CMAKE_BUILD_TYPE` variable.
Customizations that are used to pick toolset and target system:
The ``-A <arch>`` can be supplied for setting the target architecture.
``<arch>`` usually is one of "arm", "ppc", "86", etcetera. If the target architecture
is not specified then the default architecture of "arm" will be used.
The ``-T <toolset>`` can be supplied for setting the toolset to be used.
All toolsets are expected to be located at ``GHS_TOOLSET_ROOT``.
If the toolset is not specified then the latest toolset will be used.
The ``-T <toolset>`` option can be used to set the directory location of the toolset.
Both absolute and relative paths are valid. Relative paths use ``GHS_TOOLSET_ROOT``
as the root. If the toolset is not specified then the latest toolset found in
``GHS_TOOLSET_ROOT`` will be used.
Cache variables that are used for toolset and target system customization:
* ``GHS_TARGET_PLATFORM``
Default to ``integrity``.
Usual values are ``integrity``, ``threadx``, ``uvelosity``,
``velosity``, ``vxworks``, ``standalone``.
| Defaults to ``integrity``.
| Usual values are ``integrity``, ``threadx``, ``uvelosity``, ``velosity``,
``vxworks``, ``standalone``.
* ``GHS_PRIMARY_TARGET``
Sets ``primaryTarget`` field in project file.
Defaults to ``<arch>_<GHS_TARGET_PLATFORM>.tgt``.
| Sets ``primaryTarget`` entry in project file.
| Defaults to ``<arch>_<GHS_TARGET_PLATFORM>.tgt``.
* ``GHS_TOOLSET_ROOT``
Default to ``C:/ghs``. Root path for ``toolset``.
| Root path for ``toolset`` searches.
| Defaults to ``C:/ghs``.
* ``GHS_OS_ROOT``
Default to ``C:/ghs``. Root path for RTOS searches.
| Root path for RTOS searches.
| Defaults to ``C:/ghs``.
* ``GHS_OS_DIR``
Default to latest platform OS installation at ``GHS_OS_ROOT``. Set this value if
a specific RTOS is to be used.
| Sets ``-os_dir`` entry in project file.
| Defaults to latest platform OS installation at ``GHS_OS_ROOT``. Set this value if
a specific RTOS is to be used.
* ``GHS_BSP_NAME``
Defaults to ``sim<arch>`` if not set by user.
| Sets ``-bsp`` entry in project file.
| Defaults to ``sim<arch>`` for ``integrity`` platforms.
Customizations are available through the following cache variables:
* ``GHS_CUSTOMIZATION``
* ``GHS_GPJ_MACROS``
The following properties are available:
* :prop_tgt:`GHS_INTEGRITY_APP`
.. note::
This generator is deemed experimental as of CMake |release|
and is still a work in progress. Future versions of CMake

View File

@@ -194,6 +194,7 @@ Properties on Targets
/prop_tgt/FRAMEWORK
/prop_tgt/FRAMEWORK_VERSION
/prop_tgt/GENERATOR_FILE_NAME
/prop_tgt/GHS_INTEGRITY_APP
/prop_tgt/GNUtoMS
/prop_tgt/HAS_CXX
/prop_tgt/IMPLICIT_DEPENDS_INCLUDE_TRANSFORM

View File

@@ -482,11 +482,6 @@ Variables for Languages
/variable/CMAKE_LANG_FLAGS_RELEASE_INIT
/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO
/variable/CMAKE_LANG_FLAGS_RELWITHDEBINFO_INIT
/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_CONFIG
/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_DEBUG
/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_MINSIZEREL
/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELEASE
/variable/CMAKE_LANG_GHS_KERNEL_FLAGS_RELWITHDEBINFO
/variable/CMAKE_LANG_IGNORE_EXTENSIONS
/variable/CMAKE_LANG_IMPLICIT_INCLUDE_DIRECTORIES
/variable/CMAKE_LANG_IMPLICIT_LINK_DIRECTORIES

View File

@@ -0,0 +1,10 @@
GHS_INTEGRITY_APP
-----------------
``ON`` / ``OFF`` boolean to determine if an executable target should
be treated as an `Integrity Application`.
If no value is set and if a `.int` file is added as a source file to the
executable target it will be treated as an `Integrity Application`.
Supported on :generator:`Green Hills MULTI`.

View File

@@ -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)

View File

@@ -1,5 +0,0 @@
CMAKE_<LANG>_GHS_KERNEL_FLAGS_<CONFIG>
--------------------------------------
GHS kernel flags for language ``<LANG>`` when building for the ``<CONFIG>``
configuration.

View File

@@ -1,5 +0,0 @@
CMAKE_<LANG>_GHS_KERNEL_FLAGS_DEBUG
-----------------------------------
This variable is the ``Debug`` variant of the
:variable:`CMAKE_<LANG>_GHS_KERNEL_FLAGS_<CONFIG>` variable.

View File

@@ -1,5 +0,0 @@
CMAKE_<LANG>_GHS_KERNEL_FLAGS_MINSIZEREL
----------------------------------------
This variable is the ``MinSizeRel`` variant of the
:variable:`CMAKE_<LANG>_GHS_KERNEL_FLAGS_<CONFIG>` variable.

View File

@@ -1,5 +0,0 @@
CMAKE_<LANG>_GHS_KERNEL_FLAGS_RELEASE
-------------------------------------
This variable is the ``Release`` variant of the
:variable:`CMAKE_<LANG>_GHS_KERNEL_FLAGS_<CONFIG>` variable.

View File

@@ -1,5 +0,0 @@
CMAKE_<LANG>_GHS_KERNEL_FLAGS_RELWITHDEBINFO
--------------------------------------------
This variable is the ``RelWithDebInfo`` variant of the
:variable:`CMAKE_<LANG>_GHS_KERNEL_FLAGS_<CONFIG>` variable.

View File

@@ -1,4 +1,4 @@
GHS-MULTI
---------
True when using Green Hills MULTI
``True`` when using :generator:`Green Hills MULTI` generator.

View File

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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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}

View File

@@ -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}")
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")
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()

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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()

View File

@@ -8,23 +8,3 @@ string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -Odebug -g")
string(APPEND CMAKE_C_FLAGS_MINSIZEREL_INIT " -Ospace")
string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -O")
string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -O -g")
set(CMAKE_C_GHS_KERNEL_FLAGS_DEBUG_INIT "-ldebug ${CMAKE_C_FLAGS_DEBUG_INIT}")
set(CMAKE_C_GHS_KERNEL_FLAGS_MINSIZEREL_INIT "${CMAKE_C_FLAGS_MINSIZEREL_INIT}")
set(CMAKE_C_GHS_KERNEL_FLAGS_RELEASE_INIT "${CMAKE_C_FLAGS_RELEASE_INIT}")
set(CMAKE_C_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT
"-ldebug ${CMAKE_C_FLAGS_RELWITHDEBINFO_INIT}")
if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
set (CMAKE_C_GHS_KERNEL_FLAGS_DEBUG "${CMAKE_C_GHS_KERNEL_FLAGS_DEBUG_INIT}"
CACHE STRING "Kernel flags used by the compiler during debug builds.")
set (CMAKE_C_GHS_KERNEL_FLAGS_MINSIZEREL
"${CMAKE_C_GHS_KERNEL_FLAGS_MINSIZEREL_INIT}" CACHE STRING
"Kernel flags used by the compiler during release builds for minimum size.")
set (CMAKE_C_GHS_KERNEL_FLAGS_RELEASE
"${CMAKE_C_GHS_KERNEL_FLAGS_RELEASE_INIT}"
CACHE STRING "Kernel flags used by the compiler during release builds.")
set (CMAKE_C_GHS_KERNEL_FLAGS_RELWITHDEBINFO
"${CMAKE_C_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
"Kernel flags used by the compiler during release builds with debug info.")
endif()

View File

@@ -8,27 +8,3 @@ string(APPEND CMAKE_CXX_FLAGS_DEBUG_INIT " -Odebug -g")
string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT " -Ospace")
string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -O")
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -O -g")
set(CMAKE_CXX_GHS_KERNEL_FLAGS_DEBUG_INIT
"-ldebug ${CMAKE_CXX_FLAGS_DEBUG_INIT}")
set(CMAKE_CXX_GHS_KERNEL_FLAGS_MINSIZEREL_INIT
"${CMAKE_CXX_FLAGS_MINSIZEREL_INIT}")
set(CMAKE_CXX_GHS_KERNEL_FLAGS_RELEASE_INIT
"${CMAKE_CXX_FLAGS_RELEASE_INIT}")
set(CMAKE_CXX_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT
"-ldebug ${CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT}")
if(NOT CMAKE_NOT_USING_CONFIG_FLAGS)
set (CMAKE_CXX_GHS_KERNEL_FLAGS_DEBUG
"${CMAKE_CXX_GHS_KERNEL_FLAGS_DEBUG_INIT}"
CACHE STRING "Kernel flags used by the compiler during debug builds.")
set (CMAKE_CXX_GHS_KERNEL_FLAGS_MINSIZEREL
"${CMAKE_CXX_GHS_KERNEL_FLAGS_MINSIZEREL_INIT}" CACHE STRING
"Kernel flags used by the compiler during release builds for minimum size.")
set (CMAKE_CXX_GHS_KERNEL_FLAGS_RELEASE
"${CMAKE_CXX_GHS_KERNEL_FLAGS_RELEASE_INIT}"
CACHE STRING "Kernel flags used by the compiler during release builds.")
set (CMAKE_CXX_GHS_KERNEL_FLAGS_RELWITHDEBINFO
"${CMAKE_CXX_GHS_KERNEL_FLAGS_RELWITHDEBINFO_INIT}" CACHE STRING
"Kernel flags used by the compiler during release builds with debug info.")
endif()

View File

@@ -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")

View File

@@ -3,6 +3,6 @@ if(__COMPILER_GHS)
endif()
set(__COMPILER_GHS 1)
set(CMAKE_EXECUTABLE_SUFFIX ".as")
set(CMAKE_LIBRARY_PATH_TERMINATOR "\n")
set(CMAKE_LIBRARY_PATH_FLAG " -L")
set(CMAKE_EXECUTABLE_SUFFIX "")
set(CMAKE_LIBRARY_PATH_TERMINATOR "")
set(CMAKE_LIBRARY_PATH_FLAG "")

View File

@@ -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]

View File

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

View File

@@ -9,6 +9,9 @@ mark_as_advanced(GHS_OS_ROOT)
set(GHS_OS_DIR "NOTFOUND" CACHE PATH "GHS platform OS directory")
mark_as_advanced(GHS_OS_DIR)
set(GHS_OS_DIR_OPTION "-os_dir " CACHE STRING "GHS compiler os option")
mark_as_advanced(GHS_OS_DIR)
#set GHS_OS_DIR if not set by user
if ( NOT GHS_OS_DIR )
if (EXISTS ${GHS_OS_ROOT})
@@ -23,8 +26,11 @@ if ( NOT GHS_OS_DIR )
endif ()
#filter based on platform name
if (GHS_TARGET_PLATFORM STREQUAL "integrity")
if (GHS_TARGET_PLATFORM MATCHES "integrity")
list(FILTER GHS_CANDIDATE_OS_DIRS INCLUDE REGEX "int[0-9][0-9][0-9][0-9a-z].*")
else() #fall-back for standalone
unset(GHS_CANDIDATE_OS_DIRS)
set(GHS_OS_DIR "IGNORE")
endif ()
if (GHS_CANDIDATE_OS_DIRS)

View File

@@ -57,6 +57,12 @@ static std::string const kCMAKE_TRY_COMPILE_PLATFORM_VARIABLES =
"CMAKE_TRY_COMPILE_PLATFORM_VARIABLES";
static std::string const kCMAKE_WARN_DEPRECATED = "CMAKE_WARN_DEPRECATED";
/* GHS Multi platform variables */
static std::set<std::string> ghs_platform_vars{
"GHS_TARGET_PLATFORM", "GHS_PRIMARY_TARGET", "GHS_TOOLSET_ROOT",
"GHS_OS_ROOT", "GHS_OS_DIR", "GHS_BSP_NAME"
};
static void writeProperty(FILE* fout, std::string const& targetName,
std::string const& prop, std::string const& value)
{
@@ -869,6 +875,16 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
projectName = "CMAKE_TRY_COMPILE";
}
if (this->Makefile->GetState()->UseGhsMultiIDE()) {
// Forward the GHS variables to the inner project cache.
for (std::string const& var : ghs_platform_vars) {
if (const char* val = this->Makefile->GetDefinition(var)) {
std::string flag = "-D" + var + "=" + val;
cmakeFlags.push_back(std::move(flag));
}
}
}
bool erroroc = cmSystemTools::GetErrorOccuredFlag();
cmSystemTools::ResetErrorOccuredFlag();
std::string output;

View File

@@ -4,31 +4,34 @@
#include "cmGeneratedFileStream.h"
void GhsMultiGpj::WriteGpjTag(Types const gpjType,
cmGeneratedFileStream* const filestream)
static const char* GHS_TAG[] = { "[INTEGRITY Application]",
"[Library]",
"[Project]",
"[Program]",
"[Reference]",
"[Subproject]" };
const char* GhsMultiGpj::GetGpjTag(Types const gpjType)
{
char const* tag;
switch (gpjType) {
case INTERGRITY_APPLICATION:
tag = "INTEGRITY Application";
break;
case LIBRARY:
tag = "Library";
break;
case PROJECT:
tag = "Project";
break;
case PROGRAM:
tag = "Program";
break;
case REFERENCE:
tag = "Reference";
break;
case SUBPROJECT:
tag = "Subproject";
tag = GHS_TAG[gpjType];
break;
default:
tag = "";
}
*filestream << "[" << tag << "]" << std::endl;
return tag;
}
void GhsMultiGpj::WriteGpjTag(Types const gpjType, std::ostream& fout)
{
char const* tag;
tag = GhsMultiGpj::GetGpjTag(gpjType);
fout << tag << std::endl;
}

View File

@@ -4,6 +4,7 @@
#define cmGhsMultiGpj_h
#include "cmConfigure.h" // IWYU pragma: keep
#include <iosfwd>
class cmGeneratedFileStream;
@@ -20,8 +21,9 @@ public:
SUBPROJECT
};
static void WriteGpjTag(Types const gpjType,
cmGeneratedFileStream* filestream);
static void WriteGpjTag(Types const gpjType, std::ostream& fout);
static const char* GetGpjTag(Types const gpjType);
};
#endif // ! cmGhsMultiGpjType_h

View File

@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmGhsMultiTargetGenerator.h"
#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGhsMultiGenerator.h"
@@ -9,177 +10,128 @@
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmSourceGroup.h"
#include "cmTarget.h"
#include <assert.h>
std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target)
: GeneratorTarget(target)
, LocalGenerator(
static_cast<cmLocalGhsMultiGenerator*>(target->GetLocalGenerator()))
, Makefile(target->Target->GetMakefile())
, TargetGroup(DetermineIfTargetGroup(target))
, DynamicDownload(false)
, Name(target->GetName())
{
this->RelBuildFilePath = this->GetRelBuildFilePath(target);
this->RelOutputFileName = this->RelBuildFilePath + target->GetName() + ".a";
this->RelBuildFileName = this->RelBuildFilePath;
this->RelBuildFileName += this->GetBuildFileName(target);
std::string absPathToRoot = this->GetAbsPathToRoot(target);
absPathToRoot = this->AddSlashIfNeededToPath(absPathToRoot);
this->AbsBuildFilePath = absPathToRoot + this->RelBuildFilePath;
this->AbsBuildFileName = absPathToRoot + this->RelBuildFileName;
this->AbsOutputFileName = absPathToRoot + this->RelOutputFileName;
// Store the configuration name that is being used
if (const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) {
// Use the build type given by the user.
this->ConfigName = config;
} else {
// No configuration type given.
this->ConfigName.clear();
}
}
cmGhsMultiTargetGenerator::~cmGhsMultiTargetGenerator()
{
cmDeleteAll(this->FolderBuildStreams);
}
std::string cmGhsMultiTargetGenerator::GetRelBuildFilePath(
const cmGeneratorTarget* target)
{
std::string output = target->GetEffectiveFolderName();
cmSystemTools::ConvertToUnixSlashes(output);
if (!output.empty()) {
output += "/";
}
output += target->GetName() + "/";
return output;
}
std::string cmGhsMultiTargetGenerator::GetAbsPathToRoot(
const cmGeneratorTarget* target)
{
return target->GetLocalGenerator()->GetBinaryDirectory();
}
std::string cmGhsMultiTargetGenerator::GetAbsBuildFilePath(
const cmGeneratorTarget* target)
{
std::string output;
output = cmGhsMultiTargetGenerator::GetAbsPathToRoot(target);
output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
output += cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
return output;
}
std::string cmGhsMultiTargetGenerator::GetRelBuildFileName(
const cmGeneratorTarget* target)
{
std::string output;
output = cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
output += cmGhsMultiTargetGenerator::GetBuildFileName(target);
return output;
}
std::string cmGhsMultiTargetGenerator::GetBuildFileName(
const cmGeneratorTarget* target)
{
std::string output;
output = target->GetName();
output += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
return output;
}
std::string cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(
std::string const& input)
{
std::string output(input);
if (!cmHasLiteralSuffix(output, "/")) {
output += "/";
}
return output;
}
void cmGhsMultiTargetGenerator::Generate()
{
std::vector<cmSourceFile*> objectSources = this->GetSources();
if (!objectSources.empty() && this->IncludeThisTarget()) {
if (!cmSystemTools::FileExists(this->AbsBuildFilePath.c_str())) {
cmSystemTools::MakeDirectory(this->AbsBuildFilePath.c_str());
// Determine type of target for this project
switch (this->GeneratorTarget->GetType()) {
case cmStateEnums::EXECUTABLE: {
// Get the name of the executable to generate.
std::string targetName;
std::string targetNameImport;
std::string targetNamePDB;
this->GeneratorTarget->GetExecutableNames(
targetName, this->TargetNameReal, targetNameImport, targetNamePDB,
this->ConfigName);
if (cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()) {
this->TagType = GhsMultiGpj::INTERGRITY_APPLICATION;
} else {
this->TagType = GhsMultiGpj::PROGRAM;
}
break;
}
cmGlobalGhsMultiGenerator::Open(std::string(""), this->AbsBuildFileName,
&this->FolderBuildStreams);
cmGlobalGhsMultiGenerator::OpenBuildFileStream(
this->GetFolderBuildStreams());
std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
if (0 == config.length()) {
config = "RELEASE";
case cmStateEnums::STATIC_LIBRARY: {
std::string targetName;
std::string targetNameSO;
std::string targetNameImport;
std::string targetNamePDB;
this->GeneratorTarget->GetLibraryNames(
targetName, targetNameSO, this->TargetNameReal, targetNameImport,
targetNamePDB, this->ConfigName);
this->TagType = GhsMultiGpj::LIBRARY;
break;
}
const std::string language(
this->GeneratorTarget->GetLinkerLanguage(config));
config = cmSystemTools::UpperCase(config);
this->DynamicDownload = this->DetermineIfDynamicDownload(config, language);
if (this->DynamicDownload) {
*this->GetFolderBuildStreams()
<< "#component integrity_dynamic_download" << std::endl;
case cmStateEnums::SHARED_LIBRARY: {
std::string msg = "add_library(<name> SHARED ...) not supported: ";
msg += this->Name;
cmSystemTools::Message(msg.c_str());
return;
}
GhsMultiGpj::WriteGpjTag(this->GetGpjTag(), this->GetFolderBuildStreams());
cmGlobalGhsMultiGenerator::WriteDisclaimer(this->GetFolderBuildStreams());
bool const notKernel = this->IsNotKernel(config, language);
this->WriteTypeSpecifics(config, notKernel);
this->SetCompilerFlags(config, language, notKernel);
this->WriteCompilerFlags(config, language);
this->WriteCompilerDefinitions(config, language);
this->WriteIncludes(config, language);
if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
this->WriteTargetLinkLibraries(config, language);
case cmStateEnums::OBJECT_LIBRARY: {
std::string targetName;
std::string targetNameSO;
std::string targetNameImport;
std::string targetNamePDB;
this->GeneratorTarget->GetLibraryNames(
targetName, targetNameSO, this->TargetNameReal, targetNameImport,
targetNamePDB, this->ConfigName);
this->TagType = GhsMultiGpj::SUBPROJECT;
break;
}
this->WriteCustomCommands();
std::map<const cmSourceFile*, std::string> objectNames =
cmGhsMultiTargetGenerator::GetObjectNames(
&objectSources, this->LocalGenerator, this->GeneratorTarget);
this->WriteSources(objectSources, objectNames);
case cmStateEnums::MODULE_LIBRARY: {
std::string msg = "add_library(<name> MODULE ...) not supported: ";
msg += this->Name;
cmSystemTools::Message(msg.c_str());
return;
}
case cmStateEnums::UTILITY: {
std::string msg = "add_custom_target(<name> ...) not supported: ";
msg += this->Name;
cmSystemTools::Message(msg.c_str());
return;
}
default:
return;
}
// Tell the global generator the name of the project file
this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
this->Name.c_str());
this->GeneratorTarget->Target->SetProperty(
"GENERATOR_FILE_NAME_EXT", GhsMultiGpj::GetGpjTag(this->TagType));
this->GenerateTarget();
}
bool cmGhsMultiTargetGenerator::IncludeThisTarget()
void cmGhsMultiTargetGenerator::GenerateTarget()
{
bool output = true;
char const* excludeFromAll =
this->GeneratorTarget->GetProperty("EXCLUDE_FROM_ALL");
if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
'\0' == excludeFromAll[1]) {
output = false;
}
return output;
}
// 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.c_str());
fout.SetCopyIfDifferent(true);
std::vector<cmSourceFile*> cmGhsMultiTargetGenerator::GetSources() const
{
std::vector<cmSourceFile*> output;
std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
this->GeneratorTarget->GetSourceFiles(output, config);
return output;
}
this->GetGlobalGenerator()->WriteFileHeader(fout);
GhsMultiGpj::WriteGpjTag(this->TagType, fout);
GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag() const
{
return cmGhsMultiTargetGenerator::GetGpjTag(this->GeneratorTarget);
}
const std::string language(
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName));
GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag(
const cmGeneratorTarget* target)
{
GhsMultiGpj::Types output;
if (cmGhsMultiTargetGenerator::DetermineIfTargetGroup(target)) {
output = GhsMultiGpj::INTERGRITY_APPLICATION;
} else if (target->GetType() == cmStateEnums::STATIC_LIBRARY) {
output = GhsMultiGpj::LIBRARY;
} else {
output = GhsMultiGpj::PROGRAM;
}
return output;
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->WriteCustomCommands(fout);
this->WriteSources(fout);
this->WriteReferences(fout);
fout.Close();
}
cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator()
@@ -189,41 +141,27 @@ cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator()
this->LocalGenerator->GetGlobalGenerator());
}
void cmGhsMultiTargetGenerator::WriteTypeSpecifics(const std::string& config,
bool const notKernel)
void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
const std::string& config)
{
std::string outputDir(this->GetOutputDirectory(config));
std::string outputFilename(this->GetOutputFilename(config));
std::string outpath;
std::string rootpath = this->LocalGenerator->GetCurrentBinaryDirectory();
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY) {
std::string const& static_library_suffix =
this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
*this->GetFolderBuildStreams()
<< " -o \"" << outputDir << outputFilename << static_library_suffix
<< "\"" << std::endl;
} else if (this->GeneratorTarget->GetType() == cmStateEnums::EXECUTABLE) {
if (notKernel && !this->IsTargetGroup()) {
*this->GetFolderBuildStreams() << " -relprog" << std::endl;
}
if (this->IsTargetGroup()) {
*this->GetFolderBuildStreams()
<< " -o \"" << outputDir << outputFilename << ".elf\"" << std::endl;
*this->GetFolderBuildStreams()
<< " :extraOutputFile=\"" << outputDir << outputFilename
<< ".elf.ael\"" << std::endl;
} else {
std::string const executable_suffix =
this->Makefile->GetSafeDefinition("CMAKE_EXECUTABLE_SUFFIX");
*this->GetFolderBuildStreams()
<< " -o \"" << outputDir << outputFilename << executable_suffix
<< "\"" << std::endl;
}
if (this->TagType != GhsMultiGpj::SUBPROJECT) {
// set target binary file destination
outpath = this->GeneratorTarget->GetDirectory(config);
outpath = this->LocalGenerator->ConvertToRelativePath(rootpath, outpath);
fout << " :binDirRelative=\"" << outpath << "\"" << std::endl;
fout << " -o \"" << this->TargetNameReal << "\"" << std::endl;
}
// set target object file destination
outpath = this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
fout << " :outputDirRelative=\"" << outpath << "\"" << std::endl;
}
void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
const std::string& language,
bool const notKernel)
const std::string& language)
{
std::map<std::string, std::string>::iterator i =
this->FlagsByLanguage.find(language);
@@ -231,14 +169,9 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
std::string flags;
const char* lang = language.c_str();
if (notKernel) {
this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
lang, config);
} else {
this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
lang + std::string("_GHS_KERNEL"),
config);
}
this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, lang,
config);
this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget, lang,
config);
this->LocalGenerator->AddVisibilityPresetFlags(
@@ -281,21 +214,25 @@ std::string cmGhsMultiTargetGenerator::GetDefines(const std::string& language,
return i->second;
}
void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::string const&,
void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::ostream& fout,
std::string const&,
const std::string& language)
{
std::map<std::string, std::string>::iterator flagsByLangI =
this->FlagsByLanguage.find(language);
if (flagsByLangI != this->FlagsByLanguage.end()) {
if (!flagsByLangI->second.empty()) {
*this->GetFolderBuildStreams()
<< " " << flagsByLangI->second << std::endl;
std::vector<std::string> ghsCompFlags =
cmSystemTools::ParseArguments(flagsByLangI->second.c_str());
for (auto& f : ghsCompFlags) {
fout << " " << f << std::endl;
}
}
}
}
void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
const std::string& config, const std::string& language)
std::ostream& fout, const std::string& config, const std::string& language)
{
std::vector<std::string> compileDefinitions;
this->GeneratorTarget->GetCompileDefinitions(compileDefinitions, config,
@@ -303,11 +240,12 @@ void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
for (std::vector<std::string>::const_iterator cdI =
compileDefinitions.begin();
cdI != compileDefinitions.end(); ++cdI) {
*this->GetFolderBuildStreams() << " -D" << (*cdI) << std::endl;
fout << " -D" << (*cdI) << std::endl;
}
}
void cmGhsMultiTargetGenerator::WriteIncludes(const std::string& config,
void cmGhsMultiTargetGenerator::WriteIncludes(std::ostream& fout,
const std::string& config,
const std::string& language)
{
std::vector<std::string> includes;
@@ -316,80 +254,73 @@ void cmGhsMultiTargetGenerator::WriteIncludes(const std::string& config,
for (std::vector<std::string>::const_iterator includes_i = includes.begin();
includes_i != includes.end(); ++includes_i) {
*this->GetFolderBuildStreams()
<< " -I\"" << *includes_i << "\"" << std::endl;
fout << " -I\"" << *includes_i << "\"" << std::endl;
}
}
void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries(
std::string const& config, std::string const& language)
void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
std::string const& config)
{
// library directories
cmTargetDependSet tds =
this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
for (cmTargetDependSet::iterator tdsI = tds.begin(); tdsI != tds.end();
++tdsI) {
const cmGeneratorTarget* tg = *tdsI;
*this->GetFolderBuildStreams()
<< " -L\"" << GetAbsBuildFilePath(tg) << "\"" << std::endl;
}
// library targets
cmTarget::LinkLibraryVectorType llv =
this->GeneratorTarget->Target->GetOriginalLinkLibraries();
for (cmTarget::LinkLibraryVectorType::const_iterator llvI = llv.begin();
llvI != llv.end(); ++llvI) {
std::string libName = llvI->first;
// if it is a user defined target get the full path to the lib
cmTarget* tg(GetGlobalGenerator()->FindTarget(libName));
if (NULL != tg) {
libName = tg->GetName() + ".a";
}
*this->GetFolderBuildStreams()
<< " -l\"" << libName << "\"" << std::endl;
if (this->TagType == GhsMultiGpj::INTERGRITY_APPLICATION) {
return;
}
if (!this->TargetGroup) {
std::string linkLibraries;
std::string flags;
std::string linkFlags;
std::string frameworkPath;
std::string linkPath;
std::string createRule =
this->GeneratorTarget->GetCreateRuleVariable(language, config);
bool useWatcomQuote =
this->Makefile->IsOn(createRule + "_USE_WATCOM_QUOTE");
std::unique_ptr<cmLinkLineComputer> linkLineComputer(
this->GetGlobalGenerator()->CreateLinkLineComputer(
this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
linkLineComputer->SetUseWatcomQuote(useWatcomQuote);
std::string linkLibraries;
std::string flags;
std::string linkFlags;
std::string frameworkPath;
std::string linkPath;
this->LocalGenerator->GetTargetFlags(
linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
frameworkPath, linkPath, this->GeneratorTarget);
linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
std::unique_ptr<cmLinkLineComputer> linkLineComputer(
this->GetGlobalGenerator()->CreateLinkLineComputer(
this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
if (!linkPath.empty()) {
linkPath = " " + linkPath.substr(0U, linkPath.size() - 1U);
*this->GetFolderBuildStreams() << linkPath;
}
this->LocalGenerator->GetTargetFlags(
linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
frameworkPath, linkPath, this->GeneratorTarget);
if (!linkFlags.empty()) {
*this->GetFolderBuildStreams() << " " << linkFlags << std::endl;
// write out link options
std::vector<std::string> lopts =
cmSystemTools::ParseArguments(linkFlags.c_str());
for (auto& l : lopts) {
fout << " " << l << std::endl;
}
// write out link search paths
// must be quoted for paths that contain spaces
std::vector<std::string> lpath =
cmSystemTools::ParseArguments(linkPath.c_str());
for (auto& l : lpath) {
fout << " -L\"" << l << "\"" << std::endl;
}
// write out link libs
// must be quoted for filepaths that contains spaces
std::string cbd = this->LocalGenerator->GetCurrentBinaryDirectory();
std::vector<std::string> llibs =
cmSystemTools::ParseArguments(linkLibraries.c_str());
for (auto& l : llibs) {
if (l.compare(0, 2, "-l") == 0) {
fout << " \"" << l << "\"" << std::endl;
} else {
std::string rl = cmSystemTools::CollapseCombinedPath(cbd, l);
fout << " -l\"" << rl << "\"" << std::endl;
}
}
}
void cmGhsMultiTargetGenerator::WriteCustomCommands()
void cmGhsMultiTargetGenerator::WriteCustomCommands(std::ostream& fout)
{
WriteCustomCommandsHelper(this->GeneratorTarget->GetPreBuildCommands(),
WriteCustomCommandsHelper(fout, this->GeneratorTarget->GetPreBuildCommands(),
cmTarget::PRE_BUILD);
WriteCustomCommandsHelper(this->GeneratorTarget->GetPostBuildCommands(),
cmTarget::POST_BUILD);
WriteCustomCommandsHelper(
fout, this->GeneratorTarget->GetPostBuildCommands(), cmTarget::POST_BUILD);
}
void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
std::vector<cmCustomCommand> const& commandsSet,
std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet,
cmTarget::CustomCommandType const commandType)
{
for (std::vector<cmCustomCommand>::const_iterator commandsSetI =
@@ -400,10 +331,10 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
commandI != commands.end(); ++commandI) {
switch (commandType) {
case cmTarget::PRE_BUILD:
*this->GetFolderBuildStreams() << " :preexecShellSafe=";
fout << " :preexecShellSafe=";
break;
case cmTarget::POST_BUILD:
*this->GetFolderBuildStreams() << " :postexecShellSafe=";
fout << " :postexecShellSafe=";
break;
default:
assert("Only pre and post are supported");
@@ -414,242 +345,237 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
std::string subCommandE =
this->LocalGenerator->EscapeForShell(*commandLineI, true);
if (!command.empty()) {
*this->GetFolderBuildStreams()
<< (command.begin() == commandLineI ? "'" : " ");
fout << (command.begin() == commandLineI ? "'" : " ");
// Need to double escape backslashes
cmSystemTools::ReplaceString(subCommandE, "\\", "\\\\");
}
*this->GetFolderBuildStreams() << subCommandE;
fout << subCommandE;
}
if (!command.empty()) {
*this->GetFolderBuildStreams() << "'" << std::endl;
fout << "'" << std::endl;
}
}
}
}
std::map<const cmSourceFile*, std::string>
cmGhsMultiTargetGenerator::GetObjectNames(
std::vector<cmSourceFile*>* const objectSources,
cmLocalGhsMultiGenerator* const localGhsMultiGenerator,
cmGeneratorTarget* const generatorTarget)
void cmGhsMultiTargetGenerator::WriteSourceProperty(std::ostream& fout,
const cmSourceFile* sf,
std::string propName,
std::string propFlag)
{
std::map<std::string, std::vector<cmSourceFile*>> filenameToSource;
std::map<cmSourceFile*, std::string> sourceToFilename;
for (std::vector<cmSourceFile*>::const_iterator sf = objectSources->begin();
sf != objectSources->end(); ++sf) {
const std::string filename =
cmSystemTools::GetFilenameName((*sf)->GetFullPath());
const std::string lower_filename = cmSystemTools::LowerCase(filename);
filenameToSource[lower_filename].push_back(*sf);
sourceToFilename[*sf] = lower_filename;
}
std::vector<cmSourceFile*> duplicateSources;
for (std::map<std::string, std::vector<cmSourceFile*>>::const_iterator
msvSourceI = filenameToSource.begin();
msvSourceI != filenameToSource.end(); ++msvSourceI) {
if (msvSourceI->second.size() > 1) {
duplicateSources.insert(duplicateSources.end(),
msvSourceI->second.begin(),
msvSourceI->second.end());
const char* prop = sf->GetProperty(propName);
if (prop) {
std::vector<std::string> list;
cmSystemTools::ExpandListArgument(prop, list);
for (auto& p : list) {
fout << " " << propFlag << p << std::endl;
}
}
std::map<const cmSourceFile*, std::string> objectNamesCorrected;
for (std::vector<cmSourceFile*>::const_iterator sf =
duplicateSources.begin();
sf != duplicateSources.end(); ++sf) {
std::string const longestObjectDirectory(
cmGhsMultiTargetGenerator::ComputeLongestObjectDirectory(
localGhsMultiGenerator, generatorTarget, *sf));
std::string objFilenameName =
localGhsMultiGenerator->GetObjectFileNameWithoutTarget(
**sf, longestObjectDirectory);
cmsys::SystemTools::ReplaceString(objFilenameName, "/", "_");
objectNamesCorrected[*sf] = objFilenameName;
}
return objectNamesCorrected;
}
void cmGhsMultiTargetGenerator::WriteSources(
std::vector<cmSourceFile*> const& objectSources,
std::map<const cmSourceFile*, std::string> const& objectNames)
void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
{
for (const cmSourceFile* sf : objectSources) {
std::vector<cmSourceGroup> sourceGroups(this->Makefile->GetSourceGroups());
std::string const& sourceFullPath = sf->GetFullPath();
/* vector of all sources for this target */
std::vector<cmSourceFile*> sources;
this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);
/* vector of all groups defined for this target
* -- but the vector is not expanded with sub groups or in any useful order
*/
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
/* for each source file assign it to its group */
std::map<std::string, std::vector<cmSourceFile*>> groupFiles;
std::set<std::string> groupNames;
for (auto& sf : sources) {
cmSourceGroup* sourceGroup =
this->Makefile->FindSourceGroup(sourceFullPath, sourceGroups);
std::string sgPath = sourceGroup->GetFullName();
cmSystemTools::ConvertToUnixSlashes(sgPath);
cmGlobalGhsMultiGenerator::AddFilesUpToPath(
this->GetFolderBuildStreams(), &this->FolderBuildStreams,
this->LocalGenerator->GetBinaryDirectory().c_str(), sgPath,
GhsMultiGpj::SUBPROJECT, this->RelBuildFilePath);
this->Makefile->FindSourceGroup(sf->GetFullPath(), sourceGroups);
std::string gn = sourceGroup->GetFullName();
groupFiles[gn].push_back(sf);
groupNames.insert(gn);
}
std::string fullSourcePath(sf->GetFullPath());
if (sf->GetExtension() == "int" || sf->GetExtension() == "bsp") {
*this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
/* 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",
"Object Files", "Object Libraries", "Resources"
};
/* list of groups in the order they are displayed in a project file*/
std::vector<std::string> groupFilesList(groupFiles.size());
/* put the groups in the order they should be listed
* - standard groups first, and then everything else
* in the order used by std::map.
*/
int i = 0;
for (const std::string& gn : standardGroups) {
auto n = groupNames.find(gn);
if (n != groupNames.end()) {
groupFilesList[i] = *n;
i += 1;
groupNames.erase(gn);
}
}
{ /* catch-all group - is last item */
std::string gn = "";
auto n = groupNames.find(gn);
if (n != groupNames.end()) {
groupFilesList.back() = *n;
groupNames.erase(gn);
}
}
for (auto& n : groupNames) {
groupFilesList[i] = n;
i += 1;
}
/* sort the files within each group */
for (auto& n : groupFilesList) {
std::sort(groupFiles[n].begin(), groupFiles[n].end(),
[](cmSourceFile* l, cmSourceFile* r) {
return l->GetFullPath() < r->GetFullPath();
});
}
/* list of open project files */
std::vector<cmGeneratedFileStream*> gfiles;
/* write files into the proper project file
* -- groups go into main project file
* unless FOLDER property or variable is set.
*/
for (auto& sg : groupFilesList) {
std::ostream* fout;
bool useProjectFile =
cmSystemTools::IsOn(
this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
cmSystemTools::IsOn(
this->Makefile->GetDefinition("GHS_NO_SOURCE_GROUP_FILE"));
if (useProjectFile || sg.empty()) {
fout = &fout_proj;
} else {
// WORKAROUND: GHS MULTI needs the path to use backslashes without quotes
// to open files in search as of version 6.1.6
cmsys::SystemTools::ReplaceString(fullSourcePath, "/", "\\");
*this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
// Open the filestream in copy-if-different mode.
std::string gname = sg;
cmsys::SystemTools::ReplaceString(gname, "\\", "_");
std::string lpath =
this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
lpath += "/";
lpath += gname;
lpath += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
std::string fpath = this->LocalGenerator->GetCurrentBinaryDirectory();
fpath += "/";
fpath += lpath;
cmGeneratedFileStream* f = new cmGeneratedFileStream(fpath.c_str());
f->SetCopyIfDifferent(true);
gfiles.push_back(f);
fout = f;
this->GetGlobalGenerator()->WriteFileHeader(*f);
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::SUBPROJECT, *f);
fout_proj << lpath << " ";
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::SUBPROJECT, fout_proj);
}
if ("ld" != sf->GetExtension() && "int" != sf->GetExtension() &&
"bsp" != sf->GetExtension()) {
this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], sf);
if (objectNames.end() != objectNames.find(sf)) {
*this->FolderBuildStreams[sgPath]
<< " -o \"" << objectNames.find(sf)->second << "\"" << std::endl;
if (useProjectFile) {
if (sg.empty()) {
*fout << "{comment} Others" << std::endl;
} else {
*fout << "{comment} " << sg << 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()) {
this->WriteObjectLangOverride(*fout, si);
}
this->WriteObjectDir(this->FolderBuildStreams[sgPath],
this->AbsBuildFilePath + sgPath);
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;
}
}
}
for (cmGeneratedFileStream* f : gfiles) {
f->Close();
}
}
void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
cmGeneratedFileStream* fileStream, const cmSourceFile* sourceFile)
std::ostream& fout, const cmSourceFile* sourceFile)
{
const char* rawLangProp = sourceFile->GetProperty("LANGUAGE");
if (NULL != rawLangProp) {
std::string sourceLangProp(rawLangProp);
std::string extension(sourceFile->GetExtension());
if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
*fileStream << " -dotciscxx" << std::endl;
fout << " -dotciscxx" << std::endl;
}
}
}
void cmGhsMultiTargetGenerator::WriteObjectDir(
cmGeneratedFileStream* fileStream, std::string const& dir)
void cmGhsMultiTargetGenerator::WriteReferences(std::ostream& fout)
{
std::string workingDir(dir);
cmSystemTools::ConvertToUnixSlashes(workingDir);
if (!workingDir.empty()) {
workingDir += "/";
// This only applies to INTEGRITY Applications
if (this->TagType != GhsMultiGpj::INTERGRITY_APPLICATION) {
return;
}
// 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->ConvertToRelativePath(rootpath, tpath) + "/" +
tname + "REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION;
fout << outpath;
fout << " ";
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fout);
// Tell the global generator that a refernce project needs to be created
t->Target->SetProperty("GHS_REFERENCE_PROJECT", "ON");
}
workingDir += "Objs";
*fileStream << " -object_dir=\"" << workingDir << "\"" << std::endl;
}
std::string cmGhsMultiTargetGenerator::GetOutputDirectory(
const std::string& config) const
bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp(void)
{
std::string outputDir(AbsBuildFilePath);
const char* runtimeOutputProp =
this->GeneratorTarget->GetProperty("RUNTIME_OUTPUT_DIRECTORY");
if (NULL != runtimeOutputProp) {
outputDir = runtimeOutputProp;
}
std::string configCapped(cmSystemTools::UpperCase(config));
const char* runtimeOutputSProp = this->GeneratorTarget->GetProperty(
"RUNTIME_OUTPUT_DIRECTORY_" + configCapped);
if (NULL != runtimeOutputSProp) {
outputDir = runtimeOutputSProp;
}
cmSystemTools::ConvertToUnixSlashes(outputDir);
if (!outputDir.empty()) {
outputDir += "/";
}
return outputDir;
}
std::string cmGhsMultiTargetGenerator::GetOutputFilename(
const std::string& config) const
{
std::string outputFilename(this->GeneratorTarget->GetName());
const char* outputNameProp =
this->GeneratorTarget->GetProperty("OUTPUT_NAME");
if (NULL != outputNameProp) {
outputFilename = outputNameProp;
}
std::string configCapped(cmSystemTools::UpperCase(config));
const char* outputNameSProp =
this->GeneratorTarget->GetProperty(configCapped + "_OUTPUT_NAME");
if (NULL != outputNameSProp) {
outputFilename = outputNameSProp;
}
return outputFilename;
}
std::string cmGhsMultiTargetGenerator::ComputeLongestObjectDirectory(
cmLocalGhsMultiGenerator const* localGhsMultiGenerator,
cmGeneratorTarget* const generatorTarget, cmSourceFile* const sourceFile)
{
std::string dir_max;
dir_max +=
localGhsMultiGenerator->GetMakefile()->GetCurrentBinaryDirectory();
dir_max += "/";
dir_max += generatorTarget->Target->GetName();
dir_max += "/";
std::vector<cmSourceGroup> sourceGroups(
localGhsMultiGenerator->GetMakefile()->GetSourceGroups());
std::string const& sourceFullPath = sourceFile->GetFullPath();
cmSourceGroup* sourceGroup =
localGhsMultiGenerator->GetMakefile()->FindSourceGroup(sourceFullPath,
sourceGroups);
std::string const& sgPath = sourceGroup->GetFullName();
dir_max += sgPath;
dir_max += "/Objs/libs/";
dir_max += generatorTarget->Target->GetName();
dir_max += "/";
return dir_max;
}
bool cmGhsMultiTargetGenerator::IsNotKernel(std::string const& config,
const std::string& language)
{
bool output;
std::vector<std::string> options;
this->GeneratorTarget->GetCompileOptions(options, config, language);
output =
options.end() == std::find(options.begin(), options.end(), "-kernel");
return output;
}
bool cmGhsMultiTargetGenerator::DetermineIfTargetGroup(
const cmGeneratorTarget* target)
{
bool output = false;
std::vector<cmSourceFile*> sources;
std::string config =
target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
target->GetSourceFiles(sources, config);
for (std::vector<cmSourceFile*>::const_iterator sources_i = sources.begin();
sources.end() != sources_i; ++sources_i) {
if ("int" == (*sources_i)->GetExtension()) {
output = true;
const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
if (p) {
return cmSystemTools::IsOn(
this->GeneratorTarget->GetProperty("ghs_integrity_app"));
} else {
std::vector<cmSourceFile*> sources;
this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);
for (auto& sf : sources) {
if ("int" == sf->GetExtension()) {
return true;
}
}
return false;
}
return output;
}
bool cmGhsMultiTargetGenerator::DetermineIfDynamicDownload(
std::string const& config, const std::string& language)
{
std::vector<std::string> options;
bool output = false;
this->GeneratorTarget->GetCompileOptions(options, config, language);
for (std::vector<std::string>::const_iterator options_i = options.begin();
options_i != options.end(); ++options_i) {
std::string option = *options_i;
if (this->DDOption == option) {
output = true;
}
}
return output;
}

View File

@@ -24,97 +24,49 @@ public:
virtual void Generate();
bool IncludeThisTarget();
std::vector<cmSourceFile*> GetSources() const;
GhsMultiGpj::Types GetGpjTag() const;
static GhsMultiGpj::Types GetGpjTag(const cmGeneratorTarget* target);
const char* GetAbsBuildFilePath() const
{
return this->AbsBuildFilePath.c_str();
}
const char* GetRelBuildFileName() const
{
return this->RelBuildFileName.c_str();
}
const char* GetAbsBuildFileName() const
{
return this->AbsBuildFileName.c_str();
}
const char* GetAbsOutputFileName() const
{
return this->AbsOutputFileName.c_str();
}
static std::string GetRelBuildFilePath(const cmGeneratorTarget* target);
static std::string GetAbsPathToRoot(const cmGeneratorTarget* target);
static std::string GetAbsBuildFilePath(const cmGeneratorTarget* target);
static std::string GetRelBuildFileName(const cmGeneratorTarget* target);
static std::string GetBuildFileName(const cmGeneratorTarget* target);
static std::string AddSlashIfNeededToPath(std::string const& input);
private:
cmGlobalGhsMultiGenerator* GetGlobalGenerator() const;
cmGeneratedFileStream* GetFolderBuildStreams()
{
return this->FolderBuildStreams[""];
};
bool IsTargetGroup() const { return this->TargetGroup; }
void WriteTypeSpecifics(const std::string& config, bool notKernel);
void WriteCompilerFlags(const std::string& config,
void GenerateTarget();
void WriteTargetSpecifics(std::ostream& fout, const std::string& config);
void WriteCompilerFlags(std::ostream& fout, const std::string& config,
const std::string& language);
void WriteCompilerDefinitions(const std::string& config,
void WriteCompilerDefinitions(std::ostream& fout, const std::string& config,
const std::string& language);
void SetCompilerFlags(std::string const& config, const std::string& language,
bool const notKernel);
void SetCompilerFlags(std::string const& config,
const std::string& language);
std::string GetDefines(const std::string& langugae,
std::string const& config);
void WriteIncludes(const std::string& config, const std::string& language);
void WriteTargetLinkLibraries(std::string const& config,
std::string const& language);
void WriteCustomCommands();
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::vector<cmCustomCommand> const& commandsSet,
std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet,
cmTarget::CustomCommandType commandType);
void WriteSources(
std::vector<cmSourceFile*> const& objectSources,
std::map<const cmSourceFile*, std::string> const& objectNames);
static std::map<const cmSourceFile*, std::string> GetObjectNames(
std::vector<cmSourceFile*>* objectSources,
cmLocalGhsMultiGenerator* localGhsMultiGenerator,
cmGeneratorTarget* generatorTarget);
static void WriteObjectLangOverride(cmGeneratedFileStream* fileStream,
void WriteSources(std::ostream& fout_proj);
void WriteSourceProperty(std::ostream& fout, const cmSourceFile* sf,
std::string propName, std::string propFlag);
void WriteReferences(std::ostream& fout);
static void WriteObjectLangOverride(std::ostream& fout,
const cmSourceFile* sourceFile);
static void WriteObjectDir(cmGeneratedFileStream* fileStream,
std::string const& dir);
std::string GetOutputDirectory(const std::string& config) const;
std::string GetOutputFilename(const std::string& config) const;
static std::string ComputeLongestObjectDirectory(
cmLocalGhsMultiGenerator const* localGhsMultiGenerator,
cmGeneratorTarget* generatorTarget, cmSourceFile* const sourceFile);
bool IsNotKernel(std::string const& config, const std::string& language);
static bool DetermineIfTargetGroup(const cmGeneratorTarget* target);
bool DetermineIfDynamicDownload(std::string const& config,
const std::string& language);
bool DetermineIfIntegrityApp(void);
cmGeneratorTarget* GeneratorTarget;
cmLocalGhsMultiGenerator* LocalGenerator;
cmMakefile* Makefile;
std::string AbsBuildFilePath;
std::string RelBuildFilePath;
std::string AbsBuildFileName;
std::string RelBuildFileName;
std::string RelOutputFileName;
std::string AbsOutputFileName;
std::map<std::string, cmGeneratedFileStream*> FolderBuildStreams;
bool TargetGroup;
bool DynamicDownload;
static std::string const DDOption;
std::map<std::string, std::string> FlagsByLanguage;
std::map<std::string, std::string> DefinesByLanguage;
std::string TargetNameReal;
GhsMultiGpj::Types TagType;
std::string const Name;
std::string ConfigName; /* CMAKE_BUILD_TYPE */
};
#endif // ! cmGhsMultiTargetGenerator_h

View File

@@ -302,7 +302,8 @@ bool cmGlobalGenerator::CheckTargetsForMissingSources() const
for (cmGeneratorTarget* target : targets) {
if (target->GetType() == cmStateEnums::TargetType::GLOBAL_TARGET ||
target->GetType() == cmStateEnums::TargetType::INTERFACE_LIBRARY ||
target->GetType() == cmStateEnums::TargetType::UTILITY) {
target->GetType() == cmStateEnums::TargetType::UTILITY ||
cmSystemTools::IsOn(target->GetProperty("ghs_integrity_app"))) {
continue;
}

View File

@@ -11,6 +11,7 @@
#include "cmGhsMultiTargetGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
#include "cmState.h"
#include "cmVersion.h"
#include "cmake.h"
@@ -20,13 +21,12 @@ const char* cmGlobalGhsMultiGenerator::DEFAULT_TOOLSET_ROOT = "C:/ghs";
cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
: cmGlobalGenerator(cm)
, OSDirRelative(false)
{
cm->GetState()->SetGhsMultiIDE(true);
}
cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator()
{
cmDeleteAll(TargetFolderBuildStreams);
}
cmLocalGenerator* cmGlobalGhsMultiGenerator::CreateLocalGenerator(
@@ -42,46 +42,59 @@ void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
"Generates Green Hills MULTI files (experimental, work-in-progress).";
}
void cmGlobalGhsMultiGenerator::ComputeTargetObjectDirectory(
cmGeneratorTarget* gt) const
{
// Compute full path to object file directory for this target.
std::string dir;
dir += gt->LocalGenerator->GetCurrentBinaryDirectory();
dir += "/";
dir += gt->LocalGenerator->GetTargetDirectory(gt);
dir += "/";
gt->ObjectDirectory = dir;
}
bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
cmMakefile* mf)
{
std::string tsp; /* toolset path */
std::string tsn = ts; /* toolset name */
std::string tsp; /* toolset path */
GetToolset(mf, tsp, tsn);
this->GetToolset(mf, tsp, ts);
/* no toolset was found */
if (tsn.empty()) {
if (tsp.empty()) {
return false;
} else if (ts.empty()) {
std::string message;
message =
"Green Hills MULTI: -T <toolset> not specified; defaulting to \"";
message += tsn;
message += tsp;
message += "\"";
cmSystemTools::Message(message.c_str());
/* store the toolset for later use
/* store the full toolset for later use
* -- already done if -T<toolset> was specified
*/
mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsn.c_str(),
"Name of generator toolset.",
mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsp.c_str(),
"Location of generator toolset.",
cmStateEnums::INTERNAL);
}
/* set the build tool to use */
std::string gbuild(tsp + ((tsp.back() == '/') ? "" : "/") +
DEFAULT_BUILD_PROGRAM);
const char* prevTool = mf->GetDefinition("CMAKE_MAKE_PROGRAM");
std::string gbuild(tsp + "/" + tsn + "/" + DEFAULT_BUILD_PROGRAM);
/* check if the toolset changed from last generate */
if (prevTool != NULL && (gbuild != prevTool)) {
std::string message = "generator toolset: ";
std::string message = "toolset build tool: ";
message += gbuild;
message += "\nDoes not match the toolset used previously: ";
message += "\nDoes not match the previously used build tool: ";
message += prevTool;
message += "\nEither remove the CMakeCache.txt file and CMakeFiles "
"directory or choose a different binary directory.";
cmSystemTools::Error(message.c_str());
return false;
} else {
/* store the toolset that is being used for this build */
mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild.c_str(),
@@ -89,25 +102,7 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
true);
}
mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsn.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");
mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp.c_str());
return true;
}
@@ -130,6 +125,8 @@ bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
const char* tgtPlatform = mf->GetDefinition("GHS_TARGET_PLATFORM");
if (tgtPlatform == nullptr) {
cmSystemTools::Message("Green Hills MULTI: GHS_TARGET_PLATFORM not "
"specified; defaulting to \"integrity\"");
tgtPlatform = "integrity";
}
@@ -160,11 +157,11 @@ bool cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile* /*mf*/)
}
void cmGlobalGhsMultiGenerator::GetToolset(cmMakefile* mf, std::string& tsd,
std::string& ts)
const std::string& ts)
{
const char* ghsRoot = mf->GetDefinition("GHS_TOOLSET_ROOT");
if (!ghsRoot) {
if (!ghsRoot || ghsRoot[0] == '\0') {
ghsRoot = DEFAULT_TOOLSET_ROOT;
}
tsd = ghsRoot;
@@ -173,129 +170,208 @@ void cmGlobalGhsMultiGenerator::GetToolset(cmMakefile* mf, std::string& tsd,
std::vector<std::string> output;
// Use latest? version
if (tsd.back() != '/') {
tsd += "/";
}
cmSystemTools::Glob(tsd, "comp_[^;]+", output);
if (output.empty()) {
cmSystemTools::Error("GHS toolset not found in ", tsd.c_str());
ts = "";
std::string msg =
"No GHS toolsets found in GHS_TOOLSET_ROOT \"" + tsd + "\".";
cmSystemTools::Error(msg.c_str());
tsd = "";
} else {
ts = output.back();
tsd += output.back();
}
} else {
std::string tryPath = tsd + std::string("/") + ts;
std::string tryPath;
/* CollapseCombinedPath will check if ts is an absolute path */
tryPath = cmSystemTools::CollapseCombinedPath(tsd, ts);
if (!cmSystemTools::FileExists(tryPath)) {
cmSystemTools::Error("GHS toolset \"", ts.c_str(), "\" not found in ",
tsd.c_str());
ts = "";
std::string msg = "GHS toolset \"" + tryPath + "\" not found.";
cmSystemTools::Error(msg.c_str());
tsd = "";
} else {
tsd = tryPath;
}
}
}
void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
std::string const& filepath, cmGeneratedFileStream** filestream)
void cmGlobalGhsMultiGenerator::WriteFileHeader(std::ostream& fout)
{
// Get a stream where to generate things.
if (NULL == *filestream) {
*filestream = new cmGeneratedFileStream(filepath.c_str());
if (NULL != *filestream) {
OpenBuildFileStream(*filestream);
}
}
fout << "#!gbuild" << std::endl;
fout << "#" << std::endl
<< "# CMAKE generated file: DO NOT EDIT!" << std::endl
<< "# Generated by \"" << this->GetActualName() << "\""
<< " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
<< cmVersion::GetMinorVersion() << std::endl
<< "#" << std::endl
<< std::endl;
}
void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
cmGeneratedFileStream* filestream)
void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
*filestream << "#!gbuild" << std::endl;
}
WriteFileHeader(fout);
void cmGlobalGhsMultiGenerator::OpenBuildFileStream()
{
// Compute GHS MULTI's build file path.
std::string buildFilePath =
this->GetCMakeInstance()->GetHomeOutputDirectory();
buildFilePath += "/";
buildFilePath += "default";
buildFilePath += FILE_EXTENSION;
this->WriteMacros(fout);
this->WriteHighLevelDirectives(fout);
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout);
this->Open(std::string(""), buildFilePath, &this->TargetFolderBuildStreams);
OpenBuildFileStream(GetBuildFileStream());
fout << "# Top Level Project File" << std::endl;
char const* osDir =
this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR");
if (NULL == osDir) {
osDir = "";
cmSystemTools::Error("GHS_OS_DIR cache variable must be set");
} else {
this->GetCMakeInstance()->MarkCliAsUsed("GHS_OS_DIR");
}
std::string fOSDir(this->trimQuotes(osDir));
std::replace(fOSDir.begin(), fOSDir.end(), '\\', '/');
if (!fOSDir.empty() && ('c' == fOSDir[0] || 'C' == fOSDir[0])) {
this->OSDirRelative = false;
} else {
this->OSDirRelative = true;
// Specify BSP option if supplied by user
// -- not all platforms require this entry in the project file
// integrity platforms require this field; use default if needed
std::string platform;
if (const char* p =
this->GetCMakeInstance()->GetCacheDefinition("GHS_TARGET_PLATFORM")) {
platform = p;
}
std::string bspName;
char const* bspCache =
this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME");
if (bspCache) {
if (char const* bspCache =
this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME")) {
bspName = bspCache;
this->GetCMakeInstance()->MarkCliAsUsed("GHS_BSP_NAME");
} else {
bspName = "IGNORE";
}
if (bspName.empty() || bspName.compare("IGNORE") == 0) {
if (platform.find("integrity") != std::string::npos &&
cmSystemTools::IsOff(bspName.c_str())) {
const char* a =
this->GetCMakeInstance()->GetCacheDefinition("CMAKE_GENERATOR_PLATFORM");
bspName = "sim";
bspName += (a ? a : "");
}
this->WriteMacros();
this->WriteHighLevelDirectives();
if (!cmSystemTools::IsOff(bspName.c_str())) {
fout << " -bsp " << bspName << std::endl;
}
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, this->GetBuildFileStream());
this->WriteDisclaimer(this->GetBuildFileStream());
*this->GetBuildFileStream() << "# Top Level Project File" << std::endl;
*this->GetBuildFileStream() << " -bsp " << bspName << std::endl;
// Specify OS DIR if supplied by user
// -- not all platforms require this entry in the project file
std::string osDir;
std::string osDirOption;
if (char const* osDirCache =
this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR")) {
osDir = osDirCache;
}
this->WriteCompilerOptions(fOSDir);
if (char const* osDirOptionCache =
this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR_OPTION")) {
osDirOption = osDirOptionCache;
}
if (!cmSystemTools::IsOff(osDir.c_str()) ||
platform.find("integrity") != std::string::npos) {
std::replace(osDir.begin(), osDir.end(), '\\', '/');
fout << " " << osDirOption << "\"" << osDir << "\"" << std::endl;
}
WriteSubProjects(fout, root, generators);
}
void cmGlobalGhsMultiGenerator::CloseBuildFileStream(
cmGeneratedFileStream** filestream)
void cmGlobalGhsMultiGenerator::WriteSubProjects(
std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
if (filestream) {
delete *filestream;
*filestream = NULL;
} else {
cmSystemTools::Error("Build file stream was not open.");
// Collect all targets under this root generator and the transitive
// closure of their dependencies.
TargetDependSet projectTargets;
TargetDependSet originalTargets;
this->GetTargetSets(projectTargets, originalTargets, root, generators);
OrderedTargetDependSet orderedProjectTargets(projectTargets, "");
// write out all the sub-projects
std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
for (cmGeneratorTarget const* target : orderedProjectTargets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
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->ConvertToRelativePath(rootBinaryDir, dir.c_str());
if (dir == ".") {
dir.clear();
} else {
if (dir.back() != '/') {
dir += "/";
}
}
if (cmSystemTools::IsOn(target->GetProperty("EXCLUDE_FROM_ALL"))) {
fout << "{comment} ";
}
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.c_str());
fref.SetCopyIfDifferent(true);
this->WriteFileHeader(fref);
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref);
fref << " :reference=" << projFile << std::endl;
fref.Close();
}
}
}
}
void cmGlobalGhsMultiGenerator::Generate()
{
// first do the superclass method
this->cmGlobalGenerator::Generate();
if (!this->LocalGenerators.empty()) {
this->OpenBuildFileStream();
// output top-level projects
for (auto& it : this->ProjectMap) {
this->OutputTopLevelProject(it.second[0], it.second);
}
}
// Build all the folder build files
for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i) {
cmLocalGhsMultiGenerator* lg =
static_cast<cmLocalGhsMultiGenerator*>(this->LocalGenerators[i]);
const std::vector<cmGeneratorTarget*>& tgts = lg->GetGeneratorTargets();
this->UpdateBuildFiles(tgts);
}
void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
{
if (generators.empty()) {
return;
}
cmDeleteAll(TargetFolderBuildStreams);
this->TargetFolderBuildStreams.clear();
/* Name top-level projects as filename.top.gpj to avoid name clashes
* with target projects. This avoid the issue where the project has
* the same name as the executable target.
*/
std::string fname = root->GetCurrentBinaryDirectory();
fname += "/";
fname += root->GetProjectName();
fname += ".top";
fname += FILE_EXTENSION;
cmGeneratedFileStream fout(fname.c_str());
fout.SetCopyIfDifferent(true);
this->WriteTopLevelProject(fout, root, generators);
fout.Close();
}
void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
std::vector<std::string>& makeCommand, const std::string& makeProgram,
const std::string& /*projectName*/, const std::string& /*projectDir*/,
const std::string& projectName, const std::string& projectDir,
const std::string& targetName, const std::string& /*config*/, bool /*fast*/,
int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions)
{
@@ -313,16 +389,34 @@ void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
makeCommand.insert(makeCommand.end(), makeOptions.begin(),
makeOptions.end());
/* determine which top-project file to use */
std::string proj = projectName + ".top" + FILE_EXTENSION;
std::vector<std::string> files;
cmSystemTools::Glob(projectDir, ".*\\.top\\.gpj", files);
if (!files.empty()) {
auto p = std::find(files.begin(), files.end(), proj);
if (p == files.end()) {
proj = files.at(0);
}
}
makeCommand.push_back("-top");
makeCommand.push_back(proj);
if (!targetName.empty()) {
if (targetName == "clean") {
makeCommand.push_back("-clean");
} else {
makeCommand.push_back(targetName);
if (targetName.compare(targetName.size() - 4, 4, ".gpj") == 0) {
makeCommand.push_back(targetName);
} else {
makeCommand.push_back(targetName + ".gpj");
}
}
}
}
void cmGlobalGhsMultiGenerator::WriteMacros()
void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout)
{
char const* ghsGpjMacros =
this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
@@ -332,12 +426,12 @@ void cmGlobalGhsMultiGenerator::WriteMacros()
for (std::vector<std::string>::const_iterator expandedListI =
expandedList.begin();
expandedListI != expandedList.end(); ++expandedListI) {
*this->GetBuildFileStream() << "macro " << *expandedListI << std::endl;
fout << "macro " << *expandedListI << std::endl;
}
}
}
void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives()
void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(std::ostream& fout)
{
/* set primary target */
std::string tgt;
@@ -357,175 +451,16 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives()
tgt += ".tgt";
}
*this->GetBuildFileStream() << "primaryTarget=" << tgt << std::endl;
fout << "primaryTarget=" << tgt << std::endl;
char const* const customization =
this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
if (NULL != customization && strlen(customization) > 0) {
*this->GetBuildFileStream()
<< "customization=" << trimQuotes(customization) << std::endl;
fout << "customization=" << trimQuotes(customization) << std::endl;
this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
}
}
void cmGlobalGhsMultiGenerator::WriteCompilerOptions(std::string const& fOSDir)
{
*this->GetBuildFileStream()
<< " -os_dir=\"" << fOSDir << "\"" << std::endl;
}
void cmGlobalGhsMultiGenerator::WriteDisclaimer(std::ostream* os)
{
(*os) << "#" << std::endl
<< "# CMAKE generated file: DO NOT EDIT!" << std::endl
<< "# Generated by \"" << GetActualName() << "\""
<< " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
<< cmVersion::GetMinorVersion() << std::endl
<< "#" << std::endl;
}
void cmGlobalGhsMultiGenerator::AddFilesUpToPath(
cmGeneratedFileStream* mainBuildFile,
std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
char const* homeOutputDirectory, std::string const& path,
GhsMultiGpj::Types projType, std::string const& relPath)
{
std::string workingPath(path);
cmSystemTools::ConvertToUnixSlashes(workingPath);
std::vector<std::string> splitPath = cmSystemTools::SplitString(workingPath);
std::string workingRelPath(relPath);
cmSystemTools::ConvertToUnixSlashes(workingRelPath);
if (!workingRelPath.empty()) {
workingRelPath += "/";
}
std::string pathUpTo;
for (std::vector<std::string>::const_iterator splitPathI = splitPath.begin();
splitPath.end() != splitPathI; ++splitPathI) {
pathUpTo += *splitPathI;
if (targetFolderBuildStreams->end() ==
targetFolderBuildStreams->find(pathUpTo)) {
AddFilesUpToPathNewBuildFile(
mainBuildFile, targetFolderBuildStreams, homeOutputDirectory, pathUpTo,
splitPath.begin() == splitPathI, workingRelPath, projType);
}
AddFilesUpToPathAppendNextFile(targetFolderBuildStreams, pathUpTo,
splitPathI, splitPath.end(), projType);
pathUpTo += "/";
}
}
void cmGlobalGhsMultiGenerator::Open(
std::string const& mapKeyName, std::string const& fileName,
std::map<std::string, cmGeneratedFileStream*>* fileMap)
{
if (fileMap->end() == fileMap->find(fileName)) {
cmGeneratedFileStream* temp(new cmGeneratedFileStream);
temp->open(fileName.c_str());
(*fileMap)[mapKeyName] = temp;
}
}
void cmGlobalGhsMultiGenerator::AddFilesUpToPathNewBuildFile(
cmGeneratedFileStream* mainBuildFile,
std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
char const* homeOutputDirectory, std::string const& pathUpTo,
bool const isFirst, std::string const& relPath,
GhsMultiGpj::Types const projType)
{
// create folders up to file path
std::string absPath = std::string(homeOutputDirectory) + "/" + relPath;
std::string newPath = absPath + pathUpTo;
if (!cmSystemTools::FileExists(newPath.c_str())) {
cmSystemTools::MakeDirectory(newPath.c_str());
}
// Write out to filename for first time
std::string relFilename(GetFileNameFromPath(pathUpTo));
std::string absFilename = absPath + relFilename;
Open(pathUpTo, absFilename, targetFolderBuildStreams);
OpenBuildFileStream((*targetFolderBuildStreams)[pathUpTo]);
GhsMultiGpj::WriteGpjTag(projType, (*targetFolderBuildStreams)[pathUpTo]);
WriteDisclaimer((*targetFolderBuildStreams)[pathUpTo]);
// Add to main build file
if (isFirst) {
*mainBuildFile << relFilename << " ";
GhsMultiGpj::WriteGpjTag(projType, mainBuildFile);
}
}
void cmGlobalGhsMultiGenerator::AddFilesUpToPathAppendNextFile(
std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
std::string const& pathUpTo,
std::vector<std::string>::const_iterator splitPathI,
std::vector<std::string>::const_iterator end,
GhsMultiGpj::Types const projType)
{
std::vector<std::string>::const_iterator splitPathNextI = splitPathI + 1;
if (end != splitPathNextI &&
targetFolderBuildStreams->end() ==
targetFolderBuildStreams->find(pathUpTo + "/" + *splitPathNextI)) {
std::string nextFilename(*splitPathNextI);
nextFilename = GetFileNameFromPath(nextFilename);
*(*targetFolderBuildStreams)[pathUpTo] << nextFilename << " ";
GhsMultiGpj::WriteGpjTag(projType, (*targetFolderBuildStreams)[pathUpTo]);
}
}
std::string cmGlobalGhsMultiGenerator::GetFileNameFromPath(
std::string const& path)
{
std::string output(path);
if (!path.empty()) {
cmSystemTools::ConvertToUnixSlashes(output);
std::vector<std::string> splitPath = cmSystemTools::SplitString(output);
output += "/" + splitPath.back() + FILE_EXTENSION;
}
return output;
}
void cmGlobalGhsMultiGenerator::UpdateBuildFiles(
const std::vector<cmGeneratorTarget*>& tgts)
{
for (std::vector<cmGeneratorTarget*>::const_iterator tgtsI = tgts.begin();
tgtsI != tgts.end(); ++tgtsI) {
const cmGeneratorTarget* tgt = *tgtsI;
if (IsTgtForBuild(tgt)) {
std::string folderName = tgt->GetEffectiveFolderName();
if (this->TargetFolderBuildStreams.end() ==
this->TargetFolderBuildStreams.find(folderName)) {
this->AddFilesUpToPath(
GetBuildFileStream(), &this->TargetFolderBuildStreams,
this->GetCMakeInstance()->GetHomeOutputDirectory().c_str(),
folderName, GhsMultiGpj::PROJECT);
}
std::vector<std::string> splitPath = cmSystemTools::SplitString(
cmGhsMultiTargetGenerator::GetRelBuildFileName(tgt));
std::string foldNameRelBuildFile(*(splitPath.end() - 2) + "/" +
splitPath.back());
*this->TargetFolderBuildStreams[folderName] << foldNameRelBuildFile
<< " ";
GhsMultiGpj::WriteGpjTag(cmGhsMultiTargetGenerator::GetGpjTag(tgt),
this->TargetFolderBuildStreams[folderName]);
}
}
}
bool cmGlobalGhsMultiGenerator::IsTgtForBuild(const cmGeneratorTarget* tgt)
{
const std::string config =
tgt->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
std::vector<cmSourceFile*> tgtSources;
tgt->GetSourceFiles(tgtSources, config);
bool tgtInBuild = true;
char const* excludeFromAll = tgt->GetProperty("EXCLUDE_FROM_ALL");
if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
'\0' == excludeFromAll[1]) {
tgtInBuild = false;
}
return !tgtSources.empty() && tgtInBuild;
}
std::string cmGlobalGhsMultiGenerator::trimQuotes(std::string const& str)
{
std::string result;
@@ -537,3 +472,25 @@ std::string cmGlobalGhsMultiGenerator::trimQuotes(std::string const& str)
}
return result;
}
bool cmGlobalGhsMultiGenerator::TargetCompare::operator()(
cmGeneratorTarget const* l, cmGeneratorTarget const* r) const
{
// Make sure a given named target is ordered first,
// e.g. to set ALL_BUILD as the default active project.
// When the empty string is named this is a no-op.
if (r->GetName() == this->First) {
return false;
}
if (l->GetName() == this->First) {
return true;
}
return l->GetName() < r->GetName();
}
cmGlobalGhsMultiGenerator::OrderedTargetDependSet::OrderedTargetDependSet(
TargetDependSet const& targets, std::string const& first)
: derived(TargetCompare(first))
{
this->insert(targets.begin(), targets.end());
}

View File

@@ -13,7 +13,7 @@ class cmGeneratedFileStream;
class cmGlobalGhsMultiGenerator : public cmGlobalGenerator
{
public:
/// The default name of GHS MULTI's build file. Typically: monolith.gpj.
// The default filename extension of GHS MULTI's build files.
static const char* FILE_EXTENSION;
cmGlobalGhsMultiGenerator(cmake* cm);
@@ -63,29 +63,28 @@ public:
*/
bool FindMakeProgram(cmMakefile* mf) override;
cmGeneratedFileStream* GetBuildFileStream()
void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const override;
// 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*>
{
return this->TargetFolderBuildStreams[""];
}
};
class TargetCompare
{
std::string First;
static void OpenBuildFileStream(std::string const& filepath,
cmGeneratedFileStream** filestream);
static void OpenBuildFileStream(cmGeneratedFileStream* filestream);
static void CloseBuildFileStream(cmGeneratedFileStream** filestream);
/// Write the common disclaimer text at the top of each build file.
static void WriteDisclaimer(std::ostream* os);
std::vector<std::string> GetLibDirs() { return this->LibDirs; }
static void AddFilesUpToPath(
cmGeneratedFileStream* mainBuildFile,
std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
char const* homeOutputDirectory, std::string const& path,
GhsMultiGpj::Types projType, std::string const& relPath = "");
static void Open(std::string const& mapKeyName, std::string const& fileName,
std::map<std::string, cmGeneratedFileStream*>* fileMap);
static std::string trimQuotes(std::string const& str);
inline bool IsOSDirRelative() { return this->OSDirRelative; }
public:
TargetCompare(std::string const& first)
: First(first)
{
}
bool operator()(cmGeneratorTarget const* l,
cmGeneratorTarget const* r) const;
};
class OrderedTargetDependSet;
protected:
void Generate() override;
@@ -100,35 +99,35 @@ protected:
std::vector<std::string>()) override;
private:
void GetToolset(cmMakefile* mf, std::string& tsd, std::string& ts);
void OpenBuildFileStream();
void GetToolset(cmMakefile* mf, std::string& tsd, const std::string& ts);
void WriteMacros();
void WriteHighLevelDirectives();
void WriteCompilerOptions(std::string const& fOSDir);
/* 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 WriteHighLevelDirectives(std::ostream& fout);
void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
static void AddFilesUpToPathNewBuildFile(
cmGeneratedFileStream* mainBuildFile,
std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
char const* homeOutputDirectory, std::string const& pathUpTo, bool isFirst,
std::string const& relPath, GhsMultiGpj::Types projType);
static void AddFilesUpToPathAppendNextFile(
std::map<std::string, cmGeneratedFileStream*>* targetFolderBuildStreams,
std::string const& pathUpTo,
std::vector<std::string>::const_iterator splitPathI,
std::vector<std::string>::const_iterator end, GhsMultiGpj::Types projType);
static std::string GetFileNameFromPath(std::string const& path);
void UpdateBuildFiles(const std::vector<cmGeneratorTarget*>& tgts);
bool IsTgtForBuild(const cmGeneratorTarget* tgt);
std::string trimQuotes(std::string const& str);
std::vector<cmGeneratedFileStream*> TargetSubProjects;
std::map<std::string, cmGeneratedFileStream*> TargetFolderBuildStreams;
std::vector<std::string> LibDirs;
bool OSDirRelative;
static const char* DEFAULT_BUILD_PROGRAM;
static const char* DEFAULT_TOOLSET_ROOT;
};
class cmGlobalGhsMultiGenerator::OrderedTargetDependSet
: public std::multiset<cmTargetDepend,
cmGlobalGhsMultiGenerator::TargetCompare>
{
typedef std::multiset<cmTargetDepend,
cmGlobalGhsMultiGenerator::TargetCompare>
derived;
public:
typedef cmGlobalGenerator::TargetDependSet TargetDependSet;
OrderedTargetDependSet(TargetDependSet const&, std::string const& first);
};
#endif

View File

@@ -7,6 +7,7 @@
#include "cmGhsMultiTargetGenerator.h"
#include "cmGlobalGhsMultiGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
cmLocalGhsMultiGenerator::cmLocalGhsMultiGenerator(cmGlobalGenerator* gg,
cmMakefile* mf)
@@ -18,16 +19,82 @@ cmLocalGhsMultiGenerator::~cmLocalGhsMultiGenerator()
{
}
std::string cmLocalGhsMultiGenerator::GetTargetDirectory(
cmGeneratorTarget const* target) const
{
std::string dir;
dir += target->GetName();
dir += ".dir";
return dir;
}
void cmLocalGhsMultiGenerator::GenerateTargetsDepthFirst(
cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
{
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
return;
}
// Find this target in the list of remaining targets.
auto it = std::find(remaining.begin(), remaining.end(), target);
if (it == remaining.end()) {
// This target was already handled.
return;
}
// Remove this target from the list of remaining targets because
// we are handling it now.
*it = nullptr;
cmGhsMultiTargetGenerator tg(target);
tg.Generate();
}
void cmLocalGhsMultiGenerator::Generate()
{
const std::vector<cmGeneratorTarget*>& tgts = this->GetGeneratorTargets();
for (std::vector<cmGeneratorTarget*>::const_iterator l = tgts.begin();
l != tgts.end(); ++l) {
if ((*l)->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
std::vector<cmGeneratorTarget*> remaining = this->GetGeneratorTargets();
for (auto& t : remaining) {
if (t) {
GenerateTargetsDepthFirst(t, remaining);
}
cmGhsMultiTargetGenerator tg(*l);
tg.Generate();
}
}
void cmLocalGhsMultiGenerator::ComputeObjectFilenames(
std::map<cmSourceFile const*, std::string>& mapping,
cmGeneratorTarget const* gt)
{
std::string dir_max;
dir_max += this->GetCurrentBinaryDirectory();
dir_max += "/";
dir_max += this->GetTargetDirectory(gt);
dir_max += "/";
// Count the number of object files with each name. Note that
// filesystem may not be case sensitive.
std::map<std::string, int> counts;
for (auto const& si : mapping) {
cmSourceFile const* sf = si.first;
std::string objectNameLower = cmSystemTools::LowerCase(
cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath()));
objectNameLower += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
counts[objectNameLower] += 1;
}
// For all source files producing duplicate names we need unique
// object name computation.
for (auto& si : mapping) {
cmSourceFile const* sf = si.first;
std::string objectName =
cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
objectName += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
if (counts[cmSystemTools::LowerCase(objectName)] > 1) {
const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf);
bool keptSourceExtension;
objectName = this->GetObjectFileNameWithoutTarget(*sf, dir_max,
&keptSourceExtension);
cmsys::SystemTools::ReplaceString(objectName, "/", "_");
}
si.second = objectName;
}
}

View File

@@ -24,6 +24,17 @@ public:
* Generate the makefile for this directory.
*/
virtual void Generate();
std::string GetTargetDirectory(
cmGeneratorTarget const* target) const override;
void ComputeObjectFilenames(
std::map<cmSourceFile const*, std::string>& mapping,
cmGeneratorTarget const* gt = nullptr) override;
private:
void GenerateTargetsDepthFirst(cmGeneratorTarget* target,
std::vector<cmGeneratorTarget*>& remaining);
};
#endif

View File

@@ -596,6 +596,16 @@ bool cmState::UseWindowsVSIDE() const
return this->WindowsVSIDE;
}
void cmState::SetGhsMultiIDE(bool ghsMultiIDE)
{
this->GhsMultiIDE = ghsMultiIDE;
}
bool cmState::UseGhsMultiIDE() const
{
return this->GhsMultiIDE;
}
void cmState::SetWatcomWMake(bool watcomWMake)
{
this->WatcomWMake = watcomWMake;

View File

@@ -164,6 +164,8 @@ public:
bool UseWindowsShell() const;
void SetWindowsVSIDE(bool windowsVSIDE);
bool UseWindowsVSIDE() const;
void SetGhsMultiIDE(bool ghsMultiIDE);
bool UseGhsMultiIDE() const;
void SetWatcomWMake(bool watcomWMake);
bool UseWatcomWMake() const;
void SetMinGWMake(bool minGWMake);
@@ -222,6 +224,7 @@ private:
bool IsGeneratorMultiConfig = false;
bool WindowsShell = false;
bool WindowsVSIDE = false;
bool GhsMultiIDE = false;
bool WatcomWMake = false;
bool MinGWMake = false;
bool NMake = false;

View File

@@ -2260,32 +2260,104 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
endif()
if (CMake_TEST_GreenHillsMULTI)
macro(add_test_GhsMulti name primaryTarget bspName)
add_test(NAME GhsMulti.${name} COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/GhsMulti"
"${CMake_BINARY_DIR}/Tests/GhsMulti/${name}"
--build-generator "Green Hills MULTI"
--build-project ReturnNum
--build-config $<CONFIGURATION>
--build-options -DGHS_PRIMARY_TARGET=${primaryTarget}
-DGHS_BSP_NAME=${bspName}
)
endmacro ()
add_test_GhsMulti("arm_integrity_simarm" "arm_integrity.tgt" "simarm")
add_test_GhsMulti("arm64_integrity_simarm" "arm64_integrity.tgt" "simarm")
add_test(NAME GhsMulti.duplicate_source_filenames
macro(add_test_GhsMulti test_name test_dir bin_sub_dir build_opts)
separate_arguments(_ghs_build_opts UNIX_COMMAND ${build_opts})
separate_arguments(_ghs_toolset_extra UNIX_COMMAND ${ghs_toolset_extra})
if(${ARGC} GREATER 4)
set(_ghs_test_command --test-command ${ARGN})
endif()
if(ghs_config_name STREQUAL "__default__")
set(_ghs_test_name "${test_name}")
else()
set(_ghs_test_name "${ghs_config_name}.${test_name}")
endif()
add_test(NAME GhsMulti.${_ghs_test_name}
COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMake_SOURCE_DIR}/Tests/GhsMultiDuplicateSourceFilenames"
"${CMake_BINARY_DIR}/Tests/GhsMultiDuplicateSourceFilenames"
"${CMake_SOURCE_DIR}/Tests/GhsMulti/${test_dir}"
"${CMake_BINARY_DIR}/Tests/GhsMulti/${ghs_config_name}/${test_dir}/${bin_sub_dir}"
--build-generator "Green Hills MULTI"
--build-project ReturnNum
--build-project test
--build-config $<CONFIGURATION>
--build-options -DGHS_PRIMARY_TARGET=arm_integrity.tgt
-DGHS_BSP_NAME="simarm"
--build-options ${ghs_target_arch} ${ghs_toolset_name} ${ghs_toolset_root} ${ghs_target_platform}
${ghs_os_root} ${ghs_os_dir} ${ghs_bsp_name} ${_ghs_build_opts} ${_ghs_toolset_extra}
${_ghs_test_command}
)
endif ()
unset(_ghs_build_opts)
unset(_ghs_toolset_extra)
unset(_ghs_test_command)
unset(_ghs_test_name)
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)
endmacro()
#unset ghs config variables
unset(ghs_config_name)
unset(ghs_target_arch)
unset(ghs_toolset_root)
unset(ghs_toolset_name)
unset(ghs_os_root)
unset(ghs_os_dir)
unset(ghs_target_platform)
unset(ghs_bsp_name)
unset(ghs_toolset_extra)
if(NOT CMake_TEST_GreenHillsMULTI_config)
#if list of config settings not defined then just run once as default
set(CMake_TEST_GreenHillsMULTI_config "__default__")
endif()
foreach(ghs_file IN LISTS CMake_TEST_GreenHillsMULTI_config)
# source GHS tools config file
if(NOT ghs_file STREQUAL "__default__")
if(IS_ABSOLUTE ${ghs_file})
include(${ghs_file})
else()
include(${CMAKE_BINARY_DIR}/${ghs_file})
endif()
endif()
if(NOT ghs_config_name)
set(ghs_config_name "__default__")
endif()
# test integrity build
if (NOT ghs_skip_integrity AND (NOT ghs_target_platform OR ghs_target_platform MATCHES "integrity"))
add_test_GhsMulti(integrityDDInt GhsMultiIntegrity/GhsMultiIntegrityDDInt "" "")
add_test_GhsMulti(integrityMonolith GhsMultiIntegrity/GhsMultiIntegrityMonolith "" "")
add_test_GhsMulti(integrityDD GhsMultiIntegrity/GhsMultiIntegrityDD "" "")
endif()
add_test_GhsMulti(duplicate_source_filenames GhsMultiDuplicateSourceFilenames "" "")
add_test_GhsMulti_rename_install(SINGLE_EXEC)
add_test_GhsMulti_rename_install(SINGLE_EXEC_RENAMED)
add_test_GhsMulti_rename_install(EXEC_AND_LIB)
add_test_GhsMulti(multiple_source_groups GhsMultiSrcGroups Default "")
add_test_GhsMulti(multiple_source_groups_folders GhsMultiSrcGroups PropFolders "-DTEST_PROP=ON")
add_test_GhsMulti(multiple_source_groups_all_folders GhsMultiSrcGroups AllFolders "-DGHS_NO_SOURCE_GROUP_FILE=ON")
add_test_GhsMulti(unsupported_targets GhsMultiUnsupportedTargets "" "")
add_test_GhsMulti(object_library GhsMultiObjectLibrary "" "")
add_test_GhsMulti(exclude GhsMultiExclude "" ""
${CMAKE_CMAKE_COMMAND} -P ${CMake_SOURCE_DIR}/Tests/GhsMulti/GhsMultiExclude/verify.cmake)
add_test_GhsMulti(interface GhsMultiInterface "" "")
add_test_GhsMulti(transitive_link_test GhsMultiLinkTest TransitiveLink "-DRUN_TEST=NO_FLAGS")
add_test_GhsMulti(flags_link_test GhsMultiLinkTest FlagsCheck "-DRUN_TEST=CHECK_FLAGS")
add_test_GhsMulti(sub_link_test GhsMultiLinkTestSub "" "")
add_test_GhsMulti(multiple_projects GhsMultiMultipleProjects "" ""
${CMAKE_CMAKE_COMMAND} -P ${CMake_SOURCE_DIR}/Tests/GhsMulti/GhsMultiMultipleProjects/verify.cmake)
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)
unset(ghs_target_arch)
unset(ghs_toolset_root)
unset(ghs_toolset_name)
unset(ghs_os_root)
unset(ghs_os_dir)
unset(ghs_target_platform)
unset(ghs_bsp_name)
unset(ghs_toolset_extra)
endforeach()
endif()
if(tegra AND NOT "${CMake_SOURCE_DIR};${CMake_BINARY_DIR}" MATCHES " ")
macro(add_test_VSNsightTegra name generator)

View File

@@ -1,4 +0,0 @@
cmake_minimum_required(VERSION 3.1)
project(ReturnNum)
add_subdirectory(ReturnNum)

View File

@@ -0,0 +1,92 @@
# 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)
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}/test.c
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/src
)
message("Building project")
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
try_compile(RESULT
${CMAKE_CURRENT_BINARY_DIR}/build
${CMAKE_CURRENT_BINARY_DIR}/src
test
CMAKE_FLAGS
-DRUN_TEST=${RUN_TEST}
-DCMAKE_BUILD_TYPE=${RUN_TEST_BUILD_TYPE}
OUTPUT_VARIABLE OUTPUT)
message("Output from build:\n${OUTPUT}")
if (RUN_TEST STREQUAL "RELEASE_FLAGS")
find_file (fileName test_none.gpj
${CMAKE_CURRENT_BINARY_DIR}/build
${CMAKE_CURRENT_BINARY_DIR}/build/test_none
)
message("Parsing project file: ${fileName}")
file(STRINGS ${fileName} fileText)
set(opt "-unexpected_release_option")
string(FIND "${fileText}" "${opt}" opt_found)
if ( NOT opt_found EQUAL -1 )
message(SEND_ERROR "Release option found: ${opt}")
endif()
else()
unset(fileName CACHE)
find_file (fileName K1.gpj
${CMAKE_CURRENT_BINARY_DIR}/build
${CMAKE_CURRENT_BINARY_DIR}/build/K1
)
message("Parsing project file: ${fileName}")
file(STRINGS ${fileName} fileText)
set(opt "-required-debug-option")
string(FIND "${fileText}" "${opt}" opt_found)
if ( opt_found EQUAL -1 )
message(SEND_ERROR "Missing debug option: ${opt}")
endif()
unset(fileName CACHE)
find_file (fileName K2.gpj
${CMAKE_CURRENT_BINARY_DIR}/build
${CMAKE_CURRENT_BINARY_DIR}/build/K2
)
message("Parsing project file: ${fileName}")
file(STRINGS ${fileName} fileText)
set(opt "-required-debug-option")
string(FIND "${fileText}" "${opt}" opt_found)
if ( opt_found EQUAL -1 )
message(SEND_ERROR "Missing debug option: ${opt}")
endif()
unset(fileName CACHE)
find_file (fileName K3.gpj
${CMAKE_CURRENT_BINARY_DIR}/build
${CMAKE_CURRENT_BINARY_DIR}/build/K3
)
message("Parsing project file: ${fileName}")
file(STRINGS ${fileName} fileText)
set(opt "-required-debug-option")
string(FIND "${fileText}" "${opt}" opt_found)
if ( opt_found EQUAL -1 )
message(SEND_ERROR "Missing debug option: ${opt}")
endif()
unset(fileName CACHE)
find_file (fileName K4.gpj
${CMAKE_CURRENT_BINARY_DIR}/build
${CMAKE_CURRENT_BINARY_DIR}/build/K4
)
message("Parsing project file: ${fileName}")
file(STRINGS ${fileName} fileText)
set(opt "-required-debug-option")
string(FIND "${fileText}" "${opt}" opt_found)
if ( opt_found EQUAL -1 )
message(SEND_ERROR "Missing debug option: ${opt}")
endif()
endif()

View File

@@ -0,0 +1,32 @@
# 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()
if(RUN_TEST STREQUAL "RELEASE_FLAGS")
#RELEASE flags used when CMAKE_BUILD_TYPE is undefined
string(APPEND CMAKE_C_FLAGS_RELEASE " -unexpected_release_option")
add_executable(test_none test.c)
endif()
if(RUN_TEST STREQUAL "KERNEL_FLAGS")
#DEBUG flag missing when -kernel is added as a compile option
string(APPEND CMAKE_C_FLAGS_DEBUG " -required-debug-option")
add_executable(K1 test.c)
add_executable(K2 test.c)
target_compile_options(K2 PRIVATE -kernel)
add_executable(K3 test.c)
target_compile_options(K3 PRIVATE -kernel=fast)
add_executable(K4 test.c)
target_link_options(K4 PRIVATE -kernel)
endif()

View File

@@ -0,0 +1,4 @@
int main(void)
{
return -1;
}

View File

@@ -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 C)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
try_compile(RESULT
${CMAKE_CURRENT_BINARY_DIR}/build
${CMAKE_CURRENT_SOURCE_DIR}/test.c
OUTPUT_VARIABLE OUTPUT
COPY_FILE "${CMAKE_CURRENT_BINARY_DIR}/test_library"
)
message(STATUS "Output from build:\n${OUTPUT}")
if(NOT RESULT)
message(SEND_ERROR "try_compile() failed")
endif()
if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/test_library")
if (IS_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/test_library")
message(SEND_ERROR "library is folder !")
else()
message(STATUS "library seems okay")
endif()
else()
message(SEND_ERROR "library is not found !")
endif()

View File

@@ -0,0 +1,4 @@
int lib(int x)
{
return -x;
}

View File

@@ -1,15 +1,17 @@
cmake_minimum_required(VERSION 3.5)
project(demo C)
project(test C)
add_library(libdemo
test.c
testCase.c
subfolder_test.c
subfolder_test_0.c
"subfolder/test.c"
subfolder/testcase.c
)
add_executable(demo main.c)
target_link_libraries(demo libdemo)
if(GHSMULTI)
target_compile_options(demo PUBLIC "-non_shared")
if(CMAKE_C_COMPILER_ID STREQUAL "GHS")
target_link_options(demo PRIVATE "-non_shared")
endif()

View File

@@ -2,6 +2,8 @@ int test_a(void);
int test_b(void);
int test_c(void);
int test_d(void);
int test_e(void);
int test_f(void);
int main(int argc, char* argv[])
{
@@ -9,5 +11,7 @@ int main(int argc, char* argv[])
test_b();
test_c();
test_d();
test_e();
test_f();
return 0;
}

View File

@@ -0,0 +1,4 @@
int test_f()
{
return 1;
}

View File

@@ -0,0 +1,4 @@
int test_e()
{
return 1;
}

View File

@@ -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.
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_target_properties( lib1 PROPERTIES EXCLUDE_FROM_ALL yes )
add_library(lib2 EXCLUDE_FROM_ALL lib1.c)
add_executable(exe1 exe1.c)

View File

@@ -0,0 +1,4 @@
int main(void)
{
return 0;
}

View File

@@ -0,0 +1,4 @@
int func(void)
{
return 2;
}

View File

@@ -0,0 +1,54 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#test project was generated
unset(fileName CACHE)
find_file (fileName lib1.gpj
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/lib1
)
if (fileName)
message("Found target lib1: ${fileName}")
else()
message(SEND_ERROR "Could not find target lib1: ${fileName}")
endif()
#test project was built
unset(fileName CACHE)
find_file (fileName lib1.a
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/lib1
)
if (fileName)
message(SEND_ERROR "Found target lib1: ${fileName}")
else()
message("Could not find target lib1: ${fileName}")
endif()
#test project was generated
unset(fileName CACHE)
find_file (fileName lib2.gpj
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/lib2
)
if (fileName)
message("Found target lib2 ${fileName}")
else()
message(SEND_ERROR "Could not find target lib2: ${fileName}")
endif()
#test project was built
unset(fileName CACHE)
find_file (fileName lib2.a
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}/lib2
)
if (fileName)
message(SEND_ERROR "Found target lib2: ${fileName}")
else()
message("Could not find target lib2: ${fileName}")
endif()

View File

@@ -0,0 +1,19 @@
# 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)
add_link_options("-non_shared")
# create virtual AS
add_executable(vas exe.c)
target_link_libraries(vas lib)
add_library(lib func.c)
# create dynamic download INTEGRITY application
add_executable(dynamic)
set_target_properties(dynamic PROPERTIES ghs_integrity_app ON)
target_compile_options(dynamic PRIVATE -dynamic)
add_dependencies(dynamic vas)

View File

@@ -0,0 +1,5 @@
extern int func(void);
int main(void)
{
return func();
}

View File

@@ -0,0 +1,4 @@
int func(void)
{
return 2;
}

View File

@@ -1,4 +1,4 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../Lib)
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")

View File

@@ -1,3 +1,6 @@
cmake_minimum_required(VERSION 3.1)
project(test)
add_subdirectory(App)
add_subdirectory(Int)
add_subdirectory(Lib)

View File

@@ -7,6 +7,6 @@ Kernel
EndKernel
AddressSpace App
Filename "App/App.as"
Filename "App/App"
Language C
EndAddressSpace

View File

@@ -0,0 +1 @@
add_executable(AppDD AppDD.int)

View File

@@ -0,0 +1 @@
add_library(Lib HelperFun.c HelperFun.h)

View File

@@ -0,0 +1,20 @@
# 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_link_options("-non_shared")
project(test C)
# create virtual AS
add_executable(vas exe.c)
target_link_libraries(vas lib)
add_library(lib func.c)
# create kernel
add_executable(kernel kernel.c)
target_link_options(kernel PRIVATE -kernel)
# create monolith INTEGRITY application
add_executable(monolith test.int)

View File

@@ -0,0 +1,5 @@
extern int func(void);
int main(void)
{
return func();
}

View File

@@ -0,0 +1,5 @@
int func(void)
{
return 2;
}

View File

@@ -0,0 +1,15 @@
#include "INTEGRITY.h"
#include "boottable.h"
void main()
{
Exit(0);
}
/* This global table will be filled in during the Integrate phase with */
/* information about the AddressSpaces, Tasks, and Objects that are to be */
/* created. If you do not plan to use Integrate, you may omit this file from
*/
/* the kernel, and the boot table code will then not be included. */
GlobalTable TheGlobalTable = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };

View File

@@ -0,0 +1,8 @@
Kernel
Filename kernel
EndKernel
AddressSpace App
Filename vas
Language C
EndAddressSpace

View File

@@ -0,0 +1,8 @@
# 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)
add_library(iface INTERFACE)

View File

@@ -0,0 +1,92 @@
# 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)
message("Copy project")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt.in
${CMAKE_CURRENT_BINARY_DIR}/link_src/CMakeLists.txt COPYONLY)
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/exe1.c
${CMAKE_CURRENT_SOURCE_DIR}/exe1.h
${CMAKE_CURRENT_SOURCE_DIR}/func2.c
${CMAKE_CURRENT_SOURCE_DIR}/func3.c
${CMAKE_CURRENT_SOURCE_DIR}/func4.c
${CMAKE_CURRENT_SOURCE_DIR}/func5.c
${CMAKE_CURRENT_SOURCE_DIR}/func6.c
${CMAKE_CURRENT_SOURCE_DIR}/func7.c
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/link_src
)
message("Building project")
try_compile(RESULT
${CMAKE_CURRENT_BINARY_DIR}/link_build
${CMAKE_CURRENT_BINARY_DIR}/link_src
test
CMAKE_FLAGS
-DRUN_TEST=${RUN_TEST}
-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}
OUTPUT_VARIABLE OUTPUT)
message("Output from build:\n${OUTPUT}")
if (RUN_TEST STREQUAL "NO_FLAGS")
if(NOT RESULT)
message(SEND_ERROR "Could not build test project (1)!")
endif()
else()
unset(fileName CACHE)
find_file(fileName exe1.gpj
${CMAKE_CURRENT_BINARY_DIR}/link_build
${CMAKE_CURRENT_BINARY_DIR}/link_build/exe1
)
message("Parsing project file: ${fileName}")
file(STRINGS ${fileName} fileText)
set(expected_flags
-add-link-options1 -add-link-options2
link_directories_used1 link_directories_used2 "c:/absolute"
link_libraries_used1 link_libraries_used2
-lcsl1 csl2
-clinkexe1 -clinkexe2
-special-lib2-public-link)
foreach(opt IN LISTS expected_flags)
string(FIND "${fileText}" "${opt}" opt_found)
if ( opt_found EQUAL -1 )
message(SEND_ERROR "Could not find: ${opt}")
endif()
endforeach()
unset(fileName CACHE)
find_file (fileName lib1.gpj
${CMAKE_CURRENT_BINARY_DIR}/link_build
${CMAKE_CURRENT_BINARY_DIR}/link_build/lib1
)
message("Parsing project file: ${fileName}")
file(STRINGS ${fileName} fileText)
set(expected_flags
-clinkexeA1 -clinkexeA2
-static-lib-flags1 -static-lib-flags2)
foreach(opt IN LISTS expected_flags)
string(FIND "${fileText}" "${opt}" opt_found)
if (opt_found EQUAL -1)
message(SEND_ERROR "Could not find: ${opt}")
endif()
endforeach()
unset(fileName CACHE)
find_file (fileName lib2.gpj
${CMAKE_CURRENT_BINARY_DIR}/link_build
${CMAKE_CURRENT_BINARY_DIR}/link_build/lib2
)
message("Parsing project file: ${fileName}")
file(STRINGS ${fileName} fileText)
set(expected_flags
-clinkexeA1 -clinkexeA2)
foreach(opt IN LISTS expected_flags)
string(FIND "${fileText}" "${opt}" opt_found)
if ( opt_found EQUAL -1 )
message(SEND_ERROR "Could not find: ${opt}")
endif()
endforeach()
endif()

View File

@@ -0,0 +1,43 @@
# 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()
if(RUN_TEST STREQUAL "CHECK_FLAGS")
add_link_options(-add-link-options1 -add-link-options2)
link_directories(link_directories_used1 link_directories_used2 "c:/absolute")
link_libraries(link_libraries_used1 link_libraries_used2 )
set( CMAKE_C_STANDARD_LIBRARIES "${CMAKE_C_STANDARD_LIBRARIES} -lcsl1 csl2" )
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -clinkexe1 -clinkexe2")
endif()
add_executable(exe1 exe1.c)
target_link_libraries(exe1 lib1)
if(RUN_TEST STREQUAL "CHECK_FLAGS")
set_property(TARGET exe1 APPEND_STRING PROPERTY LINK_FLAGS "--link-flag-prop1 --link-flag-prop2")
set_property(TARGET exe1 APPEND PROPERTY LINK_OPTIONS --link-opt-prop1 --link-opt-prop2)
endif()
if(RUN_TEST STREQUAL "CHECK_FLAGS")
set(CMAKE_STATIC_LINKER_FLAGS ${CMAKE_STATIC_LINKER_FLAGS} "-clinkexeA1 -clinkexeA2")
endif()
add_library(lib1 STATIC func2.c func3.c func4.c)
target_link_libraries(lib1 lib2)
if(RUN_TEST STREQUAL "CHECK_FLAGS")
set_property(TARGET lib1 APPEND_STRING PROPERTY STATIC_LIBRARY_FLAGS "-static-lib-flags1 -static-lib-flags2")
endif()
add_library(lib2 STATIC func5.c func6.c func7.c)
if(RUN_TEST STREQUAL "CHECK_FLAGS")
target_link_options(lib2 PUBLIC -special-lib2-public-link)
endif()

View File

@@ -0,0 +1,6 @@
#include "exe1.h"
int main(void)
{
return func2a() + func3a() + func4a() + func5a() + func6a() + func7a();
}

View File

@@ -0,0 +1,6 @@
extern int func2a(void);
extern int func3a(void);
extern int func4a(void);
extern int func5a(void);
extern int func6a(void);
extern int func7a(void);

View File

@@ -0,0 +1,4 @@
int func2a(void)
{
return 2;
}

View File

@@ -0,0 +1,4 @@
int func3a(void)
{
return 1;
}

View File

@@ -0,0 +1,4 @@
int func4a(void)
{
return 1;
}

View File

@@ -0,0 +1,4 @@
int func5a(void)
{
return 1;
}

View File

@@ -0,0 +1,4 @@
int func6a(void)
{
return 1;
}

View File

@@ -0,0 +1,4 @@
int func7a(void)
{
return 1;
}

View File

@@ -0,0 +1,9 @@
# 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)
add_subdirectory(sub_exe)
add_subdirectory(sub_lib)

View File

@@ -0,0 +1,12 @@
# 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)
add_executable(exe1 exe1.c)
target_link_libraries(exe1 lib1)
if(CMAKE_C_COMPILER_ID STREQUAL "GHS")
target_link_options(exe1 PRIVATE "-non_shared")
endif()

View File

@@ -0,0 +1,6 @@
#include "exe1.h"
int main(void)
{
return func2a() + func3a() + func4a() + func5a() + func6a() + func7a();
}

View File

@@ -0,0 +1,6 @@
extern int func2a(void);
extern int func3a(void);
extern int func4a(void);
extern int func5a(void);
extern int func6a(void);
extern int func7a(void);

View File

@@ -0,0 +1,7 @@
# 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 func2.c func3.c func4.c)
target_link_libraries(lib1 lib2)
add_library(lib2 STATIC func5.c func6.c func7.c)

View File

@@ -0,0 +1,4 @@
int func2a(void)
{
return 2;
}

View File

@@ -0,0 +1,4 @@
int func3a(void)
{
return 1;
}

View File

@@ -0,0 +1,4 @@
int func4a(void)
{
return 1;
}

View File

@@ -0,0 +1,4 @@
int func5a(void)
{
return 1;
}

View File

@@ -0,0 +1,4 @@
int func6a(void)
{
return 1;
}

View File

@@ -0,0 +1,4 @@
int func7a(void)
{
return 1;
}

View File

@@ -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.
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)
add_executable(exe1 exe1.c)
target_link_libraries(exe1 lib1)
add_subdirectory(sub)
add_subdirectory(sub2 examples EXCLUDE_FROM_ALL)

View File

@@ -0,0 +1,5 @@
extern int lib1_func(void);
int main(void)
{
return lib1_func();
}

View File

@@ -0,0 +1,4 @@
int lib1_func(void)
{
return 2;
}

Some files were not shown because too many files have changed in this diff Show More