|
|
|
|
@@ -14,13 +14,13 @@
|
|
|
|
|
#include "cmVersion.h"
|
|
|
|
|
|
|
|
|
|
const char* cmGlobalGhsMultiGenerator::FILE_EXTENSION = ".gpj";
|
|
|
|
|
const char* cmGlobalGhsMultiGenerator::DEFAULT_MAKE_PROGRAM = "gbuild";
|
|
|
|
|
const char* cmGlobalGhsMultiGenerator::DEFAULT_BUILD_PROGRAM = "gbuild.exe";
|
|
|
|
|
const char* cmGlobalGhsMultiGenerator::DEFAULT_TOOLSET_ROOT = "C:/ghs";
|
|
|
|
|
|
|
|
|
|
cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
|
|
|
|
|
: cmGlobalGenerator(cm)
|
|
|
|
|
, OSDirRelative(false)
|
|
|
|
|
{
|
|
|
|
|
this->GhsBuildCommandInitialized = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator()
|
|
|
|
|
@@ -41,6 +41,76 @@ void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry& entry)
|
|
|
|
|
"Generates Green Hills MULTI files (experimental, work-in-progress).";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool cmGlobalGhsMultiGenerator::SetGeneratorToolset(std::string const& ts,
|
|
|
|
|
cmMakefile* mf)
|
|
|
|
|
{
|
|
|
|
|
std::string tsp; /* toolset path */
|
|
|
|
|
std::string tsn = ts; /* toolset name */
|
|
|
|
|
|
|
|
|
|
GetToolset(mf, tsp, tsn);
|
|
|
|
|
|
|
|
|
|
/* no toolset was found */
|
|
|
|
|
if (tsn.empty()) {
|
|
|
|
|
return false;
|
|
|
|
|
} else if (ts.empty()) {
|
|
|
|
|
std::string message;
|
|
|
|
|
message =
|
|
|
|
|
"Green Hills MULTI: -T <toolset> not specified; defaulting to \"";
|
|
|
|
|
message += tsn;
|
|
|
|
|
message += "\"";
|
|
|
|
|
cmSystemTools::Message(message.c_str());
|
|
|
|
|
|
|
|
|
|
/* store the toolset for later use
|
|
|
|
|
* -- already done if -T<toolset> was specified
|
|
|
|
|
*/
|
|
|
|
|
mf->AddCacheDefinition("CMAKE_GENERATOR_TOOLSET", tsn.c_str(),
|
|
|
|
|
"Name of generator toolset.",
|
|
|
|
|
cmStateEnums::INTERNAL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* set the build tool to use */
|
|
|
|
|
const char* prevTool = mf->GetDefinition("CMAKE_MAKE_PROGRAM");
|
|
|
|
|
std::string gbuild(tsp + "/" + tsn + "/" + DEFAULT_BUILD_PROGRAM);
|
|
|
|
|
|
|
|
|
|
/* check if the toolset changed from last generate */
|
|
|
|
|
if (prevTool != NULL && (gbuild != prevTool)) {
|
|
|
|
|
std::string message = "generator toolset: ";
|
|
|
|
|
message += gbuild;
|
|
|
|
|
message += "\nDoes not match the toolset used previously: ";
|
|
|
|
|
message += prevTool;
|
|
|
|
|
message += "\nEither remove the CMakeCache.txt file and CMakeFiles "
|
|
|
|
|
"directory or choose a different binary directory.";
|
|
|
|
|
cmSystemTools::Error(message.c_str());
|
|
|
|
|
} else {
|
|
|
|
|
/* store the toolset that is being used for this build */
|
|
|
|
|
mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild.c_str(),
|
|
|
|
|
"build program to use", cmStateEnums::INTERNAL,
|
|
|
|
|
true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsn.c_str());
|
|
|
|
|
|
|
|
|
|
// FIXME: compiler detection not implemented
|
|
|
|
|
// gbuild uses the primaryTarget setting in the top-level project
|
|
|
|
|
// file to determine which compiler to use. Because compiler
|
|
|
|
|
// detection is not implemented these variables must be
|
|
|
|
|
// set to skip past these tests. However cmake will verify that
|
|
|
|
|
// the executable pointed to by CMAKE_<LANG>_COMPILER exists.
|
|
|
|
|
// To pass this additional check gbuild is used as a place holder for the
|
|
|
|
|
// actual compiler.
|
|
|
|
|
mf->AddDefinition("CMAKE_C_COMPILER", gbuild.c_str());
|
|
|
|
|
mf->AddDefinition("CMAKE_C_COMPILER_ID_RUN", "TRUE");
|
|
|
|
|
mf->AddDefinition("CMAKE_C_COMPILER_ID", "GHS");
|
|
|
|
|
mf->AddDefinition("CMAKE_C_COMPILER_FORCED", "TRUE");
|
|
|
|
|
|
|
|
|
|
mf->AddDefinition("CMAKE_CXX_COMPILER", gbuild.c_str());
|
|
|
|
|
mf->AddDefinition("CMAKE_CXX_COMPILER_ID_RUN", "TRUE");
|
|
|
|
|
mf->AddDefinition("CMAKE_CXX_COMPILER_ID", "GHS");
|
|
|
|
|
mf->AddDefinition("CMAKE_CXX_COMPILER_FORCED", "TRUE");
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool cmGlobalGhsMultiGenerator::SetGeneratorPlatform(std::string const& p,
|
|
|
|
|
cmMakefile* mf)
|
|
|
|
|
{
|
|
|
|
|
@@ -65,127 +135,49 @@ void cmGlobalGhsMultiGenerator::EnableLanguage(
|
|
|
|
|
{
|
|
|
|
|
mf->AddDefinition("CMAKE_SYSTEM_NAME", "GHS-MULTI");
|
|
|
|
|
|
|
|
|
|
const std::string ghsCompRoot(GetCompRoot());
|
|
|
|
|
mf->AddDefinition("GHS_COMP_ROOT", ghsCompRoot.c_str());
|
|
|
|
|
std::string ghsCompRootStart =
|
|
|
|
|
0 == ghsCompRootStart.size() ? "" : ghsCompRoot + "/";
|
|
|
|
|
mf->AddDefinition("CMAKE_C_COMPILER",
|
|
|
|
|
std::string(ghsCompRootStart + "ccarm.exe").c_str());
|
|
|
|
|
mf->AddDefinition("CMAKE_C_COMPILER_ID_RUN", "TRUE");
|
|
|
|
|
mf->AddDefinition("CMAKE_C_COMPILER_ID", "GHS");
|
|
|
|
|
mf->AddDefinition("CMAKE_C_COMPILER_FORCED", "TRUE");
|
|
|
|
|
|
|
|
|
|
mf->AddDefinition("CMAKE_CXX_COMPILER",
|
|
|
|
|
std::string(ghsCompRootStart + "cxarm.exe").c_str());
|
|
|
|
|
mf->AddDefinition("CMAKE_CXX_COMPILER_ID_RUN", "TRUE");
|
|
|
|
|
mf->AddDefinition("CMAKE_CXX_COMPILER_ID", "GHS");
|
|
|
|
|
mf->AddDefinition("CMAKE_CXX_COMPILER_FORCED", "TRUE");
|
|
|
|
|
|
|
|
|
|
if (!ghsCompRoot.empty()) {
|
|
|
|
|
static const char* compPreFix = "comp_";
|
|
|
|
|
std::string compFilename =
|
|
|
|
|
cmsys::SystemTools::FindLastString(ghsCompRoot.c_str(), compPreFix);
|
|
|
|
|
cmsys::SystemTools::ReplaceString(compFilename, compPreFix, "");
|
|
|
|
|
mf->AddDefinition("CMAKE_SYSTEM_VERSION", compFilename.c_str());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mf->AddDefinition("GHSMULTI", "1"); // identifier for user CMake files
|
|
|
|
|
this->cmGlobalGenerator::EnableLanguage(l, mf, optional);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile* mf)
|
|
|
|
|
bool cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile* /*mf*/)
|
|
|
|
|
{
|
|
|
|
|
// The GHS generator knows how to lookup its build tool
|
|
|
|
|
// directly instead of needing a helper module to do it, so we
|
|
|
|
|
// do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
|
|
|
|
|
if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
|
|
|
|
|
mf->AddDefinition("CMAKE_MAKE_PROGRAM",
|
|
|
|
|
this->GetGhsBuildCommand().c_str());
|
|
|
|
|
}
|
|
|
|
|
// The GHS generator only knows how to lookup its build tool
|
|
|
|
|
// during generation of the project files, but this
|
|
|
|
|
// can only be done after the toolset is specified.
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string const& cmGlobalGhsMultiGenerator::GetGhsBuildCommand()
|
|
|
|
|
void cmGlobalGhsMultiGenerator::GetToolset(cmMakefile* mf, std::string& tsd,
|
|
|
|
|
std::string& ts)
|
|
|
|
|
{
|
|
|
|
|
if (!this->GhsBuildCommandInitialized) {
|
|
|
|
|
this->GhsBuildCommandInitialized = true;
|
|
|
|
|
this->GhsBuildCommand = this->FindGhsBuildCommand();
|
|
|
|
|
const char* ghsRoot = mf->GetDefinition("GHS_TOOLSET_ROOT");
|
|
|
|
|
|
|
|
|
|
if (!ghsRoot) {
|
|
|
|
|
ghsRoot = DEFAULT_TOOLSET_ROOT;
|
|
|
|
|
}
|
|
|
|
|
return this->GhsBuildCommand;
|
|
|
|
|
}
|
|
|
|
|
tsd = ghsRoot;
|
|
|
|
|
|
|
|
|
|
std::string cmGlobalGhsMultiGenerator::FindGhsBuildCommand()
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::string> userPaths;
|
|
|
|
|
userPaths.push_back(this->GetCompRoot());
|
|
|
|
|
std::string makeProgram =
|
|
|
|
|
cmSystemTools::FindProgram(DEFAULT_MAKE_PROGRAM, userPaths);
|
|
|
|
|
if (makeProgram.empty()) {
|
|
|
|
|
makeProgram = DEFAULT_MAKE_PROGRAM;
|
|
|
|
|
}
|
|
|
|
|
return makeProgram;
|
|
|
|
|
}
|
|
|
|
|
if (ts.empty()) {
|
|
|
|
|
std::vector<std::string> output;
|
|
|
|
|
|
|
|
|
|
std::string cmGlobalGhsMultiGenerator::GetCompRoot()
|
|
|
|
|
{
|
|
|
|
|
std::string output;
|
|
|
|
|
// Use latest? version
|
|
|
|
|
cmSystemTools::Glob(tsd, "comp_[^;]+", output);
|
|
|
|
|
|
|
|
|
|
const std::vector<std::string> potentialDirsHardPaths(
|
|
|
|
|
GetCompRootHardPaths());
|
|
|
|
|
const std::vector<std::string> potentialDirsRegistry(GetCompRootRegistry());
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> potentialDirsComplete;
|
|
|
|
|
potentialDirsComplete.insert(potentialDirsComplete.end(),
|
|
|
|
|
potentialDirsHardPaths.begin(),
|
|
|
|
|
potentialDirsHardPaths.end());
|
|
|
|
|
potentialDirsComplete.insert(potentialDirsComplete.end(),
|
|
|
|
|
potentialDirsRegistry.begin(),
|
|
|
|
|
potentialDirsRegistry.end());
|
|
|
|
|
|
|
|
|
|
// Use latest version
|
|
|
|
|
std::string outputDirName;
|
|
|
|
|
for (std::vector<std::string>::const_iterator potentialDirsCompleteIt =
|
|
|
|
|
potentialDirsComplete.begin();
|
|
|
|
|
potentialDirsCompleteIt != potentialDirsComplete.end();
|
|
|
|
|
++potentialDirsCompleteIt) {
|
|
|
|
|
const std::string dirName(
|
|
|
|
|
cmsys::SystemTools::GetFilenameName(*potentialDirsCompleteIt));
|
|
|
|
|
if (dirName.compare(outputDirName) > 0) {
|
|
|
|
|
output = *potentialDirsCompleteIt;
|
|
|
|
|
outputDirName = dirName;
|
|
|
|
|
if (output.empty()) {
|
|
|
|
|
cmSystemTools::Error("GHS toolset not found in ", tsd.c_str());
|
|
|
|
|
ts = "";
|
|
|
|
|
} else {
|
|
|
|
|
ts = output.back();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
std::string tryPath = tsd + std::string("/") + ts;
|
|
|
|
|
if (!cmSystemTools::FileExists(tryPath)) {
|
|
|
|
|
cmSystemTools::Error("GHS toolset \"", ts.c_str(), "\" not found in ",
|
|
|
|
|
tsd.c_str());
|
|
|
|
|
ts = "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootHardPaths()
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::string> output;
|
|
|
|
|
cmSystemTools::Glob("C:/ghs", "comp_[^;]+", output);
|
|
|
|
|
for (std::vector<std::string>::iterator outputIt = output.begin();
|
|
|
|
|
outputIt != output.end(); ++outputIt) {
|
|
|
|
|
*outputIt = "C:/ghs/" + *outputIt;
|
|
|
|
|
}
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootRegistry()
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::string> output(2);
|
|
|
|
|
cmsys::SystemTools::ReadRegistryValue(
|
|
|
|
|
"HKEY_LOCAL_"
|
|
|
|
|
"MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
|
|
|
|
|
"Windows\\CurrentVersion\\Uninstall\\"
|
|
|
|
|
"GreenHillsSoftwared771f1b4;InstallLocation",
|
|
|
|
|
output[0]);
|
|
|
|
|
cmsys::SystemTools::ReadRegistryValue(
|
|
|
|
|
"HKEY_LOCAL_"
|
|
|
|
|
"MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
|
|
|
|
|
"Windows\\CurrentVersion\\Uninstall\\"
|
|
|
|
|
"GreenHillsSoftware9881cef6;InstallLocation",
|
|
|
|
|
output[1]);
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
|
|
|
|
|
@@ -293,8 +285,10 @@ void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
|
|
|
|
|
const std::string& targetName, const std::string& /*config*/, bool /*fast*/,
|
|
|
|
|
int jobs, bool /*verbose*/, std::vector<std::string> const& makeOptions)
|
|
|
|
|
{
|
|
|
|
|
const char* gbuild =
|
|
|
|
|
this->CMakeInstance->GetCacheDefinition("CMAKE_MAKE_PROGRAM");
|
|
|
|
|
makeCommand.push_back(
|
|
|
|
|
this->SelectMakeProgram(makeProgram, this->GetGhsBuildCommand()));
|
|
|
|
|
this->SelectMakeProgram(makeProgram, (std::string)gbuild));
|
|
|
|
|
|
|
|
|
|
if (jobs != cmake::NO_BUILD_PARALLEL_LEVEL) {
|
|
|
|
|
makeCommand.push_back("-parallel");
|
|
|
|
|
|