summaryrefslogtreecommitdiffstats
path: root/Source/cmLocalUnixMakefileGenerator2.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2005-02-10 21:18:27 (GMT)
committerBrad King <brad.king@kitware.com>2005-02-10 21:18:27 (GMT)
commit6173dea153c2318e3a4ce7b4924e71543b03bc5f (patch)
treed9d522920f71124a7f363821bee2112a86f50c8a /Source/cmLocalUnixMakefileGenerator2.cxx
parent23276ca3a29a4a6a79b54d77a1ec5bfd8f0f381a (diff)
downloadCMake-6173dea153c2318e3a4ce7b4924e71543b03bc5f.zip
CMake-6173dea153c2318e3a4ce7b4924e71543b03bc5f.tar.gz
CMake-6173dea153c2318e3a4ce7b4924e71543b03bc5f.tar.bz2
ENH: Split cmLocalUnixMakefileGenerator2 away from cmLocalUnixMakefileGenerator to be a stand-alone generator.
Diffstat (limited to 'Source/cmLocalUnixMakefileGenerator2.cxx')
-rw-r--r--Source/cmLocalUnixMakefileGenerator2.cxx361
1 files changed, 342 insertions, 19 deletions
diff --git a/Source/cmLocalUnixMakefileGenerator2.cxx b/Source/cmLocalUnixMakefileGenerator2.cxx
index 8640182..a9e2d9f 100644
--- a/Source/cmLocalUnixMakefileGenerator2.cxx
+++ b/Source/cmLocalUnixMakefileGenerator2.cxx
@@ -35,13 +35,8 @@
#include <assert.h>
-// Quick-switch for generating old makefiles.
-#if 1
-# define CMLUMG_MAKEFILE_NAME "Makefile"
-#else
-# define CMLUMG_WRITE_OLD_MAKEFILE
-# define CMLUMG_MAKEFILE_NAME "Makefile2"
-#endif
+// TODO: Convert makefile name to a runtime switch.
+#define CMLUMG_MAKEFILE_NAME "Makefile"
// TODO: Add "help" target.
// TODO: Identify remaining relative path violations.
@@ -50,6 +45,12 @@
//----------------------------------------------------------------------------
cmLocalUnixMakefileGenerator2::cmLocalUnixMakefileGenerator2()
{
+ m_WindowsShell = false;
+ m_IncludeDirective = "include";
+ m_MakefileVariableSize = 0;
+ m_IgnoreLibPrefix = false;
+ m_PassMakeflags = false;
+ m_UseRelativePaths = false;
}
//----------------------------------------------------------------------------
@@ -70,10 +71,6 @@ void cmLocalUnixMakefileGenerator2::SetEmptyCommand(const char* cmd)
//----------------------------------------------------------------------------
void cmLocalUnixMakefileGenerator2::Generate(bool fromTheTop)
{
-#ifdef CMLUMG_WRITE_OLD_MAKEFILE
- // Generate old style for now.
- this->cmLocalUnixMakefileGenerator::Generate(fromTheTop);
-#else
// Make sure we never run a local generate.
if(!fromTheTop)
{
@@ -82,10 +79,8 @@ void cmLocalUnixMakefileGenerator2::Generate(bool fromTheTop)
return;
}
- // Handle EXECUTABLE_OUTPUT_PATH and LIBRARY_OUTPUT_PATH since
- // superclass generator is not called.
+ // Setup our configuration variables for this directory.
this->ConfigureOutputPaths();
-#endif
// Generate the rule files for each target.
const cmTargets& targets = m_Makefile->GetTargets();
@@ -1797,7 +1792,7 @@ cmLocalUnixMakefileGenerator2
std::string targetNameSO;
std::string targetNameReal;
std::string targetNameBase;
- this->GetLibraryNames(target.GetName(), target,
+ this->GetLibraryNames(target,
targetName, targetNameSO,
targetNameReal, targetNameBase);
@@ -2379,11 +2374,22 @@ cmLocalUnixMakefileGenerator2::ConvertToRelativeOutputPath(const char* p)
}
//----------------------------------------------------------------------------
-void
-cmLocalUnixMakefileGenerator2::ConfigureOutputPaths()
+void cmLocalUnixMakefileGenerator2::ConfigureOutputPaths()
{
- // Call superclass version first.
- this->cmLocalUnixMakefileGenerator::ConfigureOutputPaths();
+ // Save whether to use relative paths.
+ m_UseRelativePaths = m_Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
+
+ // Format the library and executable output paths.
+ if(const char* libOut = m_Makefile->GetDefinition("LIBRARY_OUTPUT_PATH"))
+ {
+ m_LibraryOutputPath = libOut;
+ this->FormatOutputPath(m_LibraryOutputPath, "LIBRARY");
+ }
+ if(const char* exeOut = m_Makefile->GetDefinition("EXECUTABLE_OUTPUT_PATH"))
+ {
+ m_ExecutableOutputPath = exeOut;
+ this->FormatOutputPath(m_ExecutableOutputPath, "EXECUTABLE");
+ }
// Setup fully collapsed paths.
m_CurrentOutputDirectory =
@@ -2433,6 +2439,37 @@ cmLocalUnixMakefileGenerator2::ConfigureOutputPaths()
}
//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator2::FormatOutputPath(std::string& path,
+ const char* name)
+{
+ if(!path.empty())
+ {
+ // Convert the output path to a full path in case it is
+ // specified as a relative path. Treat a relative path as
+ // relative to the current output directory for this makefile.
+ path =
+ cmSystemTools::CollapseFullPath(path.c_str(),
+ m_Makefile->GetStartOutputDirectory());
+
+ // Add a trailing slash for easy appending later.
+ if(path.empty() || path[path.size()-1] != '/')
+ {
+ path += "/";
+ }
+
+ // Make sure the output path exists on disk.
+ if(!cmSystemTools::MakeDirectory(path.c_str()))
+ {
+ cmSystemTools::Error("Error failed to create ",
+ name, "_OUTPUT_PATH directory:", path.c_str());
+ }
+
+ // Add this as a link directory automatically.
+ m_Makefile->AddLinkDirectory(path.c_str());
+ }
+}
+
+//----------------------------------------------------------------------------
bool cmLocalUnixMakefileGenerator2::ComparePath(const char* c1, const char* c2)
{
#if defined(_WIN32) || defined(__APPLE__)
@@ -2683,6 +2720,292 @@ cmLocalUnixMakefileGenerator2
}
}
+//============================================================================
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator2::OutputEcho(std::ostream& fout,
+ const char* msg)
+{
+ std::string echostring = msg;
+ // For UNIX we want to quote the output of echo.
+ // For NMake and Borland, the echo should not be quoted.
+ if(strcmp(m_GlobalGenerator->GetName(), "Unix Makefiles") == 0)
+ {
+ cmSystemTools::ReplaceString(echostring, "\\\n", " ");
+ cmSystemTools::ReplaceString(echostring, " \t", " ");
+ cmSystemTools::ReplaceString(echostring, "\n\t", "\"\n\t@echo \"");
+ fout << "\t@echo \"" << echostring.c_str() << "\"\n";
+ }
+ else
+ {
+ cmSystemTools::ReplaceString(echostring, "\n\t", "\n\t@echo ");
+ fout << "\t@echo " << echostring.c_str() << "\n";
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+cmLocalUnixMakefileGenerator2::SamePath(const char* path1, const char* path2)
+{
+ if (strcmp(path1, path2) == 0)
+ {
+ return true;
+ }
+#if defined(_WIN32) || defined(__APPLE__)
+ return
+ (cmSystemTools::LowerCase(this->ConvertToOutputForExisting(path1)) ==
+ cmSystemTools::LowerCase(this->ConvertToOutputForExisting(path2)));
+#else
+ return false;
+#endif
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator2::GetBaseTargetName(const cmTarget& t)
+{
+ std::string pathPrefix = "";
+#ifdef __APPLE__
+ if ( t.GetPropertyAsBool("MACOSX_BUNDLE") )
+ {
+ pathPrefix = t.GetName();
+ pathPrefix += ".app/Contents/MacOS/";
+ }
+#endif
+
+ const char* targetPrefix = t.GetProperty("PREFIX");
+ const char* prefixVar = t.GetPrefixVariable();
+ // if there is no prefix on the target use the cmake definition
+ if(!targetPrefix && prefixVar)
+ {
+ // first check for a language specific suffix var
+ const char* ll = t.GetLinkerLanguage(this->GetGlobalGenerator());
+ if(ll)
+ {
+ std::string langPrefix = prefixVar + std::string("_") + ll;
+ targetPrefix = m_Makefile->GetDefinition(langPrefix.c_str());
+ }
+ // if there not a language specific suffix then use the general one
+ if(!targetPrefix)
+ {
+ targetPrefix = m_Makefile->GetSafeDefinition(prefixVar);
+ }
+ }
+ std::string name = pathPrefix + (targetPrefix?targetPrefix:"");
+ name += t.GetName();
+ return name;
+}
+
+//----------------------------------------------------------------------------
+void cmLocalUnixMakefileGenerator2::GetLibraryNames(const cmTarget& t,
+ std::string& name,
+ std::string& soName,
+ std::string& realName,
+ std::string& baseName)
+{
+ // Check for library version properties.
+ const char* version = t.GetProperty("VERSION");
+ const char* soversion = t.GetProperty("SOVERSION");
+ if((t.GetType() != cmTarget::SHARED_LIBRARY &&
+ t.GetType() != cmTarget::MODULE_LIBRARY) ||
+ !m_Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_SONAME_C_FLAG"))
+ {
+ // Versioning is supported only for shared libraries and modules,
+ // and then only when the platform supports an soname flag.
+ version = 0;
+ soversion = 0;
+ }
+ if(version && !soversion)
+ {
+ // The soversion must be set if the library version is set. Use
+ // the library version as the soversion.
+ soversion = version;
+ }
+
+ // The library name.
+ name = this->GetFullTargetName(t.GetName(), t);
+
+ // The library's soname.
+ soName = name;
+ if(soversion)
+ {
+ soName += ".";
+ soName += soversion;
+ }
+
+ // The library's real name on disk.
+ realName = name;
+ if(version)
+ {
+ realName += ".";
+ realName += version;
+ }
+ else if(soversion)
+ {
+ realName += ".";
+ realName += soversion;
+ }
+
+ // The library name without extension.
+ baseName = this->GetBaseTargetName(t);
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator2
+::ConvertToMakeTarget(const char* tgt)
+{
+ // Make targets should not have a leading './' for a file in the
+ // directory containing the makefile.
+ std::string ret = tgt;
+ if(ret.size() > 2 &&
+ (ret[0] == '.') &&
+ ( (ret[1] == '/') || ret[1] == '\\'))
+ {
+ std::string upath = ret;
+ cmSystemTools::ConvertToUnixSlashes(upath);
+ if(upath.find(2, '/') == upath.npos)
+ {
+ ret = ret.substr(2, ret.size()-2);
+ }
+ }
+ return ret;
+}
+
+//----------------------------------------------------------------------------
+std::string&
+cmLocalUnixMakefileGenerator2::CreateSafeUniqueObjectFileName(const char* sin)
+{
+ if ( m_Makefile->IsOn("CMAKE_MANGLE_OBJECT_FILE_NAMES") )
+ {
+ std::map<cmStdString,cmStdString>::iterator it = m_UniqueObjectNamesMap.find(sin);
+ if ( it == m_UniqueObjectNamesMap.end() )
+ {
+ std::string ssin = sin;
+ bool done;
+ int cc = 0;
+ char rpstr[100];
+ sprintf(rpstr, "_p_");
+ cmSystemTools::ReplaceString(ssin, "+", rpstr);
+ std::string sssin = sin;
+ do
+ {
+ done = true;
+ for ( it = m_UniqueObjectNamesMap.begin();
+ it != m_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 );
+ m_UniqueObjectNamesMap[sin] = ssin;
+ }
+ }
+ else
+ {
+ m_UniqueObjectNamesMap[sin] = sin;
+ }
+ return m_UniqueObjectNamesMap[sin];
+}
+
+//----------------------------------------------------------------------------
+std::string
+cmLocalUnixMakefileGenerator2
+::CreateMakeVariable(const char* sin, const char* s2in)
+{
+ std::string s = sin;
+ std::string s2 = s2in;
+ std::string unmodified = s;
+ unmodified += s2;
+ // if there is no restriction on the length of make variables
+ // and there are no "." charactors in the string, then return the
+ // unmodified combination.
+ if(!m_MakefileVariableSize && unmodified.find('.') == s.npos)
+ {
+ return unmodified;
+ }
+
+ // see if the variable has been defined before and return
+ // the modified version of the variable
+ std::map<cmStdString, cmStdString>::iterator i = m_MakeVariableMap.find(unmodified);
+ if(i != m_MakeVariableMap.end())
+ {
+ return i->second;
+ }
+ // start with the unmodified variable
+ std::string ret = unmodified;
+ // if this there is no value for m_MakefileVariableSize then
+ // the string must have bad characters in it
+ if(!m_MakefileVariableSize)
+ {
+ cmSystemTools::ReplaceString(ret, ".", "_");
+ int ni = 0;
+ char buffer[5];
+ // make sure the _ version is not already used, if
+ // it is used then add number to the end of the variable
+ while(m_ShortMakeVariableMap.count(ret) && ni < 1000)
+ {
+ ++ni;
+ sprintf(buffer, "%04d", ni);
+ ret = unmodified + buffer;
+ }
+ m_ShortMakeVariableMap[ret] = "1";
+ m_MakeVariableMap[unmodified] = ret;
+ return ret;
+ }
+
+ // if the string is greater the 32 chars it is an invalid vairable name
+ // for borland make
+ if(static_cast<int>(ret.size()) > m_MakefileVariableSize)
+ {
+ int keep = m_MakefileVariableSize - 8;
+ int size = keep + 3;
+ std::string str1 = s;
+ std::string str2 = s2;
+ // we must shorten the combined string by 4 charactors
+ // keep no more than 24 charactors from the second string
+ if(static_cast<int>(str2.size()) > keep)
+ {
+ str2 = str2.substr(0, keep);
+ }
+ if(static_cast<int>(str1.size()) + static_cast<int>(str2.size()) > size)
+ {
+ str1 = str1.substr(0, size - str2.size());
+ }
+ char buffer[5];
+ int ni = 0;
+ sprintf(buffer, "%04d", ni);
+ ret = str1 + str2 + buffer;
+ while(m_ShortMakeVariableMap.count(ret) && ni < 1000)
+ {
+ ++ni;
+ sprintf(buffer, "%04d", ni);
+ ret = str1 + str2 + buffer;
+ }
+ if(ni == 1000)
+ {
+ cmSystemTools::Error("Borland makefile variable length too long");
+ return unmodified;
+ }
+ // once an unused variable is found
+ m_ShortMakeVariableMap[ret] = "1";
+ }
+ // always make an entry into the unmodified to variable map
+ m_MakeVariableMap[unmodified] = ret;
+ return ret;
+}
+//============================================================================
+
//----------------------------------------------------------------------------
std::string
cmLocalUnixMakefileGenerator2