2015-03-24 08:12:55 +03:00
|
|
|
/*============================================================================
|
|
|
|
CMake - Cross Platform Makefile Generator
|
|
|
|
Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>
|
|
|
|
|
|
|
|
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"
|
2016-04-29 16:40:20 +03:00
|
|
|
|
2016-04-29 17:53:13 +03:00
|
|
|
#include "cmGeneratedFileStream.h"
|
2015-03-24 08:12:55 +03:00
|
|
|
#include "cmGlobalGhsMultiGenerator.h"
|
|
|
|
#include "cmLocalGhsMultiGenerator.h"
|
|
|
|
#include "cmMakefile.h"
|
|
|
|
#include "cmSourceFile.h"
|
2016-04-29 17:53:13 +03:00
|
|
|
#include "cmTarget.h"
|
2015-03-24 08:12:55 +03:00
|
|
|
#include <assert.h>
|
|
|
|
#include <cmAlgorithms.h>
|
|
|
|
|
|
|
|
std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
|
|
|
|
|
2015-06-06 14:02:59 +03:00
|
|
|
cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget *target)
|
2015-10-21 22:31:00 +03:00
|
|
|
: GeneratorTarget(target)
|
2015-03-24 08:12:55 +03:00
|
|
|
, LocalGenerator(static_cast<cmLocalGhsMultiGenerator *>(
|
2015-06-06 14:02:59 +03:00
|
|
|
target->GetLocalGenerator()))
|
|
|
|
, Makefile(target->Target->GetMakefile())
|
2015-10-06 23:35:28 +03:00
|
|
|
, TargetGroup(DetermineIfTargetGroup(target))
|
2015-03-24 08:12:55 +03:00
|
|
|
, DynamicDownload(false)
|
|
|
|
{
|
2015-10-21 22:31:00 +03:00
|
|
|
this->RelBuildFilePath = this->GetRelBuildFilePath(target);
|
2015-03-24 08:12:55 +03:00
|
|
|
|
|
|
|
this->RelOutputFileName =
|
2015-10-21 22:31:00 +03:00
|
|
|
this->RelBuildFilePath + target->GetName() + ".a";
|
2015-03-24 08:12:55 +03:00
|
|
|
|
|
|
|
this->RelBuildFileName = this->RelBuildFilePath;
|
2015-10-21 22:31:00 +03:00
|
|
|
this->RelBuildFileName += this->GetBuildFileName(target);
|
2015-03-24 08:12:55 +03:00
|
|
|
|
2015-10-21 22:31:00 +03:00
|
|
|
std::string absPathToRoot = this->GetAbsPathToRoot(target);
|
2015-03-24 08:12:55 +03:00
|
|
|
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
|
2015-10-21 22:31:00 +03:00
|
|
|
cmGhsMultiTargetGenerator::GetRelBuildFilePath(
|
|
|
|
const cmGeneratorTarget *target)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
|
|
|
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
|
2015-10-21 22:31:00 +03:00
|
|
|
cmGhsMultiTargetGenerator::GetAbsPathToRoot(const cmGeneratorTarget *target)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
2015-10-21 22:31:00 +03:00
|
|
|
return target->GetLocalGenerator()->GetBinaryDirectory();
|
2015-03-24 08:12:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string
|
2015-10-21 22:31:00 +03:00
|
|
|
cmGhsMultiTargetGenerator::GetAbsBuildFilePath(const cmGeneratorTarget *target)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
|
|
|
std::string output;
|
|
|
|
output = cmGhsMultiTargetGenerator::GetAbsPathToRoot(target);
|
|
|
|
output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
|
|
|
|
output += cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string
|
2015-10-21 22:31:00 +03:00
|
|
|
cmGhsMultiTargetGenerator::GetRelBuildFileName(const cmGeneratorTarget *target)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
|
|
|
std::string output;
|
|
|
|
output = cmGhsMultiTargetGenerator::GetRelBuildFilePath(target);
|
|
|
|
output = cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(output);
|
|
|
|
output += cmGhsMultiTargetGenerator::GetBuildFileName(target);
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2015-10-21 22:31:00 +03:00
|
|
|
std::string
|
|
|
|
cmGhsMultiTargetGenerator::GetBuildFileName(const cmGeneratorTarget *target)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
|
|
|
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";
|
|
|
|
}
|
2015-08-04 20:19:49 +03:00
|
|
|
const std::string language(
|
|
|
|
this->GeneratorTarget->GetLinkerLanguage(config));
|
2015-03-24 08:12:55 +03:00
|
|
|
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);
|
2015-10-08 01:21:51 +03:00
|
|
|
if (this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
2016-03-27 06:28:31 +03:00
|
|
|
this->WriteTargetLinkLibraries(config, language);
|
2015-03-24 08:12:55 +03:00
|
|
|
}
|
|
|
|
this->WriteCustomCommands();
|
|
|
|
|
|
|
|
this->WriteSources(objectSources);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cmGhsMultiTargetGenerator::IncludeThisTarget()
|
|
|
|
{
|
|
|
|
bool output = true;
|
2015-10-21 22:31:00 +03:00
|
|
|
char const *excludeFromAll =
|
|
|
|
this->GeneratorTarget->GetProperty("EXCLUDE_FROM_ALL");
|
2015-03-24 08:12:55 +03:00
|
|
|
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");
|
2015-08-29 18:51:15 +03:00
|
|
|
this->GeneratorTarget->GetSourceFiles(output, config);
|
2015-03-24 08:12:55 +03:00
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag() const
|
|
|
|
{
|
2015-10-06 23:35:28 +03:00
|
|
|
return cmGhsMultiTargetGenerator::GetGpjTag(this->GeneratorTarget);
|
2015-03-24 08:12:55 +03:00
|
|
|
}
|
|
|
|
|
2015-10-06 23:35:28 +03:00
|
|
|
GhsMultiGpj::Types cmGhsMultiTargetGenerator::GetGpjTag(
|
|
|
|
const cmGeneratorTarget *target)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
|
|
|
GhsMultiGpj::Types output;
|
|
|
|
if (cmGhsMultiTargetGenerator::DetermineIfTargetGroup(target))
|
|
|
|
{
|
|
|
|
output = GhsMultiGpj::INTERGRITY_APPLICATION;
|
|
|
|
}
|
2015-10-08 01:21:51 +03:00
|
|
|
else if (target->GetType() == cmState::STATIC_LIBRARY)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
|
|
|
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));
|
|
|
|
|
2015-10-08 01:21:51 +03:00
|
|
|
if (this->GeneratorTarget->GetType() == cmState::STATIC_LIBRARY)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
2016-03-21 14:00:35 +03:00
|
|
|
std::string const static_library_suffix =
|
|
|
|
this->Makefile->GetSafeDefinition("CMAKE_STATIC_LIBRARY_SUFFIX");
|
2015-10-14 09:27:18 +03:00
|
|
|
*this->GetFolderBuildStreams() << " -o \""
|
2016-03-21 14:00:35 +03:00
|
|
|
<< outputDir << outputFilename
|
|
|
|
<< static_library_suffix << "\""
|
2015-03-24 08:12:55 +03:00
|
|
|
<< std::endl;
|
|
|
|
}
|
2015-10-08 01:21:51 +03:00
|
|
|
else if (this->GeneratorTarget->GetType() == cmState::EXECUTABLE)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
|
|
|
if (notKernel && !this->IsTargetGroup())
|
|
|
|
{
|
|
|
|
*this->GetFolderBuildStreams() << " -relprog" << std::endl;
|
|
|
|
}
|
|
|
|
if (this->IsTargetGroup())
|
|
|
|
{
|
2015-09-06 08:15:26 +03:00
|
|
|
*this->GetFolderBuildStreams()
|
2015-10-14 09:27:18 +03:00
|
|
|
<< " -o \"" << outputDir
|
2015-09-06 08:15:26 +03:00
|
|
|
<< outputFilename << ".elf\"" << std::endl;
|
|
|
|
*this->GetFolderBuildStreams() << " :extraOutputFile=\"" << outputDir
|
|
|
|
<< outputFilename << ".elf.ael\""
|
2015-03-24 08:12:55 +03:00
|
|
|
<< std::endl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-03-21 14:00:35 +03:00
|
|
|
std::string const executable_suffix =
|
|
|
|
this->Makefile->GetSafeDefinition("CMAKE_EXECUTABLE_SUFFIX");
|
2015-10-14 09:27:18 +03:00
|
|
|
*this->GetFolderBuildStreams() << " -o \""
|
2016-03-21 14:00:35 +03:00
|
|
|
<< outputDir << outputFilename
|
|
|
|
<< executable_suffix << "\""
|
2015-03-24 08:12:55 +03:00
|
|
|
<< 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);
|
|
|
|
}
|
2015-10-09 23:19:57 +03:00
|
|
|
this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget,
|
|
|
|
lang, config);
|
|
|
|
this->LocalGenerator->AddVisibilityPresetFlags(flags,
|
|
|
|
this->GeneratorTarget,
|
|
|
|
lang);
|
2015-03-24 08:12:55 +03:00
|
|
|
|
|
|
|
// 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.
|
2015-10-09 23:19:57 +03:00
|
|
|
this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
|
|
|
|
lang, config);
|
2015-03-24 08:12:55 +03:00
|
|
|
|
|
|
|
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.
|
2015-10-19 23:42:01 +03:00
|
|
|
if (const char *exportMacro = this->GeneratorTarget->GetExportMacro())
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
|
|
|
this->LocalGenerator->AppendDefines(defines, exportMacro);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add preprocessor definitions for this target and configuration.
|
2015-10-09 23:19:57 +03:00
|
|
|
this->LocalGenerator->AddCompileDefinitions(defines,
|
|
|
|
this->GeneratorTarget, config,
|
2015-03-24 08:12:55 +03:00
|
|
|
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;
|
2015-08-05 01:00:53 +03:00
|
|
|
this->GeneratorTarget->GetCompileDefinitions(compileDefinitions,
|
|
|
|
config, language);
|
2015-03-24 08:12:55 +03:00
|
|
|
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 =
|
2015-08-05 00:14:53 +03:00
|
|
|
this->GeneratorTarget->GetIncludeDirectories(config, language);
|
2015-03-24 08:12:55 +03:00
|
|
|
for (std::vector<std::string>::const_iterator includes_i = includes.begin();
|
|
|
|
includes_i != includes.end(); ++includes_i)
|
|
|
|
{
|
|
|
|
*this->GetFolderBuildStreams() << " -I\"" << *includes_i << "\""
|
|
|
|
<< std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-27 06:28:31 +03:00
|
|
|
void cmGhsMultiTargetGenerator::WriteTargetLinkLibraries(
|
|
|
|
std::string const& config, std::string const& language)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
|
|
|
// library directories
|
|
|
|
cmTargetDependSet tds =
|
2015-06-06 14:08:17 +03:00
|
|
|
this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
|
2015-03-24 08:12:55 +03:00
|
|
|
for (cmTargetDependSet::iterator tdsI = tds.begin(); tdsI != tds.end();
|
|
|
|
++tdsI)
|
|
|
|
{
|
2015-10-21 22:31:00 +03:00
|
|
|
const cmGeneratorTarget *tg = *tdsI;
|
2015-03-24 08:12:55 +03:00
|
|
|
*this->GetFolderBuildStreams() << " -L\"" << GetAbsBuildFilePath(tg)
|
|
|
|
<< "\"" << std::endl;
|
|
|
|
}
|
|
|
|
// library targets
|
|
|
|
cmTarget::LinkLibraryVectorType llv =
|
2015-10-21 22:31:00 +03:00
|
|
|
this->GeneratorTarget->Target->GetOriginalLinkLibraries();
|
2015-03-24 08:12:55 +03:00
|
|
|
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;
|
|
|
|
}
|
2016-03-27 06:28:31 +03:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2015-03-24 08:12:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void cmGhsMultiTargetGenerator::WriteCustomCommands()
|
|
|
|
{
|
2015-10-21 22:31:00 +03:00
|
|
|
WriteCustomCommandsHelper(
|
2015-10-23 01:42:58 +03:00
|
|
|
this->GeneratorTarget->GetPreBuildCommands(),
|
2015-10-21 22:31:00 +03:00
|
|
|
cmTarget::PRE_BUILD);
|
|
|
|
WriteCustomCommandsHelper(
|
2015-10-23 01:42:58 +03:00
|
|
|
this->GeneratorTarget->GetPostBuildCommands(),
|
2015-10-21 22:31:00 +03:00
|
|
|
cmTarget::POST_BUILD);
|
2015-03-24 08:12:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-24 22:47:48 +03:00
|
|
|
std::map<const cmSourceFile *, std::string>
|
|
|
|
cmGhsMultiTargetGenerator::GetObjectNames(
|
|
|
|
const std::vector<cmSourceFile *> &objectSources)
|
|
|
|
{
|
|
|
|
bool found_duplicate = false;
|
|
|
|
std::set<std::string> filenames;
|
|
|
|
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);
|
|
|
|
if (filenames.end() != filenames.find(lower_filename))
|
|
|
|
{
|
|
|
|
found_duplicate = true;
|
|
|
|
}
|
|
|
|
filenames.insert(lower_filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::map<const cmSourceFile *, std::string> objectNames;
|
|
|
|
if (found_duplicate)
|
|
|
|
{
|
|
|
|
for(std::vector<cmSourceFile *>::const_iterator
|
|
|
|
sf = objectSources.begin(); sf != objectSources.end(); ++sf)
|
|
|
|
{
|
|
|
|
std::string full_filename = (*sf)->GetFullPath();
|
|
|
|
cmsys::SystemTools::ReplaceString(full_filename, ":/", "_");
|
|
|
|
cmsys::SystemTools::ReplaceString(full_filename, "/", "_");
|
|
|
|
objectNames[*sf] = full_filename;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return objectNames;
|
|
|
|
}
|
|
|
|
|
2015-03-24 08:12:55 +03:00
|
|
|
void cmGhsMultiTargetGenerator::WriteSources(
|
|
|
|
std::vector<cmSourceFile *> const &objectSources)
|
|
|
|
{
|
2016-04-24 22:47:48 +03:00
|
|
|
std::map<const cmSourceFile *, std::string> objectNames =
|
|
|
|
cmGhsMultiTargetGenerator::GetObjectNames(objectSources);
|
2015-03-24 08:12:55 +03:00
|
|
|
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,
|
2015-10-07 02:17:48 +03:00
|
|
|
this->LocalGenerator->GetBinaryDirectory(), sgPath,
|
2015-03-24 08:12:55 +03:00
|
|
|
GhsMultiGpj::SUBPROJECT, this->RelBuildFilePath);
|
|
|
|
|
2015-09-06 08:15:26 +03:00
|
|
|
std::string fullSourcePath((*si)->GetFullPath());
|
|
|
|
if ((*si)->GetExtension() == "int" || (*si)->GetExtension() == "bsp")
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
2015-09-06 08:15:26 +03:00
|
|
|
*this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
|
2015-03-24 08:12:55 +03:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-09-06 08:15:26 +03:00
|
|
|
//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;
|
2015-03-24 08:12:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if ("ld" != (*si)->GetExtension() && "int" != (*si)->GetExtension() &&
|
|
|
|
"bsp" != (*si)->GetExtension())
|
|
|
|
{
|
|
|
|
this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], (*si));
|
2016-04-24 22:47:48 +03:00
|
|
|
if (objectNames.end() != objectNames.find(*si))
|
|
|
|
{
|
|
|
|
*this->FolderBuildStreams[sgPath] << " -o \"" <<
|
|
|
|
objectNames.find(*si)->second << ".o\"" << std::endl;
|
|
|
|
}
|
2015-03-24 08:12:55 +03:00
|
|
|
|
|
|
|
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 =
|
2015-10-21 22:31:00 +03:00
|
|
|
this->GeneratorTarget->GetProperty("RUNTIME_OUTPUT_DIRECTORY");
|
2015-03-24 08:12:55 +03:00
|
|
|
if (NULL != runtimeOutputProp)
|
|
|
|
{
|
|
|
|
outputDir = runtimeOutputProp;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string configCapped(cmSystemTools::UpperCase(config));
|
|
|
|
const char *runtimeOutputSProp =
|
2015-10-21 22:31:00 +03:00
|
|
|
this->GeneratorTarget
|
|
|
|
->GetProperty("RUNTIME_OUTPUT_DIRECTORY_" + configCapped);
|
2015-03-24 08:12:55 +03:00
|
|
|
if (NULL != runtimeOutputSProp)
|
|
|
|
{
|
|
|
|
outputDir = runtimeOutputSProp;
|
|
|
|
}
|
|
|
|
cmSystemTools::ConvertToUnixSlashes(outputDir);
|
|
|
|
|
|
|
|
if (!outputDir.empty())
|
|
|
|
{
|
|
|
|
outputDir += "/";
|
|
|
|
}
|
|
|
|
|
|
|
|
return outputDir;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string
|
|
|
|
cmGhsMultiTargetGenerator::GetOutputFilename(const std::string &config) const
|
|
|
|
{
|
2015-10-21 22:31:00 +03:00
|
|
|
std::string outputFilename(this->GeneratorTarget->GetName());
|
2015-03-24 08:12:55 +03:00
|
|
|
|
2015-10-21 22:31:00 +03:00
|
|
|
const char *outputNameProp =
|
|
|
|
this->GeneratorTarget->GetProperty("OUTPUT_NAME");
|
2015-03-24 08:12:55 +03:00
|
|
|
if (NULL != outputNameProp)
|
|
|
|
{
|
|
|
|
outputFilename = outputNameProp;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string configCapped(cmSystemTools::UpperCase(config));
|
|
|
|
const char *outputNameSProp =
|
2015-10-21 22:31:00 +03:00
|
|
|
this->GeneratorTarget->GetProperty(configCapped + "_OUTPUT_NAME");
|
2015-03-24 08:12:55 +03:00
|
|
|
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;
|
2015-08-05 00:43:56 +03:00
|
|
|
this->GeneratorTarget->GetCompileOptions(options, config, language);
|
2015-03-24 08:12:55 +03:00
|
|
|
output =
|
|
|
|
options.end() == std::find(options.begin(), options.end(), "-kernel");
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2015-10-06 23:35:28 +03:00
|
|
|
bool cmGhsMultiTargetGenerator::DetermineIfTargetGroup(
|
|
|
|
const cmGeneratorTarget *target)
|
2015-03-24 08:12:55 +03:00
|
|
|
{
|
|
|
|
bool output = false;
|
|
|
|
std::vector<cmSourceFile *> sources;
|
|
|
|
std::string config =
|
2015-10-06 23:35:28 +03:00
|
|
|
target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
|
2015-08-29 18:51:15 +03:00
|
|
|
target->GetSourceFiles(sources, config);
|
2015-03-24 08:12:55 +03:00
|
|
|
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;
|
2015-08-05 00:43:56 +03:00
|
|
|
this->GeneratorTarget->GetCompileOptions(options, config, language);
|
2015-03-24 08:12:55 +03:00
|
|
|
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;
|
|
|
|
}
|