summaryrefslogtreecommitdiffstats
path: root/Source/cmLocalGenerator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmLocalGenerator.cxx')
-rw-r--r--Source/cmLocalGenerator.cxx711
1 files changed, 182 insertions, 529 deletions
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index f24b717..e7dfed5 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -12,8 +12,13 @@
#include "cmInstallGenerator.h"
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
+#include "cmLinkLineComputer.h"
#include "cmMakefile.h"
+#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
+#include "cmState.h"
+#include "cmStateDirectory.h"
+#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTestGenerator.h"
@@ -22,16 +27,16 @@
#if defined(CMAKE_BUILD_WITH_CMAKE)
#define CM_LG_ENCODE_OBJECT_NAMES
-#include <cmsys/MD5.h>
+#include "cmCryptoHash.h"
#endif
#include <algorithm>
#include <assert.h>
#include <cmsys/RegularExpression.hxx>
-#include <ctype.h>
#include <iterator>
#include <sstream>
#include <stdio.h>
+#include <string.h>
#include <utility>
#if defined(__HAIKU__)
@@ -39,6 +44,28 @@
#include <StorageDefs.h>
#endif
+// 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_${LANG}_COMPILER",
+ "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_AR",
+ "CMAKE_CURRENT_SOURCE_DIR",
+ "CMAKE_CURRENT_BINARY_DIR",
+ "CMAKE_RANLIB",
+ "CMAKE_LINKER",
+ "CMAKE_CL_SHOWINCLUDES_PREFIX"
+};
+
cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
: cmOutputConverter(makefile->GetStateSnapshot())
, StateSnapshot(makefile->GetStateSnapshot())
@@ -55,6 +82,65 @@ cmLocalGenerator::cmLocalGenerator(cmGlobalGenerator* gg, cmMakefile* makefile)
this->BackwardsCompatibilityFinal = false;
this->ComputeObjectMaxPath();
+
+ std::vector<std::string> enabledLanguages =
+ this->GetState()->GetEnabledLanguages();
+
+ this->CompilerSysroot = this->Makefile->GetSafeDefinition("CMAKE_SYSROOT");
+
+ for (std::vector<std::string>::iterator i = enabledLanguages.begin();
+ i != enabledLanguages.end(); ++i) {
+ std::string const& lang = *i;
+ if (lang == "NONE") {
+ continue;
+ }
+ this->Compilers["CMAKE_" + lang + "_COMPILER"] = lang;
+
+ this->VariableMappings["CMAKE_" + lang + "_COMPILER"] =
+ this->Makefile->GetSafeDefinition("CMAKE_" + lang + "_COMPILER");
+
+ std::string const& compilerArg1 = "CMAKE_" + lang + "_COMPILER_ARG1";
+ std::string const& compilerTarget = "CMAKE_" + lang + "_COMPILER_TARGET";
+ std::string const& compilerOptionTarget =
+ "CMAKE_" + lang + "_COMPILE_OPTIONS_TARGET";
+ std::string const& compilerExternalToolchain =
+ "CMAKE_" + lang + "_COMPILER_EXTERNAL_TOOLCHAIN";
+ std::string const& compilerOptionExternalToolchain =
+ "CMAKE_" + lang + "_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN";
+ std::string const& compilerOptionSysroot =
+ "CMAKE_" + lang + "_COMPILE_OPTIONS_SYSROOT";
+
+ this->VariableMappings[compilerArg1] =
+ this->Makefile->GetSafeDefinition(compilerArg1);
+ this->VariableMappings[compilerTarget] =
+ this->Makefile->GetSafeDefinition(compilerTarget);
+ this->VariableMappings[compilerOptionTarget] =
+ this->Makefile->GetSafeDefinition(compilerOptionTarget);
+ this->VariableMappings[compilerExternalToolchain] =
+ this->Makefile->GetSafeDefinition(compilerExternalToolchain);
+ this->VariableMappings[compilerOptionExternalToolchain] =
+ this->Makefile->GetSafeDefinition(compilerOptionExternalToolchain);
+ this->VariableMappings[compilerOptionSysroot] =
+ this->Makefile->GetSafeDefinition(compilerOptionSysroot);
+
+ for (const char* const* replaceIter = cmArrayBegin(ruleReplaceVars);
+ replaceIter != cmArrayEnd(ruleReplaceVars); ++replaceIter) {
+ std::string actualReplace = *replaceIter;
+ if (actualReplace.find("${LANG}") != actualReplace.npos) {
+ cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
+ }
+
+ this->VariableMappings[actualReplace] =
+ this->Makefile->GetSafeDefinition(actualReplace);
+ }
+ }
+}
+
+cmRulePlaceholderExpander* cmLocalGenerator::CreateRulePlaceholderExpander()
+ const
+{
+ return new cmRulePlaceholderExpander(this->Compilers, this->VariableMappings,
+ this->CompilerSysroot);
}
cmLocalGenerator::~cmLocalGenerator()
@@ -116,7 +202,7 @@ void cmLocalGenerator::TraceDependencies()
std::vector<cmGeneratorTarget*> targets = this->GetGeneratorTargets();
for (std::vector<cmGeneratorTarget*>::iterator t = targets.begin();
t != targets.end(); ++t) {
- if ((*t)->GetType() == cmState::INTERFACE_LIBRARY) {
+ if ((*t)->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
(*t)->TraceDependencies();
@@ -166,7 +252,7 @@ void cmLocalGenerator::GenerateTestFiles()
(*gi)->Compute(this);
(*gi)->Generate(fout, config, configurationTypes);
}
- typedef std::vector<cmState::Snapshot> vec_t;
+ typedef std::vector<cmStateSnapshot> vec_t;
vec_t const& children = this->Makefile->GetStateSnapshot().GetChildren();
std::string parentBinDir = this->GetCurrentBinaryDirectory();
for (vec_t::const_iterator i = children.begin(); i != children.end(); ++i) {
@@ -363,12 +449,12 @@ void cmLocalGenerator::GenerateInstallRules()
this->GenerateTargetInstallRules(fout, config, configurationTypes);
// Include install scripts from subdirectories.
- std::vector<cmState::Snapshot> children =
+ std::vector<cmStateSnapshot> children =
this->Makefile->GetStateSnapshot().GetChildren();
if (!children.empty()) {
fout << "if(NOT CMAKE_INSTALL_LOCAL_ONLY)\n";
fout << " # Include the install script for each subdirectory.\n";
- for (std::vector<cmState::Snapshot>::const_iterator ci = children.begin();
+ for (std::vector<cmStateSnapshot>::const_iterator ci = children.begin();
ci != children.end(); ++ci) {
if (!ci->GetDirectory().GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
std::string odir = ci->GetDirectory().GetCurrentBinary();
@@ -459,7 +545,7 @@ void cmLocalGenerator::ComputeTargetManifest()
for (std::vector<cmGeneratorTarget*>::iterator t = targets.begin();
t != targets.end(); ++t) {
cmGeneratorTarget* target = *t;
- if (target->GetType() == cmState::INTERFACE_LIBRARY) {
+ if (target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
for (std::vector<std::string>::iterator ci = configNames.begin();
@@ -480,330 +566,11 @@ cmState* cmLocalGenerator::GetState() const
return this->GlobalGenerator->GetCMakeInstance()->GetState();
}
-cmState::Snapshot cmLocalGenerator::GetStateSnapshot() const
+cmStateSnapshot cmLocalGenerator::GetStateSnapshot() const
{
return this->Makefile->GetStateSnapshot();
}
-// 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_${LANG}_COMPILER",
- "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_AR",
- "CMAKE_CURRENT_SOURCE_DIR",
- "CMAKE_CURRENT_BINARY_DIR",
- "CMAKE_RANLIB",
- "CMAKE_LINKER",
- "CMAKE_CL_SHOWINCLUDES_PREFIX",
- CM_NULLPTR
-};
-
-std::string cmLocalGenerator::ExpandRuleVariable(
- std::string const& variable, const RuleVariables& replaceValues)
-{
- if (replaceValues.LinkFlags) {
- if (variable == "LINK_FLAGS") {
- return replaceValues.LinkFlags;
- }
- }
- if (replaceValues.Manifests) {
- if (variable == "MANIFESTS") {
- return replaceValues.Manifests;
- }
- }
- if (replaceValues.Flags) {
- if (variable == "FLAGS") {
- return replaceValues.Flags;
- }
- }
-
- if (replaceValues.Source) {
- if (variable == "SOURCE") {
- return replaceValues.Source;
- }
- }
- if (replaceValues.PreprocessedSource) {
- if (variable == "PREPROCESSED_SOURCE") {
- return replaceValues.PreprocessedSource;
- }
- }
- if (replaceValues.AssemblySource) {
- if (variable == "ASSEMBLY_SOURCE") {
- return replaceValues.AssemblySource;
- }
- }
- if (replaceValues.Object) {
- if (variable == "OBJECT") {
- return replaceValues.Object;
- }
- }
- if (replaceValues.ObjectDir) {
- if (variable == "OBJECT_DIR") {
- return replaceValues.ObjectDir;
- }
- }
- if (replaceValues.ObjectFileDir) {
- if (variable == "OBJECT_FILE_DIR") {
- return replaceValues.ObjectFileDir;
- }
- }
- if (replaceValues.Objects) {
- if (variable == "OBJECTS") {
- return replaceValues.Objects;
- }
- }
- if (replaceValues.ObjectsQuoted) {
- if (variable == "OBJECTS_QUOTED") {
- return replaceValues.ObjectsQuoted;
- }
- }
- if (replaceValues.Defines && variable == "DEFINES") {
- return replaceValues.Defines;
- }
- if (replaceValues.Includes && variable == "INCLUDES") {
- return replaceValues.Includes;
- }
- if (replaceValues.TargetPDB) {
- if (variable == "TARGET_PDB") {
- return replaceValues.TargetPDB;
- }
- }
- if (replaceValues.TargetCompilePDB) {
- if (variable == "TARGET_COMPILE_PDB") {
- return replaceValues.TargetCompilePDB;
- }
- }
- if (replaceValues.DependencyFile) {
- if (variable == "DEP_FILE") {
- return replaceValues.DependencyFile;
- }
- }
-
- if (replaceValues.Target) {
- if (variable == "TARGET_QUOTED") {
- std::string targetQuoted = replaceValues.Target;
- if (!targetQuoted.empty() && targetQuoted[0] != '\"') {
- targetQuoted = '\"';
- targetQuoted += replaceValues.Target;
- targetQuoted += '\"';
- }
- return targetQuoted;
- }
- if (variable == "TARGET_UNQUOTED") {
- std::string unquoted = replaceValues.Target;
- std::string::size_type sz = unquoted.size();
- if (sz > 2 && unquoted[0] == '\"' && unquoted[sz - 1] == '\"') {
- unquoted = unquoted.substr(1, sz - 2);
- }
- return unquoted;
- }
- if (replaceValues.LanguageCompileFlags) {
- if (variable == "LANGUAGE_COMPILE_FLAGS") {
- return replaceValues.LanguageCompileFlags;
- }
- }
- if (replaceValues.Target) {
- if (variable == "TARGET") {
- return replaceValues.Target;
- }
- }
- if (variable == "TARGET_IMPLIB") {
- return this->TargetImplib;
- }
- if (variable == "TARGET_VERSION_MAJOR") {
- if (replaceValues.TargetVersionMajor) {
- return replaceValues.TargetVersionMajor;
- }
- return "0";
- }
- if (variable == "TARGET_VERSION_MINOR") {
- if (replaceValues.TargetVersionMinor) {
- return replaceValues.TargetVersionMinor;
- }
- return "0";
- }
- if (replaceValues.Target) {
- if (variable == "TARGET_BASE") {
- // Strip the last extension off the target name.
- std::string targetBase = replaceValues.Target;
- std::string::size_type pos = targetBase.rfind('.');
- if (pos != targetBase.npos) {
- return targetBase.substr(0, pos);
- }
- return targetBase;
- }
- }
- }
- if (variable == "TARGET_SONAME" || variable == "SONAME_FLAG" ||
- variable == "TARGET_INSTALLNAME_DIR") {
- // All these variables depend on TargetSOName
- if (replaceValues.TargetSOName) {
- if (variable == "TARGET_SONAME") {
- return replaceValues.TargetSOName;
- }
- if (variable == "SONAME_FLAG" && replaceValues.SONameFlag) {
- return replaceValues.SONameFlag;
- }
- if (replaceValues.TargetInstallNameDir &&
- variable == "TARGET_INSTALLNAME_DIR") {
- return replaceValues.TargetInstallNameDir;
- }
- }
- return "";
- }
- if (replaceValues.LinkLibraries) {
- if (variable == "LINK_LIBRARIES") {
- return replaceValues.LinkLibraries;
- }
- }
- if (replaceValues.Language) {
- if (variable == "LANGUAGE") {
- return replaceValues.Language;
- }
- }
- if (replaceValues.CMTarget) {
- if (variable == "TARGET_NAME") {
- return replaceValues.CMTarget->GetName();
- }
- if (variable == "TARGET_TYPE") {
- return cmState::GetTargetTypeName(replaceValues.CMTarget->GetType());
- }
- }
- if (replaceValues.Output) {
- if (variable == "OUTPUT") {
- return replaceValues.Output;
- }
- }
- if (variable == "CMAKE_COMMAND") {
- return this->ConvertToOutputFormat(
- cmSystemTools::CollapseFullPath(cmSystemTools::GetCMakeCommand()),
- SHELL);
- }
- std::vector<std::string> enabledLanguages =
- this->GetState()->GetEnabledLanguages();
- // 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) {
- const char* lang = i->c_str();
- std::string actualReplace = ruleReplaceVars[pos];
- // If this is the compiler then look for the extra variable
- // _COMPILER_ARG1 which must be the first argument to the compiler
- const char* compilerArg1 = CM_NULLPTR;
- const char* compilerTarget = CM_NULLPTR;
- const char* compilerOptionTarget = CM_NULLPTR;
- const char* compilerExternalToolchain = CM_NULLPTR;
- const char* compilerOptionExternalToolchain = CM_NULLPTR;
- const char* compilerSysroot = CM_NULLPTR;
- const char* compilerOptionSysroot = CM_NULLPTR;
- if (actualReplace == "CMAKE_${LANG}_COMPILER") {
- std::string arg1 = actualReplace + "_ARG1";
- cmSystemTools::ReplaceString(arg1, "${LANG}", lang);
- compilerArg1 = this->Makefile->GetDefinition(arg1);
- compilerTarget = this->Makefile->GetDefinition(
- std::string("CMAKE_") + lang + "_COMPILER_TARGET");
- compilerOptionTarget = this->Makefile->GetDefinition(
- std::string("CMAKE_") + lang + "_COMPILE_OPTIONS_TARGET");
- compilerExternalToolchain = this->Makefile->GetDefinition(
- std::string("CMAKE_") + lang + "_COMPILER_EXTERNAL_TOOLCHAIN");
- compilerOptionExternalToolchain =
- this->Makefile->GetDefinition(std::string("CMAKE_") + lang +
- "_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN");
- compilerSysroot = this->Makefile->GetDefinition("CMAKE_SYSROOT");
- compilerOptionSysroot = this->Makefile->GetDefinition(
- std::string("CMAKE_") + lang + "_COMPILE_OPTIONS_SYSROOT");
- }
- if (actualReplace.find("${LANG}") != actualReplace.npos) {
- cmSystemTools::ReplaceString(actualReplace, "${LANG}", lang);
- }
- if (actualReplace == variable) {
- std::string replace = this->Makefile->GetSafeDefinition(variable);
- // if the variable is not a FLAG then treat it like a path
- if (variable.find("_FLAG") == variable.npos) {
- std::string ret = this->ConvertToOutputForExisting(replace);
- // if there is a required first argument to the compiler add it
- // to the compiler string
- if (compilerArg1) {
- ret += " ";
- ret += compilerArg1;
- }
- if (compilerTarget && compilerOptionTarget) {
- ret += " ";
- ret += compilerOptionTarget;
- ret += compilerTarget;
- }
- if (compilerExternalToolchain && compilerOptionExternalToolchain) {
- ret += " ";
- ret += compilerOptionExternalToolchain;
- ret += this->EscapeForShell(compilerExternalToolchain, true);
- }
- if (compilerSysroot && compilerOptionSysroot) {
- ret += " ";
- ret += compilerOptionSysroot;
- ret += this->EscapeForShell(compilerSysroot, true);
- }
- return ret;
- }
- return replace;
- }
- }
- pos++;
- }
- return variable;
-}
-
-void cmLocalGenerator::ExpandRuleVariables(std::string& s,
- const RuleVariables& replaceValues)
-{
- if (replaceValues.RuleLauncher) {
- this->InsertRuleLauncher(s, replaceValues.CMTarget,
- replaceValues.RuleLauncher);
- }
- std::string::size_type start = s.find('<');
- // no variables to expand
- if (start == s.npos) {
- return;
- }
- std::string::size_type pos = 0;
- std::string expandedInput;
- while (start != s.npos && start < s.size() - 2) {
- std::string::size_type end = s.find('>', start);
- // if we find a < with no > we are done
- if (end == s.npos) {
- return;
- }
- char c = s[start + 1];
- // if the next char after the < is not A-Za-z then
- // skip it and try to find the next < in the string
- if (!isalpha(c)) {
- start = s.find('<', start + 1);
- } else {
- // extract the var
- std::string var = s.substr(start + 1, end - start - 1);
- std::string replace = this->ExpandRuleVariable(var, replaceValues);
- expandedInput += s.substr(pos, start - pos);
- expandedInput += replace;
- // move to next one
- start = s.find('<', start + var.size() + 2);
- pos = end + 1;
- }
- }
- // add the rest of the input
- expandedInput += s.substr(pos, s.size() - pos);
- s = expandedInput;
-}
-
const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
const std::string& prop)
{
@@ -813,17 +580,6 @@ const char* cmLocalGenerator::GetRuleLauncher(cmGeneratorTarget* target,
return this->Makefile->GetProperty(prop);
}
-void cmLocalGenerator::InsertRuleLauncher(std::string& s,
- cmGeneratorTarget* target,
- const std::string& prop)
-{
- if (const char* val = this->GetRuleLauncher(target, prop)) {
- std::ostringstream wrapped;
- wrapped << val << " " << s;
- s = wrapped.str();
- }
-}
-
std::string cmLocalGenerator::ConvertToIncludeReference(
std::string const& path, OutputFormat format, bool forceFullPaths)
{
@@ -1148,21 +904,22 @@ void cmLocalGenerator::GetStaticLibraryFlags(std::string& flags,
}
void cmLocalGenerator::GetTargetFlags(
- const std::string& config, std::string& linkLibs, std::string& flags,
- std::string& linkFlags, std::string& frameworkPath, std::string& linkPath,
- cmGeneratorTarget* target, bool useWatcomQuote)
+ cmLinkLineComputer* linkLineComputer, const std::string& config,
+ std::string& linkLibs, std::string& flags, std::string& linkFlags,
+ std::string& frameworkPath, std::string& linkPath, cmGeneratorTarget* target)
{
const std::string buildType = cmSystemTools::UpperCase(config);
+ cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
const char* libraryLinkVariable =
"CMAKE_SHARED_LINKER_FLAGS"; // default to shared library
switch (target->GetType()) {
- case cmState::STATIC_LIBRARY:
+ case cmStateEnums::STATIC_LIBRARY:
this->GetStaticLibraryFlags(linkFlags, buildType, target);
break;
- case cmState::MODULE_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
libraryLinkVariable = "CMAKE_MODULE_LINKER_FLAGS";
- case cmState::SHARED_LIBRARY: {
+ case cmStateEnums::SHARED_LIBRARY: {
linkFlags = this->Makefile->GetSafeDefinition(libraryLinkVariable);
linkFlags += " ";
if (!buildType.empty()) {
@@ -1176,12 +933,13 @@ void cmLocalGenerator::GetTargetFlags(
!(this->Makefile->IsOn("CYGWIN") || this->Makefile->IsOn("MINGW"))) {
std::vector<cmSourceFile*> sources;
target->GetSourceFiles(sources, buildType);
+ std::string defFlag =
+ this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
for (std::vector<cmSourceFile*>::const_iterator i = sources.begin();
i != sources.end(); ++i) {
cmSourceFile* sf = *i;
if (sf->GetExtension() == "def") {
- linkFlags +=
- this->Makefile->GetSafeDefinition("CMAKE_LINK_DEF_FILE_FLAG");
+ linkFlags += defFlag;
linkFlags += this->ConvertToOutputFormat(
cmSystemTools::CollapseFullPath(sf->GetFullPath()), SHELL);
linkFlags += " ";
@@ -1202,10 +960,12 @@ void cmLocalGenerator::GetTargetFlags(
linkFlags += " ";
}
}
- this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, *target,
- false, false, useWatcomQuote);
+ if (pcli) {
+ this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
+ frameworkPath, linkPath);
+ }
} break;
- case cmState::EXECUTABLE: {
+ case cmStateEnums::EXECUTABLE: {
linkFlags += this->Makefile->GetSafeDefinition("CMAKE_EXE_LINKER_FLAGS");
linkFlags += " ";
if (!buildType.empty()) {
@@ -1222,8 +982,10 @@ void cmLocalGenerator::GetTargetFlags(
return;
}
this->AddLanguageFlags(flags, linkLanguage, buildType);
- this->OutputLinkLibraries(linkLibs, frameworkPath, linkPath, *target,
- false, false, useWatcomQuote);
+ if (pcli) {
+ this->OutputLinkLibraries(pcli, linkLineComputer, linkLibs,
+ frameworkPath, linkPath);
+ }
if (cmSystemTools::IsOn(
this->Makefile->GetDefinition("BUILD_SHARED_LIBS"))) {
std::string sFlagVar = std::string("CMAKE_SHARED_BUILD_") +
@@ -1248,6 +1010,14 @@ void cmLocalGenerator::GetTargetFlags(
linkFlags += this->Makefile->GetSafeDefinition(exportFlagVar);
linkFlags += " ";
}
+
+ std::string cmp0065Flags =
+ this->GetLinkLibsCMP0065(linkLanguage, *target);
+ if (!cmp0065Flags.empty()) {
+ linkFlags += cmp0065Flags;
+ linkFlags += " ";
+ }
+
const char* targetLinkFlags = target->GetProperty("LINK_FLAGS");
if (targetLinkFlags) {
linkFlags += targetLinkFlags;
@@ -1374,63 +1144,18 @@ std::string cmLocalGenerator::GetTargetFortranFlags(
return std::string();
}
-std::string cmLocalGenerator::ConvertToLinkReference(std::string const& lib,
- OutputFormat format)
-{
-#if defined(_WIN32) && !defined(__CYGWIN__)
- // Work-ardound command line parsing limitations in MSVC 6.0
- if (this->Makefile->IsOn("MSVC60")) {
- // Search for the last space.
- std::string::size_type pos = lib.rfind(' ');
- if (pos != lib.npos) {
- // Find the slash after the last space, if any.
- pos = lib.find('/', pos);
-
- // Convert the portion of the path with a space to a short path.
- std::string sp;
- if (cmSystemTools::GetShortPath(lib.substr(0, pos).c_str(), sp)) {
- // Append the rest of the path with no space.
- sp += lib.substr(pos);
-
- // Convert to an output path.
- return this->ConvertToOutputFormat(sp.c_str(), format);
- }
- }
- }
-#endif
-
- // Normal behavior.
- return this->ConvertToOutputFormat(
- this->ConvertToRelativePath(this->GetCurrentBinaryDirectory(), lib),
- format);
-}
-
/**
* 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::string& linkLibraries,
- std::string& frameworkPath,
- std::string& linkPath,
- cmGeneratorTarget& tgt, bool relink,
- bool forResponseFile,
- bool useWatcomQuote)
-{
- OutputFormat shellFormat =
- (forResponseFile) ? RESPONSE : ((useWatcomQuote) ? WATCOMQUOTE : SHELL);
- bool escapeAllowMakeVars = !forResponseFile;
- std::ostringstream fout;
- std::string config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
- cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config);
- if (!pcli) {
- return;
- }
+void cmLocalGenerator::OutputLinkLibraries(
+ cmComputeLinkInformation* pcli, cmLinkLineComputer* linkLineComputer,
+ std::string& linkLibraries, std::string& frameworkPath,
+ std::string& linkPath)
+{
cmComputeLinkInformation& cli = *pcli;
- // Collect library linking flags command line options.
- std::string linkLibs;
-
std::string linkLanguage = cli.GetLinkLanguage();
std::string libPathFlag =
@@ -1438,8 +1163,36 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
std::string libPathTerminator =
this->Makefile->GetSafeDefinition("CMAKE_LIBRARY_PATH_TERMINATOR");
+ // Add standard libraries for this language.
+ std::string standardLibsVar = "CMAKE_";
+ standardLibsVar += cli.GetLinkLanguage();
+ standardLibsVar += "_STANDARD_LIBRARIES";
+ std::string stdLibString;
+ if (const char* stdLibs = this->Makefile->GetDefinition(standardLibsVar)) {
+ stdLibString = stdLibs;
+ }
+
+ // Append the framework search path flags.
+ std::string fwSearchFlagVar = "CMAKE_";
+ fwSearchFlagVar += linkLanguage;
+ fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG";
+ std::string fwSearchFlag =
+ this->Makefile->GetSafeDefinition(fwSearchFlagVar);
+
+ frameworkPath = linkLineComputer->ComputeFrameworkPath(cli, fwSearchFlag);
+ linkPath =
+ linkLineComputer->ComputeLinkPath(cli, libPathFlag, libPathTerminator);
+
+ linkLibraries = linkLineComputer->ComputeLinkLibraries(cli, stdLibString);
+}
+
+std::string cmLocalGenerator::GetLinkLibsCMP0065(
+ std::string const& linkLanguage, cmGeneratorTarget& tgt) const
+{
+ std::string linkFlags;
+
// Flags to link an executable to shared libraries.
- if (tgt.GetType() == cmState::EXECUTABLE &&
+ if (tgt.GetType() == cmStateEnums::EXECUTABLE &&
this->StateSnapshot.GetState()->GetGlobalPropertyAsBool(
"TARGET_SUPPORTS_SHARED_LIBS")) {
bool add_shlib_flags = false;
@@ -1476,100 +1229,10 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
std::string linkFlagsVar = "CMAKE_SHARED_LIBRARY_LINK_";
linkFlagsVar += linkLanguage;
linkFlagsVar += "_FLAGS";
- linkLibs = this->Makefile->GetSafeDefinition(linkFlagsVar);
- linkLibs += " ";
+ linkFlags = this->Makefile->GetSafeDefinition(linkFlagsVar);
}
}
-
- // Append the framework search path flags.
- std::string fwSearchFlagVar = "CMAKE_";
- fwSearchFlagVar += linkLanguage;
- fwSearchFlagVar += "_FRAMEWORK_SEARCH_FLAG";
- const char* fwSearchFlag = this->Makefile->GetDefinition(fwSearchFlagVar);
- if (fwSearchFlag && *fwSearchFlag) {
- std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
- for (std::vector<std::string>::const_iterator fdi = fwDirs.begin();
- fdi != fwDirs.end(); ++fdi) {
- frameworkPath += fwSearchFlag;
- frameworkPath += this->ConvertToOutputFormat(*fdi, shellFormat);
- frameworkPath += " ";
- }
- }
-
- // Append the library search path flags.
- std::vector<std::string> const& libDirs = cli.GetDirectories();
- for (std::vector<std::string>::const_iterator libDir = libDirs.begin();
- libDir != libDirs.end(); ++libDir) {
- std::string libpath =
- this->ConvertToOutputForExisting(*libDir, shellFormat);
- linkPath += " " + libPathFlag;
- linkPath += libpath;
- linkPath += libPathTerminator;
- linkPath += " ";
- }
-
- // Append the link items.
- typedef cmComputeLinkInformation::ItemVector ItemVector;
- ItemVector const& items = cli.GetItems();
- for (ItemVector::const_iterator li = items.begin(); li != items.end();
- ++li) {
- if (li->Target && li->Target->GetType() == cmState::INTERFACE_LIBRARY) {
- continue;
- }
- if (li->IsPath) {
- linkLibs += this->ConvertToLinkReference(li->Value, shellFormat);
- } else {
- linkLibs += li->Value;
- }
- linkLibs += " ";
- }
-
- // Check what kind of rpath flags to use.
- if (cli.GetRuntimeSep().empty()) {
- // Each rpath entry gets its own option ("-R a -R b -R c")
- std::vector<std::string> runtimeDirs;
- cli.GetRPath(runtimeDirs, relink);
-
- std::string rpath;
- for (std::vector<std::string>::iterator ri = runtimeDirs.begin();
- ri != runtimeDirs.end(); ++ri) {
- rpath += cli.GetRuntimeFlag();
- rpath += this->ConvertToOutputFormat(*ri, shellFormat);
- rpath += " ";
- }
- fout << rpath;
- } else {
- // All rpath entries are combined ("-Wl,-rpath,a:b:c").
- std::string rpath = cli.GetRPathString(relink);
-
- // Store the rpath option in the stream.
- if (!rpath.empty()) {
- fout << cli.GetRuntimeFlag();
- fout << this->EscapeForShell(rpath, escapeAllowMakeVars);
- fout << " ";
- }
- }
-
- // Write the library flags to the build rule.
- fout << linkLibs;
-
- // Add the linker runtime search path if any.
- std::string rpath_link = cli.GetRPathLinkString();
- if (!cli.GetRPathLinkFlag().empty() && !rpath_link.empty()) {
- fout << cli.GetRPathLinkFlag();
- fout << this->EscapeForShell(rpath_link, escapeAllowMakeVars);
- fout << " ";
- }
-
- // Add standard libraries for this language.
- std::string standardLibsVar = "CMAKE_";
- standardLibsVar += cli.GetLinkLanguage();
- standardLibsVar += "_STANDARD_LIBRARIES";
- if (const char* stdLibs = this->Makefile->GetDefinition(standardLibsVar)) {
- fout << stdLibs << " ";
- }
-
- linkLibraries = fout.str();
+ return linkFlags;
}
void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
@@ -1674,8 +1337,8 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
// found is part of the inName
if (cmSystemTools::FileIsFullPath(inName.c_str())) {
std::string tLocation;
- if (target->GetType() >= cmState::EXECUTABLE &&
- target->GetType() <= cmState::MODULE_LIBRARY) {
+ if (target->GetType() >= cmStateEnums::EXECUTABLE &&
+ target->GetType() <= cmStateEnums::MODULE_LIBRARY) {
tLocation = target->GetLocation(config);
tLocation = cmSystemTools::GetFilenamePath(tLocation);
tLocation = cmSystemTools::CollapseFullPath(tLocation);
@@ -1692,23 +1355,23 @@ bool cmLocalGenerator::GetRealDependency(const std::string& inName,
}
}
switch (target->GetType()) {
- case cmState::EXECUTABLE:
- case cmState::STATIC_LIBRARY:
- case cmState::SHARED_LIBRARY:
- case cmState::MODULE_LIBRARY:
- case cmState::UNKNOWN_LIBRARY:
+ case cmStateEnums::EXECUTABLE:
+ case cmStateEnums::STATIC_LIBRARY:
+ case cmStateEnums::SHARED_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
+ case cmStateEnums::UNKNOWN_LIBRARY:
dep = target->GetLocation(config);
return true;
- case cmState::OBJECT_LIBRARY:
+ case cmStateEnums::OBJECT_LIBRARY:
// An object library has no single file on which to depend.
// This was listed to get the target-level dependency.
return false;
- case cmState::INTERFACE_LIBRARY:
+ case cmStateEnums::INTERFACE_LIBRARY:
// An interface library has no file on which to depend.
// This was listed to get the target-level dependency.
return false;
- case cmState::UTILITY:
- case cmState::GLOBAL_TARGET:
+ case cmStateEnums::UTILITY:
+ case cmStateEnums::GLOBAL_TARGET:
// A utility target has no file on which to depend. This was listed
// only to get the target-level dependency.
return false;
@@ -1924,8 +1587,8 @@ void cmLocalGenerator::AddVisibilityPresetFlags(
std::string warnCMP0063;
std::string* pWarnCMP0063 = CM_NULLPTR;
- if (target->GetType() != cmState::SHARED_LIBRARY &&
- target->GetType() != cmState::MODULE_LIBRARY &&
+ if (target->GetType() != cmStateEnums::SHARED_LIBRARY &&
+ target->GetType() != cmStateEnums::MODULE_LIBRARY &&
!target->IsExecutableWithExports()) {
switch (target->GetPolicyStatusCMP0063()) {
case cmPolicies::OLD:
@@ -1967,13 +1630,13 @@ void cmLocalGenerator::AddCMP0018Flags(std::string& flags,
{
int targetType = target->GetType();
- bool shared = ((targetType == cmState::SHARED_LIBRARY) ||
- (targetType == cmState::MODULE_LIBRARY));
+ bool shared = ((targetType == cmStateEnums::SHARED_LIBRARY) ||
+ (targetType == cmStateEnums::MODULE_LIBRARY));
if (this->GetShouldUseOldFlags(shared, lang)) {
this->AddSharedFlags(flags, lang, shared);
} else {
- if (target->GetType() == cmState::OBJECT_LIBRARY) {
+ if (target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE")) {
this->AddPositionIndependentFlags(flags, lang, targetType);
}
@@ -2036,7 +1699,7 @@ void cmLocalGenerator::AddPositionIndependentFlags(std::string& flags,
{
const char* picFlags = CM_NULLPTR;
- if (targetType == cmState::EXECUTABLE) {
+ if (targetType == cmStateEnums::EXECUTABLE) {
std::string flagsVar = "CMAKE_";
flagsVar += lang;
flagsVar += "_COMPILE_OPTIONS_PIE";
@@ -2208,7 +1871,7 @@ const char* cmLocalGenerator::GetFeature(const std::string& feature,
featureName += "_";
featureName += cmSystemTools::UpperCase(config);
}
- cmState::Snapshot snp = this->StateSnapshot;
+ cmStateSnapshot snp = this->StateSnapshot;
while (snp.IsValid()) {
if (const char* value = snp.GetDirectory().GetProperty(featureName)) {
return value;
@@ -2273,7 +1936,7 @@ void cmLocalGenerator::GenerateTargetInstallRules(
std::vector<cmGeneratorTarget*> tgts = this->GetGeneratorTargets();
for (std::vector<cmGeneratorTarget*>::iterator l = tgts.begin();
l != tgts.end(); ++l) {
- if ((*l)->GetType() == cmState::INTERFACE_LIBRARY) {
+ if ((*l)->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
@@ -2296,15 +1959,15 @@ void cmLocalGenerator::GenerateTargetInstallRules(
// Generate the proper install generator for this target type.
switch ((*l)->GetType()) {
- case cmState::EXECUTABLE:
- case cmState::STATIC_LIBRARY:
- case cmState::MODULE_LIBRARY: {
+ case cmStateEnums::EXECUTABLE:
+ case cmStateEnums::STATIC_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY: {
// Use a target install generator.
cmInstallTargetGeneratorLocal g(this, (*l)->GetName(),
destination.c_str(), false);
g.Generate(os, config, configurationTypes);
} break;
- case cmState::SHARED_LIBRARY: {
+ case cmStateEnums::SHARED_LIBRARY: {
#if defined(_WIN32) || defined(__CYGWIN__)
// Special code to handle DLL. Install the import library
// to the normal destination and the DLL to the runtime
@@ -2339,17 +2002,6 @@ void cmLocalGenerator::GenerateTargetInstallRules(
}
#if defined(CM_LG_ENCODE_OBJECT_NAMES)
-static std::string cmLocalGeneratorMD5(const char* input)
-{
- char md5out[32];
- cmsysMD5* md5 = cmsysMD5_New();
- cmsysMD5_Initialize(md5);
- cmsysMD5_Append(md5, reinterpret_cast<unsigned char const*>(input), -1);
- cmsysMD5_FinalizeHex(md5, md5out);
- cmsysMD5_Delete(md5);
- return std::string(md5out, 32);
-}
-
static bool cmLocalGeneratorShortenObjectName(std::string& objName,
std::string::size_type max_len)
{
@@ -2358,7 +2010,8 @@ static bool cmLocalGeneratorShortenObjectName(std::string& objName,
std::string::size_type pos =
objName.find('/', objName.size() - max_len + 32);
if (pos != objName.npos) {
- std::string md5name = cmLocalGeneratorMD5(objName.substr(0, pos).c_str());
+ cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+ std::string md5name = md5.HashString(objName.substr(0, pos));
md5name += objName.substr(pos);
objName = md5name;