GHS: Support add_custom_target() command

-- add new project type that runs shell scripts in proper order
This commit is contained in:
Fred Baksik 2019-04-08 09:55:34 -04:00
parent 8d3dad9a76
commit 39ee9718d9
5 changed files with 182 additions and 77 deletions

View File

@ -9,7 +9,8 @@ static const char* GHS_TAG[] = { "[INTEGRITY Application]",
"[Project]", "[Project]",
"[Program]", "[Program]",
"[Reference]", "[Reference]",
"[Subproject]" }; "[Subproject]",
"[Custom Target]" };
const char* GhsMultiGpj::GetGpjTag(Types gpjType) const char* GhsMultiGpj::GetGpjTag(Types gpjType)
{ {
@ -21,6 +22,7 @@ const char* GhsMultiGpj::GetGpjTag(Types gpjType)
case PROGRAM: case PROGRAM:
case REFERENCE: case REFERENCE:
case SUBPROJECT: case SUBPROJECT:
case CUSTOM_TARGET:
tag = GHS_TAG[gpjType]; tag = GHS_TAG[gpjType];
break; break;
default: default:

View File

@ -16,7 +16,8 @@ public:
PROJECT, PROJECT,
PROGRAM, PROGRAM,
REFERENCE, REFERENCE,
SUBPROJECT SUBPROJECT,
CUSTOM_TARGET
}; };
static void WriteGpjTag(Types gpjType, std::ostream& fout); static void WriteGpjTag(Types gpjType, std::ostream& fout);

View File

