diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmGhsMultiTargetGenerator.cxx | 70 | ||||
-rw-r--r-- | Source/cmGhsMultiTargetGenerator.h | 2 | ||||
-rw-r--r-- | Source/cmGlobalGhsMultiGenerator.cxx | 334 | ||||
-rw-r--r-- | Source/cmGlobalGhsMultiGenerator.h | 71 |
4 files changed, 322 insertions, 155 deletions
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 51d08cb..f59d410 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -13,13 +13,13 @@ #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 <ostream> @@ -94,6 +94,16 @@ void cmGhsMultiTargetGenerator::Generate() 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; } @@ -120,10 +130,9 @@ void cmGhsMultiTargetGenerator::GenerateTarget() this->GetGlobalGenerator()->WriteFileHeader(fout); GhsMultiGpj::WriteGpjTag(this->TagType, fout); - const std::string language( - this->GeneratorTarget->GetLinkerLanguage(this->ConfigName)); - 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); @@ -132,23 +141,10 @@ void cmGhsMultiTargetGenerator::GenerateTarget() this->WriteTargetLinkLine(fout, this->ConfigName); this->WriteBuildEvents(fout); } - this->WriteReferences(fout); this->WriteSources(fout); - fout.Close(); - // Open the target ref file in copy-if-different mode. - std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory(); - fname += "/"; - fname += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); - fname += "/"; - fname += this->Name + "_REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION; - cmGeneratedFileStream fref(fname); - fref.SetCopyIfDifferent(true); - this->GetGlobalGenerator()->WriteFileHeader(fref); - GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref); - fref << " :reference=" << fproj << std::endl; - fref.Close(); + this->WriteReferenceFile(fproj); } cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator() @@ -739,27 +735,25 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride( } } -void cmGhsMultiTargetGenerator::WriteReferences(std::ostream& fout) +void cmGhsMultiTargetGenerator::WriteReferenceFile(std::string fproj) { - // FIXME - compare unordered to ordered projects - // also needs transitive build order deps! - // 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); - } + // Open the target ref file in copy-if-different mode. + std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory(); + fname += "/"; + fname += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); + fname += "/"; + fname += this->Name + "_REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION; + cmGeneratedFileStream fref(fname); + fref.SetCopyIfDifferent(true); + this->GetGlobalGenerator()->WriteFileHeader(fref); + GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref); + fref << " :reference=CMakeFiles/${PROJ_NAME}.project.gpj;" << fproj + << std::endl; + fref.Close(); + + // Store location of the reference file + this->GeneratorTarget->Target->SetProperty("GHS_REFERENCE_PROJECT", + fname.c_str()); } bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp() diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h index 3ba3884..9a41c92 100644 --- a/Source/cmGhsMultiTargetGenerator.h +++ b/Source/cmGhsMultiTargetGenerator.h @@ -66,7 +66,7 @@ private: void WriteSourceProperty(std::ostream& fout, const cmSourceFile* sf, std::string const& propName, std::string const& propFlag); - void WriteReferences(std::ostream& fout); + void WriteReferenceFile(std::string fproj); static void WriteObjectLangOverride(std::ostream& fout, const cmSourceFile* sourceFile); diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx index f212efc..7cf0664 100644 --- a/Source/cmGlobalGhsMultiGenerator.cxx +++ b/Source/cmGlobalGhsMultiGenerator.cxx @@ -321,13 +321,11 @@ void cmGlobalGhsMultiGenerator::WriteCustomTargetBOD(std::ostream& fout) "}\n"; } -void cmGlobalGhsMultiGenerator::WriteTopLevelProject( - std::ostream& fout, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators) +void cmGlobalGhsMultiGenerator::WriteTopLevelProject(std::ostream& fout, + cmLocalGenerator* root) { - WriteFileHeader(fout); - - this->WriteMacros(fout); + this->WriteFileHeader(fout); + this->WriteMacros(fout, root); this->WriteHighLevelDirectives(root, fout); GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout); @@ -355,73 +353,70 @@ void cmGlobalGhsMultiGenerator::WriteTopLevelProject( fout << "\"" << this->OsDir << "\"" << std::endl; } - WriteSubProjects(fout, root, generators); + this->WriteSubProjects(fout, root); } -void cmGlobalGhsMultiGenerator::WriteSubProjects( - std::ostream& fout, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators) +void cmGlobalGhsMultiGenerator::WriteSubProjects(std::ostream& fout, + cmLocalGenerator* root) { - this->DefaultTargets.clear(); - this->ProjectTargets.clear(); - - // Collect all targets under this root generator and the transitive - // closure of their dependencies. - // FIXME -- what is correct list or is it build order - TargetDependSet projectTargets; - TargetDependSet originalTargets; - this->GetTargetSets(projectTargets, originalTargets, root, generators); - OrderedTargetDependSet orderedProjectTargets(projectTargets, ""); - - // determine the targets for ALL target - std::string rootBinaryDir = root->GetCurrentBinaryDirectory(); - for (cmGeneratorTarget const* target : orderedProjectTargets) { - if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) { - continue; - } - this->ProjectTargets.push_back(target); - if (!cmSystemTools::IsOn(target->GetProperty("EXCLUDE_FROM_ALL"))) { - this->DefaultTargets.push_back(target); - } - } - - fout << root->GetProjectName() << ".default" << FILE_EXTENSION - << " [Project]" << std::endl; - fout << "{nobuild} " << root->GetProjectName() << ".target" << FILE_EXTENSION - << " [Project]" << std::endl; - fout << "{nobuild} " << root->GetProjectName() << ".project" + fout << "CMakeFiles/" << root->GetProjectName() << this->GetAllTargetName() + << "_REF" << FILE_EXTENSION << " [Reference]" << std::endl; + fout << "{nobuild} CMakeFiles/" << root->GetProjectName() << ".target" + << FILE_EXTENSION << " [Project]" << std::endl; + fout << "{nobuild} CMakeFiles/" << root->GetProjectName() << ".project" << FILE_EXTENSION << " [Project]" << std::endl; } -void cmGlobalGhsMultiGenerator::WriteDefaultProject( - std::ostream& fout, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators) +void cmGlobalGhsMultiGenerator::WriteProjectRefLine( + std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root, + std::string& rootBinaryDir) { - // write out all the targets for this project - WriteFileHeader(fout); - GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout); - std::string rootBinaryDir = root->GetCurrentBinaryDirectory(); - for (cmGeneratorTarget const* target : this->DefaultTargets) { - this->WriteProjectLine(fout, target, root, rootBinaryDir, false); + const char* projRef = target->GetProperty("GHS_REFERENCE_PROJECT"); + if (projRef) { + std::string projFile = projRef; + projFile = root->MaybeConvertToRelativePath(rootBinaryDir, projFile); + fout << projFile << " [Reference]\n"; + } else { + /* Should never happen */ + std::string message = "The project file reference for target [" + + target->GetName() + "] is missing.\n"; + cmSystemTools::Error(message); + fout << "{comment} " << target->GetName() << " [missing reference file]\n"; } } -void cmGlobalGhsMultiGenerator::WriteTargetProjects( - std::ostream& fout, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators, bool proj) +void cmGlobalGhsMultiGenerator::WriteProjects(cmLocalGenerator* root) { - // write out all the targets for this project - WriteFileHeader(fout); - GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fout); + std::string fname = root->GetCurrentBinaryDirectory(); + fname += "/CMakeFiles/"; + fname += root->GetProjectName(); + fname += ".project"; + fname += FILE_EXTENSION; + cmGeneratedFileStream pf(fname); + pf.SetCopyIfDifferent(true); + this->WriteFileHeader(pf); + GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, pf); + std::string rootBinaryDir = root->GetCurrentBinaryDirectory(); + rootBinaryDir += "/CMakeFiles"; + for (cmGeneratorTarget const* target : this->ProjectTargets) { - this->WriteProjectLine(fout, target, root, rootBinaryDir, proj); + if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY || + target->GetType() == cmStateEnums::MODULE_LIBRARY || + target->GetType() == cmStateEnums::SHARED_LIBRARY || + (target->GetType() == cmStateEnums::GLOBAL_TARGET && + target->GetName() != this->GetInstallTargetName())) { + continue; + } + this->WriteProjectLine(pf, target, root, rootBinaryDir); } + + pf.Close(); } void cmGlobalGhsMultiGenerator::WriteProjectLine( std::ostream& fout, cmGeneratorTarget const* target, cmLocalGenerator* root, - std::string& rootBinaryDir, bool proj) + std::string& rootBinaryDir) { const char* projName = target->GetProperty("GENERATOR_FILE_NAME"); const char* projType = target->GetProperty("GENERATOR_FILE_NAME_EXT"); @@ -440,7 +435,138 @@ void cmGlobalGhsMultiGenerator::WriteProjectLine( 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"; + } +} + +void cmGlobalGhsMultiGenerator::WriteTargets(cmLocalGenerator* root) +{ + std::string fname = root->GetCurrentBinaryDirectory(); + fname += "/CMakeFiles/"; + fname += root->GetProjectName(); + fname += ".target"; + fname += FILE_EXTENSION; + cmGeneratedFileStream tf(fname); + tf.SetCopyIfDifferent(true); + WriteFileHeader(tf); + GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, tf); + + std::string rootBinaryDir = root->GetCurrentBinaryDirectory(); + rootBinaryDir += "/CMakeFiles"; + + // ALL target + tf << root->GetProjectName() + "." + this->GetAllTargetName() + + FILE_EXTENSION + << " [Project]" << std::endl; + + // All other 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; + } + + // create target build file + fname = root->GetCurrentBinaryDirectory() + "/CMakeFiles/" + + target->GetName() + FILE_EXTENSION; + 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) { + this->WriteProjectRefLine(fbld, tgt, root, rootBinaryDir); + } + } + fbld.Close(); + + tf << target->GetName() << FILE_EXTENSION << " [Project]" << std::endl; } + tf.Close(); +} + +void cmGlobalGhsMultiGenerator::WriteAllTarget( + cmLocalGenerator* root, std::vector<cmLocalGenerator*>& generators) +{ + this->ProjectTargets.clear(); + + // create target build file + std::string fname = root->GetCurrentBinaryDirectory() + "/CMakeFiles/" + + root->GetProjectName() + "." + this->GetAllTargetName() + FILE_EXTENSION; + cmGeneratedFileStream fbld(fname); + fbld.SetCopyIfDifferent(true); + this->WriteFileHeader(fbld); + GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, fbld); + + // Collect all targets under this root generator and the transitive + // closure of their dependencies. + /* NOTE: GetTargetSets() returns the set in a different order + * every time it is run even though nothing has changed. To avoid + * creating a different build order sort the targets by name so that + * the inputs of calculating build order are the same (otherwise the + * build order will be different every time). + */ + 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->WriteProjectRefLine(fbld, target, root, rootBinaryDir); + } + } + fbld.Close(); + + // Open the target ref file in copy-if-different mode. + std::string frn = root->GetCurrentBinaryDirectory() + "/CMakeFiles/" + + root->GetProjectName() + this->GetAllTargetName() + "_REF" + + FILE_EXTENSION; + cmGeneratedFileStream fref(frn); + fref.SetCopyIfDifferent(true); + this->WriteFileHeader(fref); + GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fref); + fref << " :reference=CMakeFiles/${PROJ_NAME}.target.gpj;" << fname + << std::endl; + fref.Close(); } void cmGlobalGhsMultiGenerator::Generate() @@ -495,35 +621,12 @@ void cmGlobalGhsMultiGenerator::OutputTopLevelProject( cmGeneratedFileStream top(fname); top.SetCopyIfDifferent(true); - this->WriteTopLevelProject(top, root, generators); + this->WriteTopLevelProject(top, root); top.Close(); - fname = root->GetCurrentBinaryDirectory() + "/"; - fname += root->GetProjectName(); - fname += ".target"; - fname += FILE_EXTENSION; - cmGeneratedFileStream target(fname); - target.SetCopyIfDifferent(true); - this->WriteTargetProjects(target, root, generators, false); - target.Close(); - - fname = root->GetCurrentBinaryDirectory() + "/"; - fname += root->GetProjectName(); - fname += ".project"; - fname += FILE_EXTENSION; - cmGeneratedFileStream project(fname); - project.SetCopyIfDifferent(true); - this->WriteTargetProjects(project, root, generators, true); - project.Close(); - - fname = root->GetCurrentBinaryDirectory() + "/"; - fname += root->GetProjectName(); - fname += ".default"; - fname += FILE_EXTENSION; - cmGeneratedFileStream default_targets(fname); - default_targets.SetCopyIfDifferent(true); - this->WriteDefaultProject(default_targets, root, generators); - default_targets.Close(); + this->WriteAllTarget(root, generators); + this->WriteTargets(root); + this->WriteProjects(root); } std::vector<cmGlobalGenerator::GeneratedMakeCommand> @@ -552,6 +655,7 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand( /* determine which top-project file to use */ std::string proj = projectName + ".top" + FILE_EXTENSION; + std::string target = projectName + ".target" + FILE_EXTENSION; std::vector<std::string> files; cmSystemTools::Glob(projectDir, ".*\\.top\\.gpj", files); if (!files.empty()) { @@ -567,8 +671,13 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand( targetNames.end()) { makeCommand.Add("-clean"); } else { + bool print_within = true; for (const auto& tname : targetNames) { if (!tname.empty()) { + if (print_within) { + makeCommand.Add("-within", target); + print_within = false; + } if (tname.compare(tname.size() - 4, 4, ".gpj") == 0) { makeCommand.Add(tname); } else { @@ -581,8 +690,10 @@ cmGlobalGhsMultiGenerator::GenerateBuildCommand( 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) { @@ -624,12 +735,12 @@ void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives( 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()); @@ -662,3 +773,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 5027a7c..a964af8 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,30 +95,55 @@ 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 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, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators); - void WriteTargetProjects(std::ostream& fout, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators, - bool proj); - void WriteDefaultProject(std::ostream& fout, cmLocalGenerator* root, - std::vector<cmLocalGenerator*>& generators); + void WriteSubProjects(std::ostream& fout, cmLocalGenerator* root); + void WriteTargets(cmLocalGenerator* root); + void WriteProjects(cmLocalGenerator* root); void WriteProjectLine(std::ostream& fout, cmGeneratorTarget const* target, - cmLocalGenerator* root, std::string& rootBinaryDir, - bool proj); + cmLocalGenerator* root, std::string& rootBinaryDir); + void WriteProjectRefLine(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 trimQuotes(std::string const& str); + std::string TrimQuotes(std::string const& str); std::string OsDir; static const char* DEFAULT_BUILD_PROGRAM; static const char* DEFAULT_TOOLSET_ROOT; - std::vector<cmGeneratorTarget const*> DefaultTargets; + + 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 |