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.
This commit is contained in:
Geoff Viola 2016-05-04 22:49:27 -06:00 committed by Brad King
parent 8d7ef6a8b0
commit 5e4287131b
4 changed files with 87 additions and 26 deletions

View File

@ -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))
{
found_duplicate = true;
}
filenames.insert(lower_filename);
filenameToSource[lower_filename].push_back(*sf);
sourceToFilename[*sf] = lower_filename;
}
std::map<const cmSourceFile *, std::string> objectNames;
if (found_duplicate)
std::vector<cmSourceFile *> duplicateSources;
for (std::map<std::string, std::vector<cmSourceFile *> >::const_iterator
msvSourceI = filenameToSource.begin();
msvSourceI != filenameToSource.end(); ++msvSourceI)
{
for(std::vector<cmSourceFile *>::const_iterator
sf = objectSources.begin(); sf != objectSources.end(); ++sf)
if (msvSourceI->second.size() > 1)
{
std::string full_filename = (*sf)->GetFullPath();
cmsys::SystemTools::ReplaceString(full_filename, ":/", "_");
cmsys::SystemTools::ReplaceString(full_filename, "/", "_");
objectNames[*sf] = full_filename;
duplicateSources.insert(duplicateSources.end(),
msvSourceI->second.begin(),
msvSourceI->second.end());
}
}
return objectNames;
std::map<const cmSourceFile *, std::string> objectNamesCorrected;
for (std::vector<cmSourceFile *>::const_iterator sf =
duplicateSources.begin();
sf != duplicateSources.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)
{
cmSystemTools::Error("Object path \"", fullFilename.c_str(),
"\" too long", "");
}
cmsys::SystemTools::ReplaceString(fullFilename, ":/", "_");
cmsys::SystemTools::ReplaceString(fullFilename, "/", "_");
objectNamesCorrected[*sf] = fullFilename;
}
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)
{

View File

@ -87,15 +87,22 @@ private:
void
WriteCustomCommandsHelper(std::vector<cmCustomCommand> const &commandsSet,
cmTarget::CustomCommandType commandType);
void WriteSources(std::vector<cmSourceFile *> const &objectSources);
void WriteSources(
std::vector<cmSourceFile *> const &objectSources,
std::map<const cmSourceFile *, std::string> const &objectNames);
static std::map<const cmSourceFile *, std::string>
GetObjectNames(const std::vector<cmSourceFile *> &objectSources);
GetObjectNames(std::vector<cmSourceFile *> *objectSources,
cmLocalGhsMultiGenerator *localGhsMultiGenerator,
cmGeneratorTarget *generatorTarget);
static void WriteObjectLangOverride(cmGeneratedFileStream *fileStream,
cmSourceFile *sourceFile);
static void WriteObjectDir(cmGeneratedFileStream *fileStream,
std::string const &dir);
std::string GetOutputDirectory(const std::string &config) const;
std::string GetOutputFilename(const std::string &config) const;
static std::string ComputeLongestObjectDirectory(
cmLocalGhsMultiGenerator const *localGhsMultiGenerator,
cmGeneratorTarget *generatorTarget, cmSourceFile *const sourceFile);
bool IsNotKernel(std::string const &config, const std::string &language);
static bool DetermineIfTargetGroup(const cmGeneratorTarget* target);

View File

@ -2667,7 +2667,6 @@ cmLocalGeneratorShortenObjectName(std::string& objName,
}
}
static
bool cmLocalGeneratorCheckObjectName(std::string& objName,
std::string::size_type dir_len,
std::string::size_type max_total_len)

View File

@ -404,4 +404,10 @@ private:
void ComputeObjectMaxPath();
};
#if defined(CMAKE_BUILD_WITH_CMAKE)
bool cmLocalGeneratorCheckObjectName(std::string &objName,
std::string::size_type dir_len,
std::string::size_type max_total_len);
#endif
#endif