@ -90,10 +90,9 @@ void cmGhsMultiTargetGenerator::Generate()
return; return;
} }
case cmStateEnums::UTILITY: { case cmStateEnums::UTILITY: {
std::string msg = "add_custom_target(<name> ...) not supported: "; this->TargetNameReal = this->GeneratorTarget->GetName();
msg += this->Name; this->TagType = GhsMultiGpj::CUSTOM_TARGET;
cmSystemTools::Message(msg); break;
return;
} }
default: default:
return; return;
@ -124,6 +123,7 @@ void cmGhsMultiTargetGenerator::GenerateTarget()
const std::string language( const std::string language(
this->GeneratorTarget->GetLinkerLanguage(this->ConfigName)); this->GeneratorTarget->GetLinkerLanguage(this->ConfigName));
if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
this->WriteTargetSpecifics(fout, this->ConfigName); this->WriteTargetSpecifics(fout, this->ConfigName);
this->SetCompilerFlags(this->ConfigName, language); this->SetCompilerFlags(this->ConfigName, language);
this->WriteCompilerFlags(fout, this->ConfigName, language); this->WriteCompilerFlags(fout, this->ConfigName, language);
@ -131,6 +131,7 @@ void cmGhsMultiTargetGenerator::GenerateTarget()
this->WriteIncludes(fout, this->ConfigName, language); this->WriteIncludes(fout, this->ConfigName, language);
this->WriteTargetLinkLine(fout, this->ConfigName); this->WriteTargetLinkLine(fout, this->ConfigName);
this->WriteBuildEvents(fout); this->WriteBuildEvents(fout);
}
this->WriteSources(fout); this->WriteSources(fout);
this->WriteReferences(fout); this->WriteReferences(fout);
fout.Close(); fout.Close();
@ -315,9 +316,11 @@ void cmGhsMultiTargetGenerator::WriteBuildEvents(std::ostream& fout)
fout, this->GeneratorTarget->GetPreBuildCommands(), fout, this->GeneratorTarget->GetPreBuildCommands(),
std::string("prebuild"), std::string("preexecShell")); std::string("prebuild"), std::string("preexecShell"));
if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
this->WriteBuildEventsHelper( this->WriteBuildEventsHelper(
fout, this->GeneratorTarget->GetPreLinkCommands(), std::string("prelink"), fout, this->GeneratorTarget->GetPreLinkCommands(),
std::string("preexecShell")); std::string("prelink"), std::string("preexecShell"));
}
this->WriteBuildEventsHelper( this->WriteBuildEventsHelper(
fout, this->GeneratorTarget->GetPostBuildCommands(), fout, this->GeneratorTarget->GetPostBuildCommands(),
@ -343,7 +346,12 @@ void cmGhsMultiTargetGenerator::WriteBuildEventsHelper(
f.SetCopyIfDifferent(true); f.SetCopyIfDifferent(true);
this->WriteCustomCommandsHelper(f, ccg); this->WriteCustomCommandsHelper(f, ccg);
f.Close(); f.Close();
if (this->TagType != GhsMultiGpj::CUSTOM_TARGET) {
fout << " :" << cmd << "=\"" << fname << "\"" << std::endl; fout << " :" << cmd << "=\"" << fname << "\"" << std::endl;
} else {
fout << fname << std::endl;
fout << " :outputName=\"" << fname << ".rule\"" << std::endl;
}
for (auto& byp : ccg.GetByproducts()) { for (auto& byp : ccg.GetByproducts()) {
fout << " :extraOutputFile=\"" << byp << "\"" << std::endl; fout << " :extraOutputFile=\"" << byp << "\"" << std::endl;
} }
@ -499,6 +507,14 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
groupFilesList[i] = *n; groupFilesList[i] = *n;
i += 1; i += 1;
groupNames.erase(gn); 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;
} }
} }
@ -575,22 +591,30 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
if (sg != "CMake Rules") { if (sg != "CMake Rules") {
/* output rule for each source file */ /* output rule for each source file */
for (const cmSourceFile* si : groupFiles[sg]) { for (const cmSourceFile* si : groupFiles[sg]) {
bool compile = true;
// Convert filename to native system // Convert filename to native system
// WORKAROUND: GHS MULTI 6.1.4 and 6.1.6 are known to need backslash on // 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. // windows when opening some files from the search window.
std::string fname(si->GetFullPath()); std::string fname(si->GetFullPath());
cmSystemTools::ConvertToOutputSlashes(fname); cmSystemTools::ConvertToOutputSlashes(fname);
/* Comment out any custom command dependencies to prevent from /* For custom targets list any associated sources,
* being considered part of the build. * 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; std::string comment;
if (si->GetCustomCommand()) { if ((this->TagType == GhsMultiGpj::CUSTOM_TARGET &&
!si->GetLanguage().empty()) ||
si->GetCustomCommand()) {
comment = "{comment} "; comment = "{comment} ";
compile = false;
} }
*fout << comment << fname << std::endl;
*fout << comment << fname << std::endl;
if (compile) {
if ("ld" != si->GetExtension() && "int" != si->GetExtension() && if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
"bsp" != si->GetExtension()) { "bsp" != si->GetExtension()) {
WriteObjectLangOverride(*fout, si); WriteObjectLangOverride(*fout, si);
@ -600,14 +624,15 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D"); this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D");
this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", ""); this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", "");
/* to avoid clutter in the gui only print out the objectName if it has /* to avoid clutter in the GUI only print out the objectName if it
* been renamed */ * has been renamed */
std::string objectName = this->GeneratorTarget->GetObjectName(si); std::string objectName = this->GeneratorTarget->GetObjectName(si);
if (!objectName.empty() && if (!objectName.empty() &&
this->GeneratorTarget->HasExplicitObjectName(si)) { this->GeneratorTarget->HasExplicitObjectName(si)) {
*fout << " -o " << objectName << std::endl; *fout << " -o " << objectName << std::endl;
} }
} }
}
} else { } else {
std::vector<cmSourceFile const*> customCommands; std::vector<cmSourceFile const*> customCommands;
if (ComputeCustomCommandOrder(customCommands)) { if (ComputeCustomCommandOrder(customCommands)) {
@ -649,6 +674,9 @@ void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
this->WriteCustomCommandLine(*fout, fname, ccg); this->WriteCustomCommandLine(*fout, fname, ccg);
} }
} }
if (this->TagType == GhsMultiGpj::CUSTOM_TARGET) {
this->WriteBuildEvents(*fout);
}
} }
} }

View File

