summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2004-10-21 18:34:02 (GMT)
committerBill Hoffman <bill.hoffman@kitware.com>2004-10-21 18:34:02 (GMT)
commit7cef36c628a8ef07a0c53ea08691e4e6b949a695 (patch)
tree6dddd32ad310a5a069b66462cc79ca3fea15f024
parent8ff4c079159a8c5a53017ff1b02c8ac591eb2727 (diff)
downloadCMake-7cef36c628a8ef07a0c53ea08691e4e6b949a695.zip
CMake-7cef36c628a8ef07a0c53ea08691e4e6b949a695.tar.gz
CMake-7cef36c628a8ef07a0c53ea08691e4e6b949a695.tar.bz2
ENH: add the ability to generate custom commands for a language that is not supported by an IDE
-rw-r--r--Modules/CMakeDetermineFortranCompiler.cmake2
-rw-r--r--Modules/Platform/Windows-g77.cmake15
-rw-r--r--Source/cmLocalGenerator.cxx822
-rw-r--r--Source/cmLocalGenerator.h46
-rw-r--r--Source/cmLocalUnixMakefileGenerator.cxx565
-rw-r--r--Source/cmLocalUnixMakefileGenerator.h25
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx6
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx4
-rw-r--r--Source/cmTarget.cxx73
-rw-r--r--Source/cmTarget.h15
10 files changed, 953 insertions, 620 deletions
diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake
index cff5ba4..53a1c75 100644
--- a/Modules/CMakeDetermineFortranCompiler.cmake
+++ b/Modules/CMakeDetermineFortranCompiler.cmake
@@ -48,7 +48,7 @@ IF(NOT CMAKE_Fortran_COMPILER)
# CMake/Source/CMakeLists.txt, IF YOU CHANGE THIS LIST,
# PLEASE UPDATE THAT FILE AS WELL!
SET(CMAKE_Fortran_COMPILER_LIST ifort ifc efc f95 pgf95
- lf95 xlf95 fort gfortran f90 pgf90 xlf90 epcf90 f77 fort77 frt pgf77 xlf fl32 af77 g77 )
+ lf95 xlf95 fort gfortran f90 pgf90 xlf90 epcf90 fort77 frt pgf77 xlf fl32 af77 g77 f77 )
FIND_PROGRAM(CMAKE_Fortran_COMPILER_FULLPATH NAMES ${CMAKE_Fortran_COMPILER_LIST} )
GET_FILENAME_COMPONENT(CMAKE_Fortran_COMPILER_INIT
${CMAKE_Fortran_COMPILER_FULLPATH} NAME)
diff --git a/Modules/Platform/Windows-g77.cmake b/Modules/Platform/Windows-g77.cmake
new file mode 100644
index 0000000..7ab664b
--- /dev/null
+++ b/Modules/Platform/Windows-g77.cmake
@@ -0,0 +1,15 @@
+SET(CMAKE_LINK_LIBRARY_SUFFIX "")
+SET(CMAKE_STATIC_LIBRARY_PREFIX "lib")
+SET(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
+SET(CMAKE_SHARED_LIBRARY_PREFIX "lib") # lib
+SET(CMAKE_SHARED_LIBRARY_SUFFIX ".dll") # .so
+SET(CMAKE_SHARED_MODULE_PREFIX "lib") # lib
+SET(CMAKE_SHARED_MODULE_SUFFIX ".dll") # .so
+SET(CMAKE_DL_LIBS "")
+SET(CMAKE_SHARED_LIBRARY_C_FLAGS "") # -pic
+SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared") # -shared
+SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # +s, flag for exe link to use shared lib
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "") # -rpath
+SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP "") # : or empty
+SET(CMAKE_LIBRARY_PATH_FLAG "-L")
+SET(CMAKE_LINK_LIBRARY_FLAG "-l")
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index fa4f3d8..e91f579 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -19,6 +19,7 @@
#include "cmake.h"
#include "cmMakefile.h"
#include "cmGeneratedFileStream.h"
+#include "cmSourceFile.h"
cmLocalGenerator::cmLocalGenerator()
{
@@ -26,6 +27,9 @@ cmLocalGenerator::cmLocalGenerator()
m_Makefile->SetLocalGenerator(this);
m_ExcludeFromAll = false;
m_Parent = 0;
+ m_WindowsShell = false;
+ m_IgnoreLibPrefix = false;
+ m_UseRelativePaths = false;
}
cmLocalGenerator::~cmLocalGenerator()
@@ -339,32 +343,31 @@ std::string cmLocalGenerator::GetFullTargetName(const char* n,
{
const char* targetPrefix = t.GetProperty("PREFIX");
const char* targetSuffix = t.GetProperty("SUFFIX");
- const char* prefixVar = 0;
- const char* suffixVar = 0;
- switch(t.GetType())
- {
- case cmTarget::STATIC_LIBRARY:
- prefixVar = "CMAKE_STATIC_LIBRARY_PREFIX";
- suffixVar = "CMAKE_STATIC_LIBRARY_SUFFIX";
- break;
- case cmTarget::SHARED_LIBRARY:
- prefixVar = "CMAKE_SHARED_LIBRARY_PREFIX";
- suffixVar = "CMAKE_SHARED_LIBRARY_SUFFIX";
- break;
- case cmTarget::MODULE_LIBRARY:
- prefixVar = "CMAKE_SHARED_MODULE_PREFIX";
- suffixVar = "CMAKE_SHARED_MODULE_SUFFIX";
- break;
- case cmTarget::EXECUTABLE:
+ if(!targetSuffix && t.GetType() == cmTarget::EXECUTABLE)
+ {
targetSuffix = cmSystemTools::GetExecutableExtension();
- case cmTarget::UTILITY:
- case cmTarget::INSTALL_FILES:
- case cmTarget::INSTALL_PROGRAMS:
- break;
}
+ const char* prefixVar = t.GetPrefixVariable();
+ const char* suffixVar = t.GetSuffixVariable();
+ const char* ll = t.GetLinkerLanguage(this->GetGlobalGenerator());
+ // first try language specific suffix
+ if(ll)
+ {
+ if(!targetSuffix)
+ {
+ std::string langSuff = suffixVar + std::string("_") + ll;
+ targetSuffix = m_Makefile->GetDefinition(langSuff.c_str());
+ }
+ if(!targetPrefix)
+ {
+ std::string langPrefix = prefixVar + std::string("_") + ll;
+ targetPrefix = m_Makefile->GetDefinition(langPrefix.c_str());
+ }
+ }
+
// if there is no prefix on the target use the cmake definition
if(!targetPrefix && prefixVar)
- {
+ {
targetPrefix = m_Makefile->GetSafeDefinition(prefixVar);
}
// if there is no suffix on the target use the cmake definition
@@ -451,5 +454,780 @@ std::string cmLocalGenerator::ConvertToRelativeOutputPath(const char* p)
return ret;
}
+void cmLocalGenerator::AddCustomCommandToCreateObject(const char* ofname,
+ const char* lang,
+ cmSourceFile& source,
+ cmTarget& target)
+{
+ std::string objectFile = this->ConvertToRelativeOutputPath(ofname);
+ std::string sourceFile = this->ConvertToRelativeOutputPath(source.GetFullPath().c_str());
+ std::string varString = "CMAKE_";
+ varString += lang;
+ varString += "_COMPILE_OBJECT";
+ std::vector<std::string> rules;
+ rules.push_back(m_Makefile->GetRequiredDefinition(varString.c_str()));
+ varString = "CMAKE_";
+ varString += lang;
+ varString += "_FLAGS";
+ std::string flags;
+ flags += m_Makefile->GetSafeDefinition(varString.c_str());
+ flags += " ";
+ flags += this->GetIncludeFlags(lang);
+ std::vector<std::string> commands;
+ cmSystemTools::ExpandList(rules, commands);
+ for(std::vector<std::string>::iterator i = commands.begin();
+ i != commands.end(); ++i)
+ {
+ this->ExpandRuleVariables(*i,
+ lang,
+ 0, // no objects
+ 0, // no target
+ 0, // no link libs
+ sourceFile.c_str(),
+ objectFile.c_str(),
+ flags.c_str());
+ }
+ std::vector<std::string> sourceAndDeps;
+ sourceAndDeps.push_back(sourceFile);
+ if(commands.size() > 1)
+ {
+ cmSystemTools::Error("Currently custom rules can only have one command sorry ");
+ }
+ // Check for extra object-file dependencies.
+ std::vector<std::string> depends;
+ const char* additionalDeps = source.GetProperty("OBJECT_DEPENDS");
+ if(additionalDeps)
+ {
+ cmSystemTools::ExpandListArgument(additionalDeps, depends);
+ for(std::vector<std::string>::iterator i = depends.begin();
+ i != depends.end(); ++i)
+ {
+ sourceAndDeps.push_back(this->ConvertToRelativeOutputPath(i->c_str()));
+ }
+ }
+ std::string command;
+ std::string args;
+ cmSystemTools::SplitProgramFromArgs(commands[0].c_str(), command, args);
+ std::vector<std::string> argsv;
+ argsv.push_back(args);
+ m_Makefile->AddCustomCommandToOutput(ofname,
+ command.c_str(),
+ argsv,
+ source.GetFullPath().c_str(),
+ sourceAndDeps,
+ "build from source");
+}
+
+void cmLocalGenerator::AddBuildTargetRule(const char* llang, cmTarget& target)
+{
+ cmStdString objs;
+ std::vector<std::string> objVector;
+ // Add all the sources outputs to the depends of the target
+ std::vector<cmSourceFile*>& classes = target.GetSourceFiles();
+ for(std::vector<cmSourceFile*>::iterator i = classes.begin();
+ i != classes.end(); ++i)
+ {
+ if(!(*i)->GetPropertyAsBool("HEADER_FILE_ONLY") &&
+ !(*i)->GetCustomCommand())
+ {
+ std::string outExt =
+ m_GlobalGenerator->GetLanguageOutputExtensionFromExtension(
+ (*i)->GetSourceExtension().c_str());
+ if(outExt.size() && !(*i)->GetPropertyAsBool("EXTERNAL_OBJECT") )
+ {
+ std::string ofname = m_Makefile->GetCurrentOutputDirectory();
+ ofname += "/";
+ ofname += (*i)->GetSourceName() + outExt;
+ objVector.push_back(ofname);
+ this->AddCustomCommandToCreateObject(ofname.c_str(), llang, *(*i), target);
+ objs += this->ConvertToRelativeOutputPath(ofname.c_str());
+ objs += " ";
+ }
+ }
+ }
+ std::string createRule = "CMAKE_";
+ createRule += llang;
+ createRule += target.GetCreateRuleVariable();
+ std::string targetName = this->GetFullTargetName(target.GetName(), target);
+ // Executable :
+ // Shared Library:
+ // Static Library:
+ // Shared Module:
+ std::string linkLibs; // should be set
+ std::string flags; // should be set
+ std::string linkFlags; // should be set
+ this->GetTargetFlags(linkLibs, flags, linkFlags, target);
+ // Change the type to utility
+// target.SetType(cmTarget::UTILITY, target.GetName());
+ std::string rule = m_Makefile->GetRequiredDefinition(createRule.c_str());
+ this->ExpandRuleVariables(rule,
+ llang, // language
+ objs.c_str(), // objects
+ targetName.c_str(), // target
+ linkLibs.c_str(), // link libs
+ 0, // source
+ 0, // object
+ flags.c_str(), // flags
+ 0, // objects quoted
+ 0, // target base name
+ 0, // target so name,
+ linkFlags.c_str() // link flags
+ );
+ std::string command;
+ std::string args;
+ cmSystemTools::SplitProgramFromArgs(rule.c_str(), command, args);
+ // Just like ADD_CUSTOM_TARGET(foo ALL DEPENDS a.o b.o)
+ // Add a custom command for generating each .o file
+ cmCustomCommand cc(command.c_str(), args.c_str(), objVector, targetName.c_str());
+ target.GetPostBuildCommands().push_back(cc);
+}
+void cmLocalGenerator::CreateCustomTargetsAndCommands(std::set<cmStdString> const& lang)
+{
+ cmTargets &tgts = m_Makefile->GetTargets();
+ for(cmTargets::iterator l = tgts.begin();
+ l != tgts.end(); l++)
+ {
+ cmTarget& target = l->second;
+ switch(target.GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ case cmTarget::SHARED_LIBRARY:
+ case cmTarget::MODULE_LIBRARY:
+ case cmTarget::EXECUTABLE:
+ {
+ const char* llang = target.GetLinkerLanguage(this->GetGlobalGenerator());
+ // if the language is not in the set lang then create custom
+ // commands to build the target
+ if(lang.count(llang) == 0)
+ {
+ this->AddBuildTargetRule(llang, target);
+ }
+ }
+ break;
+ }
+ }
+}
+
+
+struct RuleVariables
+{
+ const char* variable;
+};
+
+
+// List of variables that are replaced when
+// rules are expanced. These variables are
+// replaced in the form <var> with GetSafeDefinition(var).
+// ${LANG} is replaced in the variable first with all enabled
+// languages.
+static const char* ruleReplaceVars[] =
+{
+ "CMAKE_SHARED_LIBRARY_CREATE_${LANG}_FLAGS",
+ "CMAKE_SHARED_MODULE_CREATE_${LANG}_FLAGS",
+ "CMAKE_SHARED_MODULE_${LANG}_FLAGS",
+ "CMAKE_SHARED_LIBRARY_${LANG}_FLAGS",
+ "CMAKE_${LANG}_LINK_FLAGS",
+ "CMAKE_SHARED_LIBRARY_SONAME_${LANG}_FLAG",
+ "CMAKE_${LANG}_ARCHIVE",
+ "CMAKE_${LANG}_COMPILER",
+ "CMAKE_AR",
+ "CMAKE_CURRENT_SOURCE_DIR",
+ "CMAKE_CURRENT_BINARY_DIR",
+ "CMAKE_RANLIB",
+ 0
+};
+
+
+
+
+void
+cmLocalGenerator::ExpandRuleVariables(std::string& s,
+ const char* lang,
+ const char* objects,
+ const char* target,
+ const char* linkLibs,
+ const char* source,
+ const char* object,
+ const char* flags,
+ const char* objectsquoted,
+ const char* targetBase,
+ const char* targetSOName,
+ const char* linkFlags)
+{
+ std::vector<std::string> enabledLanguages;
+ m_GlobalGenerator->GetEnabledLanguages(enabledLanguages);
+
+ if(linkFlags)
+ {
+ cmSystemTools::ReplaceString(s, "<LINK_FLAGS>", linkFlags);
+ }
+ if(flags)
+ {
+ cmSystemTools::ReplaceString(s, "<FLAGS>", flags);
+ }
+
+ if(source)
+ {
+ cmSystemTools::ReplaceString(s, "<SOURCE>", source);
+ }
+ if(object)
+ {
+ cmSystemTools::ReplaceString(s, "<OBJECT>", object);
+ }
+ if(objects)
+ {
+ cmSystemTools::ReplaceString(s, "<OBJECTS>", objects);
+ }
+ if(objectsquoted)
+ {
+ cmSystemTools::ReplaceString(s, "<OBJECTS_QUOTED>", objectsquoted);
+ }
+ if(target)
+ {
+ std::string targetQuoted = target;
+ if(targetQuoted.size() && targetQuoted[0] != '\"')
+ {
+ targetQuoted = '\"';
+ targetQuoted += target;
+ targetQuoted += '\"';
+ }
+ cmSystemTools::ReplaceString(s, "<TARGET_QUOTED>", targetQuoted.c_str());
+ cmSystemTools::ReplaceString(s, "<TARGET>", target);
+ }
+ if(targetBase)
+ {
+ // special case for quoted paths with spaces
+ // if you see <TARGET_BASE>.lib then put the .lib inside
+ // the quotes, same for .dll
+ if((strlen(targetBase) > 1) && targetBase[0] == '\"')
+ {
+ std::string base = targetBase;
+ base[base.size()-1] = '.';
+ std::string baseLib = base + "lib\"";
+ std::string baseDll = base + "dll\"";
+ cmSystemTools::ReplaceString(s, "<TARGET_BASE>.lib", baseLib.c_str());
+ cmSystemTools::ReplaceString(s, "<TARGET_BASE>.dll", baseDll.c_str());
+ }
+ cmSystemTools::ReplaceString(s, "<TARGET_BASE>", targetBase);
+ }
+ if(targetSOName)
+ {
+ bool replaced = false;
+ if(lang)
+ {
+ std::string name = "CMAKE_SHARED_LIBRARY_SONAME_";
+ name += lang;
+ name += "_FLAG";
+ if(m_Makefile->GetDefinition(name.c_str()))
+ {
+ replaced = true;
+ cmSystemTools::ReplaceString(s, "<TARGET_SONAME>", targetSOName);
+ }
+ }
+ if(!replaced)
+ {
+ cmSystemTools::ReplaceString(s, "<TARGET_SONAME>", "");
+ }
+ }
+ if(linkLibs)
+ {
+ cmSystemTools::ReplaceString(s, "<LINK_LIBRARIES>", linkLibs);
+ }
+
+ // loop over language specific replace variables
+ int pos = 0;
+ while(ruleReplaceVars[pos])
+ {
+ for(std::vector<std::string>::iterator i = enabledLanguages.begin();
+ i != enabledLanguages.end(); ++i)
+ {
+ lang = i->c_str();
+ std::string replace = "<";
+ replace += ruleReplaceVars[pos];
+ replace += ">";
+ std::string replaceWith = ruleReplaceVars[pos];
+ std::string actualReplace = replace;
+ cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
+ std::string actualReplaceWith = replaceWith;
+ cmSystemTools::ReplaceString(actualReplaceWith, "${LANG}", lang);
+ replace = m_Makefile->GetSafeDefinition(actualReplaceWith.c_str());
+ // if the variable is not a FLAG then treat it like a path
+ if(actualReplaceWith.find("_FLAG") == actualReplaceWith.npos)
+ {
+ replace = this->ConvertToOutputForExisting(replace.c_str());
+ }
+ if(actualReplace.size())
+ {
+ cmSystemTools::ReplaceString(s, actualReplace.c_str(), replace.c_str());
+ }
+ }
+ pos++;
+ }
+}
+
+
+std::string
+cmLocalGenerator::ConvertToOutputForExisting(const char* p)
+{
+ std::string ret = this->ConvertToRelativeOutputPath(p);
+ // if there are spaces in the path, then get the short path version
+ // if there is one
+ if(ret.find(' ') != std::string::npos)
+ {
+ if(cmSystemTools::FileExists(p))
+ {
+ if(!cmSystemTools::GetShortPath(ret.c_str(), ret))
+ {
+ ret = this->ConvertToRelativeOutputPath(p);
+ }
+ }
+ }
+ return ret;
+}
+
+const char* cmLocalGenerator::GetIncludeFlags(const char* lang)
+{
+ if(!lang)
+ {
+ return "";
+ }
+ if(m_LanguageToIncludeFlags.count(lang))
+ {
+ return m_LanguageToIncludeFlags[lang].c_str();
+ }
+ // Output Include paths
+ cmOStringStream includeFlags;
+ std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
+ std::vector<std::string>::iterator i;
+ std::map<cmStdString, cmStdString> implicitIncludes;
+
+ // CMake versions below 2.0 would add the source tree to the -I path
+ // automatically. Preserve compatibility.
+ bool includeSourceDir = false;
+ const char* versionValue =
+ m_Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
+ if(versionValue)
+ {
+ int major = 0;
+ int minor = 0;
+ if(sscanf(versionValue, "%d.%d", &major, &minor) == 2 && major < 2)
+ {
+ includeSourceDir = true;
+ }
+ }
+ const char* vtkSourceDir =
+ m_Makefile->GetDefinition("VTK_SOURCE_DIR");
+ if(vtkSourceDir)
+ {
+ // Special hack for VTK 4.0 - 4.4.
+ const char* vtk_major = m_Makefile->GetDefinition("VTK_MAJOR_VERSION");
+ const char* vtk_minor = m_Makefile->GetDefinition("VTK_MINOR_VERSION");
+ vtk_major = vtk_major? vtk_major : "4";
+ vtk_minor = vtk_minor? vtk_minor : "4";
+ int major = 0;
+ int minor = 0;
+ if(sscanf(vtk_major, "%d", &major) && sscanf(vtk_minor, "%d", &minor) &&
+ major == 4 && minor <= 4)
+ {
+ includeSourceDir = true;
+ }
+ }
+ std::string flagVar = "CMAKE_INCLUDE_FLAG_";
+ flagVar += lang;
+ const char* includeFlag = m_Makefile->GetDefinition(flagVar.c_str());
+ flagVar = "CMAKE_INCLUDE_FLAG_SEP_";
+ flagVar += lang;
+ const char* sep = m_Makefile->GetDefinition(flagVar.c_str());
+
+ bool repeatFlag = true; // should the include flag be repeated like ie. -IA -IB
+ if(!sep)
+ {
+ sep = " ";
+ }
+ else
+ {
+ // if there is a separator then the flag is not repeated but is only given once
+ // i.e. -classpath a:b:c
+ repeatFlag = false;
+ }
+ bool flagUsed = false;
+ if(includeSourceDir)
+ {
+ includeFlags << includeFlag
+ << this->ConvertToOutputForExisting(m_Makefile->GetStartDirectory())
+ << sep;
+ flagUsed = true;
+ }
+
+ implicitIncludes["/usr/include"] = "/usr/include";
+ if(m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES"))
+ {
+ std::string arg = m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES");
+ std::vector<std::string> implicitIncludeVec;
+ cmSystemTools::ExpandListArgument(arg, implicitIncludeVec);
+ for(unsigned int k =0; k < implicitIncludeVec.size(); k++)
+ {
+ implicitIncludes[implicitIncludeVec[k]] = implicitIncludeVec[k];
+ }
+ }
+
+ for(i = includes.begin(); i != includes.end(); ++i)
+ {
+ std::string include = *i;
+ // Don't output a -I for the standard include path "/usr/include".
+ // This can cause problems with certain standard library
+ // implementations because the wrong headers may be found first.
+ if(implicitIncludes.find(include) == implicitIncludes.end())
+ {
+ if(!flagUsed || repeatFlag)
+ {
+ includeFlags << includeFlag;
+ flagUsed = true;
+ }
+ includeFlags << this->ConvertToOutputForExisting(i->c_str()) << sep;
+ }
+ }
+ std::string flags = includeFlags.str();
+ // remove trailing separators
+ if((sep[0] != ' ') && flags[flags.size()-1] == sep[0])
+ {
+ flags[flags.size()-1] = ' ';
+ }
+ flags += m_Makefile->GetDefineFlags();
+ m_LanguageToIncludeFlags[lang] = flags;
+ return m_LanguageToIncludeFlags[lang].c_str();
+
+}
+
+
+void cmLocalGenerator::GetTargetFlags(std::string& linkLibs,
+ std::string& flags,
+ std::string& linkFlags,
+ cmTarget& target)
+{
+ std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ buildType = cmSystemTools::UpperCase(buildType);
+ const char* libraryLinkVariable = "CMAKE_SHARED_LINKER_FLAGS"; // default to shared library
+
+ switch(target.GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ {
+ const char* targetLinkFlags = target.GetProperty("STATIC_LIBRARY_FLAGS");
+ if(targetLinkFlags)
+ {
+ linkFlags += targetLinkFlags;
+ linkFlags += " ";
+ }
+ }
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
+ case cmTarget::SHARED_LIBRARY:
+ {
+ linkFlags = m_Makefile->GetSafeDefinition(libraryLinkVariable);
+ linkFlags += " ";
+ if(buildType.size())
+ {
+ std::string build = libraryLinkVariable;
+ build += "_";
+ build += buildType;
+ linkFlags += m_Makefile->GetSafeDefinition(build.c_str());
+ linkFlags += " ";
+ }
+ if(m_Makefile->IsOn("WIN32") && !(m_Makefile->IsOn("CYGWIN") || m_Makefile->IsOn("MINGW")))
+ {
+ const std::vector<cmSourceFile*>& sources = target.GetSourceFiles();
+ for(std::vector<cmSourceFile*>::const_iterator i = sources.begin();
+ i != sources.end(); ++i)
+ {
+ if((*i)->GetSourceExtension() == "def")
+ {
+ linkFlags += m_Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+ linkFlags += this->ConvertToRelativeOutputPath((*i)->GetFullPath().c_str());
+ linkFlags += " ";
+ }
+ }
+ }
+ const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
+ if(targetLinkFlags)
+ {
+ linkFlags += targetLinkFlags;
+ linkFlags += " ";
+ }
+ cmOStringStream linklibsStr;
+ this->OutputLinkLibraries(linklibsStr, target.GetName(), target);
+ linkLibs = linklibsStr.str();
+ }
+ break;
+ case cmTarget::EXECUTABLE:
+ {
+ linkFlags += m_Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
+ linkFlags += " ";
+ if(buildType.size())
+ {
+ std::string build = "CMAKE_EXE_LINKER_FLAGS_";
+ build += buildType;
+ linkFlags += m_Makefile->GetSafeDefinition(build.c_str());
+ linkFlags += " ";
+ }
+ const char* linkLanguage = target.GetLinkerLanguage(this->GetGlobalGenerator());
+ std::string langVar = "CMAKE_";
+ langVar += linkLanguage;
+ std::string flagsVar = langVar + "_FLAGS";
+ std::string sharedFlagsVar = "CMAKE_SHARED_LIBRARY_";
+ sharedFlagsVar += langVar;
+ sharedFlagsVar += "_FLAGS";
+ flags += m_Makefile->GetSafeDefinition(flagsVar.c_str());
+ flags += " ";
+ flags += m_Makefile->GetSafeDefinition(sharedFlagsVar.c_str());
+ flags += " ";
+ cmOStringStream linklibs;
+ this->OutputLinkLibraries(linklibs, 0, target);
+ linkLibs = linklibs.str();
+ if(cmSystemTools::IsOn(m_Makefile->GetDefinition("BUILD_SHARED_LIBS")))
+ {
+ std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") + linkLanguage
+ + std::string("_FLAGS");
+ linkFlags += m_Makefile->GetSafeDefinition(sFlagVar.c_str());
+ linkFlags += " ";
+ }
+ if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") )
+ {
+ linkFlags += m_Makefile->GetSafeDefinition("CMAKE_CREATE_WIN32_EXE");
+ linkFlags += " ";
+ }
+ else
+ {
+ linkFlags += m_Makefile->GetSafeDefinition("CMAKE_CREATE_CONSOLE_EXE");
+ linkFlags += " ";
+ }
+ const char* targetLinkFlags = target.GetProperty("LINK_FLAGS");
+ if(targetLinkFlags)
+ {
+ linkFlags += targetLinkFlags;
+ linkFlags += " ";
+ }
+ }
+ break;
+ }
+}
+
+
+/**
+ * Output the linking rules on a command line. For executables,
+ * targetLibrary should be a NULL pointer. For libraries, it should point
+ * to the name of the library. This will not link a library against itself.
+ */
+void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
+ const char* targetLibrary,
+ const cmTarget &tgt)
+{
+ // Try to emit each search path once
+ std::set<cmStdString> emitted;
+
+ // Embed runtime search paths if possible and if required.
+ bool outputRuntime = true;
+ std::string runtimeFlag;
+ std::string runtimeSep;
+ std::vector<std::string> runtimeDirs;
+
+ std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
+ buildType = cmSystemTools::UpperCase(buildType);
+
+ const char* linkLanguage = tgt.GetLinkerLanguage(this->GetGlobalGenerator());
+ std::string runTimeFlagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
+ runTimeFlagVar += linkLanguage;
+ runTimeFlagVar += "_FLAG";
+ std::string runTimeFlagSepVar = runTimeFlagVar + "_SEP";
+ runtimeFlag = m_Makefile->GetSafeDefinition(runTimeFlagVar.c_str());
+ runtimeSep = m_Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str());
+
+ // concatenate all paths or no?
+ bool runtimeConcatenate = ( runtimeSep!="" );
+ if(runtimeFlag == "" || m_Makefile->IsOn("CMAKE_SKIP_RPATH") )
+ {
+ outputRuntime = false;
+ }
+
+ // Some search paths should never be emitted
+ emitted.insert("");
+ emitted.insert("/usr/lib");
+ std::string libPathFlag = m_Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG");
+ std::string libLinkFlag = m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
+ // collect all the flags needed for linking libraries
+ std::string linkLibs;
+
+ // Flags to link an executable to shared libraries.
+ std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
+ linkFlagsVar += linkLanguage;
+ linkFlagsVar += "_FLAGS";
+ if( tgt.GetType() == cmTarget::EXECUTABLE )
+ {
+ linkLibs = m_Makefile->GetSafeDefinition(linkFlagsVar.c_str());
+ linkLibs += " ";
+ }
+
+ const std::vector<std::string>& libdirs = tgt.GetLinkDirectories();
+ for(std::vector<std::string>::const_iterator libDir = libdirs.begin();
+ libDir != libdirs.end(); ++libDir)
+ {
+ std::string libpath = this->ConvertToOutputForExisting(libDir->c_str());
+ if(emitted.insert(libpath).second)
+ {
+ std::string fullLibPath;
+ if(!m_WindowsShell && m_UseRelativePaths)
+ {
+ fullLibPath = "\"`cd ";
+ }
+ fullLibPath += libpath;
+ if(!m_WindowsShell && m_UseRelativePaths)
+ {
+ fullLibPath += ";pwd`\"";
+ }
+ std::string::size_type pos = libDir->find(libPathFlag.c_str());
+ if((pos == std::string::npos || pos > 0)
+ && libDir->find("${") == std::string::npos)
+ {
+ linkLibs += libPathFlag;
+ if(outputRuntime)
+ {
+ runtimeDirs.push_back( fullLibPath );
+ }
+ }
+ linkLibs += fullLibPath;
+ linkLibs += " ";
+ }
+ }
+
+ std::string linkSuffix = m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
+ std::string regexp = ".*\\";
+ regexp += linkSuffix;
+ regexp += "$";
+ cmsys::RegularExpression hasSuffix(regexp.c_str());
+ std::string librariesLinked;
+ const cmTarget::LinkLibraries& libs = tgt.GetLinkLibraries();
+ for(cmTarget::LinkLibraries::const_iterator lib = libs.begin();
+ lib != libs.end(); ++lib)
+ {
+ // Don't link the library against itself!
+ if(targetLibrary && (lib->first == targetLibrary)) continue;
+ // use the correct lib for the current configuration
+ if (lib->second == cmTarget::DEBUG && buildType != "DEBUG")
+ {
+ continue;
+ }
+ if (lib->second == cmTarget::OPTIMIZED && buildType == "DEBUG")
+ {
+ continue;
+ }
+ // skip zero size library entries, this may happen
+ // if a variable expands to nothing.
+ if (lib->first.size() == 0) continue;
+ // if it is a full path break it into -L and -l
+ cmsys::RegularExpression reg("^([ \t]*\\-[lWRB])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)");
+ if(lib->first.find('/') != std::string::npos
+ && !reg.find(lib->first))
+ {
+ std::string dir, file;
+ cmSystemTools::SplitProgramPath(lib->first.c_str(),
+ dir, file);
+ std::string libpath = this->ConvertToOutputForExisting(dir.c_str());
+ if(emitted.insert(libpath).second)
+ {
+ linkLibs += libPathFlag;
+ linkLibs += libpath;
+ linkLibs += " ";
+ if(outputRuntime)
+ {
+ runtimeDirs.push_back( libpath );
+ }
+ }
+ cmsys::RegularExpression libname("^lib([^/]*)(\\.so|\\.lib|\\.dll|\\.sl|\\.a|\\.dylib).*");
+ cmsys::RegularExpression libname_noprefix("([^/]*)(\\.so|\\.lib|\\.dll|\\.sl|\\.a|\\.dylib).*");
+ if(libname.find(file))
+ {
+ // Library had "lib" prefix.
+ librariesLinked += libLinkFlag;
+ file = libname.match(1);
+ // if ignore libprefix is on,
+ // then add the lib prefix back into the name
+ if(m_IgnoreLibPrefix)
+ {
+ file = "lib" + file;
+ }
+ librariesLinked += file;
+ if(linkSuffix.size() && !hasSuffix.find(file))
+ {
+ librariesLinked += linkSuffix;
+ }
+ librariesLinked += " ";
+ }
+ else if(libname_noprefix.find(file))
+ {
+ // Library had no "lib" prefix.
+ librariesLinked += libLinkFlag;
+ file = libname_noprefix.match(1);
+ librariesLinked += file;
+ if(linkSuffix.size() && !hasSuffix.find(file))
+ {
+ librariesLinked += linkSuffix;
+ }
+ librariesLinked += " ";
+ }
+ else
+ {
+ // Error parsing the library name. Just use the full path.
+ // The linker will give an error if it is invalid.
+ librariesLinked += lib->first;
+ librariesLinked += " ";
+ }
+ }
+ // not a full path, so add -l name
+ else
+ {
+ if(!reg.find(lib->first))
+ {
+ librariesLinked += libLinkFlag;
+ }
+ librariesLinked += lib->first;
+ if(linkSuffix.size() && !hasSuffix.find(lib->first))
+ {
+ librariesLinked += linkSuffix;
+ }
+ librariesLinked += " ";
+ }
+ }
+
+ linkLibs += librariesLinked;
+
+ fout << linkLibs;
+
+ if(outputRuntime && runtimeDirs.size()>0)
+ {
+ // For the runtime search directories, do a "-Wl,-rpath,a:b:c" or
+ // a "-R a -R b -R c" type link line
+ fout << runtimeFlag;
+ std::vector<std::string>::iterator itr = runtimeDirs.begin();
+ fout << *itr;
+ ++itr;
+ for( ; itr != runtimeDirs.end(); ++itr )
+ {
+ if(runtimeConcatenate)
+ {
+ fout << runtimeSep << *itr;
+ }
+ else
+ {
+ fout << " " << runtimeFlag << *itr;
+ }
+ }
+ fout << " ";
+ }
+ if(m_Makefile->GetDefinition("CMAKE_STANDARD_LIBRARIES"))
+ {
+ fout << m_Makefile->GetDefinition("CMAKE_STANDARD_LIBRARIES") << " ";
+ }
+}
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 792d8e1..02f902e 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -22,6 +22,8 @@
class cmMakefile;
class cmGlobalGenerator;
class cmTarget;
+class cmSourceFile;
+
/** \class cmLocalGenerator
* \brief Create required build files for a directory.
@@ -92,6 +94,46 @@ public:
void SetParent(cmLocalGenerator* g) { m_Parent = g;}
protected:
+ ///! Fill out these strings for the given target. Libraries to link, flags, and linkflags.
+ void GetTargetFlags(std::string& linkLibs,
+ std::string& flags,
+ std::string& linkFlags,
+ cmTarget&target);
+
+ ///! put all the libraries for a target on into the given stream
+ virtual void OutputLinkLibraries(std::ostream&, const char* name, const cmTarget &);
+
+ ///! Get the include flags for the current makefile and language
+ const char* GetIncludeFlags(const char* lang);
+ ///! for existing files convert to output path and short path if spaces
+ std::string ConvertToOutputForExisting(const char* p);
+
+ // Expand rule variables in CMake of the type found in language rules
+ void ExpandRuleVariables(std::string& string,
+ const char* language,
+ const char* objects=0,
+ const char* target=0,
+ const char* linkLibs=0,
+ const char* source=0,
+ const char* object =0,
+ const char* flags = 0,
+ const char* objectsquoted = 0,
+ const char* targetBase = 0,
+ const char* targetSOName = 0,
+ const char* linkFlags = 0);
+ ///! Convert a target to a utility target for unsupported languages of a generator
+ void AddBuildTargetRule(const char* llang, cmTarget& target);
+ ///! add a custom command to build a .o file that is part of a target
+ void AddCustomCommandToCreateObject(const char* ofname,
+ const char* lang,
+ cmSourceFile& source,
+ cmTarget& target);
+ // Create Custom Targets and commands for unsupported languages
+ // The set passed in should contain the languages supported by the
+ // generator directly. Any targets containing files that are not
+ // of the types listed will be compiled as custom commands and added
+ // to a custom target.
+ void CreateCustomTargetsAndCommands(std::set<cmStdString> const&);
virtual void AddInstallRule(std::ostream& fout, const char* dest, int type,
const char* files, bool optional = false, const char* properties = 0);
@@ -107,6 +149,10 @@ protected:
std::string m_HomeOutputDirectoryNoSlash;
bool m_ExcludeFromAll;
cmLocalGenerator* m_Parent;
+ std::map<cmStdString, cmStdString> m_LanguageToIncludeFlags;
+ bool m_WindowsShell;
+ bool m_UseRelativePaths;
+ bool m_IgnoreLibPrefix;
};
#endif
diff --git a/Source/cmLocalUnixMakefileGenerator.cxx b/Source/cmLocalUnixMakefileGenerator.cxx
index 53ab425..80fee93 100644
--- a/Source/cmLocalUnixMakefileGenerator.cxx
+++ b/Source/cmLocalUnixMakefileGenerator.cxx
@@ -322,24 +322,7 @@ std::string cmLocalUnixMakefileGenerator::GetBaseTargetName(const char* n,
#endif
const char* targetPrefix = t.GetProperty("PREFIX");
- const char* prefixVar = 0;
- switch(t.GetType())
- {
- case cmTarget::STATIC_LIBRARY:
- prefixVar = "CMAKE_STATIC_LIBRARY_PREFIX";
- break;
- case cmTarget::SHARED_LIBRARY:
- prefixVar = "CMAKE_SHARED_LIBRARY_PREFIX";
- break;
- case cmTarget::MODULE_LIBRARY:
- prefixVar = "CMAKE_SHARED_MODULE_PREFIX";
- break;
- case cmTarget::EXECUTABLE:
- case cmTarget::UTILITY:
- case cmTarget::INSTALL_FILES:
- case cmTarget::INSTALL_PROGRAMS:
- break;
- }
+ const char* prefixVar = t.GetPrefixVariable();
// if there is no prefix on the target use the cmake definition
if(!targetPrefix && prefixVar)
{
@@ -361,49 +344,6 @@ std::string cmLocalUnixMakefileGenerator::GetBaseTargetName(const char* n,
return name;
}
-std::string cmLocalUnixMakefileGenerator::GetFullTargetName(const char* n,
- const cmTarget& t)
-{
- const char* targetSuffix = t.GetProperty("SUFFIX");
- std::string suffixVar;
- switch(t.GetType())
- {
- case cmTarget::STATIC_LIBRARY:
- suffixVar = "CMAKE_STATIC_LIBRARY_SUFFIX";
- break;
- case cmTarget::SHARED_LIBRARY:
- suffixVar = "CMAKE_SHARED_LIBRARY_SUFFIX";
- break;
- case cmTarget::MODULE_LIBRARY:
- suffixVar = "CMAKE_SHARED_MODULE_SUFFIX";
- break;
- case cmTarget::EXECUTABLE:
- targetSuffix = cmSystemTools::GetExecutableExtension();
- case cmTarget::UTILITY:
- case cmTarget::INSTALL_FILES:
- case cmTarget::INSTALL_PROGRAMS:
- break;
- }
- // if there is no suffix on the target use the cmake definition
- if(!targetSuffix && suffixVar.size())
- {
- // first check for a language specific suffix var
- const char* ll = t.GetLinkerLanguage(this->GetGlobalGenerator());
- if(ll)
- {
- std::string langSuff = suffixVar + std::string("_") + ll;
- targetSuffix = m_Makefile->GetDefinition(langSuff.c_str());
- }
- // if there not a language specific suffix then use the general one
- if(!targetSuffix)
- {
- targetSuffix = m_Makefile->GetSafeDefinition(suffixVar.c_str());
- }
- }
- std::string name = this->GetBaseTargetName(n, t);
- name += targetSuffix?targetSuffix:"";
- return name;
-}
// Output the rules for any targets
void cmLocalUnixMakefileGenerator::OutputEcho(std::ostream& fout,
@@ -683,221 +623,6 @@ void cmLocalUnixMakefileGenerator::OutputTargetRules(std::ostream& fout)
}
-/**
- * Output the linking rules on a command line. For executables,
- * targetLibrary should be a NULL pointer. For libraries, it should point
- * to the name of the library. This will not link a library against itself.
- */
-void cmLocalUnixMakefileGenerator::OutputLinkLibraries(std::ostream& fout,
- const char* targetLibrary,
- const cmTarget &tgt)
-{
- // Try to emit each search path once
- std::set<cmStdString> emitted;
-
- // Embed runtime search paths if possible and if required.
- bool outputRuntime = true;
- std::string runtimeFlag;
- std::string runtimeSep;
- std::vector<std::string> runtimeDirs;
-
- std::string buildType = m_Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- buildType = cmSystemTools::UpperCase(buildType);
-
- const char* linkLanguage = tgt.GetLinkerLanguage(this->GetGlobalGenerator());
- std::string runTimeFlagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
- runTimeFlagVar += linkLanguage;
- runTimeFlagVar += "_FLAG";
- std::string runTimeFlagSepVar = runTimeFlagVar + "_SEP";
- runtimeFlag = m_Makefile->GetSafeDefinition(runTimeFlagVar.c_str());
- runtimeSep = m_Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str());
-
- // concatenate all paths or no?
- bool runtimeConcatenate = ( runtimeSep!="" );
- if(runtimeFlag == "" || m_Makefile->IsOn("CMAKE_SKIP_RPATH") )
- {
- outputRuntime = false;
- }
-
- // Some search paths should never be emitted
- emitted.insert("");
- emitted.insert("/usr/lib");
- std::string libPathFlag = m_Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG");
- std::string libLinkFlag = m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
- // collect all the flags needed for linking libraries
- std::string linkLibs;
-
- // Flags to link an executable to shared libraries.
- std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
- linkFlagsVar += linkLanguage;
- linkFlagsVar += "_FLAGS";
- if( tgt.GetType() == cmTarget::EXECUTABLE )
- {
- linkLibs = m_Makefile->GetSafeDefinition(linkFlagsVar.c_str());
- linkLibs += " ";
- }
-
- const std::vector<std::string>& libdirs = tgt.GetLinkDirectories();
- for(std::vector<std::string>::const_iterator libDir = libdirs.begin();
- libDir != libdirs.end(); ++libDir)
- {
- std::string libpath = this->ConvertToOutputForExisting(libDir->c_str());
- if(emitted.insert(libpath).second)
- {
- std::string fullLibPath;
- if(!m_WindowsShell && m_UseRelativePaths)
- {
- fullLibPath = "\"`cd ";
- }
- fullLibPath += libpath;
- if(!m_WindowsShell && m_UseRelativePaths)
- {
- fullLibPath += ";pwd`\"";
- }
- std::string::size_type pos = libDir->find(libPathFlag.c_str());
- if((pos == std::string::npos || pos > 0)
- && libDir->find("${") == std::string::npos)
- {
- linkLibs += libPathFlag;
- if(outputRuntime)
- {
- runtimeDirs.push_back( fullLibPath );
- }
- }
- linkLibs += fullLibPath;
- linkLibs += " ";
- }
- }
-
- std::string linkSuffix = m_Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
- std::string regexp = ".*\\";
- regexp += linkSuffix;
- regexp += "$";
- cmsys::RegularExpression hasSuffix(regexp.c_str());
- std::string librariesLinked;
- const cmTarget::LinkLibraries& libs = tgt.GetLinkLibraries();
- for(cmTarget::LinkLibraries::const_iterator lib = libs.begin();
- lib != libs.end(); ++lib)
- {
- // Don't link the library against itself!
- if(targetLibrary && (lib->first == targetLibrary)) continue;
- // use the correct lib for the current configuration
- if (lib->second == cmTarget::DEBUG && buildType != "DEBUG")
- {
- continue;
- }
- if (lib->second == cmTarget::OPTIMIZED && buildType == "DEBUG")
- {
- continue;
- }
- // skip zero size library entries, this may happen
- // if a variable expands to nothing.
- if (lib->first.size() == 0) continue;
- // if it is a full path break it into -L and -l
- cmsys::RegularExpression reg("^([ \t]*\\-[lWRB])|([ \t]*\\-framework)|(\\${)|([ \t]*\\-pthread)|([ \t]*`)");
- if(lib->first.find('/') != std::string::npos
- && !reg.find(lib->first))
- {
- std::string dir, file;
- cmSystemTools::SplitProgramPath(lib->first.c_str(),
- dir, file);
- std::string libpath = this->ConvertToOutputForExisting(dir.c_str());
- if(emitted.insert(libpath).second)
- {
- linkLibs += libPathFlag;
- linkLibs += libpath;
- linkLibs += " ";
- if(outputRuntime)
- {
- runtimeDirs.push_back( libpath );
- }
- }
- cmsys::RegularExpression libname("^lib([^/]*)(\\.so|\\.lib|\\.dll|\\.sl|\\.a|\\.dylib).*");
- cmsys::RegularExpression libname_noprefix("([^/]*)(\\.so|\\.lib|\\.dll|\\.sl|\\.a|\\.dylib).*");
- if(libname.find(file))
- {
- // Library had "lib" prefix.
- librariesLinked += libLinkFlag;
- file = libname.match(1);
- // if ignore libprefix is on,
- // then add the lib prefix back into the name
- if(m_IgnoreLibPrefix)
- {
- file = "lib" + file;
- }
- librariesLinked += file;
- if(linkSuffix.size() && !hasSuffix.find(file))
- {
- librariesLinked += linkSuffix;
- }
- librariesLinked += " ";
- }
- else if(libname_noprefix.find(file))
- {
- // Library had no "lib" prefix.
- librariesLinked += libLinkFlag;
- file = libname_noprefix.match(1);
- librariesLinked += file;
- if(linkSuffix.size() && !hasSuffix.find(file))
- {
- librariesLinked += linkSuffix;
- }
- librariesLinked += " ";
- }
- else
- {
- // Error parsing the library name. Just use the full path.
- // The linker will give an error if it is invalid.
- librariesLinked += lib->first;
- librariesLinked += " ";
- }
- }
- // not a full path, so add -l name
- else
- {
- if(!reg.find(lib->first))
- {
- librariesLinked += libLinkFlag;
- }
- librariesLinked += lib->first;
- if(linkSuffix.size() && !hasSuffix.find(lib->first))
- {
- librariesLinked += linkSuffix;
- }
- librariesLinked += " ";
- }
- }
-
- linkLibs += librariesLinked;
-
- fout << linkLibs;
-
- if(outputRuntime && runtimeDirs.size()>0)
- {
- // For the runtime search directories, do a "-Wl,-rpath,a:b:c" or
- // a "-R a -R b -R c" type link line
- fout << runtimeFlag;
- std::vector<std::string>::iterator itr = runtimeDirs.begin();
- fout << *itr;
- ++itr;
- for( ; itr != runtimeDirs.end(); ++itr )
- {
- if(runtimeConcatenate)
- {
- fout << runtimeSep << *itr;
- }
- else
- {
- fout << " " << runtimeFlag << *itr;
- }
- }
- fout << " ";
- }
- if(m_Makefile->GetDefinition("CMAKE_STANDARD_LIBRARIES"))
- {
- fout << m_Makefile->GetDefinition("CMAKE_STANDARD_LIBRARIES") << " ";
- }
-}
std::string cmLocalUnixMakefileGenerator::CreatePreBuildRules(
const cmTarget &target, const char* /* targetName */)
@@ -974,163 +699,6 @@ std::string cmLocalUnixMakefileGenerator::CreatePostBuildRules(
return customRuleCode;
}
-struct RuleVariables
-{
- const char* variable;
-};
-
-
-// List of variables that are replaced when
-// rules are expanced. These variables are
-// replaced in the form <var> with GetSafeDefinition(var).
-// ${LANG} is replaced in the variable first with all enabled
-// languages.
-static const char* ruleReplaceVars[] =
-{
- "CMAKE_SHARED_LIBRARY_CREATE_${LANG}_FLAGS",
- "CMAKE_SHARED_MODULE_CREATE_${LANG}_FLAGS",
- "CMAKE_SHARED_MODULE_${LANG}_FLAGS",
- "CMAKE_SHARED_LIBRARY_${LANG}_FLAGS",
- "CMAKE_${LANG}_LINK_FLAGS",
- "CMAKE_SHARED_LIBRARY_SONAME_${LANG}_FLAG",
- "CMAKE_${LANG}_ARCHIVE",
- "CMAKE_${LANG}_COMPILER",
- "CMAKE_AR",
- "CMAKE_CURRENT_SOURCE_DIR",
- "CMAKE_CURRENT_BINARY_DIR",
- "CMAKE_RANLIB",
- 0
-};
-
-
-
-
-void
-cmLocalUnixMakefileGenerator::ExpandRuleVariables(std::string& s,
- const char* lang,
- const char* objects,
- const char* target,
- const char* linkLibs,
- const char* source,
- const char* object,
- const char* flags,
- const char* objectsquoted,
- const char* targetBase,
- const char* targetSOName,
- const char* linkFlags)
-{
- std::vector<std::string> enabledLanguages;
- m_GlobalGenerator->GetEnabledLanguages(enabledLanguages);
-
- if(linkFlags)
- {
- cmSystemTools::ReplaceString(s, "<LINK_FLAGS>", linkFlags);
- }
- if(flags)
- {
- cmSystemTools::ReplaceString(s, "<FLAGS>", flags);
- }
-
- if(source)
- {
- cmSystemTools::ReplaceString(s, "<SOURCE>", source);
- }
- if(object)
- {
- cmSystemTools::ReplaceString(s, "<OBJECT>", object);
- }
- if(objects)
- {
- cmSystemTools::ReplaceString(s, "<OBJECTS>", objects);
- }
- if(objectsquoted)
- {
- cmSystemTools::ReplaceString(s, "<OBJECTS_QUOTED>", objectsquoted);
- }
- if(target)
- {
- std::string targetQuoted = target;
- if(targetQuoted.size() && targetQuoted[0] != '\"')
- {
- targetQuoted = '\"';
- targetQuoted += target;
- targetQuoted += '\"';
- }
- cmSystemTools::ReplaceString(s, "<TARGET_QUOTED>", targetQuoted.c_str());
- cmSystemTools::ReplaceString(s, "<TARGET>", target);
- }
- if(targetBase)
- {
- // special case for quoted paths with spaces
- // if you see <TARGET_BASE>.lib then put the .lib inside
- // the quotes, same for .dll
- if((strlen(targetBase) > 1) && targetBase[0] == '\"')
- {
- std::string base = targetBase;
- base[base.size()-1] = '.';
- std::string baseLib = base + "lib\"";
- std::string baseDll = base + "dll\"";
- cmSystemTools::ReplaceString(s, "<TARGET_BASE>.lib", baseLib.c_str());
- cmSystemTools::ReplaceString(s, "<TARGET_BASE>.dll", baseDll.c_str());
- }
- cmSystemTools::ReplaceString(s, "<TARGET_BASE>", targetBase);
- }
- if(targetSOName)
- {
- bool replaced = false;
- if(lang)
- {
- std::string name = "CMAKE_SHARED_LIBRARY_SONAME_";
- name += lang;
- name += "_FLAG";
- if(m_Makefile->GetDefinition(name.c_str()))
- {
- replaced = true;
- cmSystemTools::ReplaceString(s, "<TARGET_SONAME>", targetSOName);
- }
- }
- if(!replaced)
- {
- cmSystemTools::ReplaceString(s, "<TARGET_SONAME>", "");
- }
- }
- if(linkLibs)
- {
- cmSystemTools::ReplaceString(s, "<LINK_LIBRARIES>", linkLibs);
- }
-
- // loop over language specific replace variables
- int pos = 0;
- while(ruleReplaceVars[pos])
- {
- for(std::vector<std::string>::iterator i = enabledLanguages.begin();
- i != enabledLanguages.end(); ++i)
- {
- lang = i->c_str();
- std::string replace = "<";
- replace += ruleReplaceVars[pos];
- replace += ">";
- std::string replaceWith = ruleReplaceVars[pos];
- std::string actualReplace = replace;
- cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
- std::string actualReplaceWith = replaceWith;
- cmSystemTools::ReplaceString(actualReplaceWith, "${LANG}", lang);
- replace = m_Makefile->GetSafeDefinition(actualReplaceWith.c_str());
- // if the variable is not a FLAG then treat it like a path
- if(actualReplaceWith.find("_FLAG") == actualReplaceWith.npos)
- {
- replace = this->ConvertToOutputForExisting(replace.c_str());
- }
- if(actualReplace.size())
- {
- cmSystemTools::ReplaceString(s, actualReplace.c_str(), replace.c_str());
- }
- }
- pos++;
- }
-}
-
-
void cmLocalUnixMakefileGenerator::OutputLibraryRule(std::ostream& fout,
const char* name,
@@ -2459,25 +2027,6 @@ void cmLocalUnixMakefileGenerator::OutputCustomRules(std::ostream& fout)
}
}
-std::string
-cmLocalUnixMakefileGenerator::ConvertToOutputForExisting(const char* p)
-{
- std::string ret = this->ConvertToRelativeOutputPath(p);
- // if there are spaces in the path, then get the short path version
- // if there is one
- if(ret.find(' ') != std::string::npos)
- {
- if(cmSystemTools::FileExists(p))
- {
- if(!cmSystemTools::GetShortPath(ret.c_str(), ret))
- {
- ret = this->ConvertToRelativeOutputPath(p);
- }
- }
- }
- return ret;
-}
-
void cmLocalUnixMakefileGenerator::OutputMakeVariables(std::ostream& fout)
{
@@ -2532,118 +2081,6 @@ void cmLocalUnixMakefileGenerator::OutputMakeVariables(std::ostream& fout)
fout << "\n\n";
}
-const char* cmLocalUnixMakefileGenerator::GetIncludeFlags(const char* lang)
-{
- if(!lang)
- {
- return "";
- }
- if(m_LanguageToIncludeFlags.count(lang))
- {
- return m_LanguageToIncludeFlags[lang].c_str();
- }
- // Output Include paths
- cmOStringStream includeFlags;
- std::vector<std::string>& includes = m_Makefile->GetIncludeDirectories();
- std::vector<std::string>::iterator i;
- std::map<cmStdString, cmStdString> implicitIncludes;
-
- // CMake versions below 2.0 would add the source tree to the -I path
- // automatically. Preserve compatibility.
- bool includeSourceDir = false;
- const char* versionValue =
- m_Makefile->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY");
- if(versionValue)
- {
- int major = 0;
- int minor = 0;
- if(sscanf(versionValue, "%d.%d", &major, &minor) == 2 && major < 2)
- {
- includeSourceDir = true;
- }
- }
- const char* vtkSourceDir =
- m_Makefile->GetDefinition("VTK_SOURCE_DIR");
- if(vtkSourceDir)
- {
- // Special hack for VTK 4.0 - 4.4.
- const char* vtk_major = m_Makefile->GetDefinition("VTK_MAJOR_VERSION");
- const char* vtk_minor = m_Makefile->GetDefinition("VTK_MINOR_VERSION");
- vtk_major = vtk_major? vtk_major : "4";
- vtk_minor = vtk_minor? vtk_minor : "4";
- int major = 0;
- int minor = 0;
- if(sscanf(vtk_major, "%d", &major) && sscanf(vtk_minor, "%d", &minor) &&
- major == 4 && minor <= 4)
- {
- includeSourceDir = true;
- }
- }
- std::string flagVar = "CMAKE_INCLUDE_FLAG_";
- flagVar += lang;
- const char* includeFlag = m_Makefile->GetDefinition(flagVar.c_str());
- flagVar = "CMAKE_INCLUDE_FLAG_SEP_";
- flagVar += lang;
- const char* sep = m_Makefile->GetDefinition(flagVar.c_str());
-
- bool repeatFlag = true; // should the include flag be repeated like ie. -IA -IB
- if(!sep)
- {
- sep = " ";
- }
- else
- {
- // if there is a separator then the flag is not repeated but is only given once
- // i.e. -classpath a:b:c
- repeatFlag = false;
- }
- bool flagUsed = false;
- if(includeSourceDir)
- {
- includeFlags << includeFlag
- << this->ConvertToOutputForExisting(m_Makefile->GetStartDirectory())
- << sep;
- flagUsed = true;
- }
-
- implicitIncludes["/usr/include"] = "/usr/include";
- if(m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES"))
- {
- std::string arg = m_Makefile->GetDefinition("CMAKE_PLATFORM_IMPLICIT_INCLUDE_DIRECTORIES");
- std::vector<std::string> implicitIncludeVec;
- cmSystemTools::ExpandListArgument(arg, implicitIncludeVec);
- for(unsigned int k =0; k < implicitIncludeVec.size(); k++)
- {
- implicitIncludes[implicitIncludeVec[k]] = implicitIncludeVec[k];
- }
- }
-
- for(i = includes.begin(); i != includes.end(); ++i)
- {
- std::string include = *i;
- // Don't output a -I for the standard include path "/usr/include".
- // This can cause problems with certain standard library
- // implementations because the wrong headers may be found first.
- if(implicitIncludes.find(include) == implicitIncludes.end())
- {
- if(!flagUsed || repeatFlag)
- {
- includeFlags << includeFlag;
- flagUsed = true;
- }
- includeFlags << this->ConvertToOutputForExisting(i->c_str()) << sep;
- }
- }
- std::string flags = includeFlags.str();
- // remove trailing separators
- if((sep[0] != ' ') && flags[flags.size()-1] == sep[0])
- {
- flags[flags.size()-1] = ' ';
- }
- flags += m_Makefile->GetDefineFlags();
- m_LanguageToIncludeFlags[lang] = flags;
- return m_LanguageToIncludeFlags[lang].c_str();
-}
void cmLocalUnixMakefileGenerator::OutputMakeRules(std::ostream& fout)
{
diff --git a/Source/cmLocalUnixMakefileGenerator.h b/Source/cmLocalUnixMakefileGenerator.h
index 1e37209..020ea57 100644
--- a/Source/cmLocalUnixMakefileGenerator.h
+++ b/Source/cmLocalUnixMakefileGenerator.h
@@ -95,7 +95,6 @@ protected:
virtual void ProcessDepends(const cmMakeDepend &md);
virtual void OutputMakefile(const char* file, bool withDepends);
virtual void OutputTargetRules(std::ostream& fout);
- virtual void OutputLinkLibraries(std::ostream&, const char* name, const cmTarget &);
void OutputLibraryRule(std::ostream& fout,
const char* name,
const cmTarget &t,
@@ -103,18 +102,7 @@ protected:
const char* comment,
const char* linkFlags
);
- void ExpandRuleVariables(std::string& string,
- const char* language,
- const char* objects=0,
- const char* target=0,
- const char* linkLibs=0,
- const char* source=0,
- const char* object =0,
- const char* flags = 0,
- const char* objectsquoted = 0,
- const char* targetBase = 0,
- const char* targetSOName = 0,
- const char* linkFlags = 0);
+
virtual void OutputSharedLibraryRule(std::ostream&, const char* name,
const cmTarget &);
virtual void OutputModuleLibraryRule(std::ostream&, const char* name,
@@ -211,16 +199,10 @@ protected:
///! if the OS is case insensitive then return a lower case of the path.
virtual std::string LowerCasePath(const char* path);
- ///! for existing files convert to output path and short path if spaces
- std::string ConvertToOutputForExisting(const char*);
-
/** Convert path to a format vaild for the left or right side of a
target: dependencies line in a makefile. */
virtual std::string ConvertToMakeTarget(const char*);
- /** Get the full name of the target's file, without path. */
- std::string GetFullTargetName(const char* n, const cmTarget& t);
-
/** Get the base name of the target's file, without path or extension. */
std::string GetBaseTargetName(const char* n, const cmTarget& t);
@@ -240,20 +222,15 @@ protected:
*/
std::string& CreateSafeUniqueObjectFileName(const char* sin);
- const char* GetIncludeFlags(const char* lang);
protected:
int m_MakefileVariableSize;
std::map<cmStdString, cmStdString> m_MakeVariableMap;
std::map<cmStdString, cmStdString> m_ShortMakeVariableMap;
std::map<cmStdString, cmStdString> m_UniqueObjectNamesMap;
- std::map<cmStdString, cmStdString> m_LanguageToIncludeFlags;
- bool m_IgnoreLibPrefix;
std::string m_IncludeDirective;
std::string m_MakeSilentFlag;
std::string m_ExecutableOutputPath;
std::string m_LibraryOutputPath;
- bool m_WindowsShell;
- bool m_UseRelativePaths;
bool m_PassMakeflags;
private:
};
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 20a7927..56308e3 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -34,7 +34,11 @@ cmLocalVisualStudio6Generator::~cmLocalVisualStudio6Generator()
void cmLocalVisualStudio6Generator::Generate(bool /* fromTheTop */)
-{
+{
+ std::set<cmStdString> lang;
+ lang.insert("C");
+ lang.insert("CXX");
+ this->CreateCustomTargetsAndCommands(lang);
this->OutputDSPFile();
}
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index e0cd55a..0087b3e 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -34,6 +34,10 @@ cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
void cmLocalVisualStudio7Generator::Generate(bool /* fromTheTop */)
{
+ std::set<cmStdString> lang;
+ lang.insert("C");
+ lang.insert("CXX");
+ this->CreateCustomTargetsAndCommands(lang);
this->OutputVCProjFile();
}
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 39f450e..aa75573 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -769,10 +769,7 @@ const char* cmTarget::GetLinkerLanguage(cmGlobalGenerator* gg) const
}
if(languages.size() == 0)
{
- std::string m = "Error Target: ";
- m += m_Name + " contains no source files with an enabled languages.";
- cmSystemTools::Error(m.c_str());
- return "(NullLanguage)";
+ return 0;
}
if(languages.size() == 1)
{
@@ -809,3 +806,71 @@ const char* cmTarget::GetLinkerLanguage(cmGlobalGenerator* gg) const
const_cast<cmTarget*>(this)->SetProperty("LINKER_LANGUAGE", prefLang);
return this->GetProperty("LINKER_LANGUAGE");
}
+
+const char* cmTarget::GetCreateRuleVariable()
+{
+ switch(this->GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ return "_CREATE_STATIC_LIBRARY";
+ break;
+ case cmTarget::SHARED_LIBRARY:
+ return "_CREATE_SHARED_LIBRARY";
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ return "_CREATE_SHARED_MODULE";
+ break;
+ case cmTarget::EXECUTABLE:
+ return "_LINK_EXECUTABLE";
+ break;
+ }
+ return "";
+}
+
+
+const char* cmTarget::GetSuffixVariable() const
+{
+ switch(this->GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ return "CMAKE_STATIC_LIBRARY_SUFFIX";
+ break;
+ case cmTarget::SHARED_LIBRARY:
+ return "CMAKE_SHARED_LIBRARY_SUFFIX";
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ return "CMAKE_SHARED_MODULE_SUFFIX";
+ break;
+ case cmTarget::EXECUTABLE:
+ return cmSystemTools::GetExecutableExtension();
+ case cmTarget::UTILITY:
+ case cmTarget::INSTALL_FILES:
+ case cmTarget::INSTALL_PROGRAMS:
+ break;
+ }
+ return "";
+}
+
+
+const char* cmTarget::GetPrefixVariable() const
+{
+ switch(this->GetType())
+ {
+ case cmTarget::STATIC_LIBRARY:
+ return "CMAKE_STATIC_LIBRARY_PREFIX";
+ break;
+ case cmTarget::SHARED_LIBRARY:
+ return "CMAKE_SHARED_LIBRARY_PREFIX";
+ break;
+ case cmTarget::MODULE_LIBRARY:
+ return "CMAKE_SHARED_MODULE_PREFIX";
+ break;
+ case cmTarget::EXECUTABLE:
+ return cmSystemTools::GetExecutableExtension();
+ case cmTarget::UTILITY:
+ case cmTarget::INSTALL_FILES:
+ case cmTarget::INSTALL_PROGRAMS:
+ break;
+ }
+ return "";
+}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 8599189..631de55 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -55,9 +55,9 @@ public:
/**
* Indicate whether the target is part of the all target
*/
- bool IsInAll() const { return m_InAll; }
- bool GetInAll() const { return m_InAll; }
- void SetInAll(bool f) { m_InAll = f; }
+ bool IsInAll() const { return this->GetPropertyAsBool("IN_ALL"); }
+ bool GetInAll() const { return this->GetPropertyAsBool("IN_ALL"); }
+ void SetInAll(bool f) { this->SetProperty("IN_ALL", (f) ? "TRUE" : "FALSE"); }
/**
* Get the list of the custom commands for this target
@@ -157,6 +157,14 @@ public:
///! Return the prefered linker language for this target
const char* GetLinkerLanguage(cmGlobalGenerator*) const;
+
+ ///! Return the rule variable used to create this type of target,
+ // need to add CMAKE_(LANG) for full name.
+ const char* GetCreateRuleVariable();
+ ///! Return the name of the variable to look up the target suffix
+ const char* GetSuffixVariable() const;
+ ///! Return the name of the variable to look up the target suffix
+ const char* GetPrefixVariable() const;
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
@@ -223,7 +231,6 @@ private:
LinkLibraries m_LinkLibraries;
LinkLibraries m_PrevLinkedLibraries;
std::vector<std::string> m_LinkDirectories;
- bool m_InAll;
std::string m_InstallPath;
std::string m_RuntimeInstallPath;
std::set<cmStdString> m_Utilities;