diff options
author | Brad King <brad.king@kitware.com> | 2019-04-15 14:52:11 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-04-15 14:52:21 (GMT) |
commit | 0793464d95c3dbbe9ed87bb5882d29efb7a8e3c3 (patch) | |
tree | 54458011255823399eed7a0b76f5db980e8a4aa3 | |
parent | e2128e11ac7ac38f33100f5277cb4ace8697bad8 (diff) | |
parent | 2bae6a1346cb95703a93dbf73c9689598c9056d1 (diff) | |
download | CMake-0793464d95c3dbbe9ed87bb5882d29efb7a8e3c3.zip CMake-0793464d95c3dbbe9ed87bb5882d29efb7a8e3c3.tar.gz CMake-0793464d95c3dbbe9ed87bb5882d29efb7a8e3c3.tar.bz2 |
Merge topic 'ghs_custom'
2bae6a1346 GHS: Update tests and notes
3b415c60c1 GHS: Update ExternalProject for GHS tools
83c47ef5b8 GHS: Update project layout to accommodate gbuild inconsistencies
5d2e1404bd GHS: Update project layout to build targets correctly
b6bfa7eeb2 GHS: Support add_dependencies() command
39ee9718d9 GHS: Support add_custom_target() command
8d3dad9a76 GHS: Support add_custom_command( OUTPUT ) signature
37acc9e229 GHS: Update custom command build events
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Narendhar Manimohan <narendhar15@gmail.com>
Merge-request: !3119
30 files changed, 1105 insertions, 234 deletions
diff --git a/Help/release/dev/ghs-custom-commands.rst b/Help/release/dev/ghs-custom-commands.rst new file mode 100644 index 0000000..a29ef88 --- /dev/null +++ b/Help/release/dev/ghs-custom-commands.rst @@ -0,0 +1,5 @@ +ghs_custom_commands +------------------- + +* The :generator:`Green Hills MULTI` generator now supports + :command:`add_custom_command` and :command:`add_custom_target` diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake index 8f1e194..20b37d2 100644 --- a/Modules/ExternalProject.cmake +++ b/Modules/ExternalProject.cmake @@ -422,6 +422,10 @@ External Project Definition different behavior depending on whether the build starts from a fresh build directory or re-uses previous build contents. + If the CMake generator is the ``Green Hills MULTI`` and not overridden then + the orginal projects settings for the GHS toolset and target system + customization cache variables are propagated into the external project. + ``SOURCE_SUBDIR <dir>`` When no ``CONFIGURE_COMMAND`` option is specified, the configure step assumes the external project has a ``CMakeLists.txt`` file at the top of @@ -2850,18 +2854,6 @@ function(_ep_extract_configure_command var name) set(has_cmake_cache_default_args 1) endif() - if(has_cmake_cache_args OR has_cmake_cache_default_args) - set(_ep_cache_args_script "<TMP_DIR>/${name}-cache-$<CONFIG>.cmake") - if(has_cmake_cache_args) - _ep_command_line_to_initial_cache(script_initial_cache_force "${cmake_cache_args}" 1) - endif() - if(has_cmake_cache_default_args) - _ep_command_line_to_initial_cache(script_initial_cache_default "${cmake_cache_default_args}" 0) - endif() - _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${script_initial_cache_force}${script_initial_cache_default}") - list(APPEND cmd "-C${_ep_cache_args_script}") - endif() - get_target_property(cmake_generator ${name} _EP_CMAKE_GENERATOR) get_target_property(cmake_generator_instance ${name} _EP_CMAKE_GENERATOR_INSTANCE) get_target_property(cmake_generator_platform ${name} _EP_CMAKE_GENERATOR_PLATFORM) @@ -2882,6 +2874,16 @@ function(_ep_extract_configure_command var name) list(APPEND cmd "-G${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}") else() list(APPEND cmd "-G${CMAKE_GENERATOR}") + if("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI") + set(has_cmake_cache_default_args 1) + set(cmake_cache_default_args ${cmake_cache_default_args} + "-DGHS_TARGET_PLATFORM:STRING=${GHS_TARGET_PLATFORM}" + "-DGHS_PRIMARY_TARGET:STRING=${GHS_PRIMARY_TARGET}" + "-DGHS_TOOLSET_ROOT:STRING=${GHS_TOOLSET_ROOT}" + "-DGHS_OS_ROOT:STRING=${GHS_OS_ROOT}" + "-DGHS_OS_DIR:STRING=${GHS_OS_DIR}" + "-DGHS_BSP_NAME:STRING=${GHS_BSP_NAME}") + endif() endif() if(cmake_generator_platform) message(FATAL_ERROR "Option CMAKE_GENERATOR_PLATFORM not allowed without CMAKE_GENERATOR.") @@ -2903,6 +2905,18 @@ function(_ep_extract_configure_command var name) endif() endif() + if(has_cmake_cache_args OR has_cmake_cache_default_args) + set(_ep_cache_args_script "<TMP_DIR>/${name}-cache-$<CONFIG>.cmake") + if(has_cmake_cache_args) + _ep_command_line_to_initial_cache(script_initial_cache_force "${cmake_cache_args}" 1) + endif() + if(has_cmake_cache_default_args) + _ep_command_line_to_initial_cache(script_initial_cache_default "${cmake_cache_default_args}" 0) + endif() + _ep_write_initial_cache(${name} "${_ep_cache_args_script}" "${script_initial_cache_force}${script_initial_cache_default}") + list(APPEND cmd "-C${_ep_cache_args_script}") + endif() + list(APPEND cmd "<SOURCE_DIR><SOURCE_SUBDIR>") endif() diff --git a/Source/cmGhsMultiGpj.cxx b/Source/cmGhsMultiGpj.cxx index 8b69b51..da27971 100644 --- a/Source/cmGhsMultiGpj.cxx +++ b/Source/cmGhsMultiGpj.cxx @@ -9,7 +9,8 @@ static const char* GHS_TAG[] = { "[INTEGRITY Application]", "[Project]", "[Program]", "[Reference]", - "[Subproject]" }; + "[Subproject]", + "[Custom Target]" }; const char* GhsMultiGpj::GetGpjTag(Types gpjType) { @@ -21,6 +22,7 @@ const char* GhsMultiGpj::GetGpjTag(Types gpjType) case PROGRAM: case REFERENCE: case SUBPROJECT: + case CUSTOM_TARGET: tag = GHS_TAG[gpjType]; break; default: diff --git a/Source/cmGhsMultiGpj.h b/Source/cmGhsMultiGpj.h index 420eab1..e588150 100644 --- a/Source/cmGhsMultiGpj.h +++ b/Source/cmGhsMultiGpj.h @@ -16,7 +16,8 @@ public: PROJECT, PROGRAM, REFERENCE, - SUBPROJECT + SUBPROJECT, + CUSTOM_TARGET }; static void WriteGpjTag(Types gpjType, std::ostream& fout); diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 668bcbd..b80da72 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -3,7 +3,7 @@ #include "cmGhsMultiTargetGenerator.h" #include "cmCustomCommand.h" -#include "cmCustomCommandLines.h" +#include "cmCustomCommandGenerator.h" #include "cmGeneratedFileStream.h" #include "cmGeneratorTarget.h" #include "cmGlobalGhsMultiGenerator.h" @@ -11,17 +11,17 @@ #include "cmLocalGenerator.h" #include "cmLocalGhsMultiGenerator.h" #include "cmMakefile.h" +#include "cmOutputConverter.h" #include "cmSourceFile.h" +#include "cmSourceFileLocation.h" #include "cmSourceGroup.h" #include "cmStateDirectory.h" #include "cmStateSnapshot.h" #include "cmStateTypes.h" #include "cmSystemTools.h" #include "cmTarget.h" -#include "cmTargetDepend.h" #include <algorithm> -#include <assert.h> #include <ostream> #include <set> #include <utility> @@ -32,6 +32,11 @@ cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target) static_cast<cmLocalGhsMultiGenerator*>(target->GetLocalGenerator())) , Makefile(target->Target->GetMakefile()) , Name(target->GetName()) +#ifdef _WIN32 + , CmdWindowsShell(true) +#else + , CmdWindowsShell(false) +#endif { // Store the configuration name that is being used if (const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) { @@ -85,10 +90,19 @@ void cmGhsMultiTargetGenerator::Generate() return; } case cmStateEnums::UTILITY: { - std::string msg = "add_custom_target(<name> ...) not supported: "; - msg += this->Name; - cmSystemTools::Message(msg); - return; + this->TargetNameReal = this->GeneratorTarget->GetName(); + this->TagType = GhsMultiGpj::CUSTOM_TARGET; + break; + } + case cmStateEnums::GLOBAL_TARGET: { + this->TargetNameReal = this->GeneratorTarget->GetName(); + if (this->TargetNameReal == + this->GetGlobalGenerator()->GetInstallTargetName()) { + this->TagType = GhsMultiGpj::CUSTOM_TARGET; + } else { + return; + } + break; } default: return; @@ -105,29 +119,29 @@ void cmGhsMultiTargetGenerator::Generate() void cmGhsMultiTargetGenerator::GenerateTarget() { - // Open the filestream in copy-if-different mode. - std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory(); - fname += "/"; - fname += this->Name; - fname += cmGlobalGhsMultiGenerator::FILE_EXTENSION; - cmGeneratedFileStream fout(fname); + // Open the target file in copy-if-different mode. + std::string fproj = this->LocalGenerator->GetCurrentBinaryDirectory(); + fproj += "/"; + fproj += this->Name; + fproj += cmGlobalGhsMultiGenerator::FILE_EXTENSION; + cmGeneratedFileStream fout(fproj); fout.SetCopyIfDifferent(true); this->GetGlobalGenerator()->WriteFileHeader(fout); GhsMultiGpj::WriteGpjTag(this->TagType, fout); - const std::string language( - this->GeneratorTarget->GetLinkerLanguage(this->ConfigName)); - - this->WriteTargetSpecifics(fout, this->ConfigName); - this->SetCompilerFlags(this->ConfigName, language); - this->WriteCompilerFlags(fout, this->ConfigName, language); - this->WriteCompilerDefinitions(fout, this->ConfigName, language); - this->WriteIncludes(fout, this->ConfigName, language); - this->WriteTargetLinkLine(fout, this->ConfigName); - this->WriteCustomCommands(fout); + if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) { + const std::string language( + this->GeneratorTarget->GetLinkerLanguage(this->ConfigName)); + this->WriteTargetSpecifics(fout, this->ConfigName); + this->SetCompilerFlags(this->ConfigName, language); + this->WriteCompilerFlags(fout, this->ConfigName, language); + this->WriteCompilerDefinitions(fout, this->ConfigName, language); + this->WriteIncludes(fout, this->ConfigName, language); + this->WriteTargetLinkLine(fout, this->ConfigName); + this->WriteBuildEvents(fout); + } this->WriteSources(fout); - this->WriteReferences(fout); fout.Close(); } @@ -304,47 +318,145 @@ void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout, } } -void cmGhsMultiTargetGenerator::WriteCustomCommands(std::ostream& fout) +void cmGhsMultiTargetGenerator::WriteBuildEvents(std::ostream& fout) { - WriteCustomCommandsHelper(fout, this->GeneratorTarget->GetPreBuildCommands(), - cmTarget::PRE_BUILD); - WriteCustomCommandsHelper( - fout, this->GeneratorTarget->GetPostBuildCommands(), cmTarget::POST_BUILD); + this->WriteBuildEventsHelper( + fout, this->GeneratorTarget->GetPreBuildCommands(), + std::string("prebuild"), std::string("preexecShell")); + + if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) { + this->WriteBuildEventsHelper( + fout, this->GeneratorTarget->GetPreLinkCommands(), + std::string("prelink"), std::string("preexecShell")); + } + + this->WriteBuildEventsHelper( + fout, this->GeneratorTarget->GetPostBuildCommands(), + std::string("postbuild"), std::string("postexecShell")); +} + +void cmGhsMultiTargetGenerator::WriteBuildEventsHelper( + std::ostream& fout, const std::vector<cmCustomCommand>& ccv, + std::string const& name, std::string const& cmd) +{ + int cmdcount = 0; + + for (cmCustomCommand const& cc : ccv) { + cmCustomCommandGenerator ccg(cc, this->ConfigName, this->LocalGenerator); + // Open the filestream for this custom command + std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory(); + fname += + "/" + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); + fname += "/" + this->Name + "_" + name; + fname += std::to_string(cmdcount++); + fname += this->CmdWindowsShell ? ".bat" : ".sh"; + cmGeneratedFileStream f(fname); + f.SetCopyIfDifferent(true); + this->WriteCustomCommandsHelper(f, ccg); + f.Close(); + if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) { + fout << " :" << cmd << "=\"" << fname << "\"" << std::endl; + } else { + fout << fname << std::endl; + fout << " :outputName=\"" << fname << ".rule\"" << std::endl; + } + for (auto& byp : ccg.GetByproducts()) { + fout << " :extraOutputFile=\"" << byp << "\"" << std::endl; + } + } } void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper( - std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet, - cmTarget::CustomCommandType const commandType) + std::ostream& fout, cmCustomCommandGenerator const& ccg) { - for (cmCustomCommand const& customCommand : commandsSet) { - cmCustomCommandLines const& commandLines = customCommand.GetCommandLines(); - for (cmCustomCommandLine const& command : commandLines) { - switch (commandType) { - case cmTarget::PRE_BUILD: - fout << " :preexecShellSafe="; - break; - case cmTarget::POST_BUILD: - fout << " :postexecShellSafe="; - break; - default: - assert("Only pre and post are supported"); + std::vector<std::string> cmdLines; + + // if the command specified a working directory use it. + std::string dir = this->LocalGenerator->GetCurrentBinaryDirectory(); + std::string currentBinDir = dir; + std::string workingDir = ccg.GetWorkingDirectory(); + if (!workingDir.empty()) { + dir = workingDir; + } + + // Line to check for error between commands. +#ifdef _WIN32 + std::string check_error = "if %errorlevel% neq 0 exit /b %errorlevel%"; +#else + std::string check_error = "if [[ $? -ne 0 ]]; then exit 1; fi"; +#endif + +#ifdef _WIN32 + cmdLines.push_back("@echo off"); +#endif + // Echo the custom command's comment text. + const char* comment = ccg.GetComment(); + if (comment && *comment) { + std::string echocmd = "echo "; + echocmd += comment; + cmdLines.push_back(std::move(echocmd)); + } + + // Switch to working directory + std::string cdCmd; +#ifdef _WIN32 + std::string cdStr = "cd /D "; +#else + std::string cdStr = "cd "; +#endif + cdCmd = cdStr + + this->LocalGenerator->ConvertToOutputFormat(dir, cmOutputConverter::SHELL); + cmdLines.push_back(std::move(cdCmd)); + + for (unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) { + // Build the command line in a single string. + std::string cmd = ccg.GetCommand(c); + if (!cmd.empty()) { + // Use "call " before any invocations of .bat or .cmd files + // invoked as custom commands in the WindowsShell. + // + bool useCall = false; + + if (this->CmdWindowsShell) { + std::string suffix; + if (cmd.size() > 4) { + suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size() - 4)); + if (suffix == ".bat" || suffix == ".cmd") { + useCall = true; + } + } } - bool firstIteration = true; - for (std::string const& commandLine : command) { - std::string subCommandE = - this->LocalGenerator->EscapeForShell(commandLine, true); - fout << (firstIteration ? "'" : " "); - // Need to double escape backslashes - cmSystemTools::ReplaceString(subCommandE, "\\", "\\\\"); - fout << subCommandE; - firstIteration = false; + cmSystemTools::ReplaceString(cmd, "/./", "/"); + // Convert the command to a relative path only if the current + // working directory will be the start-output directory. + bool had_slash = cmd.find('/') != std::string::npos; + if (workingDir.empty()) { + cmd = + this->LocalGenerator->MaybeConvertToRelativePath(currentBinDir, cmd); } - if (!command.empty()) { - fout << "'" << std::endl; + bool has_slash = cmd.find('/') != std::string::npos; + if (had_slash && !has_slash) { + // This command was specified as a path to a file in the + // current directory. Add a leading "./" so it can run + // without the current directory being in the search path. + cmd = "./" + cmd; } + cmd = this->LocalGenerator->ConvertToOutputFormat( + cmd, cmOutputConverter::SHELL); + if (useCall) { + cmd = "call " + cmd; + } + ccg.AppendArguments(c, cmd); + cmdLines.push_back(std::move(cmd)); } } + + // push back the custom commands + for (auto const& c : cmdLines) { + fout << c << std::endl; + fout << check_error << std::endl; + } } void cmGhsMultiTargetGenerator::WriteSourceProperty( @@ -385,7 +497,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) /* list of known groups and the order they are displayed in a project file */ const std::vector<std::string> standardGroups = { - "Header Files", "Source Files", "CMake Rules", + "CMake Rules", "Header Files", "Source Files", "Object Files", "Object Libraries", "Resources" }; @@ -403,6 +515,14 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) groupFilesList[i] = *n; i += 1; groupNames.erase(gn); + } else if (this->TagType == GhsMultiGpj::CUSTOM_TARGET && + gn == "CMake Rules") { + /* make sure that rules folder always exists in case of custom targets + * that have no custom commands except for pre or post build events. + */ + groupFilesList.resize(groupFilesList.size() + 1); + groupFilesList[i] = gn; + i += 1; } } @@ -433,7 +553,7 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) /* write files into the proper project file * -- groups go into main project file - * unless FOLDER property or variable is set. + * unless NO_SOURCE_GROUP_FILE property or variable is set. */ for (auto& sg : groupFilesList) { std::ostream* fout; @@ -472,33 +592,98 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) } else { *fout << "{comment} " << sg << std::endl; } + } else if (sg.empty()) { + *fout << "{comment} Others" << std::endl; } - /* output rule for each source file */ - for (const cmSourceFile* si : groupFiles[sg]) { - - // Convert filename to native system - // WORKAROUND: GHS MULTI 6.1.4 and 6.1.6 are known to need backslash on - // windows when opening some files from the search window. - std::string fname(si->GetFullPath()); - cmSystemTools::ConvertToOutputSlashes(fname); - *fout << fname << std::endl; - - if ("ld" != si->GetExtension() && "int" != si->GetExtension() && - "bsp" != si->GetExtension()) { - WriteObjectLangOverride(*fout, si); + if (sg != "CMake Rules") { + /* output rule for each source file */ + for (const cmSourceFile* si : groupFiles[sg]) { + bool compile = true; + // Convert filename to native system + // WORKAROUND: GHS MULTI 6.1.4 and 6.1.6 are known to need backslash on + // windows when opening some files from the search window. + std::string fname(si->GetFullPath()); + cmSystemTools::ConvertToOutputSlashes(fname); + + /* For custom targets list any associated sources, + * comment out source code to prevent it from being + * compiled when processing this target. + * Otherwise, comment out any custom command (main) dependencies that + * are listed as source files to prevent them from being considered + * part of the build. + */ + std::string comment; + if ((this->TagType == GhsMultiGpj::CUSTOM_TARGET && + !si->GetLanguage().empty()) || + si->GetCustomCommand()) { + comment = "{comment} "; + compile = false; + } + + *fout << comment << fname << std::endl; + if (compile) { + if ("ld" != si->GetExtension() && "int" != si->GetExtension() && + "bsp" != si->GetExtension()) { + WriteObjectLangOverride(*fout, si); + } + + this->WriteSourceProperty(*fout, si, "INCLUDE_DIRECTORIES", "-I"); + this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D"); + this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", ""); + + /* to avoid clutter in the GUI only print out the objectName if it + * has been renamed */ + std::string objectName = this->GeneratorTarget->GetObjectName(si); + if (!objectName.empty() && + this->GeneratorTarget->HasExplicitObjectName(si)) { + *fout << " -o " << objectName << std::endl; + } + } } - - this->WriteSourceProperty(*fout, si, "INCLUDE_DIRECTORIES", "-I"); - this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D"); - this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", ""); - - /* to avoid clutter in the gui only print out the objectName if it has - * been renamed */ - std::string objectName = this->GeneratorTarget->GetObjectName(si); - if (!objectName.empty() && - this->GeneratorTarget->HasExplicitObjectName(si)) { - *fout << " -o " << objectName << std::endl; + } else { + std::vector<cmSourceFile const*> customCommands; + if (ComputeCustomCommandOrder(customCommands)) { + std::string message = "The custom commands for target [" + + this->GeneratorTarget->GetName() + "] had a cycle.\n"; + cmSystemTools::Error(message); + } else { + /* Custom targets do not have a dependency on SOURCES files. + * Therefore the dependency list may include SOURCES files after the + * custom target. Because nothing can depend on the custom target just + * move it to the last item. + */ + for (auto sf = customCommands.begin(); sf != customCommands.end(); + ++sf) { + if (((*sf)->GetLocation()).GetName() == this->Name + ".rule") { + std::rotate(sf, sf + 1, customCommands.end()); + break; + } + } + int cmdcount = 0; + for (auto& sf : customCommands) { + const cmCustomCommand* cc = sf->GetCustomCommand(); + cmCustomCommandGenerator ccg(*cc, this->ConfigName, + this->LocalGenerator); + + // Open the filestream for this custom command + std::string fname = + this->LocalGenerator->GetCurrentBinaryDirectory(); + fname += "/" + + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); + fname += "/" + this->Name + "_cc"; + fname += std::to_string(cmdcount++) + "_"; + fname += (sf->GetLocation()).GetName(); + fname += this->CmdWindowsShell ? ".bat" : ".sh"; + cmGeneratedFileStream f(fname); + f.SetCopyIfDifferent(true); + this->WriteCustomCommandsHelper(f, ccg); + f.Close(); + this->WriteCustomCommandLine(*fout, fname, ccg); + } + } + if (this->TagType == GhsMultiGpj::CUSTOM_TARGET) { + this->WriteBuildEvents(*fout); } } } @@ -508,6 +693,33 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj) } } +void cmGhsMultiTargetGenerator::WriteCustomCommandLine( + std::ostream& fout, std::string& fname, cmCustomCommandGenerator const& ccg) +{ + /* NOTE: Customization Files are not well documented. Testing showed + * that ":outputName=file" can only be used once per script. The + * script will only run if ":outputName=file" is missing or just run + * once if ":outputName=file" is not specified. If there are + * multiple outputs then the script needs to be listed multiple times + * for each output. Otherwise it won't rerun the script if one of + * the outputs is manually deleted. + */ + bool specifyExtra = true; + for (auto& out : ccg.GetOutputs()) { + fout << fname << std::endl; + fout << " :outputName=\"" << out << "\"" << std::endl; + if (specifyExtra) { + for (auto& byp : ccg.GetByproducts()) { + fout << " :extraOutputFile=\"" << byp << "\"" << std::endl; + } + for (auto& dep : ccg.GetDepends()) { + fout << " :depends=\"" << dep << "\"" << std::endl; + } + specifyExtra = false; + } + } +} + void cmGhsMultiTargetGenerator::WriteObjectLangOverride( std::ostream& fout, const cmSourceFile* sourceFile) { @@ -521,35 +733,6 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride( } } -void cmGhsMultiTargetGenerator::WriteReferences(std::ostream& fout) -{ - // 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->MaybeConvertToRelativePath(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"); - } -} - bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp() { const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app"); @@ -566,3 +749,51 @@ bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp() } return false; } + +bool cmGhsMultiTargetGenerator::ComputeCustomCommandOrder( + std::vector<cmSourceFile const*>& order) +{ + std::set<cmSourceFile const*> temp; + std::set<cmSourceFile const*> perm; + + // Collect all custom commands for this target + std::vector<cmSourceFile const*> customCommands; + this->GeneratorTarget->GetCustomCommands(customCommands, this->ConfigName); + + for (cmSourceFile const* si : customCommands) { + bool r = VisitCustomCommand(temp, perm, order, si); + if (r) { + return r; + } + } + return false; +} + +bool cmGhsMultiTargetGenerator::VisitCustomCommand( + std::set<cmSourceFile const*>& temp, std::set<cmSourceFile const*>& perm, + std::vector<cmSourceFile const*>& order, cmSourceFile const* si) +{ + /* check if permanent mark is set*/ + if (perm.find(si) == perm.end()) { + /* set temporary mark; check if revisit*/ + if (temp.insert(si).second) { + for (auto& di : si->GetCustomCommand()->GetDepends()) { + cmSourceFile const* sf = this->GeneratorTarget->GetLocalGenerator() + ->GetMakefile() + ->GetSourceFileWithOutput(di); + /* if sf exists then visit */ + if (sf && this->VisitCustomCommand(temp, perm, order, sf)) { + return true; + } + } + /* mark as complete; insert into beginning of list*/ + perm.insert(si); + order.push_back(si); + return false; + } + /* revisiting item - not a DAG */ + return true; + } + /* already complete */ + return false; +} diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h index a4e23d9..a131567 100644 --- a/Source/cmGhsMultiTargetGenerator.h +++ b/Source/cmGhsMultiTargetGenerator.h @@ -5,14 +5,14 @@ #include "cmGhsMultiGpj.h" -#include "cmTarget.h" - #include <iosfwd> #include <map> +#include <set> #include <string> #include <vector> class cmCustomCommand; +class cmCustomCommandGenerator; class cmGeneratorTarget; class cmGlobalGhsMultiGenerator; class cmLocalGhsMultiGenerator; @@ -49,15 +49,23 @@ private: void WriteIncludes(std::ostream& fout, const std::string& config, const std::string& language); void WriteTargetLinkLine(std::ostream& fout, std::string const& config); - void WriteCustomCommands(std::ostream& fout); - void WriteCustomCommandsHelper( - std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet, - cmTarget::CustomCommandType commandType); + void WriteBuildEvents(std::ostream& fout); + void WriteBuildEventsHelper(std::ostream& fout, + const std::vector<cmCustomCommand>& ccv, + std::string const& name, std::string const& cmd); + void WriteCustomCommandsHelper(std::ostream& fout, + cmCustomCommandGenerator const& ccg); + void WriteCustomCommandLine(std::ostream& fout, std::string& fname, + cmCustomCommandGenerator const& ccg); + bool ComputeCustomCommandOrder(std::vector<cmSourceFile const*>& order); + bool VisitCustomCommand(std::set<cmSourceFile const*>& temp, + std::set<cmSourceFile const*>& perm, + std::vector<cmSourceFile const*>& order, + cmSourceFile const* sf); void WriteSources(std::ostream& fout_proj); void WriteSourceProperty(std::ostream& fout, const cmSourceFile* sf, std::string const& propName, std::string const& propFlag); - void WriteReferences(std::ostream& fout); static void WriteObjectLangOverride(std::ostream& fout, const cmSourceFile* sourceFile); @@ -71,7 +79,8 @@ private: std::string TargetNameReal; GhsMultiGpj::Types TagType; std::string const Name; - std::string ConfigName; /* CMAKE_BUILD_TYPE */ + std::string ConfigName; /* CMAKE_BUILD_TYPE */ + bool const CmdWindowsShell; /* custom commands run in cmd.exe or /bin/sh */ }; #endif // ! cmGhsMultiTargetGenerator_h diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index 9f361f6..b69dea0 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -265,14 +265,68 @@ void cmGlobalGhsMultiGenerator::WriteFileHeader(std::ostream& fout) << std::endl; } -void cmGlobalGhsMultiGenerator::WriteTopLevelProject( - std::ostream& fout, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators) +void cmGlobalGhsMultiGenerator::WriteCustomRuleBOD(std::ostream& fout) { - WriteFileHeader(fout); + fout << "Commands {\n" + " Custom_Rule_Command {\n" + " name = \"Custom Rule Command\"\n" + " exec = \""; +#ifdef _WIN32 + fout << "cmd.exe"; +#else + fout << "/bin/sh"; +#endif + fout << "\"\n" + " options = {\"SpecialOptions\"}\n" + " }\n" + "}\n"; + + fout << "\n\n"; + fout << "FileTypes {\n" + " CmakeRule {\n" + " name = \"Custom Rule\"\n" + " action = \"&Run\"\n" + " extensions = {\""; +#ifdef _WIN32 + fout << "bat"; +#else + fout << "sh"; +#endif + fout << "\"}\n" + " grepable = false\n" + " command = \"Custom Rule Command\"\n" + " commandLine = \"$COMMAND "; +#ifdef _WIN32 + fout << "/c"; +#endif + fout << " $INPUTFILE\"\n" + " progress = \"Processing Custom Rule\"\n" + " promoteToFirstPass = true\n" + " outputType = \"None\"\n" + " color = \"#800080\"\n" + " }\n" + "}\n"; +} - this->WriteMacros(fout); - this->WriteHighLevelDirectives(fout); +void cmGlobalGhsMultiGenerator::WriteCustomTargetBOD(std::ostream& fout) +{ + fout << "FileTypes {\n" + " CmakeTarget {\n" + " name = \"Custom Target\"\n" + " action = \"&Execute\"\n" + " grepable = false\n" + " outputType = \"None\"\n" + " color = \"#800080\"\n" + " }\n" + "}\n"; +} + +void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout, + cmLocalGenerator* root) +{ + this->WriteFileHeader(fout); + this->WriteMacros(fout, root); + this->WriteHighLevelDirectives(root, fout); GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout); fout << "# Top Level Project File" << std::endl; @@ -298,71 +352,152 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject( } fout << "\"" << this->OsDir << "\"" << std::endl; } - - WriteSubProjects(fout, root, generators); } -void cmGlobalGhsMultiGenerator::WriteSubProjects( - std::ostream& fout, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators) +void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout, + std::string& all_target) { - // 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) { + fout << "CMakeFiles/" << all_target << " [Project]" << std::endl; + // All known targets + for (cmGeneratorTarget const* target : this->ProjectTargets) { + if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY || + target->GetType() == cmStateEnums::MODULE_LIBRARY || + target->GetType() == cmStateEnums::SHARED_LIBRARY || + (target->GetType() == cmStateEnums::GLOBAL_TARGET && + target->GetName() != GetInstallTargetName())) { continue; } + fout << "CMakeFiles/" << target->GetName() + ".tgt" + FILE_EXTENSION + << " [Project]" << std::endl; + } +} - const char* projName = target->GetProperty("GENERATOR_FILE_NAME"); - const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT"); - if (projName && projType) { - cmLocalGenerator* lg = target->GetLocalGenerator(); - std::string dir = lg->GetCurrentBinaryDirectory(); - dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir); - if (dir == ".") { - dir.clear(); - } else { - if (dir.back() != '/') { - dir += "/"; - } +void cmGlobalGhsMultiGenerator::WriteProjectLine( + std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root, + std::string& rootBinaryDir) +{ + const char* projName = target->GetProperty("GENERATOR_FILE_NAME"); + const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT"); + if (projName && projType) { + cmLocalGenerator* lg = target->GetLocalGenerator(); + std::string dir = lg->GetCurrentBinaryDirectory(); + dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir); + 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; + std::string projFile = dir + projName + FILE_EXTENSION; + fout << projFile; + fout << " " << projType << std::endl; + } else { + /* Should never happen */ + std::string message = + "The project file for target [" + target->GetName() + "] is missing.\n"; + cmSystemTools::Error(message); + fout << "{comment} " << target->GetName() << " [missing project file]\n"; + } +} - if (cmSystemTools::IsOn(target->GetProperty("GHS_REFERENCE_PROJECT"))) { - // create reference project - std::string fname = dir; - fname += target->GetName(); - fname += "REF"; - fname += FILE_EXTENSION; +void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root) +{ + std::string rootBinaryDir = root->GetCurrentBinaryDirectory(); + rootBinaryDir += "/CMakeFiles"; + + // All known targets + for (cmGeneratorTarget const* target : this->ProjectTargets) { + if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY || + target->GetType() == cmStateEnums::MODULE_LIBRARY || + target->GetType() == cmStateEnums::SHARED_LIBRARY || + (target->GetType() == cmStateEnums::GLOBAL_TARGET && + target->GetName() != GetInstallTargetName())) { + continue; + } - cmGeneratedFileStream fref(fname); - fref.SetCopyIfDifferent(true); + // create target build file + std::string name = target->GetName() + ".tgt" + FILE_EXTENSION; + std::string fname = rootBinaryDir + "/" + name; + cmGeneratedFileStream fbld(fname); + fbld.SetCopyIfDifferent(true); + this->WriteFileHeader(fbld); + GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld); + std::vector<cmGeneratorTarget const*> build; + if (ComputeTargetBuildOrder(target, build)) { + std::string message = "The inter-target dependency graph for target [" + + target->GetName() + "] had a cycle.\n"; + cmSystemTools::Error(message); + } else { + for (auto& tgt : build) { + WriteProjectLine(fbld, tgt, root, rootBinaryDir); + } + } + fbld.Close(); + } +} - this->WriteFileHeader(fref); - GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref); - fref << " :reference=" << projFile << std::endl; +void cmGlobalGhsMultiGenerator::WriteAllTarget( + cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators, + std::string& all_target) +{ + this->ProjectTargets.clear(); + + // create target build file + all_target = root->GetProjectName() + "." + this->GetAllTargetName() + + ".tgt" + FILE_EXTENSION; + std::string fname = + root->GetCurrentBinaryDirectory() + "/CMakeFiles/" + all_target; + cmGeneratedFileStream fbld(fname); + fbld.SetCopyIfDifferent(true); + this->WriteFileHeader(fbld); + GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld); - fref.Close(); + // 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 sortedProjectTargets(projectTargets, ""); + std::vector<cmGeneratorTarget const*> defaultTargets; + for (cmGeneratorTarget const* t : sortedProjectTargets) { + /* save list of all targets in sorted order */ + this->ProjectTargets.push_back(t); + } + for (cmGeneratorTarget const* t : sortedProjectTargets) { + if (t->GetType() == cmStateEnums::INTERFACE_LIBRARY) { + continue; + } + if (!cmSystemTools::IsOn(t->GetProperty("EXCLUDE_FROM_ALL"))) { + defaultTargets.push_back(t); + } + } + std::vector<cmGeneratorTarget const*> build; + if (ComputeTargetBuildOrder(defaultTargets, build)) { + std::string message = "The inter-target dependency graph for project [" + + root->GetProjectName() + "] had a cycle.\n"; + cmSystemTools::Error(message); + } else { + // determine the targets for ALL target + std::string rootBinaryDir = root->GetCurrentBinaryDirectory(); + rootBinaryDir += "/CMakeFiles"; + for (cmGeneratorTarget const* target : build) { + if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY || + target->GetType() == cmStateEnums::MODULE_LIBRARY || + target->GetType() == cmStateEnums::SHARED_LIBRARY) { + continue; } + this->WriteProjectLine(fbld, target, root, rootBinaryDir); } } + fbld.Close(); } void cmGlobalGhsMultiGenerator::Generate() { + std::string fname; + // first do the superclass method this->cmGlobalGenerator::Generate(); @@ -370,11 +505,32 @@ void cmGlobalGhsMultiGenerator::Generate() for (auto& it : this->ProjectMap) { this->OutputTopLevelProject(it.second[0], it.second); } + + // create custom rule BOD file + fname = this->GetCMakeInstance()->GetHomeOutputDirectory() + + "/CMakeFiles/custom_rule.bod"; + cmGeneratedFileStream frule(fname); + frule.SetCopyIfDifferent(true); + this->WriteFileHeader(frule); + this->WriteCustomRuleBOD(frule); + frule.Close(); + + // create custom target BOD file + fname = this->GetCMakeInstance()->GetHomeOutputDirectory() + + "/CMakeFiles/custom_target.bod"; + cmGeneratedFileStream ftarget(fname); + ftarget.SetCopyIfDifferent(true); + this->WriteFileHeader(ftarget); + this->WriteCustomTargetBOD(ftarget); + ftarget.Close(); } void cmGlobalGhsMultiGenerator::OutputTopLevelProject( cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) { + std::string fname; + std::string all_target; + if (generators.empty()) { return; } @@ -383,18 +539,21 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject( * with target projects. This avoid the issue where the project has * the same name as the executable target. */ - std::string fname = root->GetCurrentBinaryDirectory(); + fname = root->GetCurrentBinaryDirectory(); fname += "/"; fname += root->GetProjectName(); fname += ".top"; fname += FILE_EXTENSION; - cmGeneratedFileStream fout(fname); - fout.SetCopyIfDifferent(true); + cmGeneratedFileStream top(fname); + top.SetCopyIfDifferent(true); + this->WriteTopLevelProject(top, root); - this->WriteTopLevelProject(fout, root, generators); + this->WriteAllTarget(root, generators, all_target); + this->WriteTargets(root); - fout.Close(); + this->WriteSubProjects(top, all_target); + top.Close(); } std::vector<cmGlobalGenerator::GeneratedMakeCommand> @@ -426,6 +585,9 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand( std::vector<std::string> files; cmSystemTools::Glob(projectDir, ".*\\.top\\.gpj", files); if (!files.empty()) { + /* if multiple top-projects are found in build directory + * then prefer projectName top-project. + */ auto p = std::find(files.begin(), files.end(), proj); if (p == files.end()) { proj = files.at(0); @@ -440,20 +602,24 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand( } else { for (const auto& tname : targetNames) { if (!tname.empty()) { - if (tname.compare(tname.size() - 4, 4, ".gpj") == 0) { - makeCommand.Add(tname); - } else { - makeCommand.Add(tname + ".gpj"); - } + makeCommand.Add(tname + ".tgt.gpj"); } } } + } else { + /* transform name to default build */; + std::string all = proj; + all.replace(all.end() - 7, all.end(), + std::string(this->GetAllTargetName()) + ".tgt.gpj"); + makeCommand.Add(all); } return { makeCommand }; } -void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout) +void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout, + cmLocalGenerator* root) { + fout << "macro PROJ_NAME=" << root->GetProjectName() << std::endl; char const* ghsGpjMacros = this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS"); if (nullptr != ghsGpjMacros) { @@ -465,13 +631,14 @@ void cmGlobalGhsMultiGenerator::WriteMacros(std::ostream& fout) } } -void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(std::ostream& fout) +void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives( + cmLocalGenerator* root, std::ostream& fout) { /* set primary target */ std::string tgt; const char* t = this->GetCMakeInstance()->GetCacheDefinition("GHS_PRIMARY_TARGET"); - if (t) { + if (t && *t != '\0') { tgt = t; this->GetCMakeInstance()->MarkCliAsUsed("GHS_PRIMARY_TARGET"); } else { @@ -486,16 +653,20 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(std::ostream& fout) } fout << "primaryTarget=" << tgt << std::endl; + fout << "customization=" << root->GetBinaryDirectory() + << "/CMakeFiles/custom_rule.bod" << std::endl; + fout << "customization=" << root->GetBinaryDirectory() + << "/CMakeFiles/custom_target.bod" << std::endl; char const* const customization = this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION"); if (nullptr != customization && strlen(customization) > 0) { - fout << "customization=" << trimQuotes(customization) << std::endl; + fout << "customization=" << this->TrimQuotes(customization) << std::endl; this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION"); } } -std::string cmGlobalGhsMultiGenerator::trimQuotes(std::string const& str) +std::string cmGlobalGhsMultiGenerator::TrimQuotes(std::string const& str) { std::string result; result.reserve(str.size()); @@ -528,3 +699,56 @@ cmGlobalGhsMultiGenerator::OrderedTargetDependSet::OrderedTargetDependSet( { this->insert(targets.begin(), targets.end()); } + +bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder( + cmGeneratorTarget const* tgt, std::vector<cmGeneratorTarget const*>& build) +{ + std::vector<cmGeneratorTarget const*> t{ tgt }; + return ComputeTargetBuildOrder(t, build); +} + +bool cmGlobalGhsMultiGenerator::ComputeTargetBuildOrder( + std::vector<cmGeneratorTarget const*>& tgt, + std::vector<cmGeneratorTarget const*>& build) +{ + std::set<cmGeneratorTarget const*> temp; + std::set<cmGeneratorTarget const*> perm; + + for (auto ti : tgt) { + bool r = VisitTarget(temp, perm, build, ti); + if (r) { + return r; + } + } + return false; +} + +bool cmGlobalGhsMultiGenerator::VisitTarget( + std::set<cmGeneratorTarget const*>& temp, + std::set<cmGeneratorTarget const*>& perm, + std::vector<cmGeneratorTarget const*>& order, cmGeneratorTarget const* ti) +{ + /* check if permanent mark is set*/ + if (perm.find(ti) == perm.end()) { + /* set temporary mark; check if revisit*/ + if (temp.insert(ti).second) { + /* sort targets lexicographically to ensure that nodes are always visited + * in the same order */ + OrderedTargetDependSet sortedTargets(this->GetTargetDirectDepends(ti), + ""); + for (auto& di : sortedTargets) { + if (this->VisitTarget(temp, perm, order, di)) { + return true; + } + } + /* mark as complete; insert into beginning of list*/ + perm.insert(ti); + order.push_back(ti); + return false; + } + /* revisiting item - not a DAG */ + return true; + } + /* already complete */ + return false; +} diff --git a/Source/cmGlobalGhsMultiGenerator.h b/Source/cmGlobalGhsMultiGenerator.h index 1aeb1dc..98358c7 100644 --- a/Source/cmGlobalGhsMultiGenerator.h +++ b/Source/cmGlobalGhsMultiGenerator.h @@ -78,23 +78,7 @@ public: // Write the common disclaimer text at the top of each build file. void WriteFileHeader(std::ostream& fout); - // Target dependency sorting - class TargetSet : public std::set<cmGeneratorTarget const*> - { - }; - class TargetCompare - { - std::string First; - - public: - TargetCompare(std::string first) - : First(std::move(first)) - { - } - bool operator()(cmGeneratorTarget const* l, - cmGeneratorTarget const* r) const; - }; - class OrderedTargetDependSet; + const char* GetInstallTargetName() const override { return "install"; } protected: void Generate() override; @@ -111,18 +95,53 @@ private: /* top-level project */ void OutputTopLevelProject(cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators); - void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators); - void WriteMacros(std::ostream& fout); - void WriteHighLevelDirectives(std::ostream& fout); - void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators); - - std::string trimQuotes(std::string const& str); + void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root); + void WriteMacros(std::ostream& fout, cmLocalGenerator* root); + void WriteHighLevelDirectives(cmLocalGenerator* root, std::ostream& fout); + void WriteSubProjects(std::ostream& fout, std::string& all_target); + void WriteTargets(cmLocalGenerator* root); + void WriteProjectLine(std::ostream& fout, cmGeneratorTarget const* target, + cmLocalGenerator* root, std::string& rootBinaryDir); + void WriteCustomRuleBOD(std::ostream& fout); + void WriteCustomTargetBOD(std::ostream& fout); + void WriteAllTarget(cmLocalGenerator* root, + std::vector<cmLocalGenerator*>& generators, + std::string& all_target); + + std::string TrimQuotes(std::string const& str); std::string OsDir; static const char* DEFAULT_BUILD_PROGRAM; static const char* DEFAULT_TOOLSET_ROOT; + + bool ComputeTargetBuildOrder(cmGeneratorTarget const* tgt, + std::vector<cmGeneratorTarget const*>& build); + bool ComputeTargetBuildOrder(std::vector<cmGeneratorTarget const*>& tgt, + std::vector<cmGeneratorTarget const*>& build); + bool VisitTarget(std::set<cmGeneratorTarget const*>& temp, + std::set<cmGeneratorTarget const*>& perm, + std::vector<cmGeneratorTarget const*>& order, + cmGeneratorTarget const* ti); + + std::vector<cmGeneratorTarget const*> ProjectTargets; + + // Target sorting + class TargetSet : public std::set<cmGeneratorTarget const*> + { + }; + class TargetCompare + { + std::string First; + + public: + TargetCompare(std::string first) + : First(std::move(first)) + { + } + bool operator()(cmGeneratorTarget const* l, + cmGeneratorTarget const* r) const; + }; + class OrderedTargetDependSet; }; class cmGlobalGhsMultiGenerator::OrderedTargetDependSet diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 3746965..2e0902c 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2336,7 +2336,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release endmacro() macro(add_test_GhsMulti_rename_install test_name) add_test_GhsMulti( ${test_name} GhsMultiRenameInstall ${test_name} - "-DCMAKE_INSTALL_PREFIX=. -DRUN_TEST=${test_name}" ${CMAKE_CMAKE_COMMAND} -P ./cmake_install.cmake) + "-DCMAKE_INSTALL_PREFIX=. -DRUN_TEST=${test_name}" ${CMAKE_CMAKE_COMMAND} --build . --target install) endmacro() #unset ghs config variables unset(ghs_config_name) @@ -2391,6 +2391,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_test_GhsMulti(compiler_options_kernel GhsMultiCompilerOptions Kernel "-DRUN_TEST=KERNEL_FLAGS -DRUN_TEST_BUILD_TYPE=DEBUG") add_test_GhsMulti(try_compile_copy GhsMultiCopyFile "" "") add_test_GhsMulti(ghs_platform GhsMultiPlatform "" "") + add_test_GhsMulti(custom_target GhsMultiCustomTarget "" "") + add_test_GhsMulti(dep_order GhsMultiDepOrder "" "") + add_test_GhsMulti(external_project GhsMultiExternalProject "" "") list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/GhsMulti/${ghs_config_name}") #unset ghs config variables unset(ghs_config_name) diff --git a/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt b/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt new file mode 100644 index 0000000..93d668b --- /dev/null +++ b/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt @@ -0,0 +1,110 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + +project(test C) + +# Tests assume no previous builds in the build directory +file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/build) + +macro (test_output) + if (BUILD_OUTPUT STREQUAL EXPECTED_LINES ) + message("Build OK") + else() + message("BUILD_OUTPUT") + foreach(Line IN LISTS BUILD_OUTPUT) + message("${Line}") + endforeach() + message("EXPECTED_LINES") + foreach(Line IN LISTS EXPECTED_LINES) + message("${Line}") + endforeach() + message(SEND_ERROR "Build KO") + endif() +endmacro() + +message("Copy project") +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt.in + ${CMAKE_CURRENT_BINARY_DIR}/src/CMakeLists.txt COPYONLY) + +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/exe1.c + ${CMAKE_CURRENT_SOURCE_DIR}/lib1.c + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/src +) + +message("Building ALL target") +try_compile(RESULT + ${CMAKE_CURRENT_BINARY_DIR}/build + ${CMAKE_CURRENT_BINARY_DIR}/src + test + CMAKE_FLAGS + -DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS} + OUTPUT_VARIABLE BUILD_OUTPUT) + +message("Output from build:\n${BUILD_OUTPUT}") + +#filter outputs +string(REPLACE "\r" "" BUILD_OUTPUT "${BUILD_OUTPUT}") +string(REPLACE "\n" ";" BUILD_OUTPUT "${BUILD_OUTPUT}") +list(FILTER BUILD_OUTPUT INCLUDE REGEX "^.*CT:") + +unset(EXPECTED_LINES) +list(APPEND EXPECTED_LINES "CT: Processing target_empty_prebuild") +list(APPEND EXPECTED_LINES "CT: Processing target_empty_postbuild") +list(APPEND EXPECTED_LINES "CT: Processing target_cmd") +list(APPEND EXPECTED_LINES "CT: Processing target_cmd_prebuild") +list(APPEND EXPECTED_LINES "CT: Processing target_cmd_postbuild") + +test_output() + +message("Building target_update_files target") +try_compile(RESULT + ${CMAKE_CURRENT_BINARY_DIR}/build + ${CMAKE_CURRENT_BINARY_DIR}/src + test target_update_files + CMAKE_FLAGS + -DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS} + OUTPUT_VARIABLE BUILD_OUTPUT) + +message("Output from build:\n${BUILD_OUTPUT}") + +#filter outputs +string(REPLACE "\r" "" BUILD_OUTPUT "${BUILD_OUTPUT}") +string(REPLACE "\n" ";" BUILD_OUTPUT "${BUILD_OUTPUT}") +list(FILTER BUILD_OUTPUT INCLUDE REGEX "^.*CT:") + +unset(EXPECTED_LINES) +list(APPEND EXPECTED_LINES "CT: Processing target_empty_prebuild") +list(APPEND EXPECTED_LINES "CT: Processing target_empty_postbuild") +list(APPEND EXPECTED_LINES "CT: generate C file another_file") +list(APPEND EXPECTED_LINES "CT: generate text file dependsA") +list(APPEND EXPECTED_LINES "CT: generate text file out_of_order_dep") +list(APPEND EXPECTED_LINES "CT: generate text files A, B, and C") +list(APPEND EXPECTED_LINES "CT: Processing target_update_files") + +test_output() + +message("Rerun target_update_files target") +try_compile(RESULT + ${CMAKE_CURRENT_BINARY_DIR}/build + ${CMAKE_CURRENT_BINARY_DIR}/src + test target_update_files + CMAKE_FLAGS + -DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS} + OUTPUT_VARIABLE BUILD_OUTPUT) + +message("Output from build:\n${BUILD_OUTPUT}") + +#filter outputs +string(REPLACE "\r" "" BUILD_OUTPUT "${BUILD_OUTPUT}") +string(REPLACE "\n" ";" BUILD_OUTPUT "${BUILD_OUTPUT}") +list(FILTER BUILD_OUTPUT INCLUDE REGEX "^.*CT:") + +unset(EXPECTED_LINES) +list(APPEND EXPECTED_LINES "CT: Processing target_empty_prebuild") +list(APPEND EXPECTED_LINES "CT: Processing target_empty_postbuild") +list(APPEND EXPECTED_LINES "CT: generate text files A, B, and C") +list(APPEND EXPECTED_LINES "CT: Processing target_update_files") + +test_output() diff --git a/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt.in b/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt.in new file mode 100644 index 0000000..fed946c --- /dev/null +++ b/Tests/GhsMulti/GhsMultiCustomTarget/CMakeLists.txt.in @@ -0,0 +1,108 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + +project(test C) + +if(CMAKE_C_COMPILER_ID STREQUAL "GHS") + add_link_options("-non_shared") +endif() + +add_library(lib1 lib1.c) + +set(TEST_MISSING_TARGET_SRC 0) +set(TEST_MISSING_TARGET_DEP 0) +set(TEST_MISSING_DEP 0) +set(TEST_DEP_CYCLE 0) + +add_executable(exe1 exe1.c) +target_link_libraries(exe1 lib1) + +add_custom_target(target_cmd ALL + COMMAND ${CMAKE_COMMAND} -E echo "target_cmd" > target_cmd + COMMAND ${CMAKE_COMMAND} -E echo "target_cmd_extra" > target_cmd_extra.txt + BYPRODUCTS target_cmd target_cmd_extra.txt + COMMENT "CT: Processing target_cmd") + +add_custom_command(TARGET target_cmd PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "target_cmd_prebuild" > target_cmd_prebuild.txt + BYPRODUCTS target_cmd_prebuild.txt + COMMENT "CT: Processing target_cmd_prebuild") +#event does not run for custom targets +add_custom_command(TARGET target_cmd PRE_LINK + COMMAND ${CMAKE_COMMAND} -E echo "executing target_cmd_prelink commands" + COMMAND ${CMAKE_COMMAND} -E echo "target_cmd_prelink" > target_cmd_prelink.txt + BYPRODUCTS target_cmd_prelink.txt + COMMENT "CT: Processing target_cmd_prelink") +add_custom_command(TARGET target_cmd POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "executing target_cmd_postbuild commands" + COMMAND ${CMAKE_COMMAND} -E echo "target_cmd_postbuild" > target_cmd_postbuild.txt + BYPRODUCTS target_cmd_postbuild.txt + COMMENT "CT: Processing target_cmd_postbuild") + +add_custom_target(target_empty ALL + COMMENT "CT: Processing target_empty") + +add_custom_command(TARGET target_empty PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "target_empty_prebuild" > target_empty_prebuild.txt + BYPRODUCTS target_empty_prebuild.txt + COMMENT "CT: Processing target_empty_prebuild") +add_custom_command(TARGET target_empty POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "target_empty_postbuild" > target_empty_postbuild.txt + BYPRODUCTS target_empty_postbuild.txt + COMMENT "CT: Processing target_empty_postbuild") + +add_dependencies(target_cmd target_empty) + +add_custom_command( + OUTPUT out_of_order_dep.txt + COMMAND ${CMAKE_COMMAND} -E echo "out_of_order_dep" > out_of_order_dep.txt + COMMENT "CT: generate text file out_of_order_dep" + DEPENDS dependsA.txt +) + +if(TEST_MISSING_TARGET_SRC) + set(SRC_FILE does_not_exist) +endif() +if(TEST_MISSING_TARGET_DEP) + set(DEP_FILE does_not_exist) +endif() + +add_custom_target(target_update_files + DEPENDS genc_do_not_list.txt ${DEP_FILE} + SOURCES gena.txt genb.txt another_file.c ${SRC_FILE} + BYPRODUCTS junkit.txt + COMMAND ${CMAKE_COMMAND} -E copy another_file.c junkit.txt + COMMENT "CT: Processing target_update_files") + +add_custom_command( + OUTPUT force_rebuild gena.txt genb.txt genc_do_not_list.txt + COMMAND ${CMAKE_COMMAND} -E copy dependsA.txt gena.txt + COMMAND ${CMAKE_COMMAND} -E echo "genb" > genb.txt + COMMAND ${CMAKE_COMMAND} -E echo "genc" > genc_do_not_list.txt + DEPENDS out_of_order_dep.txt dependsA.txt + COMMENT "CT: generate text files A, B, and C" +) + +if(TEST_MISSING_DEP) + set(MISSING_DEP MISSING_DEP) +endif() +if(TEST_DEP_CYCLE) + set(DEP_CYCLE out_of_order_dep.txt) +endif() + +add_custom_command( + OUTPUT dependsA.txt + COMMAND ${CMAKE_COMMAND} -E echo "dependsA" > dependsA.txt + DEPENDS ${MISSING_DEP} ${DEP_CYCLE} another_file.c + COMMENT "CT: generate text file dependsA" +) + +add_custom_command( + OUTPUT another_file.c + COMMAND ${CMAKE_COMMAND} -E echo "//auto-gen file" > another_file.c + COMMENT "CT: generate C file another_file" +) + +add_dependencies(target_update_files target_empty) diff --git a/Tests/GhsMulti/GhsMultiCustomTarget/exe1.c b/Tests/GhsMulti/GhsMultiCustomTarget/exe1.c new file mode 100644 index 0000000..29ad70a --- /dev/null +++ b/Tests/GhsMulti/GhsMultiCustomTarget/exe1.c @@ -0,0 +1,5 @@ +extern int func(void); +int main(void) +{ + return func(); +} diff --git a/Tests/GhsMulti/GhsMultiCustomTarget/lib1.c b/Tests/GhsMulti/GhsMultiCustomTarget/lib1.c new file mode 100644 index 0000000..b35e9cc --- /dev/null +++ b/Tests/GhsMulti/GhsMultiCustomTarget/lib1.c @@ -0,0 +1,4 @@ +int func(void) +{ + return 2; +} diff --git a/Tests/GhsMulti/GhsMultiDepOrder/CMakeLists.txt b/Tests/GhsMulti/GhsMultiDepOrder/CMakeLists.txt new file mode 100644 index 0000000..2e2871b --- /dev/null +++ b/Tests/GhsMulti/GhsMultiDepOrder/CMakeLists.txt @@ -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) + +#set_property( GLOBAL PROPERTY GLOBAL_DEPENDS_DEBUG_MODE 1) +add_subdirectory(exec) +add_subdirectory(lib) +add_subdirectory(protolib) +add_dependencies(lib1 proto) diff --git a/Tests/GhsMulti/GhsMultiDepOrder/exec/CMakeLists.txt b/Tests/GhsMulti/GhsMultiDepOrder/exec/CMakeLists.txt new file mode 100644 index 0000000..85ee805 --- /dev/null +++ b/Tests/GhsMulti/GhsMultiDepOrder/exec/CMakeLists.txt @@ -0,0 +1,11 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + +add_executable(exe1 exe1.c) +target_link_libraries(exe1 lib1) +target_include_directories(exe1 PRIVATE "${test_BINARY_DIR}") +if(CMAKE_C_COMPILER_ID STREQUAL "GHS") + target_link_options(exe1 PRIVATE "-non_shared") +endif() diff --git a/Tests/GhsMulti/GhsMultiDepOrder/exec/exe1.c b/Tests/GhsMulti/GhsMultiDepOrder/exec/exe1.c new file mode 100644 index 0000000..fbf4ed4 --- /dev/null +++ b/Tests/GhsMulti/GhsMultiDepOrder/exec/exe1.c @@ -0,0 +1,8 @@ +#include "lib1.h" +#include "p.h" + +int main(void) +{ + return func1() + func2() + func3() + func1p() + func2p() + func3p() + + PROTO1 + PROTO2 + PROTO3; +} diff --git a/Tests/GhsMulti/GhsMultiDepOrder/lib/CMakeLists.txt b/Tests/GhsMulti/GhsMultiDepOrder/lib/CMakeLists.txt new file mode 100644 index 0000000..ae30fa2 --- /dev/null +++ b/Tests/GhsMulti/GhsMultiDepOrder/lib/CMakeLists.txt @@ -0,0 +1,17 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +add_library(lib1 STATIC + func1.c lib1.h + "${test_BINARY_DIR}/protolib/proto1.c" + "${test_BINARY_DIR}/protolib/proto1.h") +set_source_files_properties( + "${test_BINARY_DIR}/protolib/proto1.c" + "${test_BINARY_DIR}/protolib/proto1.h" + PROPERTIES GENERATED 1) +target_include_directories(lib1 PRIVATE "${test_BINARY_DIR}/protolib" + PUBLIC .) +add_custom_command( TARGET lib1 POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy "${test_BINARY_DIR}/protolib/proto1.h" "${test_BINARY_DIR}/p.h" + COMMENT "Copy ${test_BINARY_DIR}/protolib/proto1.h ${test_BINARY_DIR}/p.h" + BYPRODUCTS "${test_BINARY_DIR}/p.h") diff --git a/Tests/GhsMulti/GhsMultiDepOrder/lib/func1.c b/Tests/GhsMulti/GhsMultiDepOrder/lib/func1.c new file mode 100644 index 0000000..53334fe --- /dev/null +++ b/Tests/GhsMulti/GhsMultiDepOrder/lib/func1.c @@ -0,0 +1,17 @@ +#include "lib1.h" +#include "proto1.h" + +int func1(void) +{ + return 1 + PROTO1; +} + +int func2(void) +{ + return 2 + PROTO2; +} + +int func3(void) +{ + return 3 + PROTO3; +} diff --git a/Tests/GhsMulti/GhsMultiDepOrder/lib/lib1.h b/Tests/GhsMulti/GhsMultiDepOrder/lib/lib1.h new file mode 100644 index 0000000..5e99f02 --- /dev/null +++ b/Tests/GhsMulti/GhsMultiDepOrder/lib/lib1.h @@ -0,0 +1,3 @@ +extern int func1(void); +extern int func2(void); +extern int func3(void); diff --git a/Tests/GhsMulti/GhsMultiDepOrder/protolib/CMakeLists.txt b/Tests/GhsMulti/GhsMultiDepOrder/protolib/CMakeLists.txt new file mode 100644 index 0000000..8cb6869 --- /dev/null +++ b/Tests/GhsMulti/GhsMultiDepOrder/protolib/CMakeLists.txt @@ -0,0 +1,28 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) + +add_custom_target(proto ALL + DEPENDS proto1.c + proto1.h + SOURCES + ${test_SOURCE_DIR}/protolib/proto1.c.in + ${test_SOURCE_DIR}/protolib/proto1.h.in + COMMENT "Creating proto files") + +add_custom_command( + OUTPUT proto1.c + COMMAND ${CMAKE_COMMAND} -E copy + ${test_SOURCE_DIR}/protolib/proto1.c.in proto1.c + DEPENDS ${test_SOURCE_DIR}/protolib/proto1.c.in + COMMENT "generate proto C files" +) + +add_custom_command( + OUTPUT proto1.h + COMMAND ${CMAKE_COMMAND} -E copy + ${test_SOURCE_DIR}/protolib/proto1.h.in proto1.h + DEPENDS ${test_SOURCE_DIR}/protolib/proto1.h.in + COMMENT "generate proto H files" +) diff --git a/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.c.in b/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.c.in new file mode 100644 index 0000000..0efb1bd --- /dev/null +++ b/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.c.in @@ -0,0 +1,16 @@ +#include "proto1.h" + +int func1p(void) +{ + return 1; +} + +int func2p(void) +{ + return 2; +} + +int func3p(void) +{ + return 3; +} diff --git a/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.h.in b/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.h.in new file mode 100644 index 0000000..f2f93af --- /dev/null +++ b/Tests/GhsMulti/GhsMultiDepOrder/protolib/proto1.h.in @@ -0,0 +1,7 @@ +extern int func1p(void); +extern int func2p(void); +extern int func3p(void); + +#define PROTO1 0x1 +#define PROTO2 0x2 +#define PROTO3 0x3 diff --git a/Tests/GhsMulti/GhsMultiExternalProject/CMakeLists.txt b/Tests/GhsMulti/GhsMultiExternalProject/CMakeLists.txt new file mode 100644 index 0000000..24126c8 --- /dev/null +++ b/Tests/GhsMulti/GhsMultiExternalProject/CMakeLists.txt @@ -0,0 +1,14 @@ +# 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) +include(ExternalProject) + +ExternalProject_Add(another_project + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/empty + BINARY_DIR empty_build + INSTALL_COMMAND "" + TEST_COMMAND "" + ) diff --git a/Tests/GhsMulti/GhsMultiExternalProject/empty/CMakeLists.txt b/Tests/GhsMulti/GhsMultiExternalProject/empty/CMakeLists.txt new file mode 100644 index 0000000..6846a98 --- /dev/null +++ b/Tests/GhsMulti/GhsMultiExternalProject/empty/CMakeLists.txt @@ -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(empty NONE) + +message("EMPTY PROJECT") diff --git a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/App/CMakeLists.txt b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/App/CMakeLists.txt index e431217..3837b5a 100644 --- a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/App/CMakeLists.txt +++ b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/App/CMakeLists.txt @@ -1,4 +1,3 @@ add_executable(App Main.c) -target_include_directories(App PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../Lib) target_link_libraries(App Lib) target_compile_options(App PUBLIC "-non_shared") diff --git a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/Lib/CMakeLists.txt b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/Lib/CMakeLists.txt index 00e0f59..bb9849a 100644 --- a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/Lib/CMakeLists.txt +++ b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityDDInt/Lib/CMakeLists.txt @@ -1 +1,2 @@ add_library(Lib HelperFun.c HelperFun.h) +target_include_directories(Lib PUBLIC .) diff --git a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityMonolith/CMakeLists.txt b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityMonolith/CMakeLists.txt index c5db155..3f2f0eb 100644 --- a/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityMonolith/CMakeLists.txt +++ b/Tests/GhsMulti/GhsMultiIntegrity/GhsMultiIntegrityMonolith/CMakeLists.txt @@ -18,3 +18,4 @@ target_link_options(kernel PRIVATE -kernel) # create monolith INTEGRITY application add_executable(monolith test.int) +add_dependencies(monolith vas) diff --git a/Tests/GhsMulti/GhsMultiPlatform/file1.c b/Tests/GhsMulti/GhsMultiPlatform/file1.c deleted file mode 100644 index 4132aa4..0000000 --- a/Tests/GhsMulti/GhsMultiPlatform/file1.c +++ /dev/null @@ -1,4 +0,0 @@ -int main(void) -{ - return -42; -} diff --git a/Tests/GhsMulti/GhsMultiRenameInstall/CMakeLists.txt b/Tests/GhsMulti/GhsMultiRenameInstall/CMakeLists.txt index f5792b4..b2540d9 100644 --- a/Tests/GhsMulti/GhsMultiRenameInstall/CMakeLists.txt +++ b/Tests/GhsMulti/GhsMultiRenameInstall/CMakeLists.txt @@ -13,7 +13,7 @@ endif() if(RUN_TEST STREQUAL "SINGLE_EXEC") add_executable(exe1 exe.c) - set(targets_to_install ${targets_to_install} exe1) + set(targets_to_install exe1) endif() if(RUN_TEST STREQUAL "SINGLE_EXEC_RENAMED") @@ -22,7 +22,7 @@ if(RUN_TEST STREQUAL "SINGLE_EXEC_RENAMED") set_property(TARGET exe1 PROPERTY RUNTIME_OUTPUT_DIRECTORY ${name}_bin_$<CONFIG>) set_property(TARGET exe1 PROPERTY OUTPUT_NAME ${name}_$<CONFIG>) set_property(TARGET exe1 PROPERTY SUFFIX .bin) - set(targets_to_install ${targets_to_install} exe1) + set(targets_to_install exe1) endif() if(RUN_TEST STREQUAL "EXEC_AND_LIB") @@ -33,7 +33,7 @@ if(RUN_TEST STREQUAL "EXEC_AND_LIB") add_executable(exe1 exe1.c) target_link_libraries(exe1 lib1) - set(targets_to_install ${targets_to_install} exe1 lib1) + set(targets_to_install exe1 lib1) endif() install(TARGETS ${targets_to_install} diff --git a/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt b/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt index ed3094b..f5f3c55 100644 --- a/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt +++ b/Tests/GhsMulti/GhsMultiUnsupportedTargets/CMakeLists.txt @@ -5,8 +5,6 @@ cmake_minimum_required(VERSION 3.12 FATAL_ERROR) project(test C) -add_custom_target(testTarget ALL echo this is a test) - add_library(sharedLib SHARED file.c) add_library(moduleLib MODULE file.c) |