@ -308,8 +308,21 @@ void cmGlobalGhsMultiGenerator::WriteCustomRuleBOD(std::ostream& fout)
"}\n"; "}\n";
} }
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( void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
std::ostream& fout, cmLocalGenerator* root, std::ostream& fout, std::string& ename, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators) std::vector<cmLocalGenerator*>& generators)
{ {
WriteFileHeader(fout); WriteFileHeader(fout);
@ -342,13 +355,15 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject(
fout << "\"" << this->OsDir << "\"" << std::endl; fout << "\"" << this->OsDir << "\"" << std::endl;
} }
WriteSubProjects(fout, root, generators); WriteSubProjects(fout, ename, root, generators);
} }
void cmGlobalGhsMultiGenerator::WriteSubProjects( void cmGlobalGhsMultiGenerator::WriteSubProjects(
std::ostream& fout, cmLocalGenerator* root, std::ostream& fout, std::string& ename, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators) std::vector<cmLocalGenerator*>& generators)
{ {
this->ExcludedTargets.clear();
// Collect all targets under this root generator and the transitive // Collect all targets under this root generator and the transitive
// closure of their dependencies. // closure of their dependencies.
TargetDependSet projectTargets; TargetDependSet projectTargets;
@ -356,19 +371,48 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(
this->GetTargetSets(projectTargets, originalTargets, root, generators); this->GetTargetSets(projectTargets, originalTargets, root, generators);
OrderedTargetDependSet orderedProjectTargets(projectTargets, ""); OrderedTargetDependSet orderedProjectTargets(projectTargets, "");
// write out all the sub-projects // write out all the targets for ALL target
std::string rootBinaryDir = root->GetCurrentBinaryDirectory(); std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
for (cmGeneratorTarget const* target : orderedProjectTargets) { for (cmGeneratorTarget const* target : orderedProjectTargets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue; continue;
} }
if (cmSystemTools::IsOn(target->GetProperty("EXCLUDE_FROM_ALL"))) {
this->ExcludedTargets.push_back(target);
continue;
}
this->WriteProjectLine(fout, target, root, rootBinaryDir);
}
if (!this->ExcludedTargets.empty()) {
fout << "{nobuild} " << ename << " [Project]" << std::endl;
}
}
void cmGlobalGhsMultiGenerator::WriteExcludedProjects(
std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators)
{
// write out all the excluded targets
std::string rootBinaryDir = root->GetCurrentBinaryDirectory();
for (cmGeneratorTarget const* target : this->ExcludedTargets) {
if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
this->WriteProjectLine(fout, target, root, rootBinaryDir);
}
this->ExcludedTargets.clear();
}
void cmGlobalGhsMultiGenerator::WriteProjectLine(
std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root,
std::string& rootBinaryDir)
{
const char* projName = target->GetProperty("GENERATOR_FILE_NAME"); const char* projName = target->GetProperty("GENERATOR_FILE_NAME");
const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT"); const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT");
if (projName && projType) { if (projName && projType) {
cmLocalGenerator* lg = target->GetLocalGenerator(); cmLocalGenerator* lg = target->GetLocalGenerator();
std::string dir = lg->GetCurrentBinaryDirectory(); std::string dir = lg->GetCurrentBinaryDirectory();
dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir); dir = root->MaybeConvertToRelativePath(rootBinaryDir, dir.c_str());
if (dir == ".") { if (dir == ".") {
dir.clear(); dir.clear();
} else { } else {
@ -377,9 +421,6 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(
} }
} }
if (cmSystemTools::IsOn(target->GetProperty("EXCLUDE_FROM_ALL"))) {
fout << "{comment} ";
}
std::string projFile = dir + projName + FILE_EXTENSION; std::string projFile = dir + projName + FILE_EXTENSION;
fout << projFile; fout << projFile;
fout << " " << projType << std::endl; fout << " " << projType << std::endl;
@ -401,7 +442,6 @@ void cmGlobalGhsMultiGenerator::WriteSubProjects(
fref.Close(); fref.Close();
} }
} }
}
} }
void cmGlobalGhsMultiGenerator::Generate() void cmGlobalGhsMultiGenerator::Generate()
@ -424,11 +464,23 @@ void cmGlobalGhsMultiGenerator::Generate()
this->WriteFileHeader(frule); this->WriteFileHeader(frule);
this->WriteCustomRuleBOD(frule); this->WriteCustomRuleBOD(frule);
frule.Close(); frule.Close();
// create custom target BOD file
fname = this->GetCMakeInstance()->GetHomeOutputDirectory() +
"/CMakeFiles/custom_target.bod";
cmGeneratedFileStream ftarget(fname.c_str());
ftarget.SetCopyIfDifferent(true);
this->WriteFileHeader(ftarget);
this->WriteCustomTargetBOD(ftarget);
ftarget.Close();
} }
void cmGlobalGhsMultiGenerator::OutputTopLevelProject( void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators)
{ {
std::string fname;
std::string ename;
if (generators.empty()) { if (generators.empty()) {
return; return;
} }
@ -437,18 +489,30 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject(
* with target projects. This avoid the issue where the project has * with target projects. This avoid the issue where the project has
* the same name as the executable target. * the same name as the executable target.
*/ */
std::string fname = root->GetCurrentBinaryDirectory(); fname = root->GetCurrentBinaryDirectory();
fname += "/"; fname += "/";
fname += root->GetProjectName(); fname += root->GetProjectName();
fname += ".top"; fname += ".top";
fname += FILE_EXTENSION; fname += FILE_EXTENSION;
cmGeneratedFileStream fout(fname); ename = root->GetProjectName();
fout.SetCopyIfDifferent(true); ename += ".nobuild";
ename += FILE_EXTENSION;
this->WriteTopLevelProject(fout, root, generators); cmGeneratedFileStream top(fname);
top.SetCopyIfDifferent(true);
this->WriteTopLevelProject(top, ename, root, generators);
top.Close();
fout.Close(); if (!this->ExcludedTargets.empty()) {
ename = root->GetCurrentBinaryDirectory() + "/" + ename;
cmGeneratedFileStream exclude(ename);
exclude.SetCopyIfDifferent(true);
WriteFileHeader(exclude);
GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, exclude);
this->WriteExcludedProjects(exclude, root, generators);
exclude.Close();
}
} }
std::vector<cmGlobalGenerator::GeneratedMakeCommand> std::vector<cmGlobalGenerator::GeneratedMakeCommand>
@ -543,6 +607,8 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives(
fout << "primaryTarget=" << tgt << std::endl; fout << "primaryTarget=" << tgt << std::endl;
fout << "customization=" << root->GetBinaryDirectory() fout << "customization=" << root->GetBinaryDirectory()
<< "/CMakeFiles/custom_rule.bod" << std::endl; << "/CMakeFiles/custom_rule.bod" << std::endl;
fout << "customization=" << root->GetBinaryDirectory()
<< "/CMakeFiles/custom_target.bod" << std::endl;
char const* const customization = char const* const customization =
this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION"); this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");

