diff options
author | Fred Baksik <frodak17@gmail.com> | 2019-01-05 16:01:21 (GMT) |
---|---|---|
committer | Fred Baksik <frodak17@gmail.com> | 2019-01-16 15:41:15 (GMT) |
commit | e7825386e2e9e69728e5a5c3dcbc94814bb7cb1c (patch) | |
tree | 0b5e2d72d945a19acd4db7d68a10ae4c7d6d64e7 | |
parent | 447b57a2676b5bb7e9f97b15c9fe5fe7d3817a86 (diff) | |
download | CMake-e7825386e2e9e69728e5a5c3dcbc94814bb7cb1c.zip CMake-e7825386e2e9e69728e5a5c3dcbc94814bb7cb1c.tar.gz CMake-e7825386e2e9e69728e5a5c3dcbc94814bb7cb1c.tar.bz2 |
GHS: Cleanup how source files are listed
-- Sort the items of the project files, previously they were unsorted
The layout is similar to Visual Studio projects
-- Do not make a make a tree of directories and projects files
The main project file is in the binary folder
The sub-project files are located in the project object directory
This is similar to the Makefile generator
-- Allow the creation of a single project file
If the variable or target property GHS_NO_SOURCE_GROUP_FILE is set
then all sources will be listed in the main project file
-rw-r--r-- | Source/cmGhsMultiTargetGenerator.cxx | 187 | ||||
-rw-r--r-- | Source/cmGhsMultiTargetGenerator.h | 7 | ||||
-rw-r--r-- | Tests/CMakeLists.txt | 3 | ||||
-rw-r--r-- | Tests/GhsMulti/GhsMultiSrcGroups/CMakeLists.txt | 3 |
4 files changed, 152 insertions, 48 deletions
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 20f3f9e..4fcc63d 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -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( diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h index a80d6b2..a54901d 100644 --- a/Source/cmGhsMultiTargetGenerator.h +++ b/Source/cmGhsMultiTargetGenerator.h @@ -80,17 +80,14 @@ private: void WriteCustomCommandsHelper( std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet, cmTarget::CustomCommandType commandType); - void WriteSources( - std::vector<cmSourceFile*> const& objectSources, - std::map<const cmSourceFile*, std::string> const& objectNames); + void WriteSources(std::ostream& fout_proj); static std::map<const cmSourceFile*, std::string> GetObjectNames( std::vector<cmSourceFile*>* objectSources, cmLocalGhsMultiGenerator* localGhsMultiGenerator, cmGeneratorTarget* generatorTarget); static void WriteObjectLangOverride(std::ostream* fout, const cmSourceFile* sourceFile); - static void WriteObjectDir(cmGeneratedFileStream* fileStream, - std::string const& dir); + static void WriteObjectDir(std::ostream& fout, std::string const& dir); std::string GetOutputDirectory(const std::string& config) const; std::string GetOutputFilename(const std::string& config) const; static std::string ComputeLongestObjectDirectory( diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 1bdb6f3..f06bfbf 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2298,7 +2298,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_test_GhsMulti_rename_install(SINGLE_EXEC_RENAMED) add_test_GhsMulti_rename_install(EXEC_AND_LIB) add_test_GhsMulti(multiple_source_groups GhsMultiSrcGroups Default "" "") - add_test_GhsMulti(multiple_source_groups_folders GhsMultiSrcGroups Folders "-DCMAKE_FOLDER=ON" "") + add_test_GhsMulti(multiple_source_groups_folders GhsMultiSrcGroups PropFolders "-DTEST_PROP=ON" "") + add_test_GhsMulti(multiple_source_groups_all_folders GhsMultiSrcGroups AllFolders "-DGHS_NO_SOURCE_GROUP_FILE=ON" "") add_test_GhsMulti(unsupported_targets GhsMultiUnsupportedTargets "" "" "") set_tests_properties(GhsMulti.${ghs_config_name}.unsupported_targets PROPERTIES TIMEOUT 15) add_test_GhsMulti(object_library GhsMultiObjectLibrary "" "" "") diff --git a/Tests/GhsMulti/GhsMultiSrcGroups/CMakeLists.txt b/Tests/GhsMulti/GhsMultiSrcGroups/CMakeLists.txt index 5043e7f..a4f84ca 100644 --- a/Tests/GhsMulti/GhsMultiSrcGroups/CMakeLists.txt +++ b/Tests/GhsMulti/GhsMultiSrcGroups/CMakeLists.txt @@ -32,6 +32,9 @@ add_executable(groups standard.h ) +if(TEST_PROP) + set_target_properties(groups PROPERTIES GHS_NO_SOURCE_GROUP_FILE ON) +endif() source_group( gC FILES sub/testOBJ.h testOBJ.c testOBJ.h sub/testOBJ.c ) source_group( gA FILES test1.c test1.h) source_group( gB test[65].c ) |