summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmDocumentGeneratorExpressions.h23
-rw-r--r--Source/cmExportBuildFileGenerator.cxx1
-rw-r--r--Source/cmExportFileGenerator.cxx287
-rw-r--r--Source/cmExportFileGenerator.h8
-rw-r--r--Source/cmExportInstallFileGenerator.cxx89
-rw-r--r--Source/cmExportInstallFileGenerator.h2
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx2
-rw-r--r--Source/cmFLTKWrapUICommand.cxx6
-rw-r--r--Source/cmFindPackageCommand.cxx20
-rw-r--r--Source/cmGeneratorExpression.cxx8
-rw-r--r--Source/cmGeneratorExpression.h5
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx61
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h9
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx268
-rw-r--r--Source/cmGeneratorExpressionEvaluator.h1
-rw-r--r--Source/cmGeneratorTarget.cxx29
-rw-r--r--Source/cmGeneratorTarget.h2
-rw-r--r--Source/cmGlobalGenerator.cxx4
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx4
-rw-r--r--Source/cmIncludeDirectoryCommand.cxx92
-rw-r--r--Source/cmIncludeDirectoryCommand.h8
-rw-r--r--Source/cmLinkDirectoriesCommand.h6
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx17
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx4
-rw-r--r--Source/cmMakefile.cxx37
-rw-r--r--Source/cmMakefile.h11
-rw-r--r--Source/cmMakefileTargetGenerator.cxx4
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx2
-rw-r--r--Source/cmNinjaTargetGenerator.cxx4
-rw-r--r--Source/cmPolicies.cxx21
-rw-r--r--Source/cmPolicies.h1
-rw-r--r--Source/cmQtAutomoc.cxx6
-rw-r--r--Source/cmSystemTools.cxx51
-rw-r--r--Source/cmTarget.cxx389
-rw-r--r--Source/cmTarget.h21
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.cxx39
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.h16
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx52
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.h16
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx67
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h13
-rw-r--r--Source/cmTargetPropCommandBase.cxx25
-rw-r--r--Source/cmTargetPropCommandBase.h23
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx4
-rw-r--r--Source/cmake.cxx4
-rw-r--r--Source/kwsys/DynamicLoader.cxx52
-rw-r--r--Source/kwsys/Glob.cxx2
-rw-r--r--Source/kwsys/IOStream.cxx1
-rw-r--r--Source/kwsys/ProcessUNIX.c2
-rw-r--r--Source/kwsys/SystemInformation.cxx5
-rw-r--r--Source/kwsys/SystemTools.cxx4
-rw-r--r--Source/kwsys/testCommandLineArguments.cxx16
-rw-r--r--Source/kwsys/testDynamicLoader.cxx2
-rw-r--r--Source/kwsys/testProcess.c22
-rw-r--r--Source/kwsys/testSystemTools.cxx26
56 files changed, 1425 insertions, 471 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 73e99df..8a54237 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -2,5 +2,5 @@
set(CMake_VERSION_MAJOR 2)
set(CMake_VERSION_MINOR 8)
set(CMake_VERSION_PATCH 10)
-set(CMake_VERSION_TWEAK 20130118)
+set(CMake_VERSION_TWEAK 20130205)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h
index fa21907..3993f7d 100644
--- a/Source/cmDocumentGeneratorExpressions.h
+++ b/Source/cmDocumentGeneratorExpressions.h
@@ -47,9 +47,24 @@
" $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n" \
" $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n" \
"\n" \
- " $<TARGET_PROPERTY:tgt,prop> = The value of the property prop\n" \
- "on the target tgt. Note that tgt is not added as a dependency of\n" \
- "the target this expression is evaluated on.\n" \
+ " $<TARGET_PROPERTY:tgt,prop> = The value of the property prop " \
+ "on the target tgt.\n" \
+ "Note that tgt is not added as a dependency of the target this " \
+ "expression is evaluated on.\n" \
+ " $<LINKED:item> = An empty string if item is not a " \
+ "target. If item is a target then the " \
+ "INTERFACE_INCLUDE_DIRECTORIES or INTERFACE_COMPILE_DEFINITIONS " \
+ "content is read from the target. " \
+ "This generator expression can only be used in evaluation of the " \
+ "INCLUDE_DIRECTORIES or COMPILE_DEFINITIONS property. Note that " \
+ "this expression is for internal use and may be changed or removed " \
+ "in the future.\n" \
+ " $<TARGET_POLICY:pol> = '1' if the policy was NEW when " \
+ "the 'head' target was created, else '0'. If the policy was not " \
+ "set, the warning message for the policy will be emitted. This " \
+ "generator expression only works for a subset of policies.\n" \
+ " $<INSTALL_PREFIX> = Content of the install prefix when " \
+ "the target is exported via INSTALL(EXPORT) and empty otherwise.\n" \
"Boolean expressions:\n" \
" $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \
" $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \
@@ -60,7 +75,7 @@
#define CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS \
CM_DOCUMENT_ADD_TEST_GENERATOR_EXPRESSIONS \
"Expressions with an implicit 'this' target:\n" \
- " $<TARGET_PROPERTY:prop> = The value of the property prop on\n" \
+ " $<TARGET_PROPERTY:prop> = The value of the property prop on " \
"the target on which the generator expression is evaluated.\n" \
""
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 61e130d..7147f86 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -74,6 +74,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
te, properties);
+ this->PopulateCompatibleInterfaceProperties(te, properties);
this->GenerateInterfaceProperties(te, os, properties);
}
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 4a7c6f9..7e4c3df 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -21,9 +21,12 @@
#include "cmTarget.h"
#include "cmTargetExport.h"
#include "cmVersion.h"
+#include "cmComputeLinkInformation.h"
#include <cmsys/auto_ptr.hxx>
+#include "assert.h"
+
//----------------------------------------------------------------------------
cmExportFileGenerator::cmExportFileGenerator()
{
@@ -81,16 +84,16 @@ bool cmExportFileGenerator::GenerateImportFile()
// Protect that file against use with older CMake versions.
os << "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n";
- os << "IF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
- << " MESSAGE(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
- << "ENDIF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n";
+ os << "if(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
+ << " message(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
+ << "endif()\n";
// Isolate the file policy level.
// We use 2.6 here instead of the current version because newer
// versions of CMake should be able to export files imported by 2.6
// until the import format changes.
- os << "CMAKE_POLICY(PUSH)\n"
- << "CMAKE_POLICY(VERSION 2.6)\n";
+ os << "cmake_policy(PUSH)\n"
+ << "cmake_policy(VERSION 2.6)\n";
// Start with the import file header.
this->GenerateImportHeaderCode(os);
@@ -100,7 +103,7 @@ bool cmExportFileGenerator::GenerateImportFile()
// End with the import file footer.
this->GenerateImportFooterCode(os);
- os << "CMAKE_POLICY(POP)\n";
+ os << "cmake_policy(POP)\n";
return result;
}
@@ -159,7 +162,7 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
preprocessRule);
if (!prepro.empty())
{
- this->ResolveTargetsInGeneratorExpressions(prepro, target,
+ this->ResolveTargetsInGeneratorExpressions(prepro, target, propName,
missingTargets);
properties[outputName] = prepro;
}
@@ -177,6 +180,85 @@ void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
properties, missingTargets);
}
+
+//----------------------------------------------------------------------------
+void getPropertyContents(cmTarget *tgt, const char *prop,
+ std::set<std::string> &ifaceProperties)
+{
+ const char *p = tgt->GetProperty(prop);
+ if (!p)
+ {
+ return;
+ }
+ std::vector<std::string> content;
+ cmSystemTools::ExpandListArgument(p, content);
+ for (std::vector<std::string>::const_iterator ci = content.begin();
+ ci != content.end(); ++ci)
+ {
+ ifaceProperties.insert(*ci);
+ }
+}
+
+//----------------------------------------------------------------------------
+void getCompatibleInterfaceProperties(cmTarget *target,
+ std::set<std::string> &ifaceProperties,
+ const char *config)
+{
+ cmComputeLinkInformation *info = target->GetLinkInformation(config);
+
+ const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+ for(cmComputeLinkInformation::ItemVector::const_iterator li =
+ deps.begin();
+ li != deps.end(); ++li)
+ {
+ if (!li->Target)
+ {
+ continue;
+ }
+ getPropertyContents(li->Target,
+ "COMPATIBLE_INTERFACE_BOOL",
+ ifaceProperties);
+ getPropertyContents(li->Target,
+ "COMPATIBLE_INTERFACE_STRING",
+ ifaceProperties);
+ }
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
+ cmTarget *target,
+ ImportPropertyMap &properties)
+{
+ this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL",
+ target, properties);
+ this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING",
+ target, properties);
+
+ std::set<std::string> ifaceProperties;
+
+ getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties);
+ getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties);
+
+ getCompatibleInterfaceProperties(target, ifaceProperties, 0);
+
+ std::vector<std::string> configNames;
+ target->GetMakefile()->GetConfigurations(configNames);
+
+ for (std::vector<std::string>::const_iterator ci = configNames.begin();
+ ci != configNames.end(); ++ci)
+ {
+ getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str());
+ }
+
+ for (std::set<std::string>::const_iterator it = ifaceProperties.begin();
+ it != ifaceProperties.end(); ++it)
+ {
+ this->PopulateInterfaceProperty(("INTERFACE_" + *it).c_str(),
+ target, properties);
+ }
+}
+
//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
std::ostream& os,
@@ -184,15 +266,16 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
{
if (!properties.empty())
{
+ os << "if(NOT ${CMAKE_FIND_PACKAGE_NAME}_NO_INTERFACES)\n";
std::string targetName = this->Namespace;
targetName += target->GetName();
- os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n";
+ os << " set_target_properties(" << targetName << " PROPERTIES\n";
for(ImportPropertyMap::const_iterator pi = properties.begin();
pi != properties.end(); ++pi)
{
- os << " " << pi->first << " \"" << pi->second << "\"\n";
+ os << " " << pi->first << " \"" << pi->second << "\"\n";
}
- os << ")\n\n";
+ os << " )\nendif()\n\n";
}
}
@@ -243,13 +326,14 @@ static bool isGeneratorExpression(const std::string &lib)
void
cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
std::string &input,
- cmTarget* target,
+ cmTarget* target, const char *propName,
std::vector<std::string> &missingTargets,
FreeTargetsReplace replace)
{
if (replace == NoReplaceFreeTargets)
{
- this->ResolveTargetsInGeneratorExpression(input, target, missingTargets);
+ this->ResolveTargetsInGeneratorExpression(input, target, propName,
+ missingTargets);
return;
}
std::vector<std::string> parts;
@@ -268,7 +352,7 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
{
this->ResolveTargetsInGeneratorExpression(
*li,
- target,
+ target, propName,
missingTargets);
}
input += sep + *li;
@@ -280,14 +364,13 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
void
cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
std::string &input,
- cmTarget* target,
+ cmTarget* target, const char *propName,
std::vector<std::string> &missingTargets)
{
std::string::size_type pos = 0;
std::string::size_type lastPos = pos;
cmMakefile *mf = target->GetMakefile();
- std::string errorString;
while((pos = input.find("$<TARGET_PROPERTY:", lastPos)) != input.npos)
{
@@ -308,14 +391,58 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
std::string targetName = input.substr(nameStartPos,
commaPos - nameStartPos);
- if (!this->AddTargetNamespace(targetName, target, missingTargets))
+ if (this->AddTargetNamespace(targetName, target, missingTargets))
+ {
+ input.replace(nameStartPos, commaPos - nameStartPos, targetName);
+ }
+ lastPos = nameStartPos + targetName.size() + 1;
+ }
+
+ std::string errorString;
+ pos = 0;
+ lastPos = pos;
+ while((pos = input.find("$<LINKED:", lastPos)) != input.npos)
+ {
+ std::string::size_type nameStartPos = pos + sizeof("$<LINKED:") - 1;
+ std::string::size_type endPos = input.find(">", nameStartPos);
+ if (endPos == input.npos)
+ {
+ errorString = "$<LINKED:...> expression incomplete";
+ break;
+ }
+ std::string targetName = input.substr(nameStartPos,
+ endPos - nameStartPos);
+ if(targetName.find("$<") != input.npos)
{
- errorString = "$<TARGET_PROPERTY:" + targetName + ",prop> requires "
- "its first parameter to be a reachable target.";
+ errorString = "$<LINKED:...> requires its parameter to be a "
+ "literal.";
break;
}
- input.replace(nameStartPos, commaPos - nameStartPos, targetName);
- lastPos = pos + targetName.size();
+ if (this->AddTargetNamespace(targetName, target, missingTargets))
+ {
+ assert(propName); // The link libraries strings will
+ // never contain $<LINKED>
+ std::string replacement = "$<TARGET_PROPERTY:"
+ + targetName + "," + propName;
+ input.replace(pos, endPos - pos, replacement);
+ lastPos = pos + replacement.size() + 1;
+ }
+ else
+ {
+ if (pos != 0)
+ {
+ if (input[pos - 1] == ';')
+ {
+ --pos;
+ }
+ }
+ else if (input[endPos + 1] == ';')
+ {
+ ++endPos;
+ }
+ input.replace(pos, endPos - pos + 1, "");
+ lastPos = pos;
+ }
}
if (!errorString.empty())
{
@@ -351,6 +478,9 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
input.replace(pos, endPos - pos + 1, targetName);
lastPos = endPos;
}
+
+ this->ReplaceInstallPrefix(input);
+
if (!errorString.empty())
{
mf->IssueMessage(cmake::FATAL_ERROR, errorString);
@@ -359,6 +489,13 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
//----------------------------------------------------------------------------
void
+cmExportFileGenerator::ReplaceInstallPrefix(std::string &)
+{
+ // Do nothing
+}
+
+//----------------------------------------------------------------------------
+void
cmExportFileGenerator
::SetImportLinkInterface(const char* config, std::string const& suffix,
cmGeneratorExpression::PreprocessContext preprocessRule,
@@ -408,7 +545,7 @@ cmExportFileGenerator
preprocessRule);
if (!prepro.empty())
{
- this->ResolveTargetsInGeneratorExpressions(prepro, target,
+ this->ResolveTargetsInGeneratorExpressions(prepro, target, 0,
missingTargets,
ReplaceFreeTargets);
properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
@@ -536,7 +673,7 @@ void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
void cmExportFileGenerator::GenerateImportFooterCode(std::ostream& os)
{
os << "# Commands beyond this point should not need to know the version.\n"
- << "SET(CMAKE_IMPORT_FILE_VERSION)\n";
+ << "set(CMAKE_IMPORT_FILE_VERSION)\n";
}
//----------------------------------------------------------------------------
@@ -545,7 +682,7 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
// Store an import file format version. This will let us change the
// format later while still allowing old import files to work.
os << "# Commands may need to know the format version.\n"
- << "SET(CMAKE_IMPORT_FILE_VERSION 1)\n"
+ << "set(CMAKE_IMPORT_FILE_VERSION 1)\n"
<< "\n";
}
@@ -553,31 +690,31 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os,
const std::string &expectedTargets)
{
- os << "SET(_targetsDefined)\n"
- "SET(_targetsNotDefined)\n"
- "SET(_expectedTargets)\n"
- "FOREACH(_expectedTarget " << expectedTargets << ")\n"
- " LIST(APPEND _expectedTargets ${_expectedTarget})\n"
- " IF(NOT TARGET ${_expectedTarget})\n"
- " LIST(APPEND _targetsNotDefined ${_expectedTarget})\n"
- " ENDIF(NOT TARGET ${_expectedTarget})\n"
- " IF(TARGET ${_expectedTarget})\n"
- " LIST(APPEND _targetsDefined ${_expectedTarget})\n"
- " ENDIF(TARGET ${_expectedTarget})\n"
- "ENDFOREACH(_expectedTarget)\n"
- "IF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
- " SET(CMAKE_IMPORT_FILE_VERSION)\n"
- " CMAKE_POLICY(POP)\n"
- " RETURN()\n"
- "ENDIF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
- "IF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
- " MESSAGE(FATAL_ERROR \"Some (but not all) targets in this export "
+ os << "set(_targetsDefined)\n"
+ "set(_targetsNotDefined)\n"
+ "set(_expectedTargets)\n"
+ "foreach(_expectedTarget " << expectedTargets << ")\n"
+ " list(APPEND _expectedTargets ${_expectedTarget})\n"
+ " if(NOT TARGET ${_expectedTarget})\n"
+ " list(APPEND _targetsNotDefined ${_expectedTarget})\n"
+ " endif()\n"
+ " if(TARGET ${_expectedTarget})\n"
+ " list(APPEND _targetsDefined ${_expectedTarget})\n"
+ " endif()\n"
+ "endforeach()\n"
+ "if(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n"
+ " set(CMAKE_IMPORT_FILE_VERSION)\n"
+ " cmake_policy(POP)\n"
+ " return()\n"
+ "endif()\n"
+ "if(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
+ " message(FATAL_ERROR \"Some (but not all) targets in this export "
"set were already defined.\\nTargets Defined: ${_targetsDefined}\\n"
"Targets not yet defined: ${_targetsNotDefined}\\n\")\n"
- "ENDIF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n"
- "UNSET(_targetsDefined)\n"
- "UNSET(_targetsNotDefined)\n"
- "UNSET(_expectedTargets)\n"
+ "endif()\n"
+ "unset(_targetsDefined)\n"
+ "unset(_targetsNotDefined)\n"
+ "unset(_expectedTargets)\n"
"\n\n";
}
//----------------------------------------------------------------------------
@@ -594,16 +731,16 @@ cmExportFileGenerator
switch(target->GetType())
{
case cmTarget::EXECUTABLE:
- os << "ADD_EXECUTABLE(" << targetName << " IMPORTED)\n";
+ os << "add_executable(" << targetName << " IMPORTED)\n";
break;
case cmTarget::STATIC_LIBRARY:
- os << "ADD_LIBRARY(" << targetName << " STATIC IMPORTED)\n";
+ os << "add_library(" << targetName << " STATIC IMPORTED)\n";
break;
case cmTarget::SHARED_LIBRARY:
- os << "ADD_LIBRARY(" << targetName << " SHARED IMPORTED)\n";
+ os << "add_library(" << targetName << " SHARED IMPORTED)\n";
break;
case cmTarget::MODULE_LIBRARY:
- os << "ADD_LIBRARY(" << targetName << " MODULE IMPORTED)\n";
+ os << "add_library(" << targetName << " MODULE IMPORTED)\n";
break;
default: // should never happen
break;
@@ -612,27 +749,27 @@ cmExportFileGenerator
// Mark the imported executable if it has exports.
if(target->IsExecutableWithExports())
{
- os << "SET_PROPERTY(TARGET " << targetName
+ os << "set_property(TARGET " << targetName
<< " PROPERTY ENABLE_EXPORTS 1)\n";
}
// Mark the imported library if it is a framework.
if(target->IsFrameworkOnApple())
{
- os << "SET_PROPERTY(TARGET " << targetName
+ os << "set_property(TARGET " << targetName
<< " PROPERTY FRAMEWORK 1)\n";
}
// Mark the imported executable if it is an application bundle.
if(target->IsAppBundleOnApple())
{
- os << "SET_PROPERTY(TARGET " << targetName
+ os << "set_property(TARGET " << targetName
<< " PROPERTY MACOSX_BUNDLE 1)\n";
}
if (target->IsCFBundleOnApple())
{
- os << "SET_PROPERTY(TARGET " << targetName
+ os << "set_property(TARGET " << targetName
<< " PROPERTY BUNDLE 1)\n";
}
os << "\n";
@@ -652,7 +789,7 @@ cmExportFileGenerator
// Set the import properties.
os << "# Import target \"" << targetName << "\" for configuration \""
<< config << "\"\n";
- os << "SET_PROPERTY(TARGET " << targetName
+ os << "set_property(TARGET " << targetName
<< " APPEND PROPERTY IMPORTED_CONFIGURATIONS ";
if(config && *config)
{
@@ -663,7 +800,7 @@ cmExportFileGenerator
os << "NOCONFIG";
}
os << ")\n";
- os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n";
+ os << "set_target_properties(" << targetName << " PROPERTIES\n";
for(ImportPropertyMap::const_iterator pi = properties.begin();
pi != properties.end(); ++pi)
{
@@ -689,17 +826,17 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os,
{
if (emitted.insert(missingTargets[i]).second)
{
- os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n"
- << " IF(CMAKE_FIND_PACKAGE_NAME)\n"
- << " SET( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n"
- << " SET( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "
+ os << "if(NOT TARGET \"" << missingTargets[i] << "\" )\n"
+ << " if(CMAKE_FIND_PACKAGE_NAME)\n"
+ << " set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n"
+ << " set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "
<< "\"Required imported target \\\"" << missingTargets[i]
<< "\\\" not found ! \")\n"
- << " ELSE()\n"
- << " MESSAGE(FATAL_ERROR \"Required imported target \\\""
+ << " else()\n"
+ << " message(FATAL_ERROR \"Required imported target \\\""
<< missingTargets[i] << "\\\" not found ! \")\n"
- << " ENDIF()\n"
- << "ENDIF()\n";
+ << " endif()\n"
+ << "endif()\n";
}
}
os << "\n";
@@ -718,10 +855,10 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
// on SUSE with a mysql pkg-config file, which claimed everything is fine,
// but the development package was not installed.).
os << "# Loop over all imported files and verify that they actually exist\n"
- "FOREACH(target ${_IMPORT_CHECK_TARGETS} )\n"
- " FOREACH(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
- " IF(NOT EXISTS \"${file}\" )\n"
- " MESSAGE(FATAL_ERROR \"The imported target \\\"${target}\\\""
+ "foreach(target ${_IMPORT_CHECK_TARGETS} )\n"
+ " foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
+ " if(NOT EXISTS \"${file}\" )\n"
+ " message(FATAL_ERROR \"The imported target \\\"${target}\\\""
" references the file\n"
" \\\"${file}\\\"\n"
"but this file does not exist. Possible reasons include:\n"
@@ -731,11 +868,11 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
" \\\"${CMAKE_CURRENT_LIST_FILE}\\\"\n"
"but not all the files it references.\n"
"\")\n"
- " ENDIF()\n"
- " ENDFOREACH()\n"
- " UNSET(_IMPORT_CHECK_FILES_FOR_${target})\n"
- "ENDFOREACH()\n"
- "UNSET(_IMPORT_CHECK_TARGETS)\n"
+ " endif()\n"
+ " endforeach()\n"
+ " unset(_IMPORT_CHECK_FILES_FOR_${target})\n"
+ "endforeach()\n"
+ "unset(_IMPORT_CHECK_TARGETS)\n"
"\n";
}
@@ -751,8 +888,8 @@ cmExportFileGenerator
std::string targetName = this->Namespace;
targetName += target->GetName();
- os << "LIST(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n"
- "LIST(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " ";
+ os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n"
+ "list(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " ";
for(std::set<std::string>::const_iterator li = importedLocations.begin();
li != importedLocations.end();
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index eb3f3c3..5ad27bf 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -103,6 +103,8 @@ protected:
std::vector<std::string> &missingTargets);
void PopulateInterfaceProperty(const char *propName, cmTarget *target,
ImportPropertyMap &properties);
+ void PopulateCompatibleInterfaceProperties(cmTarget *target,
+ ImportPropertyMap &properties);
void GenerateInterfaceProperties(cmTarget *target, std::ostream& os,
const ImportPropertyMap &properties);
@@ -117,7 +119,7 @@ protected:
};
void ResolveTargetsInGeneratorExpressions(std::string &input,
- cmTarget* target,
+ cmTarget* target, const char *propName,
std::vector<std::string> &missingTargets,
FreeTargetsReplace replace = NoReplaceFreeTargets);
@@ -148,8 +150,10 @@ private:
std::vector<std::string> &missingTargets);
void ResolveTargetsInGeneratorExpression(std::string &input,
- cmTarget* target,
+ cmTarget* target, const char *propName,
std::vector<std::string> &missingTargets);
+
+ virtual void ReplaceInstallPrefix(std::string &input);
};
#endif
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index 965f63d..b6600f0 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -57,7 +57,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
else
{
cmOStringStream e;
- e << "INSTALL(EXPORT \""
+ e << "install(EXPORT \""
<< this->IEGen->GetExportSet()->GetName()
<< "\" ...) " << "includes target \"" << te->Target->GetName()
<< "\" more than once in the export set.";
@@ -69,6 +69,27 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateExpectedTargetsCode(os, expectedTargets);
}
+ // Add code to compute the installation prefix relative to the
+ // import file location.
+ const char* installDest = this->IEGen->GetDestination();
+ if(!cmSystemTools::FileIsFullPath(installDest))
+ {
+ std::string dest = installDest;
+ os << "# Compute the installation prefix relative to this file.\n"
+ << "get_filename_component(_IMPORT_PREFIX "
+ << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
+ while(!dest.empty())
+ {
+ os <<
+ "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
+ dest = cmSystemTools::GetFilenamePath(dest);
+ }
+ os << "\n";
+
+ // Import location properties may reference this variable.
+ this->ImportPrefix = "${_IMPORT_PREFIX}/";
+ }
+
std::vector<std::string> missingTargets;
// Create all the imported targets.
@@ -91,6 +112,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
properties, missingTargets);
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
te, properties);
+ this->PopulateCompatibleInterfaceProperties(te, properties);
this->GenerateInterfaceProperties(te, os, properties);
}
@@ -98,14 +120,21 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
// Now load per-configuration properties for them.
os << "# Load information for each installed configuration.\n"
- << "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
- << "FILE(GLOB CONFIG_FILES \"${_DIR}/"
+ << "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n"
+ << "file(GLOB CONFIG_FILES \"${_DIR}/"
<< this->GetConfigImportFileGlob() << "\")\n"
- << "FOREACH(f ${CONFIG_FILES})\n"
- << " INCLUDE(${f})\n"
- << "ENDFOREACH(f)\n"
+ << "foreach(f ${CONFIG_FILES})\n"
+ << " include(${f})\n"
+ << "endforeach()\n"
<< "\n";
+ // Cleanup the import prefix variable.
+ if(!this->ImportPrefix.empty())
+ {
+ os << "# Cleanup temporary variables.\n"
+ << "set(_IMPORT_PREFIX)\n"
+ << "\n";
+ }
this->GenerateImportedFileCheckLoop(os);
// Generate an import file for each configuration.
@@ -126,6 +155,21 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
}
//----------------------------------------------------------------------------
+void
+cmExportInstallFileGenerator::ReplaceInstallPrefix(std::string &input)
+{
+ std::string::size_type pos = 0;
+ std::string::size_type lastPos = pos;
+
+ while((pos = input.find("$<INSTALL_PREFIX>", lastPos)) != input.npos)
+ {
+ std::string::size_type endPos = pos + sizeof("$<INSTALL_PREFIX>") - 1;
+ input.replace(pos, endPos - pos, "${_IMPORT_PREFIX}");
+ lastPos = endPos;
+ }
+}
+
+//----------------------------------------------------------------------------
bool
cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
std::vector<std::string> &missingTargets)
@@ -186,27 +230,6 @@ cmExportInstallFileGenerator
const char* config, std::string const& suffix,
std::vector<std::string> &missingTargets)
{
- // Add code to compute the installation prefix relative to the
- // import file location.
- const char* installDest = this->IEGen->GetDestination();
- if(!cmSystemTools::FileIsFullPath(installDest))
- {
- std::string dest = installDest;
- os << "# Compute the installation prefix relative to this file.\n"
- << "GET_FILENAME_COMPONENT(_IMPORT_PREFIX "
- << "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
- while(!dest.empty())
- {
- os <<
- "GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
- dest = cmSystemTools::GetFilenamePath(dest);
- }
- os << "\n";
-
- // Import location properties may reference this variable.
- this->ImportPrefix = "${_IMPORT_PREFIX}/";
- }
-
// Add each target in the set to the export.
for(std::vector<cmTargetExport*>::const_iterator
tei = this->IEGen->GetExportSet()->GetTargetExports()->begin();
@@ -252,14 +275,6 @@ cmExportInstallFileGenerator
importedLocations);
}
}
-
- // Cleanup the import prefix variable.
- if(!this->ImportPrefix.empty())
- {
- os << "# Cleanup temporary variables.\n"
- << "SET(_IMPORT_PREFIX)\n"
- << "\n";
- }
}
//----------------------------------------------------------------------------
@@ -427,7 +442,7 @@ cmExportInstallFileGenerator
{
const char* installDest = this->IEGen->GetDestination();
cmOStringStream e;
- e << "INSTALL(EXPORT \""
+ e << "install(EXPORT \""
<< this->IEGen->GetExportSet()->GetName()
<< "\") given absolute "
<< "DESTINATION \"" << installDest << "\" but the export "
@@ -445,7 +460,7 @@ cmExportInstallFileGenerator
int occurrences)
{
cmOStringStream e;
- e << "INSTALL(EXPORT \""
+ e << "install(EXPORT \""
<< this->IEGen->GetExportSet()->GetName()
<< "\" ...) "
<< "includes target \"" << depender->GetName()
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index e187749..7a70431 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -64,6 +64,8 @@ protected:
cmTarget* depender,
cmTarget* dependee);
+ virtual void ReplaceInstallPrefix(std::string &input);
+
void ComplainAboutMissingTarget(cmTarget* depender,
cmTarget* dependee,
int occurrences);
diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx
index 0cf9cbb..6d5d5b5 100644
--- a/Source/cmExtraCodeBlocksGenerator.cxx
+++ b/Source/cmExtraCodeBlocksGenerator.cxx
@@ -621,7 +621,7 @@ void cmExtraCodeBlocksGenerator::AppendTarget(cmGeneratedFileStream& fout,
->GetGeneratorTarget(target);
// the compilerdefines for this target
- std::string cdefs = gtgt->GetCompileDefinitions();
+ std::string cdefs = target->GetCompileDefinitions();
if(!cdefs.empty())
{
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index a4aa75a..b08c335 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -37,9 +37,13 @@ bool cmFLTKWrapUICommand
// get the list of GUI files from which .cxx and .h will be generated
std::string outputDirectory = this->Makefile->GetCurrentOutputDirectory();
+ {
// Some of the generated files are *.h so the directory "GUI"
// where they are created have to be added to the include path
- this->Makefile->AddIncludeDirectory( outputDirectory.c_str() );
+ std::vector<std::string> outputDirectories;
+ outputDirectories.push_back(outputDirectory);
+ this->Makefile->AddIncludeDirectories( outputDirectories );
+ }
for(std::vector<std::string>::iterator i = (newArgs.begin() + 1);
i != newArgs.end(); i++)
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 470ceca..6e78bd7 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -376,6 +376,26 @@ void cmFindPackageCommand::GenerateDocumentation()
"The package configuration file may set <package>_FOUND to false "
"to tell find_package that component requirements are not satisfied."
"\n"
+ "A package configuration file may include() a <package>Targets.cmake "
+ "file, created by install(EXPORT) in the upstream source, to import "
+ "targets into the downstream consumer. "
+ "When a new version of the upstream adds INTERFACE properties not "
+ "present in a previous version it can change behavior for existing "
+ "downstreams. "
+ "In order to remain source compatible the upstream package configuration "
+ "file may set <package>_NO_INTERFACES to disable INTERFACE properties. "
+ "For example, code of the form:\n"
+ " if(<package>_FIND_VERSION VERSION_LESS <new-version>\n"
+ " AND NOT <package>_INTERFACES)\n"
+ " set(<package>_NO_INTERFACES 1)\n"
+ " endif()\n"
+ " include(\"${CMAKE_CURRENT_LIST_DIR}/<package>Targets.cmake\")\n"
+ "tells <package>Targets.cmake not to provide the INTERFACE properties "
+ "unless the downstream requests at least <new-version> or sets "
+ "<package>_INTERFACES to explicitly request them. "
+ "This allows consumers to decide when to enable the new interfaces when "
+ "upgrading."
+ "\n"
"See the cmake_policy() command documentation for discussion of the "
"NO_POLICY_SCOPE option."
;
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 78ae8f2..7add1bf 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -88,6 +88,7 @@ const char *cmCompiledGeneratorExpression::Evaluate(
context.Config = config;
context.Quiet = quiet;
context.HadError = false;
+ context.HadContextSensitiveCondition = false;
context.HeadTarget = headTarget;
context.CurrentTarget = currentTarget ? currentTarget : headTarget;
context.Backtrace = this->Backtrace;
@@ -109,6 +110,10 @@ const char *cmCompiledGeneratorExpression::Evaluate(
break;
}
}
+ if (!context.HadError)
+ {
+ this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
+ }
this->Targets = context.Targets;
// TODO: Return a std::string from here instead?
@@ -118,7 +123,8 @@ const char *cmCompiledGeneratorExpression::Evaluate(
cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
cmListFileBacktrace const& backtrace,
const char *input)
- : Backtrace(backtrace), Input(input ? input : "")
+ : Backtrace(backtrace), Input(input ? input : ""),
+ HadContextSensitiveCondition(false)
{
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens =
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index 8f1aef6..700fe03 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -100,6 +100,10 @@ public:
{
return this->Backtrace;
}
+ bool GetHadContextSensitiveCondition() const
+ {
+ return this->HadContextSensitiveCondition;
+ }
private:
cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace,
@@ -118,6 +122,7 @@ private:
mutable std::set<cmTarget*> Targets;
mutable std::map<cmStdString, cmStdString> SeenTargetProperties;
mutable std::string Output;
+ mutable bool HadContextSensitiveCondition;
};
#endif
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 2e5b5ae..b9069ef 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -24,7 +24,33 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
: Parent(parent), Target(target), Property(property),
Content(content), Backtrace(backtrace)
{
+ const cmGeneratorExpressionDAGChecker *top = this;
+ const cmGeneratorExpressionDAGChecker *p = this->Parent;
+ while (p)
+ {
+ top = p;
+ p = p->Parent;
+ }
this->CheckResult = this->checkGraph();
+
+ if (CheckResult == DAG && (top->Property == "INCLUDE_DIRECTORIES"
+ || top->Property == "COMPILE_DEFINITIONS") )
+ {
+ std::map<cmStdString, std::set<cmStdString> >::const_iterator it
+ = top->Seen.find(target);
+ if (it != top->Seen.end())
+ {
+ const std::set<cmStdString> &propSet = it->second;
+ const std::set<cmStdString>::const_iterator i = propSet.find(property);
+ if (i != propSet.end())
+ {
+ this->CheckResult = ALREADY_SEEN;
+ return;
+ }
+ }
+ const_cast<cmGeneratorExpressionDAGChecker *>(top)
+ ->Seen[target].insert(property);
+ }
}
//----------------------------------------------------------------------------
@@ -106,3 +132,38 @@ cmGeneratorExpressionDAGChecker::checkGraph() const
}
return DAG;
}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries()
+{
+ const cmGeneratorExpressionDAGChecker *top = this;
+ const cmGeneratorExpressionDAGChecker *parent = this->Parent;
+ while (parent)
+ {
+ top = parent;
+ parent = parent->Parent;
+ }
+
+ const char *prop = top->Property.c_str();
+ return (strcmp(prop, "LINK_LIBRARIES") == 0
+ || strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0
+ || strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0
+ || strncmp(prop, "LINK_INTERFACE_LIBRARIES_", 26) == 0
+ || strncmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_", 35) == 0);
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpressionDAGChecker::EvaluatingIncludeDirectories()
+{
+ const char *prop = this->Property.c_str();
+ return (strcmp(prop, "INCLUDE_DIRECTORIES") == 0
+ || strcmp(prop, "INTERFACE_INCLUDE_DIRECTORIES") == 0 );
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratorExpressionDAGChecker::EvaluatingCompileDefinitions()
+{
+ const char *prop = this->Property.c_str();
+ return (strcmp(prop, "COMPILE_DEFINITIONS") == 0
+ || strcmp(prop, "INTERFACE_COMPILE_DEFINITIONS") == 0 );
+}
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index 48f26ed..a2e5ce4 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -28,13 +28,19 @@ struct cmGeneratorExpressionDAGChecker
enum Result {
DAG,
SELF_REFERENCE,
- CYCLIC_REFERENCE
+ CYCLIC_REFERENCE,
+ ALREADY_SEEN
};
Result check() const;
void reportError(cmGeneratorExpressionContext *context,
const std::string &expr);
+
+ bool EvaluatingLinkLibraries();
+ bool EvaluatingIncludeDirectories();
+ bool EvaluatingCompileDefinitions();
+
private:
Result checkGraph() const;
@@ -42,6 +48,7 @@ private:
const cmGeneratorExpressionDAGChecker * const Parent;
const std::string Target;
const std::string Property;
+ std::map<cmStdString, std::set<cmStdString> > Seen;
const GeneratorExpressionContent * const Content;
const cmListFileBacktrace Backtrace;
Result CheckResult;
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index 8e40815a..5d94718 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -238,6 +238,7 @@ static const struct ConfigurationNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent *,
cmGeneratorExpressionDAGChecker *) const
{
+ context->HadContextSensitiveCondition = true;
return context->Config ? context->Config : "";
}
} configurationNode;
@@ -262,6 +263,7 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
"Expression syntax not recognized.");
return std::string();
}
+ context->HadContextSensitiveCondition = true;
if (!context->Config)
{
return parameters.front().empty() ? "1" : "0";
@@ -435,6 +437,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
// No error. We just skip cyclic references.
return std::string();
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ // No error. We're not going to find anything new here.
+ return std::string();
case cmGeneratorExpressionDAGChecker::DAG:
break;
}
@@ -442,6 +447,39 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
const char *prop = target->GetProperty(propertyName.c_str());
if (!prop)
{
+ if (target->IsImported())
+ {
+ return std::string();
+ }
+ if (dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries())
+ {
+ return std::string();
+ }
+ if (propertyName == "POSITION_INDEPENDENT_CODE")
+ {
+ context->HadContextSensitiveCondition = true;
+ return target->GetLinkInterfaceDependentBoolProperty(
+ "POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0";
+ }
+ if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ return target->GetLinkInterfaceDependentBoolProperty(
+ propertyName,
+ context->Config) ? "1" : "0";
+ }
+ if (target->IsLinkInterfaceDependentStringProperty(propertyName,
+ context->Config))
+ {
+ context->HadContextSensitiveCondition = true;
+ const char *propContent =
+ target->GetLinkInterfaceDependentStringProperty(
+ propertyName,
+ context->Config);
+ return propContent ? propContent : "";
+ }
+
return std::string();
}
@@ -453,12 +491,19 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
if (targetPropertyTransitiveWhitelist[i] == propertyName)
{
cmGeneratorExpression ge(context->Backtrace);
- return ge.Parse(prop)->Evaluate(context->Makefile,
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
+ std::string result = cge->Evaluate(context->Makefile,
context->Config,
context->Quiet,
context->HeadTarget,
target,
&dagChecker);
+
+ if (cge->GetHadContextSensitiveCondition())
+ {
+ context->HadContextSensitiveCondition = true;
+ }
+ return result;
}
}
return prop;
@@ -488,6 +533,221 @@ static const struct TargetNameNode : public cmGeneratorExpressionNode
} targetNameNode;
//----------------------------------------------------------------------------
+static const char* targetPolicyWhitelist[] = {
+ "CMP0003"
+ , "CMP0004"
+ , "CMP0008"
+ , "CMP0020"
+};
+
+cmPolicies::PolicyStatus statusForTarget(cmTarget *tgt, const char *policy)
+{
+#define RETURN_POLICY(POLICY) \
+ if (strcmp(policy, #POLICY) == 0) \
+ { \
+ return tgt->GetPolicyStatus ## POLICY (); \
+ } \
+
+ RETURN_POLICY(CMP0003)
+ RETURN_POLICY(CMP0004)
+ RETURN_POLICY(CMP0008)
+ RETURN_POLICY(CMP0020)
+
+#undef RETURN_POLICY
+
+ assert("!Unreachable code. Not a valid policy");
+ return cmPolicies::WARN;
+}
+
+cmPolicies::PolicyID policyForString(const char *policy_id)
+{
+#define RETURN_POLICY_ID(POLICY_ID) \
+ if (strcmp(policy_id, #POLICY_ID) == 0) \
+ { \
+ return cmPolicies:: POLICY_ID; \
+ } \
+
+ RETURN_POLICY_ID(CMP0003)
+ RETURN_POLICY_ID(CMP0004)
+ RETURN_POLICY_ID(CMP0008)
+ RETURN_POLICY_ID(CMP0020)
+
+#undef RETURN_POLICY_ID
+
+ assert("!Unreachable code. Not a valid policy");
+ return cmPolicies::CMP0002;
+}
+
+//----------------------------------------------------------------------------
+static const struct TargetPolicyNode : public cmGeneratorExpressionNode
+{
+ TargetPolicyNode() {}
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context ,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ if (!context->HeadTarget)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_POLICY:prop> may only be used with targets. It may not "
+ "be used with add_custom_command.");
+ return std::string();
+ }
+
+ context->HadContextSensitiveCondition = true;
+
+ for (size_t i = 0;
+ i < (sizeof(targetPolicyWhitelist) /
+ sizeof(*targetPolicyWhitelist));
+ ++i)
+ {
+ const char *policy = targetPolicyWhitelist[i];
+ if (parameters.front() == policy)
+ {
+ cmMakefile *mf = context->HeadTarget->GetMakefile();
+ switch(statusForTarget(context->HeadTarget, policy))
+ {
+ case cmPolicies::WARN:
+ mf->IssueMessage(cmake::AUTHOR_WARNING,
+ mf->GetPolicies()->
+ GetPolicyWarning(policyForString(policy)));
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ case cmPolicies::OLD:
+ return "0";
+ case cmPolicies::NEW:
+ return "1";
+ }
+ }
+ }
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_POLICY:prop> may only be used with a limited number of "
+ "policies. Currently it may be used with policies CMP0003, CMP0004, "
+ "CMP0008 and CMP0020."
+ );
+ return std::string();
+ }
+
+} targetPolicyNode;
+
+//----------------------------------------------------------------------------
+static const struct InstallPrefixNode : public cmGeneratorExpressionNode
+{
+ InstallPrefixNode() {}
+
+ virtual bool GeneratesContent() const { return true; }
+ virtual int NumExpectedParameters() const { return 0; }
+
+ std::string Evaluate(const std::vector<std::string> &,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "INSTALL_PREFIX is a marker for install(EXPORT) only. It "
+ "should never be evaluated.");
+ return std::string();
+ }
+
+} installPrefixNode;
+
+//----------------------------------------------------------------------------
+static const struct LinkedNode : public cmGeneratorExpressionNode
+{
+ LinkedNode() {}
+
+ virtual bool GeneratesContent() const { return true; }
+ virtual int NumExpectedParameters() const { return 1; }
+ virtual bool RequiresLiteralInput() const { return true; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagChecker) const
+ {
+ if (dagChecker->EvaluatingIncludeDirectories())
+ {
+ return this->GetInterfaceProperty(parameters.front(),
+ "INCLUDE_DIRECTORIES",
+ context, content, dagChecker);
+ }
+ if (dagChecker->EvaluatingCompileDefinitions())
+ {
+ return this->GetInterfaceProperty(parameters.front(),
+ "COMPILE_DEFINITIONS",
+ context, content, dagChecker);
+ }
+
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINKED:...> may only be used in INCLUDE_DIRECTORIES and "
+ "COMPILE_DEFINITIONS properties.");
+
+ return std::string();
+ }
+
+private:
+ std::string GetInterfaceProperty(const std::string &item,
+ const std::string &prop,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *content,
+ cmGeneratorExpressionDAGChecker *dagCheckerParent) const
+ {
+ cmTarget *target = context->CurrentTarget
+ ->GetMakefile()->FindTargetToUse(item.c_str());
+ if (!target)
+ {
+ return std::string();
+ }
+ std::string propertyName = "INTERFACE_" + prop;
+ const char *propContent = target->GetProperty(propertyName.c_str());
+ if (!propContent)
+ {
+ return std::string();
+ }
+
+ cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace,
+ target->GetName(),
+ propertyName,
+ content,
+ dagCheckerParent);
+
+ switch (dagChecker.check())
+ {
+ case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+ dagChecker.reportError(context, content->GetOriginalExpression());
+ return std::string();
+ case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+ // No error. We just skip cyclic references.
+ return std::string();
+ case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+ // No error. We're not going to find anything new here.
+ return std::string();
+ case cmGeneratorExpressionDAGChecker::DAG:
+ break;
+ }
+
+ cmGeneratorExpression ge(context->Backtrace);
+ cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(propContent);
+ std::string result = cge->Evaluate(context->Makefile,
+ context->Config,
+ context->Quiet,
+ context->HeadTarget,
+ target,
+ &dagChecker);
+ if (cge->GetHadContextSensitiveCondition())
+ {
+ context->HadContextSensitiveCondition = true;
+ }
+ return result;
+ }
+
+} linkedNode;
+
+//----------------------------------------------------------------------------
template<bool linker, bool soname>
struct TargetFilesystemArtifactResultCreator
{
@@ -714,12 +974,18 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier)
return &targetPropertyNode;
else if (identifier == "TARGET_NAME")
return &targetNameNode;
+ else if (identifier == "TARGET_POLICY")
+ return &targetPolicyNode;
else if (identifier == "BUILD_INTERFACE")
return &buildInterfaceNode;
else if (identifier == "INSTALL_INTERFACE")
return &installInterfaceNode;
else if (identifier == "TARGET_DEFINED")
return &targetDefinedNode;
+ else if (identifier == "INSTALL_PREFIX")
+ return &installPrefixNode;
+ else if (identifier == "LINKED")
+ return &linkedNode;
return 0;
}
diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h
index fb6c7ee..37d5c86 100644
--- a/Source/cmGeneratorExpressionEvaluator.h
+++ b/Source/cmGeneratorExpressionEvaluator.h
@@ -32,6 +32,7 @@ struct cmGeneratorExpressionContext
// directly or indirectly in the property.
bool Quiet;
bool HadError;
+ bool HadContextSensitiveCondition;
};
struct cmGeneratorExpressionDAGChecker;
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 62ee26a..335ba0f 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -254,32 +254,3 @@ std::vector<std::string> cmGeneratorTarget::GetIncludeDirectories(
{
return this->Target->GetIncludeDirectories(config);
}
-
-//----------------------------------------------------------------------------
-std::string cmGeneratorTarget::GetCompileDefinitions(const char *config)
-{
- std::string defPropName = "COMPILE_DEFINITIONS";
- if (config)
- {
- defPropName += "_" + cmSystemTools::UpperCase(config);
- }
-
- const char *prop = this->Target->GetProperty(defPropName.c_str());
-
- if (!prop)
- {
- return "";
- }
-
- cmListFileBacktrace lfbt;
- cmGeneratorExpression ge(lfbt);
-
- cmGeneratorExpressionDAGChecker dagChecker(lfbt,
- this->GetName(),
- defPropName, 0, 0);
- return ge.Parse(prop)->Evaluate(this->Makefile,
- config,
- false,
- this->Target,
- &dagChecker);
-}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 6f5ecb7..cbcd8a5 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -68,8 +68,6 @@ public:
/** Get the include directories for this target. */
std::vector<std::string> GetIncludeDirectories(const char *config);
- std::string GetCompileDefinitions(const char *config = 0);
-
private:
void ClassifySources();
void LookupObjectLibraries();
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index d8afa53..ba29589 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -994,6 +994,7 @@ void cmGlobalGenerator::Generate()
// Generate project files
for (i = 0; i < this->LocalGenerators.size(); ++i)
{
+ this->LocalGenerators[i]->GetMakefile()->SetGeneratingBuildSystem();
this->SetCurrentLocalGenerator(this->LocalGenerators[i]);
this->LocalGenerators[i]->Generate();
this->LocalGenerators[i]->GenerateInstallRules();
@@ -1077,7 +1078,8 @@ void cmGlobalGenerator::CreateAutomocTargets()
if(target.GetType() == cmTarget::EXECUTABLE ||
target.GetType() == cmTarget::STATIC_LIBRARY ||
target.GetType() == cmTarget::SHARED_LIBRARY ||
- target.GetType() == cmTarget::MODULE_LIBRARY)
+ target.GetType() == cmTarget::MODULE_LIBRARY ||
+ target.GetType() == cmTarget::OBJECT_LIBRARY)
{
if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported())
{
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 316ecfd..9600771 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1700,11 +1700,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
this->AppendDefines(ppDefs, exportMacro);
}
cmGeneratorTarget *gtgt = this->GetGeneratorTarget(&target);
- this->AppendDefines(ppDefs, gtgt->GetCompileDefinitions().c_str());
+ this->AppendDefines(ppDefs, target.GetCompileDefinitions().c_str());
if(configName)
{
this->AppendDefines(ppDefs,
- gtgt->GetCompileDefinitions(configName).c_str());
+ target.GetCompileDefinitions(configName).c_str());
}
buildSettings->AddAttribute
("GCC_PREPROCESSOR_DEFINITIONS", ppDefs.CreateList());
diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx
index ba81849..671e09f 100644
--- a/Source/cmIncludeDirectoryCommand.cxx
+++ b/Source/cmIncludeDirectoryCommand.cxx
@@ -36,6 +36,10 @@ bool cmIncludeDirectoryCommand
++i;
}
+ std::vector<std::string> beforeIncludes;
+ std::vector<std::string> afterIncludes;
+ std::set<cmStdString> systemIncludes;
+
for(; i != args.end(); ++i)
{
if(*i == "SYSTEM")
@@ -49,9 +53,37 @@ bool cmIncludeDirectoryCommand
return false;
}
- this->AddDirectory(i->c_str(),before,system);
+ std::vector<std::string> includes;
+
+ GetIncludes(*i, includes);
+ if (before)
+ {
+ beforeIncludes.insert(beforeIncludes.end(),
+ includes.begin(),
+ includes.end());
+ }
+ else
+ {
+ afterIncludes.insert(afterIncludes.end(),
+ includes.begin(),
+ includes.end());
+ }
+ if (system)
+ {
+ for (std::vector<std::string>::const_iterator li = includes.begin();
+ li != includes.end(); ++li)
+ {
+ systemIncludes.insert(*li);
+ }
+ }
}
+ std::reverse(beforeIncludes.begin(), beforeIncludes.end());
+
+ this->Makefile->AddIncludeDirectories(afterIncludes);
+ this->Makefile->AddIncludeDirectories(beforeIncludes, before);
+ this->Makefile->AddSystemIncludeDirectories(systemIncludes);
+
return true;
}
@@ -72,57 +104,49 @@ static bool StartsWithGeneratorExpression(const std::string &input)
// output from a program and passing it into a command the cleanup doesn't
// always happen
//
-void cmIncludeDirectoryCommand::AddDirectory(const char *i,
- bool before,
- bool system)
+void cmIncludeDirectoryCommand::GetIncludes(const std::string &arg,
+ std::vector<std::string> &incs)
{
// break apart any line feed arguments
- std::string ret = i;
std::string::size_type pos = 0;
- if((pos = ret.find('\n', pos)) != std::string::npos)
+ std::string::size_type lastPos = 0;
+ while((pos = arg.find('\n', lastPos)) != std::string::npos)
{
if (pos)
{
- this->AddDirectory(ret.substr(0,pos).c_str(), before, system);
- }
- if (ret.size()-pos-1)
- {
- this->AddDirectory(ret.substr(pos+1,ret.size()-pos-1).c_str(),
- before, system);
+ std::string inc = arg.substr(lastPos,pos);
+ NormalizeInclude(inc);
+ incs.push_back(inc);
}
- return;
+ lastPos = pos + 1;
}
+ std::string inc = arg.substr(lastPos);
+ NormalizeInclude(inc);
+ incs.push_back(inc);
+}
- // remove any leading or trailing spaces and \r
- std::string::size_type b = ret.find_first_not_of(" \r");
- std::string::size_type e = ret.find_last_not_of(" \r");
- if ((b!=ret.npos) && (e!=ret.npos))
- {
- ret.assign(ret, b, 1+e-b); // copy the remaining substring
- }
- else
+void cmIncludeDirectoryCommand::NormalizeInclude(std::string &inc)
+{
+ std::string::size_type b = inc.find_first_not_of(" \r");
+ std::string::size_type e = inc.find_last_not_of(" \r");
+ if ((b!=inc.npos) && (e!=inc.npos))
{
- return; // if we get here, we had only whitespace in the string
+ inc.assign(inc, b, 1+e-b); // copy the remaining substring
}
- if (!cmSystemTools::IsOff(ret.c_str()))
+ if (!cmSystemTools::IsOff(inc.c_str()))
{
- cmSystemTools::ConvertToUnixSlashes(ret);
- if(!cmSystemTools::FileIsFullPath(ret.c_str()))
+ cmSystemTools::ConvertToUnixSlashes(inc);
+
+ if(!cmSystemTools::FileIsFullPath(inc.c_str()))
{
- if(!StartsWithGeneratorExpression(ret))
+ if(!StartsWithGeneratorExpression(inc))
{
std::string tmp = this->Makefile->GetStartDirectory();
tmp += "/";
- tmp += ret;
- ret = tmp;
+ tmp += inc;
+ inc = tmp;
}
}
}
- this->Makefile->AddIncludeDirectory(ret.c_str(), before);
- if(system)
- {
- this->Makefile->AddSystemIncludeDirectory(ret.c_str());
- }
}
-
diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h
index dd37b82..77a340a 100644
--- a/Source/cmIncludeDirectoryCommand.h
+++ b/Source/cmIncludeDirectoryCommand.h
@@ -59,8 +59,9 @@ public:
return
" include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 ...)\n"
"Add the given directories to those the compiler uses to search "
- "for include files. "
- "These directories are added to the directory property "
+ "for include files. Relative paths are interpreted as relative to "
+ "the current source directory. \n"
+ "The include directories are added to the directory property "
"INCLUDE_DIRECTORIES for the current CMakeLists file. "
"They are also added to the target property INCLUDE_DIRECTORIES "
"for each target in the current CMakeLists file. "
@@ -84,7 +85,8 @@ public:
protected:
// used internally
- void AddDirectory(const char *arg, bool before, bool system);
+ void GetIncludes(const std::string &arg, std::vector<std::string> &incs);
+ void NormalizeInclude(std::string &inc);
};
diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h
index 889118c..9218f44 100644
--- a/Source/cmLinkDirectoriesCommand.h
+++ b/Source/cmLinkDirectoriesCommand.h
@@ -62,10 +62,8 @@ public:
" link_directories(directory1 directory2 ...)\n"
"Specify the paths in which the linker should search for libraries. "
"The command will apply only to targets created after it is called. "
- "For historical reasons, relative paths given to this command are "
- "passed to the linker unchanged "
- "(unlike many CMake commands which interpret them relative to the "
- "current source directory).\n"
+ "Relative paths given to this command are interpreted as relative to "
+ "the current source directory, see CMP0015. \n"
"Note that this command is rarely necessary. Library locations "
"returned by find_package() and find_library() are absolute paths. "
"Pass these absolute library file paths directly to the "
diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 6c78ac4..c35288c 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -325,6 +325,9 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
if(!cmSystemTools::FileExists(source.c_str()))
{
cmSystemTools::ReplaceString(source, "$(IntDir)/", "");
+ // Make sure the path exists for the file
+ std::string path = cmSystemTools::GetFilenamePath(source);
+ cmSystemTools::MakeDirectory(path.c_str());
#if defined(_WIN32) || defined(__CYGWIN__)
std::ofstream sourceFout(source.c_str(),
std::ios::binary | std::ios::out
@@ -1697,25 +1700,21 @@ void cmLocalVisualStudio6Generator
std::set<std::string> minsizeDefinesSet;
std::set<std::string> debugrelDefinesSet;
-
- cmGeneratorTarget* gt =
- this->GlobalGenerator->GetGeneratorTarget(&target);
-
this->AppendDefines(
definesSet,
- gt->GetCompileDefinitions());
+ target.GetCompileDefinitions());
this->AppendDefines(
debugDefinesSet,
- gt->GetCompileDefinitions("DEBUG"));
+ target.GetCompileDefinitions("DEBUG"));
this->AppendDefines(
releaseDefinesSet,
- gt->GetCompileDefinitions("RELEASE"));
+ target.GetCompileDefinitions("RELEASE"));
this->AppendDefines(
minsizeDefinesSet,
- gt->GetCompileDefinitions("MINSIZEREL"));
+ target.GetCompileDefinitions("MINSIZEREL"));
this->AppendDefines(
debugrelDefinesSet,
- gt->GetCompileDefinitions("RELWITHDEBINFO"));
+ target.GetCompileDefinitions("RELWITHDEBINFO"));
std::string defines = " ";
std::string debugDefines = " ";
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 918b21e..f9df861 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -745,8 +745,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(std::ostream& fout,
targetOptions.ParseFinish();
cmGeneratorTarget* gt =
this->GlobalGenerator->GetGeneratorTarget(&target);
- targetOptions.AddDefines(gt->GetCompileDefinitions().c_str());
- targetOptions.AddDefines(gt->GetCompileDefinitions(configName).c_str());
+ targetOptions.AddDefines(target.GetCompileDefinitions().c_str());
+ targetOptions.AddDefines(target.GetCompileDefinitions(configName).c_str());
targetOptions.SetVerboseMakefile(
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index b45a61c..dbd0c36 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -99,6 +99,7 @@ cmMakefile::cmMakefile(): Internal(new Internals)
this->AddDefaultDefinitions();
this->Initialize();
this->PreOrder = false;
+ this->GeneratingBuildSystem = false;
}
cmMakefile::cmMakefile(const cmMakefile& mf): Internal(new Internals)
@@ -1616,20 +1617,31 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath,
}
//----------------------------------------------------------------------------
-void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
+void cmMakefile::AddIncludeDirectories(const std::vector<std::string> &incs,
+ bool before)
{
- if (!inc)
+ if (incs.empty())
{
return;
}
+ std::string incString;
+ std::string sep;
+
+ for(std::vector<std::string>::const_iterator li = incs.begin();
+ li != incs.end(); ++li)
+ {
+ incString += sep + *li;
+ sep = ";";
+ }
+
std::vector<IncludeDirectoriesEntry>::iterator position =
- before ? this->IncludeDirectoriesEntries.begin()
- : this->IncludeDirectoriesEntries.end();
+ before ? this->IncludeDirectoriesEntries.begin()
+ : this->IncludeDirectoriesEntries.end();
cmListFileBacktrace lfbt;
this->GetBacktrace(lfbt);
- IncludeDirectoriesEntry entry(inc, lfbt);
+ IncludeDirectoriesEntry entry(incString, lfbt);
this->IncludeDirectoriesEntries.insert(position, entry);
// Property on each target:
@@ -1642,9 +1654,14 @@ void cmMakefile::AddIncludeDirectory(const char* inc, bool before)
}
//----------------------------------------------------------------------------
-void cmMakefile::AddSystemIncludeDirectory(const char* dir)
+void
+cmMakefile::AddSystemIncludeDirectories(const std::set<cmStdString> &incs)
{
- this->SystemIncludeDirectories.insert(dir);
+ for(std::set<cmStdString>::const_iterator li = incs.begin();
+ li != incs.end(); ++li)
+ {
+ this->SystemIncludeDirectories.insert(*li);
+ }
}
//----------------------------------------------------------------------------
@@ -2243,7 +2260,7 @@ bool cmMakefile::CanIWriteThisFile(const char* fileName)
{
return true;
}
- // If we are doing an in-source build, than the test will always fail
+ // If we are doing an in-source build, then the test will always fail
if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
this->GetHomeOutputDirectory()) )
{
@@ -2254,8 +2271,8 @@ bool cmMakefile::CanIWriteThisFile(const char* fileName)
return true;
}
- // Check if this is subdirectory of the source tree but not a
- // subdirectory of a build tree
+ // Check if this is a subdirectory of the source tree but not a
+ // subdirectory of the build tree
if ( cmSystemTools::IsSubDirectory(fileName,
this->GetHomeDirectory()) &&
!cmSystemTools::IsSubDirectory(fileName,
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index a85015f..a2783f2 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -287,7 +287,8 @@ public:
/**
* Add an include directory to the build.
*/
- void AddIncludeDirectory(const char*, bool before = false);
+ void AddIncludeDirectories(const std::vector<std::string> &incs,
+ bool before = false);
/**
* Add a variable definition to the build. This variable
@@ -545,7 +546,7 @@ public:
/**
* Mark include directories as system directories.
*/
- void AddSystemIncludeDirectory(const char* dir);
+ void AddSystemIncludeDirectories(const std::set<cmStdString> &incs);
bool IsSystemIncludeDirectory(const char* dir);
/** Expand out any arguements in the vector that have ; separated
@@ -869,6 +870,9 @@ public:
return this->IncludeDirectoriesEntries;
}
+ bool IsGeneratingBuildSystem(){ return this->GeneratingBuildSystem; }
+ void SetGeneratingBuildSystem(){ this->GeneratingBuildSystem = true; }
+
protected:
// add link libraries and directories to the target
void AddGlobalLinkInformation(const char* name, cmTarget& target);
@@ -1018,6 +1022,9 @@ private:
// Enforce rules about CMakeLists.txt files.
void EnforceDirectoryLevelRules();
+
+ bool GeneratingBuildSystem;
+
};
//----------------------------------------------------------------------------
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 64fcfce..d9aa7fe 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -303,10 +303,10 @@ std::string cmMakefileTargetGenerator::GetDefines(const std::string &l)
// Add preprocessor definitions for this target and configuration.
this->LocalGenerator->AppendDefines
- (defines, this->GeneratorTarget->GetCompileDefinitions());
+ (defines, this->Target->GetCompileDefinitions());
this->LocalGenerator->AppendDefines
- (defines, this->GeneratorTarget->GetCompileDefinitions(
+ (defines, this->Target->GetCompileDefinitions(
this->LocalGenerator->ConfigurationName.c_str()));
std::string definesString;
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index 65967a5..7e48cd7 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -190,7 +190,7 @@ cmNinjaNormalTargetGenerator
linkOptionVar += cmTarget::GetTargetTypeName(targetType);
const std::string linkOption =
GetMakefile()->GetSafeDefinition(linkOptionVar.c_str());
- rspcontent = "$in " + linkOption + " $LINK_PATH $LINK_LIBRARIES";
+ rspcontent = "$in_newline "+linkOption+" $LINK_PATH $LINK_LIBRARIES";
vars.Objects = responseFlag.c_str();
vars.LinkLibraries = "";
}
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 0f484da..f8e4399 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -228,7 +228,7 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
// Add preprocessor definitions for this target and configuration.
this->LocalGenerator->AppendDefines
(defines,
- this->GeneratorTarget->GetCompileDefinitions());
+ this->Target->GetCompileDefinitions());
this->LocalGenerator->AppendDefines
(defines,
source->GetProperty("COMPILE_DEFINITIONS"));
@@ -237,7 +237,7 @@ ComputeDefines(cmSourceFile *source, const std::string& language)
defPropName += cmSystemTools::UpperCase(this->GetConfigName());
this->LocalGenerator->AppendDefines
(defines,
- this->GeneratorTarget->GetCompileDefinitions(this->GetConfigName()));
+ this->Target->GetCompileDefinitions(this->GetConfigName()));
this->LocalGenerator->AppendDefines
(defines,
source->GetProperty(defPropName.c_str()));
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index eb7d666..831e92e 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -508,6 +508,27 @@ cmPolicies::cmPolicies()
"for strict compatibility. "
"The NEW behavior for this policy is to leave the values untouched.",
2,8,11,0, cmPolicies::WARN);
+
+ this->DefinePolicy(
+ CMP0020, "CMP0020",
+ "Automatically link Qt executables to qtmain target on Windows.",
+ "CMake 2.8.10 and lower required users of Qt to always specify a link "
+ "dependency to the qtmain.lib static library manually on Windows. CMake "
+ "2.8.11 gained the ability to evaluate generator expressions while "
+ "determining the link dependencies from IMPORTED targets. This allows "
+ "CMake itself to automatically link executables which link to Qt to the "
+ "qtmain.lib library when using IMPORTED Qt targets. For applications "
+ "already linking to qtmain.lib, this should have little impact. For "
+ "applications which supply their own alternative WinMain implementation "
+ "and for applications which use the QAxServer library, this automatic "
+ "linking will need to be disabled as per the documentation."
+ "\n"
+ "The OLD behavior for this policy is not to link executables to "
+ "qtmain.lib automatically when they link to the QtCore IMPORTED"
+ "target. "
+ "The NEW behavior for this policy is to link executables to "
+ "qtmain.lib automatically when they link to QtCore IMPORTED target.",
+ 2,8,11,0, cmPolicies::WARN);
}
cmPolicies::~cmPolicies()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index d7d945c..c11af07 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -69,6 +69,7 @@ public:
/// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C}
/// instead.
CMP0019, ///< No variable re-expansion in include and link info
+ CMP0020, ///< Automatically link Qt executables to qtmain target
/** \brief Always the last entry.
*
diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index bf034cf..cc42175 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -229,7 +229,11 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
}
const char* tmp = target->GetProperty("COMPILE_DEFINITIONS");
- std::string _moc_compile_defs = (tmp!=0 ? tmp : "");
+ std::string _moc_compile_defs;
+ if (tmp)
+ {
+ _moc_compile_defs = target->GetCompileDefinitions();
+ }
tmp = makefile->GetProperty("COMPILE_DEFINITIONS");
if (tmp)
{
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index c2521d9..525efb4 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1180,46 +1180,35 @@ bool cmSystemTools::CopyFileIfDifferent(const char* source,
bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
{
#ifdef _WIN32
- /* On Windows the move functions will not replace existing files.
- Check if the destination exists. */
- struct stat newFile;
- if(stat(newname, &newFile) == 0)
+# ifndef INVALID_FILE_ATTRIBUTES
+# define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+# endif
+ /* Windows MoveFileEx may not replace read-only or in-use files. If it
+ fails then remove the read-only attribute from any existing destination.
+ Try multiple times since we may be racing against another process
+ creating/opening the destination file just before our MoveFileEx. */
+ int tries = 5;
+ while(!MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) && --tries)
{
- /* The destination exists. We have to replace it carefully. The
- MoveFileEx function does what we need but is not available on
- Win9x. */
- OSVERSIONINFO osv;
- DWORD attrs;
-
- /* Make sure the destination is not read only. */
- attrs = GetFileAttributes(newname);
- if(attrs & FILE_ATTRIBUTE_READONLY)
+ // Try again only if failure was due to access permissions.
+ if(GetLastError() != ERROR_ACCESS_DENIED)
{
- SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
+ return false;
}
-
- /* Check the windows version number. */
- osv.dwOSVersionInfoSize = sizeof(osv);
- GetVersionEx(&osv);
- if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+ DWORD attrs = GetFileAttributes(newname);
+ if((attrs != INVALID_FILE_ATTRIBUTES) &&
+ (attrs & FILE_ATTRIBUTE_READONLY))
{
- /* This is Win9x. There is no MoveFileEx implementation. We
- cannot quite rename the file atomically. Just delete the
- destination and then move the file. */
- DeleteFile(newname);
- return MoveFile(oldname, newname) != 0;
+ // Remove the read-only attribute from the destination file.
+ SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
}
else
{
- /* This is not Win9x. Use the MoveFileEx implementation. */
- return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) != 0;
+ // The file may be temporarily in use so wait a bit.
+ cmSystemTools::Delay(100);
}
}
- else
- {
- /* The destination does not exist. Just move the file. */
- return MoveFile(oldname, newname) != 0;
- }
+ return tries > 0;
#else
/* On UNIX we have an OS-provided call to do this atomically. */
return rename(oldname, newname) == 0;
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 815da40..ca0e24b 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -134,6 +134,7 @@ public:
: ge(cge)
{}
const cmsys::auto_ptr<cmCompiledGeneratorExpression> ge;
+ std::vector<std::string> CachedIncludes;
};
std::vector<IncludeDirectoriesEntry*> IncludeDirectoriesEntries;
};
@@ -145,12 +146,14 @@ cmTarget::cmTarget()
this->PolicyStatusCMP0003 = cmPolicies::WARN;
this->PolicyStatusCMP0004 = cmPolicies::WARN;
this->PolicyStatusCMP0008 = cmPolicies::WARN;
+ this->PolicyStatusCMP0020 = cmPolicies::WARN;
this->LinkLibrariesAnalyzed = false;
this->HaveInstallRule = false;
this->DLLPlatform = false;
this->IsApple = false;
this->IsImportedTarget = false;
this->BuildInterfaceIncludesAppended = false;
+ this->DebugIncludesDone = false;
}
//----------------------------------------------------------------------------
@@ -906,6 +909,17 @@ void cmTarget::DefineProperties(cmake *cm)
"property is not set, then it is ignored.");
cm->DefineProperty
+ ("COMPATIBLE_INTERFACE_STRING", cmProperty::TARGET,
+ "Properties which must be string-compatible with their link interface",
+ "The COMPATIBLE_INTERFACE_STRING property may contain a list of "
+ "properties for this target which must be the same when evaluated as "
+ "a string in the INTERFACE of all linked dependencies. For example, "
+ "if a property \"FOO\" appears in the list, then the \"INTERFACE_FOO\" "
+ "property content in all dependencies must be equal with each "
+ "other, and with the \"FOO\" property in this target. If the "
+ "property is not set, then it is ignored.");
+
+ cm->DefineProperty
("POST_INSTALL_SCRIPT", cmProperty::TARGET,
"Deprecated install support.",
"The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the "
@@ -1499,6 +1513,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->Makefile->GetPolicyStatus(cmPolicies::CMP0004);
this->PolicyStatusCMP0008 =
this->Makefile->GetPolicyStatus(cmPolicies::CMP0008);
+ this->PolicyStatusCMP0020 =
+ this->Makefile->GetPolicyStatus(cmPolicies::CMP0020);
}
//----------------------------------------------------------------------------
@@ -1520,6 +1536,13 @@ void cmTarget::ClearLinkMaps()
this->Internal->LinkImplMap.clear();
this->Internal->LinkInterfaceMap.clear();
this->Internal->LinkClosureMap.clear();
+ for (cmTargetLinkInformationMap::const_iterator it
+ = this->LinkInformation.begin();
+ it != this->LinkInformation.end(); ++it)
+ {
+ delete it->second;
+ }
+ this->LinkInformation.clear();
}
//----------------------------------------------------------------------------
@@ -2269,8 +2292,9 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
const bool isNonImportedTarget = tgt && !tgt->IsImported();
- std::string libName = isNonImportedTarget ? targetNameGenex(lib)
- : std::string(lib);
+ const std::string libName = (isNonImportedTarget && llt != GENERAL)
+ ? targetNameGenex(lib)
+ : std::string(lib);
this->AppendProperty("LINK_LIBRARIES",
this->GetDebugGeneratorExpressions(libName,
llt).c_str());
@@ -2739,53 +2763,106 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
cmSystemTools::ExpandListArgument(debugProp, debugProperties);
}
- bool debugIncludes = std::find(debugProperties.begin(),
+ bool debugIncludes = !this->DebugIncludesDone
+ && std::find(debugProperties.begin(),
debugProperties.end(),
"INCLUDE_DIRECTORIES")
!= debugProperties.end();
+ if (this->Makefile->IsGeneratingBuildSystem())
+ {
+ this->DebugIncludesDone = true;
+ }
+
for (std::vector<cmTargetInternals::IncludeDirectoriesEntry*>::const_iterator
it = this->Internal->IncludeDirectoriesEntries.begin(),
end = this->Internal->IncludeDirectoriesEntries.end();
it != end; ++it)
{
- std::vector<std::string> entryIncludes;
- cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
- config,
- false,
- this,
- &dagChecker),
- entryIncludes);
+
+ bool testIsOff = true;
+ bool cacheIncludes = false;
+ std::vector<std::string> entryIncludes = (*it)->CachedIncludes;
+ if(!entryIncludes.empty())
+ {
+ testIsOff = false;
+ }
+ else
+ {
+ cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile,
+ config,
+ false,
+ this,
+ &dagChecker),
+ entryIncludes);
+ if (!(*it)->ge->GetHadContextSensitiveCondition())
+ {
+ cacheIncludes = true;
+ }
+ }
std::string usedIncludes;
- for(std::vector<std::string>::const_iterator
+ for(std::vector<std::string>::iterator
li = entryIncludes.begin(); li != entryIncludes.end(); ++li)
{
- std::string inc = *li;
- if (!cmSystemTools::IsOff(inc.c_str()))
+ if (testIsOff && !cmSystemTools::IsOff(li->c_str()))
{
- cmSystemTools::ConvertToUnixSlashes(inc);
+ cmSystemTools::ConvertToUnixSlashes(*li);
}
+ std::string inc = *li;
if(uniqueIncludes.insert(inc).second)
{
- includes.push_back(*li);
+ includes.push_back(inc);
if (debugIncludes)
{
- usedIncludes += " * " + *li + "\n";
+ usedIncludes += " * " + inc + "\n";
}
}
}
+ if (cacheIncludes)
+ {
+ (*it)->CachedIncludes = entryIncludes;
+ }
if (!usedIncludes.empty())
{
this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG,
- "Used includes:\n" + usedIncludes,
- (*it)->ge->GetBacktrace());
+ "Used includes for target " + this->Name + ":\n"
+ + usedIncludes, (*it)->ge->GetBacktrace());
}
}
return includes;
}
//----------------------------------------------------------------------------
+std::string cmTarget::GetCompileDefinitions(const char *config)
+{
+ std::string defPropName = "COMPILE_DEFINITIONS";
+ if (config)
+ {
+ defPropName += "_" + cmSystemTools::UpperCase(config);
+ }
+
+ const char *prop = this->GetProperty(defPropName.c_str());
+
+ if (!prop)
+ {
+ return "";
+ }
+
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+ this->GetName(),
+ defPropName, 0, 0);
+ return ge.Parse(prop)->Evaluate(this->Makefile,
+ config,
+ false,
+ this,
+ &dagChecker);
+}
+
+//----------------------------------------------------------------------------
void cmTarget::MaybeInvalidatePropertyCache(const char* prop)
{
// Wipe out maps caching information affected by this property.
@@ -4482,22 +4559,69 @@ void cmTarget::AddLinkDependentTargetsForProperties(
}
//----------------------------------------------------------------------------
-bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
- const char *config)
+template<typename PropertyType>
+PropertyType getTypedProperty(cmTarget *tgt, const char *prop,
+ PropertyType *);
+
+//----------------------------------------------------------------------------
+template<>
+bool getTypedProperty<bool>(cmTarget *tgt, const char *prop, bool *)
+{
+ return tgt->GetPropertyAsBool(prop);
+}
+
+//----------------------------------------------------------------------------
+template<>
+const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop,
+ const char **)
{
- bool propContent = this->GetPropertyAsBool(p.c_str());
- const bool explicitlySet = this->GetProperties()
+ return tgt->GetProperty(prop);
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+bool consistentProperty(PropertyType lhs, PropertyType rhs);
+
+//----------------------------------------------------------------------------
+template<>
+bool consistentProperty(bool lhs, bool rhs)
+{
+ return lhs == rhs;
+}
+
+//----------------------------------------------------------------------------
+template<>
+bool consistentProperty(const char *lhs, const char *rhs)
+{
+ if (!lhs && !rhs)
+ return true;
+ if (!lhs || !rhs)
+ return false;
+ return strcmp(lhs, rhs) == 0;
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt,
+ const std::string &p,
+ const char *config,
+ const char *defaultValue,
+ PropertyType *)
+{
+ PropertyType propContent = getTypedProperty<PropertyType>(tgt, p.c_str(),
+ 0);
+ const bool explicitlySet = tgt->GetProperties()
.find(p.c_str())
- != this->GetProperties().end();
+ != tgt->GetProperties().end();
std::set<std::string> dependentTargets;
- this->GetLinkDependentTargetsForProperty(p,
+ tgt->GetLinkDependentTargetsForProperty(p,
dependentTargets);
const bool impliedByUse =
- this->IsNullImpliedByLinkLibraries(p);
+ tgt->IsNullImpliedByLinkLibraries(p);
assert((impliedByUse ^ explicitlySet)
|| (!impliedByUse && !explicitlySet));
- cmComputeLinkInformation *info = this->GetLinkInformation(config);
+ cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
bool propInitialized = explicitlySet;
@@ -4519,20 +4643,22 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
const bool ifaceIsSet = li->Target->GetProperties()
.find("INTERFACE_" + p)
!= li->Target->GetProperties().end();
- const bool ifacePropContent = li->Target->GetPropertyAsBool(
- ("INTERFACE_" + p).c_str());
+ PropertyType ifacePropContent =
+ getTypedProperty<PropertyType>(li->Target,
+ ("INTERFACE_" + p).c_str(), 0);
if (explicitlySet)
{
if (ifaceIsSet)
{
- if (propContent != ifacePropContent)
+ if (!consistentProperty(propContent, ifacePropContent))
{
cmOStringStream e;
e << "Property " << p << " on target \""
- << this->GetName() << "\" does\nnot match the "
+ << tgt->GetName() << "\" does\nnot match the "
"INTERFACE_" << p << " property requirement\nof "
"dependency \"" << li->Target->GetName() << "\".\n";
cmSystemTools::Error(e.str().c_str());
+ break;
}
else
{
@@ -4550,15 +4676,16 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
{
if (ifaceIsSet)
{
- if (propContent != ifacePropContent)
+ if (!consistentProperty(propContent, ifacePropContent))
{
cmOStringStream e;
e << "Property " << p << " on target \""
- << this->GetName() << "\" is\nimplied to be FALSE because it "
- "was used to determine the link libraries\nalready. The "
- "INTERFACE_" << p << " property on\ndependency \""
+ << tgt->GetName() << "\" is\nimplied to be " << defaultValue
+ << " because it was used to determine the link libraries\n"
+ "already. The INTERFACE_" << p << " property on\ndependency \""
<< li->Target->GetName() << "\" is in conflict.\n";
cmSystemTools::Error(e.str().c_str());
+ break;
}
else
{
@@ -4578,14 +4705,15 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
{
if (propInitialized)
{
- if (propContent != ifacePropContent)
+ if (!consistentProperty(propContent, ifacePropContent))
{
cmOStringStream e;
e << "The INTERFACE_" << p << " property of \""
<< li->Target->GetName() << "\" does\nnot agree with the value "
"of " << p << " already determined\nfor \""
- << this->GetName() << "\".\n";
+ << tgt->GetName() << "\".\n";
cmSystemTools::Error(e.str().c_str());
+ break;
}
else
{
@@ -4610,6 +4738,80 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
}
//----------------------------------------------------------------------------
+bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
+ const char *config)
+{
+ return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE",
+ 0);
+}
+
+//----------------------------------------------------------------------------
+const char * cmTarget::GetLinkInterfaceDependentStringProperty(
+ const std::string &p,
+ const char *config)
+{
+ return checkInterfacePropertyCompatibility<const char *>(this,
+ p,
+ config,
+ "empty", 0);
+}
+
+//----------------------------------------------------------------------------
+bool isLinkDependentProperty(cmTarget *tgt, const std::string &p,
+ const char *interfaceProperty,
+ const char *config)
+{
+ cmComputeLinkInformation *info = tgt->GetLinkInformation(config);
+
+ const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+ for(cmComputeLinkInformation::ItemVector::const_iterator li =
+ deps.begin();
+ li != deps.end(); ++li)
+ {
+ if (!li->Target)
+ {
+ continue;
+ }
+ const char *prop = li->Target->GetProperty(interfaceProperty);
+ if (!prop)
+ {
+ continue;
+ }
+
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(prop, props);
+
+ for(std::vector<std::string>::iterator pi = props.begin();
+ pi != props.end(); ++pi)
+ {
+ if (*pi == p)
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
+ const char *config)
+{
+ return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_BOOL",
+ config);
+}
+
+//----------------------------------------------------------------------------
+bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
+ const char *config)
+{
+ return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_STRING",
+ config);
+}
+
+//----------------------------------------------------------------------------
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
{
for(std::vector<cmSourceFile*>::const_iterator
@@ -5349,6 +5551,73 @@ std::string cmTarget::CheckCMP0004(std::string const& item)
return lib;
}
+template<typename PropertyType>
+PropertyType getLinkInterfaceDependentProperty(cmTarget *tgt,
+ const std::string prop,
+ const char *config,
+ PropertyType *);
+
+template<>
+bool getLinkInterfaceDependentProperty(cmTarget *tgt,
+ const std::string prop,
+ const char *config, bool *)
+{
+ return tgt->GetLinkInterfaceDependentBoolProperty(prop, config);
+}
+
+template<>
+const char * getLinkInterfaceDependentProperty(cmTarget *tgt,
+ const std::string prop,
+ const char *config,
+ const char **)
+{
+ return tgt->GetLinkInterfaceDependentStringProperty(prop, config);
+}
+
+//----------------------------------------------------------------------------
+template<typename PropertyType>
+void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee,
+ const char *propName,
+ std::set<cmStdString> &emitted,
+ const char *config,
+ PropertyType *)
+{
+ const char *prop = dependee->GetProperty(propName);
+ if (!prop)
+ {
+ return;
+ }
+
+ std::vector<std::string> props;
+ cmSystemTools::ExpandListArgument(prop, props);
+
+ for(std::vector<std::string>::iterator pi = props.begin();
+ pi != props.end(); ++pi)
+ {
+ if (depender->GetMakefile()->GetCMakeInstance()
+ ->GetIsPropertyDefined(pi->c_str(),
+ cmProperty::TARGET))
+ {
+ cmOStringStream e;
+ e << "Target \"" << dependee->GetName() << "\" has property \""
+ << *pi << "\" listed in its " << propName << " property. "
+ "This is not allowed. Only user-defined properties may appear "
+ "listed in the " << propName << " property.";
+ depender->GetMakefile()->IssueMessage(cmake::FATAL_ERROR, e.str());
+ return;
+ }
+ if(emitted.insert(*pi).second)
+ {
+ getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config,
+ 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ }
+ }
+}
+
//----------------------------------------------------------------------------
void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
const char* config)
@@ -5365,38 +5634,20 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info,
{
continue;
}
- const char *prop = li->Target->GetProperty("COMPATIBLE_INTERFACE_BOOL");
- if (!prop)
+
+ checkPropertyConsistency<bool>(this, li->Target,
+ "COMPATIBLE_INTERFACE_BOOL",
+ emitted, config, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
{
- continue;
+ return;
}
-
- std::vector<std::string> props;
- cmSystemTools::ExpandListArgument(prop, props);
-
- for(std::vector<std::string>::iterator pi = props.begin();
- pi != props.end(); ++pi)
+ checkPropertyConsistency<const char *>(this, li->Target,
+ "COMPATIBLE_INTERFACE_STRING",
+ emitted, config, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
{
- if (this->Makefile->GetCMakeInstance()
- ->GetIsPropertyDefined(pi->c_str(),
- cmProperty::TARGET))
- {
- cmOStringStream e;
- e << "Target \"" << li->Target->GetName() << "\" has property \""
- << *pi << "\" listed in its COMPATIBLE_INTERFACE_BOOL property. "
- "This is not allowed. Only user-defined properties may appear "
- "listed in the COMPATIBLE_INTERFACE_BOOL property.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- return;
- }
- if(emitted.insert(*pi).second)
- {
- this->GetLinkInterfaceDependentBoolProperty(*pi, config);
- if (cmSystemTools::GetErrorOccuredFlag())
- {
- return;
- }
- }
+ return;
}
}
}
@@ -5422,14 +5673,14 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head)
info = 0;
}
+ // Store the information for this configuration.
+ cmTargetLinkInformationMap::value_type entry(key, info);
+ i = this->LinkInformation.insert(entry).first;
+
if (info)
{
this->CheckPropertyCompatibility(info, config);
}
-
- // Store the information for this configuration.
- cmTargetLinkInformationMap::value_type entry(key, info);
- i = this->LinkInformation.insert(entry).first;
}
return i->second;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 69a00c1..7577a59 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -102,6 +102,10 @@ public:
cmPolicies::PolicyStatus GetPolicyStatusCMP0008() const
{ return this->PolicyStatusCMP0008; }
+ /** Get the status of policy CMP0020 when the target was created. */
+ cmPolicies::PolicyStatus GetPolicyStatusCMP0020() const
+ { return this->PolicyStatusCMP0020; }
+
/**
* Get the list of the custom commands for this target
*/
@@ -426,6 +430,8 @@ public:
If no macro should be defined null is returned. */
const char* GetExportMacro();
+ std::string GetCompileDefinitions(const char *config = 0);
+
// Compute the set of languages compiled by the target. This is
// computed every time it is called because the languages can change
// when source file properties are changed and we do not have enough
@@ -495,12 +501,22 @@ public:
void GetLinkDependentTargetsForProperty(const std::string &p,
std::set<std::string> &targets);
bool IsNullImpliedByLinkLibraries(const std::string &p);
+ bool IsLinkInterfaceDependentBoolProperty(const std::string &p,
+ const char *config);
+ bool IsLinkInterfaceDependentStringProperty(const std::string &p,
+ const char *config);
void AddLinkDependentTargetsForProperties(
const std::map<cmStdString, cmStdString> &map);
bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
const char *config);
+
+ const char *GetLinkInterfaceDependentStringProperty(const std::string &p,
+ const char *config);
+
+ std::string GetDebugGeneratorExpressions(const std::string &value,
+ cmTarget::LinkLibraryType llt);
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
@@ -610,6 +626,7 @@ private:
bool DLLPlatform;
bool IsApple;
bool IsImportedTarget;
+ bool DebugIncludesDone;
mutable std::map<cmStdString, std::set<std::string> >
LinkDependentProperties;
mutable std::set<std::string> LinkImplicitNullProperties;
@@ -645,9 +662,6 @@ private:
void ProcessSourceExpression(std::string const& expr);
- std::string GetDebugGeneratorExpressions(const std::string &value,
- cmTarget::LinkLibraryType llt);
-
// The cmMakefile instance that owns this target. This should
// always be set.
cmMakefile* Makefile;
@@ -656,6 +670,7 @@ private:
cmPolicies::PolicyStatus PolicyStatusCMP0003;
cmPolicies::PolicyStatus PolicyStatusCMP0004;
cmPolicies::PolicyStatus PolicyStatusCMP0008;
+ cmPolicies::PolicyStatus PolicyStatusCMP0020;
// Internal representation details.
friend class cmTargetInternals;
diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx
index 492a1b7..7645833 100644
--- a/Source/cmTargetCompileDefinitionsCommand.cxx
+++ b/Source/cmTargetCompileDefinitionsCommand.cxx
@@ -20,13 +20,11 @@ bool cmTargetCompileDefinitionsCommand
}
void cmTargetCompileDefinitionsCommand
-::HandleImportedTargetInvalidScope(const std::string &scope,
- const std::string &tgt)
+::HandleImportedTarget(const std::string &tgt)
{
cmOStringStream e;
- e << "Cannot specify " << scope << " compile definitions for imported "
- "target \"" << tgt << "\". Compile definitions can only be "
- "specified for an imported target in the INTERFACE mode.";
+ e << "Cannot specify compile definitions for imported target \""
+ << tgt << "\".";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
@@ -39,19 +37,32 @@ void cmTargetCompileDefinitionsCommand
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
-bool cmTargetCompileDefinitionsCommand
-::HandleNonTargetArg(std::string &content,
- const std::string &sep,
- const std::string &entry,
- const std::string &)
+//----------------------------------------------------------------------------
+std::string cmTargetCompileDefinitionsCommand
+::Join(const std::vector<std::string> &content)
{
- content += sep + entry;
- return true;
+ std::string defs;
+ std::string sep;
+ for(std::vector<std::string>::const_iterator it = content.begin();
+ it != content.end(); ++it)
+ {
+ if (strncmp(it->c_str(), "-D", 2) == 0)
+ {
+ defs += sep + it->substr(2);
+ }
+ else
+ {
+ defs += sep + *it;
+ }
+ sep = ";";
+ }
+ return defs;
}
+//----------------------------------------------------------------------------
void cmTargetCompileDefinitionsCommand
-::HandleDirectContent(cmTarget *tgt, const std::string &content,
+::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
bool)
{
- tgt->AppendProperty("COMPILE_DEFINITIONS", content.c_str());
+ tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content).c_str());
}
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
index 4b066b7a..c93cacb 100644
--- a/Source/cmTargetCompileDefinitionsCommand.h
+++ b/Source/cmTargetCompileDefinitionsCommand.h
@@ -59,7 +59,7 @@ public:
"Specify compile definitions or targets to use when compiling a given "
"target. "
"The named <target> must have been created by a command such as "
- "add_executable or add_library. "
+ "add_executable or add_library and must not be an IMPORTED target. "
"The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
"the scope of the following arguments. PRIVATE and PUBLIC items will "
"populate the COMPILE_DEFINITIONS property of <target>. PUBLIC and "
@@ -75,20 +75,16 @@ public:
;
}
- cmTypeMacro(cmTargetCompileDefinitionsCommand, cmCommand);
+ cmTypeMacro(cmTargetCompileDefinitionsCommand, cmTargetPropCommandBase);
private:
- virtual void HandleImportedTargetInvalidScope(const std::string &scope,
- const std::string &tgt);
+ virtual void HandleImportedTarget(const std::string &tgt);
virtual void HandleMissingTarget(const std::string &name);
- virtual bool HandleNonTargetArg(std::string &content,
- const std::string &sep,
- const std::string &entry,
- const std::string &tgt);
-
- virtual void HandleDirectContent(cmTarget *tgt, const std::string &content,
+ virtual void HandleDirectContent(cmTarget *tgt,
+ const std::vector<std::string> &content,
bool prepend);
+ virtual std::string Join(const std::vector<std::string> &content);
};
#endif
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index 18e2cba..eaacfa9 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -22,13 +22,11 @@ bool cmTargetIncludeDirectoriesCommand
//----------------------------------------------------------------------------
void cmTargetIncludeDirectoriesCommand
-::HandleImportedTargetInvalidScope(const std::string &tgt,
- const std::string &scope)
+::HandleImportedTarget(const std::string &tgt)
{
cmOStringStream e;
- e << "Cannot specify " << scope << " include directories for imported "
- "target \"" << tgt << "\". Include directories can only be "
- "specified for an imported target in the INTERFACE mode.";
+ e << "Cannot specify include directories for imported target \""
+ << tgt << "\".";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}
@@ -43,32 +41,44 @@ void cmTargetIncludeDirectoriesCommand
}
//----------------------------------------------------------------------------
-bool cmTargetIncludeDirectoriesCommand
-::HandleNonTargetArg(std::string &content,
- const std::string &sep,
- const std::string &entry,
- const std::string &tgt)
+static bool isGeneratorExpression(const std::string &lib)
+{
+ const std::string::size_type openpos = lib.find("$<");
+ return (openpos != std::string::npos)
+ && (lib.find(">", openpos) != std::string::npos);
+}
+
+//----------------------------------------------------------------------------
+std::string cmTargetIncludeDirectoriesCommand
+::Join(const std::vector<std::string> &content)
{
- if (!cmSystemTools::FileIsFullPath(entry.c_str()))
+ std::string dirs;
+ std::string sep;
+ std::string prefix = this->Makefile->GetStartDirectory() + std::string("/");
+ for(std::vector<std::string>::const_iterator it = content.begin();
+ it != content.end(); ++it)
{
- cmOStringStream e;
- e << "Cannot specify relative include directory \"" << entry << "\" for "
- "target \"" << tgt << "\". Only absolute paths are permitted";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- return false;
+ if (cmSystemTools::FileIsFullPath(it->c_str())
+ || isGeneratorExpression(*it))
+ {
+ dirs += sep + *it;
+ }
+ else
+ {
+ dirs += sep + prefix + *it;
+ }
+ sep = ";";
}
-
- content += sep + entry;
- return true;
+ return dirs;
}
//----------------------------------------------------------------------------
void cmTargetIncludeDirectoriesCommand
-::HandleDirectContent(cmTarget *tgt, const std::string &content,
+::HandleDirectContent(cmTarget *tgt, const std::vector<std::string> &content,
bool prepend)
{
cmListFileBacktrace lfbt;
this->Makefile->GetBacktrace(lfbt);
- cmMakefileIncludeDirectoriesEntry entry(content, lfbt);
+ cmMakefileIncludeDirectoriesEntry entry(this->Join(content), lfbt);
tgt->InsertInclude(entry, prepend);
}
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index 90e039c..2bc7bef 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.h
+++ b/Source/cmTargetIncludeDirectoriesCommand.h
@@ -60,7 +60,7 @@ public:
"Specify include directories or targets to use when compiling a given "
"target. "
"The named <target> must have been created by a command such as "
- "add_executable or add_library.\n"
+ "add_executable or add_library and must not be an IMPORTED target.\n"
"If BEFORE is specified, the content will be prepended to the property "
"instead of being appended.\n"
"The INTERFACE, PUBLIC and PRIVATE keywords are required to specify "
@@ -79,20 +79,16 @@ public:
;
}
- cmTypeMacro(cmTargetIncludeDirectoriesCommand, cmCommand);
+ cmTypeMacro(cmTargetIncludeDirectoriesCommand, cmTargetPropCommandBase);
private:
- virtual void HandleImportedTargetInvalidScope(const std::string &tgt,
- const std::string &scope);
+ virtual void HandleImportedTarget(const std::string &tgt);
virtual void HandleMissingTarget(const std::string &name);
- virtual bool HandleNonTargetArg(std::string &content,
- const std::string &sep,
- const std::string &entry,
- const std::string &tgt);
-
- virtual void HandleDirectContent(cmTarget *tgt, const std::string &content,
+ virtual void HandleDirectContent(cmTarget *tgt,
+ const std::vector<std::string> &content,
bool prepend);
+ virtual std::string Join(const std::vector<std::string> &content);
};
#endif
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 0705fb4..cb913f5 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -35,10 +35,6 @@ bool cmTargetLinkLibrariesCommand
->GetGlobalGenerator()->FindTarget(0, args[0].c_str());
if(!this->Target)
{
- this->Target = this->Makefile->FindTargetToUse(args[0].c_str());
- }
- if(!this->Target)
- {
cmake::MessageType t = cmake::FATAL_ERROR; // fail by default
cmOStringStream e;
e << "Cannot specify link libraries for target \"" << args[0] << "\" "
@@ -254,23 +250,54 @@ cmTargetLinkLibrariesCommand
}
//----------------------------------------------------------------------------
+static std::string compileProperty(cmTarget *tgt, const std::string &lib,
+ bool isGenex,
+ const std::string &property,
+ cmTarget::LinkLibraryType llt)
+{
+ std::string value = !isGenex ? "$<LINKED:" + lib + ">"
+ : "$<$<TARGET_DEFINED:" + lib + ">:" +
+ "$<TARGET_PROPERTY:" + lib +
+ ",INTERFACE_" + property + ">"
+ ">";
+
+ return tgt->GetDebugGeneratorExpressions(value, llt);
+}
+
+//----------------------------------------------------------------------------
+static bool isGeneratorExpression(const std::string &lib)
+{
+ const std::string::size_type openpos = lib.find("$<");
+ return (openpos != std::string::npos)
+ && (lib.find(">", openpos) != std::string::npos);
+}
+
+//----------------------------------------------------------------------------
void
cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
cmTarget::LinkLibraryType llt)
{
+ const bool isGenex = isGeneratorExpression(lib);
+
+ cmsys::RegularExpression targetNameValidator;
+ targetNameValidator.compile("^[A-Za-z0-9_.:-]+$");
+ const bool potentialTargetName = targetNameValidator.find(lib);
+
+ if (potentialTargetName || isGenex)
+ {
+ this->Target->AppendProperty("INCLUDE_DIRECTORIES",
+ compileProperty(this->Target, lib,
+ isGenex,
+ "INCLUDE_DIRECTORIES", llt).c_str());
+ this->Target->AppendProperty("COMPILE_DEFINITIONS",
+ compileProperty(this->Target, lib,
+ isGenex,
+ "COMPILE_DEFINITIONS", llt).c_str());
+ }
+
// Handle normal case first.
if(this->CurrentProcessingState != ProcessingLinkInterface)
{
- if (this->Target->IsImported())
- {
- cmOStringStream e;
- e << "Imported targets may only be used with the "
- "LINK_INTERFACE_LIBRARIES specifier to target_link_libraries.";
- this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
- return;
- }
-
-
this->Makefile
->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt);
if (this->CurrentProcessingState != ProcessingPublicInterface)
@@ -280,6 +307,18 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
}
}
+ if (potentialTargetName || isGenex)
+ {
+ this->Target->AppendProperty("INTERFACE_COMPILE_DEFINITIONS",
+ compileProperty(this->Target, lib,
+ isGenex,
+ "COMPILE_DEFINITIONS", llt).c_str());
+ this->Target->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
+ compileProperty(this->Target, lib,
+ isGenex,
+ "INCLUDE_DIRECTORIES", llt).c_str());
+ }
+
// Get the list of configurations considered to be DEBUG.
std::vector<std::string> const& debugConfigs =
this->Makefile->GetCMakeInstance()->GetDebugConfigs();
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index 34fe54c..aaabdfa 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -93,7 +93,18 @@ public:
"linked to this target will appear on the link line for the other "
"target too. "
"See the LINK_INTERFACE_LIBRARIES target property to override the "
- "set of transitive link dependencies for a target."
+ "set of transitive link dependencies for a target. "
+ "Calls to other signatures of this command may set the property "
+ "making any libraries linked exclusively by this signature private."
+ "\n"
+ "Target usage requirements are also consumed by this command. If the "
+ "<target> is linked to another target which has "
+ "a populated INTERFACE_INCLUDE_DIRECTORIES, the content of it is "
+ "appended to the INCLUDE_DIRECTORIES of <target>. Similarly, the "
+ "INTERFACE_COMPILE_DEFINITONS of a dependee are added to the "
+ "COMPILE_DEFINITONS of <target>, and the "
+ "INTERFACE_POSITION_INDEPENDENT_CODE property is used to determine the "
+ "POSITION_INDEPENDENT_CODE property of <target>."
"\n"
" target_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n"
" [[debug|optimized|general] <lib>] ...)\n"
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 69aaf17..18a1d2a 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -80,17 +80,16 @@ bool cmTargetPropCommandBase
return false;
}
- if(this->Target->IsImported() && scope != "INTERFACE")
+ if(this->Target->IsImported())
{
- this->HandleImportedTargetInvalidScope(args[0], scope);
+ this->HandleImportedTarget(args[0]);
return false;
}
++argIndex;
- std::string content;
+ std::vector<std::string> content;
- std::string sep;
for(unsigned int i=argIndex; i < args.size(); ++i, ++argIndex)
{
if(args[i] == "PUBLIC"
@@ -100,16 +99,7 @@ bool cmTargetPropCommandBase
this->PopulateTargetProperies(scope, content, prepend);
return true;
}
- if (this->Makefile->FindTargetToUse(args[i].c_str()))
- {
- content += sep + "$<TARGET_PROPERTY:" + args[i]
- + ",INTERFACE_" + this->Property + ">";
- }
- else if (!this->HandleNonTargetArg(content, sep, args[i], args[0]))
- {
- return false;
- }
- sep = ";";
+ content.push_back(args[i]);
}
this->PopulateTargetProperies(scope, content, prepend);
return true;
@@ -118,7 +108,8 @@ bool cmTargetPropCommandBase
//----------------------------------------------------------------------------
void cmTargetPropCommandBase
::PopulateTargetProperies(const std::string &scope,
- const std::string &content, bool prepend)
+ const std::vector<std::string> &content,
+ bool prepend)
{
if (scope == "PRIVATE" || scope == "PUBLIC")
{
@@ -130,7 +121,7 @@ void cmTargetPropCommandBase
{
const std::string propName = std::string("INTERFACE_") + this->Property;
const char *propValue = this->Target->GetProperty(propName.c_str());
- const std::string totalContent = content + (propValue
+ const std::string totalContent = this->Join(content) + (propValue
? std::string(";") + propValue
: std::string());
this->Target->SetProperty(propName.c_str(), totalContent.c_str());
@@ -138,7 +129,7 @@ void cmTargetPropCommandBase
else
{
this->Target->AppendProperty(("INTERFACE_" + this->Property).c_str(),
- content.c_str());
+ this->Join(content).c_str());
}
}
}
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index e757f9d..8047a48 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -31,28 +31,25 @@ public:
bool HandleArguments(std::vector<std::string> const& args,
const char *prop, ArgumentFlags flags = NO_FLAGS);
+ cmTypeMacro(cmTargetPropCommandBase, cmCommand);
+protected:
+ std::string Property;
+ cmTarget *Target;
+
private:
- virtual void HandleImportedTargetInvalidScope(const std::string &tgt,
- const std::string &scope) = 0;
+ virtual void HandleImportedTarget(const std::string &tgt) = 0;
virtual void HandleMissingTarget(const std::string &name) = 0;
- virtual bool HandleNonTargetArg(std::string &content,
- const std::string &sep,
- const std::string &entry,
- const std::string &tgt) = 0;
-
virtual void HandleDirectContent(cmTarget *tgt,
- const std::string &content,
+ const std::vector<std::string> &content,
bool prepend) = 0;
+ virtual std::string Join(const std::vector<std::string> &content) = 0;
bool ProcessContentArgs(std::vector<std::string> const& args,
unsigned int &argIndex, bool prepend);
void PopulateTargetProperies(const std::string &scope,
- const std::string &content, bool prepend);
-
-private:
- cmTarget *Target;
- std::string Property;
+ const std::vector<std::string> &content,
+ bool prepend);
};
#endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 2596d73..171ed9a 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -1221,8 +1221,8 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
clOptions.Parse(flags.c_str());
clOptions.Parse(defineFlags.c_str());
clOptions.AddDefines(
- this->GeneratorTarget->GetCompileDefinitions().c_str());
- clOptions.AddDefines(this->GeneratorTarget->GetCompileDefinitions(
+ this->Target->GetCompileDefinitions().c_str());
+ clOptions.AddDefines(this->Target->GetCompileDefinitions(
configName.c_str()).c_str());
clOptions.SetVerboseMakefile(
this->Makefile->IsOn("CMAKE_VERBOSE_MAKEFILE"));
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 18622f3..d57e981 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -4449,6 +4449,10 @@ void cmake::IssueMessage(cmake::MessageType t, std::string const& text,
isError = true;
msg << "CMake Internal Error (please report a bug)";
}
+ else if(t == cmake::LOG)
+ {
+ msg << "CMake Debug Log";
+ }
else
{
msg << "CMake Warning";
diff --git a/Source/kwsys/DynamicLoader.cxx b/Source/kwsys/DynamicLoader.cxx
index c4ee095..fd83752 100644
--- a/Source/kwsys/DynamicLoader.cxx
+++ b/Source/kwsys/DynamicLoader.cxx
@@ -428,6 +428,58 @@ const char* DynamicLoader::LastError()
} // namespace KWSYS_NAMESPACE
#endif
+#ifdef __MINT__
+#define DYNAMICLOADER_DEFINED 1
+#define _GNU_SOURCE /* for program_invocation_name */
+#include <string.h>
+#include <malloc.h>
+#include <errno.h>
+#include <dld.h>
+
+namespace KWSYS_NAMESPACE
+{
+
+//----------------------------------------------------------------------------
+DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(const char* libname )
+{
+ char *name = (char *)calloc(1, strlen(libname) + 1);
+ dld_init(program_invocation_name);
+ strncpy(name, libname, strlen(libname));
+ dld_link(libname);
+ return (void *)name;
+}
+
+//----------------------------------------------------------------------------
+int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
+{
+ dld_unlink_by_file((char *)lib, 0);
+ free(lib);
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
+ DynamicLoader::LibraryHandle lib, const char* sym)
+{
+ // Hack to cast pointer-to-data to pointer-to-function.
+ union
+ {
+ void* pvoid;
+ DynamicLoader::SymbolPointer psym;
+ } result;
+ result.pvoid = dld_get_symbol(sym);
+ return result.psym;
+}
+
+//----------------------------------------------------------------------------
+const char* DynamicLoader::LastError()
+{
+ return dld_strerror(dld_errno);
+}
+
+} // namespace KWSYS_NAMESPACE
+#endif
+
// ---------------------------------------------------------------
// 6. Implementation for default UNIX machines.
// if nothing has been defined then use this
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 513eb64..46a7e4f 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -399,7 +399,7 @@ bool Glob::FindFiles(const kwsys_stl::string& inexpr)
if ( last_slash > 0 )
{
//kwsys_ios::cout << "I can skip: " << fexpr.substr(0, last_slash)
- //<< kwsys_ios::endl;
+ // << kwsys_ios::endl;
skip = last_slash;
}
if ( skip == 0 )
diff --git a/Source/kwsys/IOStream.cxx b/Source/kwsys/IOStream.cxx
index 57b696e..a31f8c8 100644
--- a/Source/kwsys/IOStream.cxx
+++ b/Source/kwsys/IOStream.cxx
@@ -272,6 +272,7 @@ namespace KWSYS_NAMESPACE
// Create one public symbol in this object file to avoid warnings from
// archivers.
+void IOStreamSymbolToAvoidWarning();
void IOStreamSymbolToAvoidWarning()
{
}
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 2db1254..fc9e8bf 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -102,7 +102,7 @@ static inline void kwsysProcess_usleep(unsigned int msec)
* pipes' file handles to be non-blocking and just poll them directly
* without select().
*/
-#if !defined(__BEOS__) && !defined(__VMS)
+#if !defined(__BEOS__) && !defined(__VMS) && !defined(__MINT__)
# define KWSYSPE_USE_SELECT 1
#endif
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index b20d724..f057e0f 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -2466,7 +2466,9 @@ bool SystemInformationImplementation::RetrieveCPUPowerManagement()
#endif
}
-void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
+#if USE_CPUID
+// Used only in USE_CPUID implementation below.
+static void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
{
// Because some manufacturers have leading white space - we have to post-process the name.
kwsys_stl::string::size_type pos = str.find_first_not_of(" ");
@@ -2475,6 +2477,7 @@ void SystemInformationStripLeadingSpace(kwsys_stl::string& str)
str = str.substr(pos);
}
}
+#endif
/** */
bool SystemInformationImplementation::RetrieveExtendedCPUIdentity()
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index b75993e..881c49a 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -3037,7 +3037,7 @@ void SystemTools::CheckTranslationPath(kwsys_stl::string & path)
path.erase(path.end()-1, path.end());
}
-void
+static void
SystemToolsAppendComponents(
kwsys_stl::vector<kwsys_stl::string>& out_components,
kwsys_stl::vector<kwsys_stl::string>::const_iterator first,
@@ -4704,7 +4704,7 @@ bool SystemTools::ParseURL( const kwsys_stl::string& URL,
// ----------------------------------------------------------------------
// These must NOT be initialized. Default initialization to zero is
// necessary.
-unsigned int SystemToolsManagerCount;
+static unsigned int SystemToolsManagerCount;
SystemToolsTranslationMap *SystemTools::TranslationMap;
SystemToolsTranslationMap *SystemTools::LongPathMap;
#ifdef __CYGWIN__
diff --git a/Source/kwsys/testCommandLineArguments.cxx b/Source/kwsys/testCommandLineArguments.cxx
index e75a87e..72e6544 100644
--- a/Source/kwsys/testCommandLineArguments.cxx
+++ b/Source/kwsys/testCommandLineArguments.cxx
@@ -24,9 +24,9 @@
#include <stddef.h> /* size_t */
#include <string.h> /* strcmp */
-void* random_ptr = reinterpret_cast<void*>(0x123);
+static void* random_ptr = reinterpret_cast<void*>(0x123);
-int argument(const char* arg, const char* value, void* call_data)
+static int argument(const char* arg, const char* value, void* call_data)
{
kwsys_ios::cout << "Got argument: \"" << arg << "\" value: \"" << (value?value:"(null)") << "\"" << kwsys_ios::endl;
if ( call_data != random_ptr )
@@ -37,7 +37,7 @@ int argument(const char* arg, const char* value, void* call_data)
return 1;
}
-int unknown_argument(const char* argument, void* call_data)
+static int unknown_argument(const char* argument, void* call_data)
{
kwsys_ios::cout << "Got unknown argument: \"" << argument << "\"" << kwsys_ios::endl;
if ( call_data != random_ptr )
@@ -48,12 +48,12 @@ int unknown_argument(const char* argument, void* call_data)
return 1;
}
-bool CompareTwoItemsOnList(bool i1, bool i2) { return i1 == i2; }
-bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
-bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
-bool CompareTwoItemsOnList(const char* i1,
+static bool CompareTwoItemsOnList(bool i1, bool i2) { return i1 == i2; }
+static bool CompareTwoItemsOnList(int i1, int i2) { return i1 == i2; }
+static bool CompareTwoItemsOnList(double i1, double i2) { return i1 == i2; }
+static bool CompareTwoItemsOnList(const char* i1,
const char* i2) { return strcmp(i1, i2) == 0; }
-bool CompareTwoItemsOnList(const kwsys_stl::string& i1,
+static bool CompareTwoItemsOnList(const kwsys_stl::string& i1,
const kwsys_stl::string& i2) { return i1 == i2; }
int testCommandLineArguments(int argc, char* argv[])
diff --git a/Source/kwsys/testDynamicLoader.cxx b/Source/kwsys/testDynamicLoader.cxx
index cbfb65b..61c1572 100644
--- a/Source/kwsys/testDynamicLoader.cxx
+++ b/Source/kwsys/testDynamicLoader.cxx
@@ -35,7 +35,7 @@
// left on disk.
#include <testSystemTools.h>
-kwsys_stl::string GetLibName(const char* lname)
+static kwsys_stl::string GetLibName(const char* lname)
{
// Construct proper name of lib
kwsys_stl::string slname;
diff --git a/Source/kwsys/testProcess.c b/Source/kwsys/testProcess.c
index 269b84b..6d5eb71 100644
--- a/Source/kwsys/testProcess.c
+++ b/Source/kwsys/testProcess.c
@@ -47,7 +47,7 @@ int runChild(const char* cmd[], int state, int exception, int value,
int share, int output, int delay, double timeout, int poll,
int repeat, int disown);
-int test1(int argc, const char* argv[])
+static int test1(int argc, const char* argv[])
{
(void)argc; (void)argv;
fprintf(stdout, "Output on stdout from test returning 0.\n");
@@ -55,7 +55,7 @@ int test1(int argc, const char* argv[])
return 0;
}
-int test2(int argc, const char* argv[])
+static int test2(int argc, const char* argv[])
{
(void)argc; (void)argv;
fprintf(stdout, "Output on stdout from test returning 123.\n");
@@ -63,7 +63,7 @@ int test2(int argc, const char* argv[])
return 123;
}
-int test3(int argc, const char* argv[])
+static int test3(int argc, const char* argv[])
{
(void)argc; (void)argv;
fprintf(stdout, "Output before sleep on stdout from timeout test.\n");
@@ -80,7 +80,7 @@ int test3(int argc, const char* argv[])
return 0;
}
-int test4(int argc, const char* argv[])
+static int test4(int argc, const char* argv[])
{
/* Prepare a pointer to an invalid address. Don't use null, because
dereferencing null is undefined behaviour and compilers are free to
@@ -109,7 +109,7 @@ int test4(int argc, const char* argv[])
return 0;
}
-int test5(int argc, const char* argv[])
+static int test5(int argc, const char* argv[])
{
int r;
const char* cmd[4];
@@ -132,7 +132,7 @@ int test5(int argc, const char* argv[])
}
#define TEST6_SIZE (4096*2)
-void test6(int argc, const char* argv[])
+static void test6(int argc, const char* argv[])
{
int i;
char runaway[TEST6_SIZE+1];
@@ -156,7 +156,7 @@ void test6(int argc, const char* argv[])
delaying 1/10th of a second should ever have to poll. */
#define MINPOLL 5
#define MAXPOLL 20
-int test7(int argc, const char* argv[])
+static int test7(int argc, const char* argv[])
{
(void)argc; (void)argv;
fprintf(stdout, "Output on stdout before sleep.\n");
@@ -176,7 +176,7 @@ int test7(int argc, const char* argv[])
return 0;
}
-int test8(int argc, const char* argv[])
+static int test8(int argc, const char* argv[])
{
/* Create a disowned grandchild to test handling of processes
that exit before their children. */
@@ -200,7 +200,7 @@ int test8(int argc, const char* argv[])
return r;
}
-int test8_grandchild(int argc, const char* argv[])
+static int test8_grandchild(int argc, const char* argv[])
{
(void)argc; (void)argv;
fprintf(stdout, "Output on stdout from grandchild before sleep.\n");
@@ -221,7 +221,7 @@ int test8_grandchild(int argc, const char* argv[])
return 0;
}
-int runChild2(kwsysProcess* kp,
+static int runChild2(kwsysProcess* kp,
const char* cmd[], int state, int exception, int value,
int share, int output, int delay, double timeout,
int poll, int disown)
@@ -505,7 +505,7 @@ int main(int argc, const char* argv[])
fprintf(stderr, "Output on stderr after test %d.\n", n);
fflush(stdout);
fflush(stderr);
-#if _WIN32
+#if defined(_WIN32)
if(argv0) { free(argv0); }
#endif
return r;
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 3ac0cb3..1690fd5 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -32,7 +32,7 @@
#include <string.h> /* strcmp */
//----------------------------------------------------------------------------
-const char* toUnixPaths[][2] =
+static const char* toUnixPaths[][2] =
{
{ "/usr/local/bin/passwd", "/usr/local/bin/passwd" },
{ "/usr/lo cal/bin/pa sswd", "/usr/lo cal/bin/pa sswd" },
@@ -52,8 +52,8 @@ const char* toUnixPaths[][2] =
{0, 0}
};
-bool CheckConvertToUnixSlashes(kwsys_stl::string input,
- kwsys_stl::string output)
+static bool CheckConvertToUnixSlashes(kwsys_stl::string input,
+ kwsys_stl::string output)
{
kwsys_stl::string result = input;
kwsys::SystemTools::ConvertToUnixSlashes(result);
@@ -69,17 +69,17 @@ bool CheckConvertToUnixSlashes(kwsys_stl::string input,
}
//----------------------------------------------------------------------------
-const char* checkEscapeChars[][4] =
+static const char* checkEscapeChars[][4] =
{
{ "1 foo 2 bar 2", "12", "\\", "\\1 foo \\2 bar \\2"},
{ " {} ", "{}", "#", " #{#} "},
{0, 0, 0, 0}
};
-bool CheckEscapeChars(kwsys_stl::string input,
- const char *chars_to_escape,
- char escape_char,
- kwsys_stl::string output)
+static bool CheckEscapeChars(kwsys_stl::string input,
+ const char *chars_to_escape,
+ char escape_char,
+ kwsys_stl::string output)
{
kwsys_stl::string result = kwsys::SystemTools::EscapeChars(
input.c_str(), chars_to_escape, escape_char);
@@ -95,7 +95,7 @@ bool CheckEscapeChars(kwsys_stl::string input,
}
//----------------------------------------------------------------------------
-bool CheckFileOperations()
+static bool CheckFileOperations()
{
bool res = true;
@@ -129,7 +129,7 @@ bool CheckFileOperations()
}
//----------------------------------------------------------------------------
-bool CheckStringOperations()
+static bool CheckStringOperations()
{
bool res = true;
@@ -329,7 +329,7 @@ bool CheckStringOperations()
//----------------------------------------------------------------------------
-bool CheckPutEnv(const char* env, const char* name, const char* value)
+static bool CheckPutEnv(const char* env, const char* name, const char* value)
{
if(!kwsys::SystemTools::PutEnv(env))
{
@@ -348,7 +348,7 @@ bool CheckPutEnv(const char* env, const char* name, const char* value)
return true;
}
-bool CheckUnPutEnv(const char* env, const char* name)
+static bool CheckUnPutEnv(const char* env, const char* name)
{
if(!kwsys::SystemTools::UnPutEnv(env))
{
@@ -365,7 +365,7 @@ bool CheckUnPutEnv(const char* env, const char* name)
return true;
}
-bool CheckEnvironmentOperations()
+static bool CheckEnvironmentOperations()
{
bool res = true;
res &= CheckPutEnv("A=B", "A", "B");