|  | @@ -9,8 +9,8 @@
 | 
	
		
			
				|  |  |  #include "cmLocalGhsMultiGenerator.h"
 | 
	
		
			
				|  |  |  #include "cmMakefile.h"
 | 
	
		
			
				|  |  |  #include "cmSourceFile.h"
 | 
	
		
			
				|  |  | +#include "cmSourceGroup.h"
 | 
	
		
			
				|  |  |  #include "cmTarget.h"
 | 
	
		
			
				|  |  | -#include <assert.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  std::string const cmGhsMultiTargetGenerator::DDOption("-dynamic");
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -106,8 +106,7 @@ void cmGhsMultiTargetGenerator::Generate()
 | 
	
		
			
				|  |  |                                               this->Name.c_str());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Skip if empty or not included in build
 | 
	
		
			
				|  |  | -  std::vector<cmSourceFile*> objectSources = this->GetSources();
 | 
	
		
			
				|  |  | -  if (!objectSources.empty() && this->IncludeThisTarget()) {
 | 
	
		
			
				|  |  | +  if (!this->GetSources().empty() && this->IncludeThisTarget()) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      // Open the filestream in copy-if-different mode.
 | 
	
		
			
				|  |  |      std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
 | 
	
	
		
			
				|  | @@ -143,13 +142,7 @@ void cmGhsMultiTargetGenerator::Generate()
 | 
	
		
			
				|  |  |        this->WriteTargetLinkLibraries(fout, config, language);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      this->WriteCustomCommands(fout);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    std::map<const cmSourceFile*, std::string> objectNames =
 | 
	
		
			
				|  |  | -      cmGhsMultiTargetGenerator::GetObjectNames(
 | 
	
		
			
				|  |  | -        &objectSources, this->LocalGenerator, this->GeneratorTarget);
 | 
	
		
			
				|  |  | -#if 0 /* temp stub - this generates its own files */
 | 
	
		
			
				|  |  | -    this->WriteSources(objectSources, objectNames);
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | +    this->WriteSources(fout);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      fout.Close();
 | 
	
		
			
				|  |  |    }
 | 
	
	
		
			
				|  | @@ -481,44 +474,154 @@ cmGhsMultiTargetGenerator::GetObjectNames(
 | 
	
		
			
				|  |  |    return objectNamesCorrected;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void cmGhsMultiTargetGenerator::WriteSources(
 | 
	
		
			
				|  |  | -  std::vector<cmSourceFile*> const& objectSources,
 | 
	
		
			
				|  |  | -  std::map<const cmSourceFile*, std::string> const& objectNames)
 | 
	
		
			
				|  |  | +void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -  for (const cmSourceFile* sf : objectSources) {
 | 
	
		
			
				|  |  | -    std::vector<cmSourceGroup> sourceGroups(this->Makefile->GetSourceGroups());
 | 
	
		
			
				|  |  | -    std::string const& sourceFullPath = sf->GetFullPath();
 | 
	
		
			
				|  |  | +  /* vector of all sources for this target */
 | 
	
		
			
				|  |  | +  std::vector<cmSourceFile*> sources = this->GetSources();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* vector of all groups defined for this target
 | 
	
		
			
				|  |  | +   * -- but the vector is not expanded with sub groups or in any useful order
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* for each source file assign it to its group */
 | 
	
		
			
				|  |  | +  std::map<std::string, std::vector<cmSourceFile*>> groupFiles;
 | 
	
		
			
				|  |  | +  std::set<std::string> groupNames;
 | 
	
		
			
				|  |  | +  for (auto& sf : sources) {
 | 
	
		
			
				|  |  |      cmSourceGroup* sourceGroup =
 | 
	
		
			
				|  |  | -      this->Makefile->FindSourceGroup(sourceFullPath, sourceGroups);
 | 
	
		
			
				|  |  | -    std::string sgPath = sourceGroup->GetFullName();
 | 
	
		
			
				|  |  | -    cmSystemTools::ConvertToUnixSlashes(sgPath);
 | 
	
		
			
				|  |  | -    cmGlobalGhsMultiGenerator::AddFilesUpToPath(
 | 
	
		
			
				|  |  | -      this->GetFolderBuildStreams(), &this->FolderBuildStreams,
 | 
	
		
			
				|  |  | -      this->LocalGenerator->GetBinaryDirectory().c_str(), sgPath,
 | 
	
		
			
				|  |  | -      GhsMultiGpj::SUBPROJECT, this->RelBuildFilePath);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    std::string fullSourcePath(sf->GetFullPath());
 | 
	
		
			
				|  |  | -    if (sf->GetExtension() == "int" || sf->GetExtension() == "bsp") {
 | 
	
		
			
				|  |  | -      *this->FolderBuildStreams[sgPath] << fullSourcePath << std::endl;
 | 
	
		
			
				|  |  | +      this->Makefile->FindSourceGroup(sf->GetFullPath(), sourceGroups);
 | 
	
		
			
				|  |  | +    std::string gn = sourceGroup->GetFullName();
 | 
	
		
			
				|  |  | +    groupFiles[gn].push_back(sf);
 | 
	
		
			
				|  |  | +    groupNames.insert(gn);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* list of known groups and the order they are displayed in a project file */
 | 
	
		
			
				|  |  | +  const std::vector<std::string> standardGroups = {
 | 
	
		
			
				|  |  | +    "Header Files", "Source Files",     "CMake Rules",
 | 
	
		
			
				|  |  | +    "Object Files", "Object Libraries", "Resources"
 | 
	
		
			
				|  |  | +  };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* list of groups in the order they are displayed in a project file*/
 | 
	
		
			
				|  |  | +  std::vector<std::string> groupFilesList(groupFiles.size());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* put the groups in the order they should be listed
 | 
	
		
			
				|  |  | +   * - standard groups first, and then everything else
 | 
	
		
			
				|  |  | +   *   in the order used by std::map.
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  int i = 0;
 | 
	
		
			
				|  |  | +  for (const std::string& gn : standardGroups) {
 | 
	
		
			
				|  |  | +    auto n = groupNames.find(gn);
 | 
	
		
			
				|  |  | +    if (n != groupNames.end()) {
 | 
	
		
			
				|  |  | +      groupFilesList[i] = *n;
 | 
	
		
			
				|  |  | +      i += 1;
 | 
	
		
			
				|  |  | +      groupNames.erase(gn);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  { /* catch-all group - is last item */
 | 
	
		
			
				|  |  | +    std::string gn = "";
 | 
	
		
			
				|  |  | +    auto n = groupNames.find(gn);
 | 
	
		
			
				|  |  | +    if (n != groupNames.end()) {
 | 
	
		
			
				|  |  | +      groupFilesList.back() = *n;
 | 
	
		
			
				|  |  | +      groupNames.erase(gn);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  for (auto& n : groupNames) {
 | 
	
		
			
				|  |  | +    groupFilesList[i] = n;
 | 
	
		
			
				|  |  | +    i += 1;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* sort the files within each group */
 | 
	
		
			
				|  |  | +  for (auto& n : groupFilesList) {
 | 
	
		
			
				|  |  | +    std::sort(groupFiles[n].begin(), groupFiles[n].end(),
 | 
	
		
			
				|  |  | +              [](cmSourceFile* l, cmSourceFile* r) {
 | 
	
		
			
				|  |  | +                return l->GetFullPath() < r->GetFullPath();
 | 
	
		
			
				|  |  | +              });
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* get all the object names for these sources */
 | 
	
		
			
				|  |  | +  std::map<const cmSourceFile*, std::string> objectNames =
 | 
	
		
			
				|  |  | +    cmGhsMultiTargetGenerator::GetObjectNames(&sources, this->LocalGenerator,
 | 
	
		
			
				|  |  | +                                              this->GeneratorTarget);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* list of open project files */
 | 
	
		
			
				|  |  | +  std::vector<cmGeneratedFileStream*> gfiles;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /* write files into the proper project file
 | 
	
		
			
				|  |  | +   * -- groups go into main project file
 | 
	
		
			
				|  |  | +   *    unless FOLDER property or variable is set.
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  | +  for (auto& sg : groupFilesList) {
 | 
	
		
			
				|  |  | +    std::ostream* fout;
 | 
	
		
			
				|  |  | +    bool useProjectFile =
 | 
	
		
			
				|  |  | +      cmSystemTools::IsOn(
 | 
	
		
			
				|  |  | +        this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
 | 
	
		
			
				|  |  | +      cmSystemTools::IsOn(
 | 
	
		
			
				|  |  | +        this->Makefile->GetDefinition("GHS_NO_SOURCE_GROUP_FILE"));
 | 
	
		
			
				|  |  | +    if (useProjectFile || sg.empty()) {
 | 
	
		
			
				|  |  | +      fout = &fout_proj;
 | 
	
		
			
				|  |  |      } 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;
 | 
	
		
			
				|  |  | +      // Open the filestream in copy-if-different mode.
 | 
	
		
			
				|  |  | +      std::string gname = sg;
 | 
	
		
			
				|  |  | +      cmsys::SystemTools::ReplaceString(gname, "\\", "_");
 | 
	
		
			
				|  |  | +      std::string lpath =
 | 
	
		
			
				|  |  | +        this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
 | 
	
		
			
				|  |  | +      lpath += "/";
 | 
	
		
			
				|  |  | +      lpath += gname;
 | 
	
		
			
				|  |  | +      lpath += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
 | 
	
		
			
				|  |  | +      std::string fpath = this->LocalGenerator->GetCurrentBinaryDirectory();
 | 
	
		
			
				|  |  | +      fpath += "/";
 | 
	
		
			
				|  |  | +      fpath += lpath;
 | 
	
		
			
				|  |  | +      cmGeneratedFileStream* f = new cmGeneratedFileStream(fpath.c_str());
 | 
	
		
			
				|  |  | +      f->SetCopyIfDifferent(true);
 | 
	
		
			
				|  |  | +      gfiles.push_back(f);
 | 
	
		
			
				|  |  | +      fout = f;
 | 
	
		
			
				|  |  | +      cmGlobalGhsMultiGenerator::OpenBuildFileStream(f);
 | 
	
		
			
				|  |  | +      *fout << "[Subproject]" << std::endl;
 | 
	
		
			
				|  |  | +      cmGlobalGhsMultiGenerator::WriteDisclaimer(f);
 | 
	
		
			
				|  |  | +      fout_proj << lpath << " ";
 | 
	
		
			
				|  |  | +      fout_proj << "[Subproject]" << std::endl;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    if (useProjectFile) {
 | 
	
		
			
				|  |  | +      if (sg.empty()) {
 | 
	
		
			
				|  |  | +        *fout << "{comment} Others" << std::endl;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        *fout << "{comment} " << sg << std::endl;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    if ("ld" != sf->GetExtension() && "int" != sf->GetExtension() &&
 | 
	
		
			
				|  |  | -        "bsp" != sf->GetExtension()) {
 | 
	
		
			
				|  |  | -      this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], sf);
 | 
	
		
			
				|  |  | -      if (objectNames.end() != objectNames.find(sf)) {
 | 
	
		
			
				|  |  | -        *this->FolderBuildStreams[sgPath]
 | 
	
		
			
				|  |  | -          << "    -o \"" << objectNames.find(sf)->second << "\"" << std::endl;
 | 
	
		
			
				|  |  | +    /* output rule for each source file */
 | 
	
		
			
				|  |  | +    for (const cmSourceFile* si : groupFiles[sg]) {
 | 
	
		
			
				|  |  | +      std::string fullSourcePath(si->GetFullPath());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if (si->GetExtension() == "int" || si->GetExtension() == "bsp") {
 | 
	
		
			
				|  |  | +        *fout << 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, "/", "\\");
 | 
	
		
			
				|  |  | +        *fout << fullSourcePath << std::endl;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -      this->WriteObjectDir(this->FolderBuildStreams[sgPath],
 | 
	
		
			
				|  |  | -                           this->AbsBuildFilePath + sgPath);
 | 
	
		
			
				|  |  | +      if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
 | 
	
		
			
				|  |  | +          "bsp" != si->GetExtension()) {
 | 
	
		
			
				|  |  | +        this->WriteObjectLangOverride(fout, si);
 | 
	
		
			
				|  |  | +        if (objectNames.end() != objectNames.find(si)) {
 | 
	
		
			
				|  |  | +          *fout << "    -o \"" << objectNames.find(si)->second << "\""
 | 
	
		
			
				|  |  | +                << std::endl;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        this->WriteObjectDir(*fout, this->AbsBuildFilePath);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  for (cmGeneratedFileStream* f : gfiles) {
 | 
	
		
			
				|  |  | +    f->Close();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
 | 
	
	
		
			
				|  | @@ -534,8 +637,8 @@ void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void cmGhsMultiTargetGenerator::WriteObjectDir(
 | 
	
		
			
				|  |  | -  cmGeneratedFileStream* fileStream, std::string const& dir)
 | 
	
		
			
				|  |  | +void cmGhsMultiTargetGenerator::WriteObjectDir(std::ostream& fout,
 | 
	
		
			
				|  |  | +                                               std::string const& dir)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    std::string workingDir(dir);
 | 
	
		
			
				|  |  |    cmSystemTools::ConvertToUnixSlashes(workingDir);
 | 
	
	
		
			
				|  | @@ -543,7 +646,7 @@ void cmGhsMultiTargetGenerator::WriteObjectDir(
 | 
	
		
			
				|  |  |      workingDir += "/";
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    workingDir += "Objs";
 | 
	
		
			
				|  |  | -  *fileStream << "    -object_dir=\"" << workingDir << "\"" << std::endl;
 | 
	
		
			
				|  |  | +  fout << "    -object_dir=\"" << workingDir << "\"" << std::endl;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  std::string cmGhsMultiTargetGenerator::GetOutputDirectory(
 |