View File

@ -111,19 +111,27 @@ private:
/* top-level project */ /* top-level project */
void OutputTopLevelProject(cmLocalGenerator* root, void OutputTopLevelProject(cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators); std::vector<cmLocalGenerator*>& generators);
void WriteTopLevelProject(std::ostream& fout, cmLocalGenerator* root, void WriteTopLevelProject(std::ostream& fout, std::string& ename,
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators); std::vector<cmLocalGenerator*>& generators);
void WriteMacros(std::ostream& fout); void WriteMacros(std::ostream& fout);
void WriteHighLevelDirectives(cmLocalGenerator* root, std::ostream& fout); void WriteHighLevelDirectives(cmLocalGenerator* root, std::ostream& fout);
void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root, void WriteSubProjects(std::ostream& fout, std::string& ename,
cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators); std::vector<cmLocalGenerator*>& generators);
void WriteExcludedProjects(std::ostream& fout, cmLocalGenerator* root,
std::vector<cmLocalGenerator*>& generators);
void WriteProjectLine(std::ostream& fout, cmGeneratorTarget const* target,
cmLocalGenerator* root, std::string& rootBinaryDir);
void WriteCustomRuleBOD(std::ostream& fout); void WriteCustomRuleBOD(std::ostream& fout);
void WriteCustomTargetBOD(std::ostream& fout);
std::string trimQuotes(std::string const& str); std::string trimQuotes(std::string const& str);
std::string OsDir; std::string OsDir;
static const char* DEFAULT_BUILD_PROGRAM; static const char* DEFAULT_BUILD_PROGRAM;
static const char* DEFAULT_TOOLSET_ROOT; static const char* DEFAULT_TOOLSET_ROOT;
std::vector<cmGeneratorTarget const*> ExcludedTargets;
}; };
class cmGlobalGhsMultiGenerator::OrderedTargetDependSet class cmGlobalGhsMultiGenerator::OrderedTargetDependSet