summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2006-07-11 15:41:38 (GMT)
committerBrad King <brad.king@kitware.com>2006-07-11 15:41:38 (GMT)
commit9bf5af6e32570195b06df594c1cb07f8c7a6a83e (patch)
treead72b8722793ae974c26b9b2138547f3cab62aae /Source
parentc05b8fb993a4e92fded0d735a66063bb8b265630 (diff)
downloadCMake-9bf5af6e32570195b06df594c1cb07f8c7a6a83e.zip
CMake-9bf5af6e32570195b06df594c1cb07f8c7a6a83e.tar.gz
CMake-9bf5af6e32570195b06df594c1cb07f8c7a6a83e.tar.bz2
ENH: Moved unique object file name computation from cmLocalUnixMakefileGenerator3 up to cmLocalGenerator for use by all generators. Created cmLocalVisualStudioGenerator as superclass for all VS generators. Implemented on-demand unique object file name computation for VS 7 generator to avoid slow compiles when all sources are in subdirectories.
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt2
-rw-r--r--Source/cmLocalGenerator.cxx117
-rw-r--r--Source/cmLocalGenerator.h5
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx118
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.h2
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx10
-rw-r--r--Source/cmLocalVisualStudio7Generator.h10
-rw-r--r--Source/cmLocalVisualStudioGenerator.cxx89
-rw-r--r--Source/cmLocalVisualStudioGenerator.h43
9 files changed, 270 insertions, 126 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 35f4fcf..ff49466 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -205,6 +205,8 @@ IF (WIN32)
cmLocalVisualStudio6Generator.h
cmLocalVisualStudio7Generator.cxx
cmLocalVisualStudio7Generator.h
+ cmLocalVisualStudioGenerator.cxx
+ cmLocalVisualStudioGenerator.h
cmWin32ProcessExecution.cxx
cmWin32ProcessExecution.h
)
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index a73fbce..e604320 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -2081,3 +2081,120 @@ cmLocalGenerator
}
}
}
+
+//----------------------------------------------------------------------------
+std::string& cmLocalGenerator::CreateSafeUniqueObjectFileName(const char* sin)
+{
+ // Look for an existing mapped name for this object file.
+ std::map<cmStdString,cmStdString>::iterator it =
+ this->UniqueObjectNamesMap.find(sin);
+
+ // If no entry exists create one.
+ if(it == this->UniqueObjectNamesMap.end())
+ {
+ // Start with the original name.
+ std::string ssin = sin;
+
+ // Avoid full paths by removing leading slashes.
+ std::string::size_type pos = 0;
+ for(;pos < ssin.size() && ssin[pos] == '/'; ++pos);
+ ssin = ssin.substr(pos);
+
+ // Avoid full paths by removing colons.
+ cmSystemTools::ReplaceString(ssin, ":", "_");
+
+ // Avoid relative paths that go up the tree.
+ cmSystemTools::ReplaceString(ssin, "../", "__/");
+
+ // Avoid spaces.
+ cmSystemTools::ReplaceString(ssin, " ", "_");
+
+ // Mangle the name if necessary.
+ if(this->Makefile->IsOn("CMAKE_MANGLE_OBJECT_FILE_NAMES"))
+ {
+ bool done;
+ int cc = 0;
+ char rpstr[100];
+ sprintf(rpstr, "_p_");
+ cmSystemTools::ReplaceString(ssin, "+", rpstr);
+ std::string sssin = sin;
+ do
+ {
+ done = true;
+ for ( it = this->UniqueObjectNamesMap.begin();
+ it != this->UniqueObjectNamesMap.end();
+ ++ it )
+ {
+ if ( it->second == ssin )
+ {
+ done = false;
+ }
+ }
+ if ( done )
+ {
+ break;
+ }
+ sssin = ssin;
+ cmSystemTools::ReplaceString(ssin, "_p_", rpstr);
+ sprintf(rpstr, "_p%d_", cc++);
+ }
+ while ( !done );
+ }
+
+ // Insert the newly mapped object file name.
+ std::map<cmStdString, cmStdString>::value_type e(sin, ssin);
+ it = this->UniqueObjectNamesMap.insert(e).first;
+ }
+
+ // Return the map entry.
+ return it->second;
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalGenerator::GetObjectFileNameWithoutTarget(const cmSourceFile& source)
+{
+ // If the source file is located below the current binary directory
+ // then use that relative path for the object file name.
+ std::string objectName = this->Convert(source.GetFullPath().c_str(),
+ START_OUTPUT);
+ if(cmSystemTools::FileIsFullPath(objectName.c_str()) ||
+ objectName.empty() || objectName[0] == '.')
+ {
+ // If the source file is located below the current source
+ // directory then use that relative path for the object file name.
+ // Otherwise just use the relative path from the current binary
+ // directory.
+ std::string relFromSource = this->Convert(source.GetFullPath().c_str(),
+ START);
+ if(!cmSystemTools::FileIsFullPath(relFromSource.c_str()) &&
+ !relFromSource.empty() && relFromSource[0] != '.')
+ {
+ objectName = relFromSource;
+ }
+ }
+
+ // Replace the original source file extension with the object file
+ // extension.
+ std::string::size_type dot_pos = objectName.rfind(".");
+ if(dot_pos != std::string::npos)
+ {
+ objectName = objectName.substr(0, dot_pos);
+ }
+ if ( source.GetPropertyAsBool("KEEP_EXTENSION") )
+ {
+ if ( !source.GetSourceExtension().empty() )
+ {
+ objectName += "." + source.GetSourceExtension();
+ }
+ }
+ else
+ {
+ objectName +=
+ this->GlobalGenerator->GetLanguageOutputExtensionFromExtension(
+ source.GetSourceExtension().c_str());
+ }
+
+ // Convert to a safe name.
+ return this->CreateSafeUniqueObjectFileName(objectName.c_str());
+}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 6e4c60e..49bae5b 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -254,6 +254,10 @@ protected:
std::ostream& os, const char* config,
std::vector<std::string> const& configurationTypes);
+ // Compute object file names.
+ std::string GetObjectFileNameWithoutTarget(const cmSourceFile& source);
+ std::string& CreateSafeUniqueObjectFileName(const char* sin);
+
cmMakefile *Makefile;
cmGlobalGenerator *GlobalGenerator;
// members used for relative path function ConvertToMakefilePath
@@ -267,6 +271,7 @@ protected:
cmLocalGenerator* Parent;
std::vector<cmLocalGenerator*> Children;
std::map<cmStdString, cmStdString> LanguageToIncludeFlags;
+ std::map<cmStdString, cmStdString> UniqueObjectNamesMap;
bool WindowsShell;
bool ForceUnixPath;
bool UseRelativePaths;
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index dca1669..2252c16 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1062,75 +1062,6 @@ std::string cmLocalUnixMakefileGenerator3
}
//----------------------------------------------------------------------------
-std::string&
-cmLocalUnixMakefileGenerator3::CreateSafeUniqueObjectFileName(const char* sin)
-{
- // Look for an existing mapped name for this object file.
- std::map<cmStdString,cmStdString>::iterator it =
- this->UniqueObjectNamesMap.find(sin);
-
- // If no entry exists create one.
- if(it == this->UniqueObjectNamesMap.end())
- {
- // Start with the original name.
- std::string ssin = sin;
-
- // Avoid full paths by removing leading slashes.
- std::string::size_type pos = 0;
- for(;pos < ssin.size() && ssin[pos] == '/'; ++pos);
- ssin = ssin.substr(pos);
-
- // Avoid full paths by removing colons.
- cmSystemTools::ReplaceString(ssin, ":", "_");
-
- // Avoid relative paths that go up the tree.
- cmSystemTools::ReplaceString(ssin, "../", "__/");
-
- // Avoid spaces.
- cmSystemTools::ReplaceString(ssin, " ", "_");
-
- // Mangle the name if necessary.
- if(this->Makefile->IsOn("CMAKE_MANGLE_OBJECT_FILE_NAMES"))
- {
- bool done;
- int cc = 0;
- char rpstr[100];
- sprintf(rpstr, "_p_");
- cmSystemTools::ReplaceString(ssin, "+", rpstr);
- std::string sssin = sin;
- do
- {
- done = true;
- for ( it = this->UniqueObjectNamesMap.begin();
- it != this->UniqueObjectNamesMap.end();
- ++ it )
- {
- if ( it->second == ssin )
- {
- done = false;
- }
- }
- if ( done )
- {
- break;
- }
- sssin = ssin;
- cmSystemTools::ReplaceString(ssin, "_p_", rpstr);
- sprintf(rpstr, "_p%d_", cc++);
- }
- while ( !done );
- }
-
- // Insert the newly mapped object file name.
- std::map<cmStdString, cmStdString>::value_type e(sin, ssin);
- it = this->UniqueObjectNamesMap.insert(e).first;
- }
-
- // Return the map entry.
- return it->second;
-}
-
-//----------------------------------------------------------------------------
std::string
cmLocalUnixMakefileGenerator3
::CreateMakeVariable(const char* sin, const char* s2in)
@@ -1707,50 +1638,13 @@ cmLocalUnixMakefileGenerator3
const cmSourceFile& source,
std::string* nameWithoutTargetDir)
{
- // If the source file is located below the current binary directory
- // then use that relative path for the object file name.
- std::string objectName = this->Convert(source.GetFullPath().c_str(),
- START_OUTPUT);
- if(cmSystemTools::FileIsFullPath(objectName.c_str()) ||
- objectName.empty() || objectName[0] == '.')
- {
- // If the source file is located below the current source
- // directory then use that relative path for the object file name.
- // Otherwise just use the relative path from the current binary
- // directory.
- std::string relFromSource = this->Convert(source.GetFullPath().c_str(),
- START);
- if(!cmSystemTools::FileIsFullPath(relFromSource.c_str()) &&
- !relFromSource.empty() && relFromSource[0] != '.')
- {
- objectName = relFromSource;
- }
- }
-
- // Replace the original source file extension with the object file
- // extension.
- std::string::size_type dot_pos = objectName.rfind(".");
- if(dot_pos != std::string::npos)
- {
- objectName = objectName.substr(0, dot_pos);
- }
- if ( source.GetPropertyAsBool("KEEP_EXTENSION") )
- {
- if ( !source.GetSourceExtension().empty() )
- {
- objectName += "." + source.GetSourceExtension();
- }
- }
- else
+ // Get the object file name independent of target.
+ std::string objectName = this->GetObjectFileNameWithoutTarget(source);
+ if(nameWithoutTargetDir)
{
- objectName +=
- this->GlobalGenerator->GetLanguageOutputExtensionFromExtension(
- source.GetSourceExtension().c_str());
+ *nameWithoutTargetDir = objectName;
}
- // Convert to a safe name.
- objectName = this->CreateSafeUniqueObjectFileName(objectName.c_str());
-
// Prepend the target directory.
std::string obj;
const char* fileTargetDirectory =
@@ -1788,10 +1682,6 @@ cmLocalUnixMakefileGenerator3
}
obj += "/";
obj += objectName;
- if(nameWithoutTargetDir)
- {
- *nameWithoutTargetDir = objectName;
- }
return obj;
}
diff --git a/Source/cmLocalUnixMakefileGenerator3.h b/Source/cmLocalUnixMakefileGenerator3.h
index cae19a3..5674790 100644
--- a/Source/cmLocalUnixMakefileGenerator3.h
+++ b/Source/cmLocalUnixMakefileGenerator3.h
@@ -168,7 +168,6 @@ public:
static std::string ConvertToQuotedOutputPath(const char* p);
- std::string& CreateSafeUniqueObjectFileName(const char* sin);
std::string CreateMakeVariable(const char* sin, const char* s2in);
// cleanup the name of a potential target
@@ -326,7 +325,6 @@ private:
std::vector<cmMakefileTargetGenerator *> TargetGenerators;
std::map<cmStdString, cmStdString> MakeVariableMap;
std::map<cmStdString, cmStdString> ShortMakeVariableMap;
- std::map<cmStdString, cmStdString> UniqueObjectNamesMap;
};
#endif
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index c755dfb..4466e8d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -1012,6 +1012,9 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
sourceGroup.AssignSource(*i);
}
+ // Compute which sources need unique object computation.
+ this->ComputeObjectNameRequirements(sourceGroups);
+
// open the project
this->WriteProjectStart(fout, libName, target, sourceGroups);
// write the configuration information
@@ -1064,12 +1067,9 @@ void cmLocalVisualStudio7Generator
const cmCustomCommand *command = (*sf)->GetCustomCommand();
std::string compileFlags;
std::string additionalDeps;
- objectName = (*sf)->GetSourceName();
- if(!(*sf)->GetPropertyAsBool("HEADER_FILE_ONLY" )
- && objectName.find("/") != objectName.npos)
+ if(this->NeedObjectName.find(*sf) != this->NeedObjectName.end())
{
- cmSystemTools::ReplaceString(objectName, "/", "_");
- objectName += ".obj";
+ objectName = this->GetObjectFileNameWithoutTarget(*(*sf));
}
else
{
diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h
index 22d5d0b..ad81085 100644
--- a/Source/cmLocalVisualStudio7Generator.h
+++ b/Source/cmLocalVisualStudio7Generator.h
@@ -17,7 +17,7 @@
#ifndef cmLocalVisualStudio7Generator_h
#define cmLocalVisualStudio7Generator_h
-#include "cmLocalGenerator.h"
+#include "cmLocalVisualStudioGenerator.h"
class cmMakeDepend;
class cmTarget;
@@ -27,12 +27,12 @@ class cmSourceGroup;
struct cmVS7FlagTable;
/** \class cmLocalVisualStudio7Generator
- * \brief Write a LocalUnix makefiles.
+ * \brief Write Visual Studio .NET project files.
*
- * cmLocalVisualStudio7Generator produces a LocalUnix makefile from its
- * member Makefile.
+ * cmLocalVisualStudio7Generator produces a Visual Studio .NET project
+ * file for each target in its directory.
*/
-class cmLocalVisualStudio7Generator : public cmLocalGenerator
+class cmLocalVisualStudio7Generator : public cmLocalVisualStudioGenerator
{
public:
///! Set cache only and recurse to false by default.
diff --git a/Source/cmLocalVisualStudioGenerator.cxx b/Source/cmLocalVisualStudioGenerator.cxx
new file mode 100644
index 0000000..344fcc6
--- /dev/null
+++ b/Source/cmLocalVisualStudioGenerator.cxx
@@ -0,0 +1,89 @@
+/*=========================================================================
+
+ Program: CMake - Cross-Platform Makefile Generator
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
+ See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+#include "cmLocalVisualStudioGenerator.h"
+
+#include "cmMakefile.h"
+#include "cmSourceFile.h"
+#include "cmSystemTools.h"
+
+//----------------------------------------------------------------------------
+cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator()
+{
+}
+
+//----------------------------------------------------------------------------
+void
+cmLocalVisualStudioGenerator
+::ComputeObjectNameRequirements(std::vector<cmSourceGroup> const& sourceGroups)
+{
+ // Clear the current set of requirements.
+ this->NeedObjectName.clear();
+
+ // Count the number of object files with each name.
+ std::map<cmStdString, int> objectNameCounts;
+ for(unsigned int i = 0; i < sourceGroups.size(); ++i)
+ {
+ cmSourceGroup sg = sourceGroups[i];
+ std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles();
+ for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin();
+ s != srcs.end(); ++s)
+ {
+ const cmSourceFile& sf = *(*s);
+ if(!sf.GetCustomCommand() &&
+ !sf.GetPropertyAsBool("HEADER_FILE_ONLY") &&
+ !sf.GetPropertyAsBool("EXTERNAL_OBJECT"))
+ {
+ std::string objectName =
+ cmSystemTools::GetFilenameWithoutLastExtension(
+ sf.GetFullPath().c_str());
+ objectName += ".obj";
+ objectNameCounts[objectName] += 1;
+ }
+ }
+ }
+
+ // For all source files producing duplicate names we need unique
+ // object name computation.
+ for(unsigned int i = 0; i < sourceGroups.size(); ++i)
+ {
+ cmSourceGroup sg = sourceGroups[i];
+ std::vector<const cmSourceFile*> const& srcs = sg.GetSourceFiles();
+ for(std::vector<const cmSourceFile*>::const_iterator s = srcs.begin();
+ s != srcs.end(); ++s)
+ {
+ const cmSourceFile* sf = *s;
+ if(!sf->GetCustomCommand() &&
+ !sf->GetPropertyAsBool("HEADER_FILE_ONLY") &&
+ !sf->GetPropertyAsBool("EXTERNAL_OBJECT"))
+ {
+ std::string objectName =
+ cmSystemTools::GetFilenameWithoutLastExtension(
+ sf->GetFullPath().c_str());
+ objectName += ".obj";
+ if(objectNameCounts[objectName] > 1)
+ {
+ this->NeedObjectName.insert(sf);
+ }
+ }
+ }
+ }
+}
diff --git a/Source/cmLocalVisualStudioGenerator.h b/Source/cmLocalVisualStudioGenerator.h
new file mode 100644
index 0000000..6fe0034
--- /dev/null
+++ b/Source/cmLocalVisualStudioGenerator.h
@@ -0,0 +1,43 @@
+/*=========================================================================
+
+ Program: CMake - Cross-Platform Makefile Generator
+ Module: $RCSfile$
+ Language: C++
+ Date: $Date$
+ Version: $Revision$
+
+ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
+ See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef cmLocalVisualStudioGenerator_h
+#define cmLocalVisualStudioGenerator_h
+
+#include "cmLocalGenerator.h"
+
+class cmSourceFile;
+class cmSourceGroup;
+
+/** \class cmLocalVisualStudioGenerator
+ * \brief Base class for Visual Studio generators.
+ *
+ * cmLocalVisualStudioGenerator provides functionality common to all
+ * Visual Studio generators.
+ */
+class cmLocalVisualStudioGenerator : public cmLocalGenerator
+{
+public:
+ cmLocalVisualStudioGenerator();
+ virtual ~cmLocalVisualStudioGenerator();
+
+protected:
+ // Safe object file name generation.
+ void ComputeObjectNameRequirements(std::vector<cmSourceGroup> const&);
+ std::set<const cmSourceFile*> NeedObjectName;
+};
+
+#endif