ENH: add the ability to generate custom commands for a language that is not supported by an IDE
This commit is contained in:
parent
8ff4c07915
commit
7cef36c628
|
@ -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)
|
||||
|
|
|
@ -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")
|
|
@ -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())
|
||||
if(!targetSuffix && t.GetType() == cmTarget::EXECUTABLE)
|
||||
{
|
||||
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:
|
||||
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") << " ";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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:
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 "";
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue