summaryrefslogtreecommitdiffstats
path: root/Source/cmGhsMultiTargetGenerator.cxx
diff options
context:
space:
mode:
authorGeoff Viola <geoffrey.viola@asirobots.com>2016-05-05 04:49:27 (GMT)
committerBrad King <brad.king@kitware.com>2016-05-06 12:21:05 (GMT)
commit5e4287131bc53824eac949dcc56a4cee9f6f907d (patch)
tree6dc819dfd41d4d80688fbd4bcb5764571514bc81 /Source/cmGhsMultiTargetGenerator.cxx
parent8d7ef6a8b02f2fca4ccb9aaad71ca0d2235ce8a6 (diff)
downloadCMake-5e4287131bc53824eac949dcc56a4cee9f6f907d.zip
CMake-5e4287131bc53824eac949dcc56a4cee9f6f907d.tar.gz
CMake-5e4287131bc53824eac949dcc56a4cee9f6f907d.tar.bz2
GHS: Shorten long object paths with duplicate source names
Detect when the resulting object path is too long and compute an alternative name using a hash.
Diffstat (limited to 'Source/cmGhsMultiTargetGenerator.cxx')
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx91
1 files changed, 70 insertions, 21 deletions
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index f845c59..4ca59cb 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -114,7 +114,7 @@ cmGhsMultiTargetGenerator::AddSlashIfNeededToPath(std::string const &input)
void cmGhsMultiTargetGenerator::Generate()
{
- const std::vector<cmSourceFile *> objectSources = this->GetSources();
+ std::vector<cmSourceFile *> objectSources = this->GetSources();
if (!objectSources.empty() && this->IncludeThisTarget())
{
if (!cmSystemTools::FileExists(this->AbsBuildFilePath.c_str()))
@@ -154,7 +154,11 @@ void cmGhsMultiTargetGenerator::Generate()
}
this->WriteCustomCommands();
- this->WriteSources(objectSources);
+ std::map<const cmSourceFile *, std::string> objectNames =
+ cmGhsMultiTargetGenerator::GetObjectNames(
+ &objectSources, this->LocalGenerator, this->GeneratorTarget);
+
+ this->WriteSources(objectSources, objectNames);
}
}
@@ -484,44 +488,65 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
std::map<const cmSourceFile *, std::string>
cmGhsMultiTargetGenerator::GetObjectNames(
- const std::vector<cmSourceFile *> &objectSources)
+ std::vector<cmSourceFile *> *const objectSources,
+ cmLocalGhsMultiGenerator *const localGhsMultiGenerator,
+ cmGeneratorTarget *const generatorTarget)
{
- bool found_duplicate = false;
- std::set<std::string> filenames;
+ std::map<std::string, std::vector<cmSourceFile *> > filenameToSource;
+ std::map<cmSourceFile *, std::string> sourceToFilename;
for(std::vector<cmSourceFile *>::const_iterator
- sf = objectSources.begin(); sf != objectSources.end(); ++sf)
+ sf = objectSources->begin(); sf != objectSources->end(); ++sf)
{
const std::string filename =
cmSystemTools::GetFilenameName((*sf)->GetFullPath());
const std::string lower_filename = cmSystemTools::LowerCase(filename);
- if (filenames.end() != filenames.find(lower_filename))
+ filenameToSource[lower_filename].push_back(*sf);
+ sourceToFilename[*sf] = lower_filename;
+ }
+
+ std::vector<cmSourceFile *> duplicateSources;
+ for (std::map<std::string, std::vector<cmSourceFile *> >::const_iterator
+ msvSourceI = filenameToSource.begin();
+ msvSourceI != filenameToSource.end(); ++msvSourceI)
+ {
+ if (msvSourceI->second.size() > 1)
{
- found_duplicate = true;
+ duplicateSources.insert(duplicateSources.end(),
+ msvSourceI->second.begin(),
+ msvSourceI->second.end());
}
- filenames.insert(lower_filename);
}
- std::map<const cmSourceFile *, std::string> objectNames;
- if (found_duplicate)
+ std::map<const cmSourceFile *, std::string> objectNamesCorrected;
+
+ for (std::vector<cmSourceFile *>::const_iterator sf =
+ duplicateSources.begin();
+ sf != duplicateSources.end(); ++sf)
{
- for(std::vector<cmSourceFile *>::const_iterator
- sf = objectSources.begin(); sf != objectSources.end(); ++sf)
+ static std::string::size_type const MAX_FULL_PATH_LENGTH = 247;
+ std::string const longestObjectDirectory(
+ cmGhsMultiTargetGenerator::ComputeLongestObjectDirectory(
+ localGhsMultiGenerator, generatorTarget, *sf));
+ std::string fullFilename = (*sf)->GetFullPath();
+ bool const ObjPathFound = cmLocalGeneratorCheckObjectName(
+ fullFilename, longestObjectDirectory.size(), MAX_FULL_PATH_LENGTH);
+ if (!ObjPathFound)
{
- std::string full_filename = (*sf)->GetFullPath();
- cmsys::SystemTools::ReplaceString(full_filename, ":/", "_");
- cmsys::SystemTools::ReplaceString(full_filename, "/", "_");
- objectNames[*sf] = full_filename;
+ cmSystemTools::Error("Object path \"", fullFilename.c_str(),
+ "\" too long", "");
}
+ cmsys::SystemTools::ReplaceString(fullFilename, ":/", "_");
+ cmsys::SystemTools::ReplaceString(fullFilename, "/", "_");
+ objectNamesCorrected[*sf] = fullFilename;
}
- return objectNames;
+ return objectNamesCorrected;
}
void cmGhsMultiTargetGenerator::WriteSources(
- std::vector<cmSourceFile *> const &objectSources)
+ std::vector<cmSourceFile *> const &objectSources,
+ std::map<const cmSourceFile *, std::string> const &objectNames)
{
- std::map<const cmSourceFile *, std::string> objectNames =
- cmGhsMultiTargetGenerator::GetObjectNames(objectSources);
for (std::vector<cmSourceFile *>::const_iterator si = objectSources.begin();
si != objectSources.end(); ++si)
{
@@ -646,6 +671,30 @@ cmGhsMultiTargetGenerator::GetOutputFilename(const std::string &config) const
return outputFilename;
}
+std::string cmGhsMultiTargetGenerator::ComputeLongestObjectDirectory(
+ cmLocalGhsMultiGenerator const *localGhsMultiGenerator,
+ cmGeneratorTarget *const generatorTarget, cmSourceFile *const sourceFile)
+{
+ std::string dir_max;
+ dir_max +=
+ localGhsMultiGenerator->GetMakefile()->GetCurrentBinaryDirectory();
+ dir_max += "/";
+ dir_max += generatorTarget->Target->GetName();
+ dir_max += "/";
+ std::vector<cmSourceGroup> sourceGroups(
+ localGhsMultiGenerator->GetMakefile()->GetSourceGroups());
+ char const *const sourceFullPath = sourceFile->GetFullPath().c_str();
+ cmSourceGroup *sourceGroup =
+ localGhsMultiGenerator->GetMakefile()->FindSourceGroup(sourceFullPath,
+ sourceGroups);
+ std::string const sgPath(sourceGroup->GetFullName());
+ dir_max += sgPath;
+ dir_max += "/Objs/libs/";
+ dir_max += generatorTarget->Target->GetName();
+ dir_max += "/";
+ return dir_max;
+}
+
bool cmGhsMultiTargetGenerator::IsNotKernel(std::string const &config,
const std::string &language)
{