diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index f845c5975..4ca59cb61 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 objectSources = this->GetSources(); + std::vector 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 objectNames = + cmGhsMultiTargetGenerator::GetObjectNames( + &objectSources, this->LocalGenerator, this->GeneratorTarget); + + this->WriteSources(objectSources, objectNames); } } @@ -484,44 +488,65 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper( std::map cmGhsMultiTargetGenerator::GetObjectNames( - const std::vector &objectSources) + std::vector *const objectSources, + cmLocalGhsMultiGenerator *const localGhsMultiGenerator, + cmGeneratorTarget *const generatorTarget) { - bool found_duplicate = false; - std::set filenames; + std::map > filenameToSource; + std::map sourceToFilename; for(std::vector::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 objectNames; - if (found_duplicate) + std::vector duplicateSources; + for (std::map >::const_iterator + msvSourceI = filenameToSource.begin(); + msvSourceI != filenameToSource.end(); ++msvSourceI) { - for(std::vector::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 objectNamesCorrected; + + for (std::vector::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 const &objectSources) + std::vector const &objectSources, + std::map const &objectNames) { - std::map objectNames = - cmGhsMultiTargetGenerator::GetObjectNames(objectSources); for (std::vector::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 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) { diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h index 93761f2d9..9f18eeb8f 100644 --- a/Source/cmGhsMultiTargetGenerator.h +++ b/Source/cmGhsMultiTargetGenerator.h @@ -87,15 +87,22 @@ private: void WriteCustomCommandsHelper(std::vector const &commandsSet, cmTarget::CustomCommandType commandType); - void WriteSources(std::vector const &objectSources); + void WriteSources( + std::vector const &objectSources, + std::map const &objectNames); static std::map - GetObjectNames(const std::vector &objectSources); + GetObjectNames(std::vector *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); diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 6c2ba0523..6db18f74a 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -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) diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 0bad0d693..33db68c74 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -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