| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652 |
- /*============================================================================
- CMake - Cross Platform Makefile Generator
- Copyright 2015 Geoffrey Viola <[email protected]>
- Distributed under the OSI-approved BSD License (the "License");
- see accompanying file Copyright.txt for details.
- This software is distributed WITHOUT ANY WARRANTY; without even the
- implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the License for more information.
- ============================================================================*/
- #include "cmGhsMultiTargetGenerator.h"
- #include "cmGlobalGhsMultiGenerator.h"
- #include "cmLocalGhsMultiGenerator.h"
- #include "cmMakefile.h"
- #include "cmTarget.h"
- #include "cmGeneratedFileStream.h"
- #include "cmSourceFile.h"
- #include <assert.h>
- #include <cmAlgorithms.h>
- std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
- cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget *target)
- : GeneratorTarget(target)
- , LocalGenerator(static_cast<cmLocalGhsMultiGenerator *>(
- target->GetLocalGenerator()))
- , Makefile(target->Target->GetMakefile())
- , TargetGroup(DetermineIfTargetGroup(target))
- , DynamicDownload(false)
- {
- 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;
- }
- cmGhsMultiTargetGenerator::~cmGhsMultiTargetGenerator()
- {
- cmDeleteAll(this->FolderBuildStreams);
- }
- std::string
- cmGhsMultiTargetGenerator::GetRelBuildFilePath(
- const cmGeneratorTarget *target)
- {
- std::string output;
- char const *folderProp = target->GetProperty("FOLDER");
- output = NULL == folderProp ? "" : folderProp;
- cmSystemTools::ConvertToUnixSlashes(output);
- if (!output.empty())
- {
- output += "/";
- }
- output += target->GetName() + "/";
- return output;
- }
- std::string
- cmGhsMultiTargetGenerator::GetAbsPathToRoot(const 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()
- {
- const std::vector<cmSourceFile *> objectSources = this->GetSources();
- if (!objectSources.empty() && this->IncludeThisTarget())
- {
- if (!cmSystemTools::FileExists(this->AbsBuildFilePath.c_str()))
- {
- cmSystemTools::MakeDirectory(this->AbsBuildFilePath.c_str());
- }
- cmGlobalGhsMultiGenerator::Open(std::string(""), this->AbsBuildFileName,
- &this->FolderBuildStreams);
- cmGlobalGhsMultiGenerator::OpenBuildFileStream(
- this->GetFolderBuildStreams());
- std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- if (0 == config.length())
- {
- config = "RELEASE";
- }
- const std::string language(
- this->GeneratorTarget->GetLinkerLanguage(config));
- config = cmSystemTools::UpperCase(config);
- this->DynamicDownload = this->DetermineIfDynamicDownload(config, language);
- if (this->DynamicDownload)
- {
- *this->GetFolderBuildStreams() << "#component integrity_dynamic_download"
- << std::endl;
- }
- GhsMultiGpj::WriteGpjTag(this->GetGpjTag(), this->GetFolderBuildStreams());
- cmGlobalGhsMultiGenerator::WriteDisclaimer(this->GetFolderBuildStreams());
- bool const notKernel = this->IsNotKernel(config, language);
- this->WriteTypeSpecifics(config, notKernel);
- this->SetCompilerFlags(config, language, notKernel);
- this->WriteCompilerFlags(config, language);
- this->WriteCompilerDefinitions(config, language);
- this->WriteIncludes(config, language);
- if (this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
- {
- this->WriteTargetLinkLibraries(config, language);
- }
- this->WriteCustomCommands();
- this->WriteSources(objectSources);
- }
- }
- bool cmGhsMultiTargetGenerator::IncludeThisTarget()
- {
- 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;
- }
- 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;
- }
- GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag() const
- {
- return cmGhsMultiTargetGenerator::GetGpjTag(this->GeneratorTarget);
- }
- GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag(
- const cmGeneratorTarget *target)
- {
- GhsMultiGpj::Types output;
- if (cmGhsMultiTargetGenerator::DetermineIfTargetGroup(target))
- {
- output = GhsMultiGpj::INTERGRITY_APPLICATION;
- }
- else if (target->GetType() == cmState::STATIC_LIBRARY)
- {
- output = GhsMultiGpj::LIBRARY;
- }
- else
- {
- output = GhsMultiGpj::PROGRAM;
- }
- return output;
- }
- cmGlobalGhsMultiGenerator*
- cmGhsMultiTargetGenerator::GetGlobalGenerator() const
- {
- return static_cast<cmGlobalGhsMultiGenerator *>(
- this->LocalGenerator->GetGlobalGenerator());
- }
- void cmGhsMultiTargetGenerator::WriteTypeSpecifics(const std::string &config,
- bool const notKernel)
- {
- std::string outputDir(this->GetOutputDirectory(config));
- std::string outputFilename(this->GetOutputFilename(config));
- if (this->GeneratorTarget->GetType() == cmState::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() == cmState::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;
- }
- }
- }
- void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const &config,
- const std::string &language,
- bool const notKernel)
- {
- std::map<std::string, std::string>::iterator i =
- this->FlagsByLanguage.find(language);
- if (i == this->FlagsByLanguage.end())
- {
- std::string flags;
- const char *lang = language.c_str();
- if (notKernel)
- {
- this->LocalGenerator->AddLanguageFlags(flags, lang, config);
- }
- else
- {
- this->LocalGenerator->AddLanguageFlags(
- flags, lang + std::string("_GHS_KERNEL"), config);
- }
- this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget,
- lang, config);
- this->LocalGenerator->AddVisibilityPresetFlags(flags,
- this->GeneratorTarget,
- lang);
- // Append old-style preprocessor definition flags.
- if (std::string(" ") != std::string(this->Makefile->GetDefineFlags()))
- {
- this->LocalGenerator->AppendFlags(flags,
- this->Makefile->GetDefineFlags());
- }
- // Add target-specific flags.
- this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
- lang, config);
- std::map<std::string, std::string>::value_type entry(language, flags);
- i = this->FlagsByLanguage.insert(entry).first;
- }
- }
- std::string cmGhsMultiTargetGenerator::GetDefines(const std::string &language,
- std::string const &config)
- {
- std::map<std::string, std::string>::iterator i =
- this->DefinesByLanguage.find(language);
- if (i == this->DefinesByLanguage.end())
- {
- std::set<std::string> defines;
- const char *lang = language.c_str();
- // Add the export symbol definition for shared library objects.
- if (const char *exportMacro = this->GeneratorTarget->GetExportMacro())
- {
- this->LocalGenerator->AppendDefines(defines, exportMacro);
- }
- // Add preprocessor definitions for this target and configuration.
- this->LocalGenerator->AddCompileDefinitions(defines,
- this->GeneratorTarget, config,
- language);
- std::string definesString;
- this->LocalGenerator->JoinDefines(defines, definesString, lang);
- std::map<std::string, std::string>::value_type entry(language,
- definesString);
- i = this->DefinesByLanguage.insert(entry).first;
- }
- return i->second;
- }
- void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::string const &,
- const std::string &language)
- {
- std::map<std::string, std::string>::iterator flagsByLangI =
- this->FlagsByLanguage.find(language);
- if (flagsByLangI != this->FlagsByLanguage.end())
- {
- if (!flagsByLangI->second.empty())
- {
- *this->GetFolderBuildStreams() << " " << flagsByLangI->second
- << std::endl;
- }
- }
- }
- void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
- const std::string &config, const std::string &language)
- {
- std::vector<std::string> compileDefinitions;
- this->GeneratorTarget->GetCompileDefinitions(compileDefinitions,
- config, language);
- for (std::vector<std::string>::const_iterator cdI =
- compileDefinitions.begin();
- cdI != compileDefinitions.end(); ++cdI)
- {
- *this->GetFolderBuildStreams() << " -D" << (*cdI) << std::endl;
- }
- }
- void cmGhsMultiTargetGenerator::WriteIncludes(const std::string &config,
- const std::string &language)
- {
- std::vector<std::string> includes =
- this->GeneratorTarget->GetIncludeDirectories(config, language);
- for (std::vector<std::string>::const_iterator includes_i = includes.begin();
- includes_i != includes.end(); ++includes_i)
- {
- *this->GetFolderBuildStreams() << " -I\"" << *includes_i << "\""
- << std::endl;
- }
- }
- void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries(
- std::string const& config, std::string const& language)
- {
- // 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->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");
- this->LocalGenerator->GetTargetFlags(
- linkLibraries, flags, linkFlags,
- frameworkPath, linkPath,
- this->GeneratorTarget, useWatcomQuote);
- linkFlags = cmSystemTools::TrimWhitespace(linkFlags);
- if (!linkPath.empty())
- {
- linkPath = " " + linkPath.substr(0U, linkPath.size() - 1U);
- *this->GetFolderBuildStreams() << linkPath;
- }
- if (!linkFlags.empty())
- {
- *this->GetFolderBuildStreams() << " " << linkFlags << std::endl;
- }
- }
- }
- void cmGhsMultiTargetGenerator::WriteCustomCommands()
- {
- WriteCustomCommandsHelper(
- this->GeneratorTarget->GetPreBuildCommands(),
- cmTarget::PRE_BUILD);
- WriteCustomCommandsHelper(
- this->GeneratorTarget->GetPostBuildCommands(),
- cmTarget::POST_BUILD);
- }
- void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
- std::vector<cmCustomCommand> const &commandsSet,
- cmTarget::CustomCommandType const commandType)
- {
- for (std::vector<cmCustomCommand>::const_iterator commandsSetI =
- commandsSet.begin();
- commandsSetI != commandsSet.end(); ++commandsSetI)
- {
- cmCustomCommandLines const &commands = commandsSetI->GetCommandLines();
- for (cmCustomCommandLines::const_iterator commandI = commands.begin();
- commandI != commands.end(); ++commandI)
- {
- switch (commandType)
- {
- case cmTarget::PRE_BUILD:
- *this->GetFolderBuildStreams() << " :preexecShellSafe=";
- break;
- case cmTarget::POST_BUILD:
- *this->GetFolderBuildStreams() << " :postexecShellSafe=";
- break;
- default:
- assert("Only pre and post are supported");
- }
- cmCustomCommandLine const &command = *commandI;
- for (cmCustomCommandLine::const_iterator commandLineI = command.begin();
- commandLineI != command.end(); ++commandLineI)
- {
- std::string subCommandE =
- this->LocalGenerator->EscapeForShell(*commandLineI, true);
- if (!command.empty())
- {
- *this->GetFolderBuildStreams()
- << (command.begin() == commandLineI ? "'" : " ");
- //Need to double escape backslashes
- cmSystemTools::ReplaceString(subCommandE, "\\", "\\\\");
- }
- *this->GetFolderBuildStreams() << subCommandE;
- }
- if (!command.empty())
- {
- *this->GetFolderBuildStreams() << "'" << std::endl;
- }
- }
- }
- }
- void cmGhsMultiTargetGenerator::WriteSources(
- std::vector<cmSourceFile *> const &objectSources)
- {
- for (std::vector<cmSourceFile *>::const_iterator si = objectSources.begin();
- si != objectSources.end(); ++si)
- {
- std::vector<cmSourceGroup> sourceGroups(this->Makefile->GetSourceGroups());
- char const *sourceFullPath = (*si)->GetFullPath().c_str();
- cmSourceGroup *sourceGroup =
- this->Makefile->FindSourceGroup(sourceFullPath, sourceGroups);
- std::string sgPath(sourceGroup->GetFullName());
- cmSystemTools::ConvertToUnixSlashes(sgPath);
- cmGlobalGhsMultiGenerator::AddFilesUpToPath(
- this->GetFolderBuildStreams(), &this->FolderBuildStreams,
- this->LocalGenerator->GetBinaryDirectory(), sgPath,
- GhsMultiGpj::SUBPROJECT, this->RelBuildFilePath);
- std::string fullSourcePath((*si)->GetFullPath());
- if ((*si)->GetExtension() == "int" || (*si)->GetExtension() == "bsp")
- {
- *this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
- }
- 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;
- }
- if ("ld" != (*si)->GetExtension() && "int" != (*si)->GetExtension() &&
- "bsp" != (*si)->GetExtension())
- {
- this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], (*si));
- this->WriteObjectDir(this->FolderBuildStreams[sgPath],
- this->AbsBuildFilePath + sgPath);
- }
- }
- }
- void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
- cmGeneratedFileStream *fileStream, cmSourceFile *sourceFile)
- {
- const char *rawLangProp = sourceFile->GetProperty("LANGUAGE");
- if (NULL != rawLangProp)
- {
- std::string sourceLangProp(rawLangProp);
- std::string extension(sourceFile->GetExtension());
- if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension))
- {
- *fileStream << " -dotciscxx" << std::endl;
- }
- }
- }
- void cmGhsMultiTargetGenerator::WriteObjectDir(
- cmGeneratedFileStream *fileStream, std::string const &dir)
- {
- std::string workingDir(dir);
- cmSystemTools::ConvertToUnixSlashes(workingDir);
- if (!workingDir.empty())
- {
- workingDir += "/";
- }
- workingDir += "Objs";
- *fileStream << " -object_dir=\"" << workingDir << "\"" << std::endl;
- }
- std::string
- cmGhsMultiTargetGenerator::GetOutputDirectory(const std::string &config) const
- {
- std::string outputDir(AbsBuildFilePath);
- const char *runtimeOutputProp =
- this->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;
- }
- 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;
- }
- }
- 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;
- }
|