summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Maynard <robert.maynard@kitware.com>2013-02-11 22:20:00 (GMT)
committerBrad King <brad.king@kitware.com>2013-02-19 19:44:57 (GMT)
commit674bd6e7788f9e6ff35c0082c9c85e9aa83b642d (patch)
tree59d9ba014199e9b7252cee9f170c60768ed5bd25
parent4760eade425e8e294ac9400785ffce70912d5b43 (diff)
parent3e7bba3fb2d431b512181e99c6333e9dfdc8a9fd (diff)
downloadCMake-674bd6e7788f9e6ff35c0082c9c85e9aa83b642d.zip
CMake-674bd6e7788f9e6ff35c0082c9c85e9aa83b642d.tar.gz
CMake-674bd6e7788f9e6ff35c0082c9c85e9aa83b642d.tar.bz2
Merge branch 'master' into sublime-text-2-generator
-rw-r--r--Modules/CMakePackageConfigHelpers.cmake26
-rw-r--r--Modules/ExternalProject.cmake7
-rw-r--r--Modules/FindQt4.cmake28
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmDocumentGeneratorExpressions.h14
-rw-r--r--Source/cmExportBuildFileGenerator.cxx20
-rw-r--r--Source/cmExportBuildFileGenerator.h3
-rw-r--r--Source/cmExportFileGenerator.cxx485
-rw-r--r--Source/cmExportFileGenerator.h32
-rw-r--r--Source/cmExportInstallFileGenerator.cxx49
-rw-r--r--Source/cmExportInstallFileGenerator.h6
-rw-r--r--Source/cmExtraCodeBlocksGenerator.cxx2
-rw-r--r--Source/cmFLTKWrapUICommand.cxx6
-rw-r--r--Source/cmGeneratorExpression.cxx97
-rw-r--r--Source/cmGeneratorExpression.h3
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx19
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h3
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx147
-rw-r--r--Source/cmGeneratorTarget.cxx29
-rw-r--r--Source/cmGeneratorTarget.h2
-rw-r--r--Source/cmGlobalGenerator.cxx18
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx19
-rw-r--r--Source/cmIncludeDirectoryCommand.cxx92
-rw-r--r--Source/cmIncludeDirectoryCommand.h3
-rw-r--r--Source/cmLocalVisualStudio6Generator.cxx14
-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/cmNinjaTargetGenerator.cxx4
-rw-r--r--Source/cmPolicies.cxx21
-rw-r--r--Source/cmPolicies.h1
-rw-r--r--Source/cmQtAutomoc.cxx6
-rw-r--r--Source/cmTarget.cxx436
-rw-r--r--Source/cmTarget.h24
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.cxx8
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.h8
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx8
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.h8
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx14
-rw-r--r--Source/cmTargetLinkLibrariesCommand.h11
-rw-r--r--Source/cmTargetPropCommandBase.cxx16
-rw-r--r--Source/cmTargetPropCommandBase.h4
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx4
-rw-r--r--Source/cmake.cxx17
-rw-r--r--Source/cmake.h2
-rw-r--r--Source/kwsys/CMakeLists.txt23
-rw-r--r--Source/kwsys/ProcessUNIX.c5
-rw-r--r--Source/kwsys/SystemInformation.cxx247
-rw-r--r--Source/kwsys/kwsysPlatformTestsCXX.cxx27
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt7
-rw-r--r--Tests/CMakeCommands/target_compile_definitions/consumer.cpp8
-rw-r--r--Tests/CMakeCommands/target_include_directories/CMakeLists.txt13
-rw-r--r--Tests/CMakeCommands/target_include_directories/consumer.cpp5
-rw-r--r--Tests/CMakeCommands/target_link_libraries/CMakeLists.txt13
-rw-r--r--Tests/CMakeCommands/target_link_libraries/depD.cpp13
-rw-r--r--Tests/CMakeCommands/target_link_libraries/depD.h11
-rw-r--r--Tests/CMakeCommands/target_link_libraries/targetB.cpp10
-rw-r--r--Tests/CMakeLists.txt1
-rw-r--r--Tests/CMakeTests/CMakeLists.txt5
-rw-r--r--Tests/CMakeTests/ProcessorCountTest.cmake.in11
-rw-r--r--Tests/CompatibleInterface/CMakeLists.txt57
-rw-r--r--Tests/CompatibleInterface/empty.cpp1
-rw-r--r--Tests/CompatibleInterface/iface2.cpp7
-rw-r--r--Tests/CompatibleInterface/iface2.h13
-rw-r--r--Tests/CompatibleInterface/main.cpp32
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt58
-rw-r--r--Tests/ExportImport/Export/sublib/CMakeLists.txt6
-rw-r--r--Tests/ExportImport/Export/sublib/subdir.cpp7
-rw-r--r--Tests/ExportImport/Export/sublib/subdir.h12
-rw-r--r--Tests/ExportImport/Export/testSharedLibDepends.cpp8
-rw-r--r--Tests/ExportImport/Export/testSharedLibDepends.h14
-rw-r--r--Tests/ExportImport/Export/testSharedLibRequired.cpp7
-rw-r--r--Tests/ExportImport/Export/testSharedLibRequired.h12
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt53
-rw-r--r--Tests/ExportImport/Import/A/deps_iface.c (renamed from Tests/ExportImport/Import/A/deps_iface.cpp)2
-rw-r--r--Tests/ExportImport/Import/A/deps_shared_iface.cpp41
-rw-r--r--Tests/ExternalProject/CMakeLists.txt4
-rw-r--r--Tests/Qt4Targets/CMakeLists.txt27
-rw-r--r--Tests/Qt4Targets/activeqtexe.cpp36
-rw-r--r--Tests/QtAutomoc/CMakeLists.txt9
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt1
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-NEW.cmake9
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt1
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-OLD.cmake21
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt0
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt1
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt2
-rw-r--r--Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake14
-rw-r--r--Tests/RunCMake/CMP0004/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CMP0004/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/CMP0004/empty.cpp0
-rw-r--r--Tests/RunCMake/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/CompatibleInterface/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt5
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake11
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt3
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake11
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt3
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake10
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt4
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake9
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt5
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake11
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt3
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake11
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt3
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake10
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt1
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt4
-rw-r--r--Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake9
-rw-r--r--Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake10
-rw-r--r--Tests/RunCMake/CompatibleInterface/main.cpp5
-rw-r--r--Tests/RunCMake/include_directories/DebugIncludes-stderr.txt23
-rw-r--r--Tests/VSExternalInclude/Lib1/CMakeLists.txt1
-rw-r--r--Tests/VSExternalInclude/Lib2/CMakeLists.txt1
125 files changed, 2300 insertions, 505 deletions
diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake
index a92ce7c..393d05c 100644
--- a/Modules/CMakePackageConfigHelpers.cmake
+++ b/Modules/CMakePackageConfigHelpers.cmake
@@ -9,6 +9,8 @@
# configure_file() command when creating the <Name>Config.cmake or <Name>-config.cmake
# file for installing a project or library. It helps making the resulting package
# relocatable by avoiding hardcoded paths in the installed Config.cmake file.
+# <Name>Config.cmake files installed under UNIX into /lib(64) or /usr/lib(64) are
+# considered system packages and are not relocatable.
#
# In a FooConfig.cmake file there may be code like this to make the
# install destinations know to the using project:
@@ -173,17 +175,33 @@ function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile)
else()
set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}")
endif()
+
+ # with the /usr-move, /lib(64) is a symlink to /usr/lib on Fedora, ArchLinux, Mageira and others.
+ # If we are installed to such a location, force using absolute paths.
+ set(forceAbsolutePaths FALSE)
+ if("${absInstallDir}" MATCHES "^(/usr)?/lib(64)?/.+")
+ set(forceAbsolutePaths TRUE)
+ endif()
+
file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" )
foreach(var ${CCF_PATH_VARS})
if(NOT DEFINED ${var})
message(FATAL_ERROR "Variable ${var} does not exist")
else()
- if(IS_ABSOLUTE "${${var}}")
- string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
- PACKAGE_${var} "${${var}}")
+ if(forceAbsolutePaths)
+ if(IS_ABSOLUTE "${${var}}")
+ set(PACKAGE_${var} "${${var}}")
+ else()
+ set(PACKAGE_${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
+ endif()
else()
- set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
+ if(IS_ABSOLUTE "${${var}}")
+ string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}"
+ PACKAGE_${var} "${${var}}")
+ else()
+ set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}")
+ endif()
endif()
endif()
endforeach()
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 2355dac..ed7fd7c 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -1558,8 +1558,11 @@ function(_ep_add_configure_command name)
set(file_deps)
get_property(deps TARGET ${name} PROPERTY _EP_DEPENDS)
foreach(dep IN LISTS deps)
- _ep_get_step_stampfile(${dep} "done" done_stamp_file)
- list(APPEND file_deps ${done_stamp_file})
+ get_property(is_ep TARGET ${dep} PROPERTY _EP_IS_EXTERNAL_PROJECT)
+ if(is_ep)
+ _ep_get_step_stampfile(${dep} "done" done_stamp_file)
+ list(APPEND file_deps ${done_stamp_file})
+ endif()
endforeach()
get_property(cmd_set TARGET ${name} PROPERTY _EP_CONFIGURE_COMMAND SET)
diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake
index 7baa11b..35420b4 100644
--- a/Modules/FindQt4.cmake
+++ b/Modules/FindQt4.cmake
@@ -65,6 +65,12 @@
# is much more flexible, but requires that FindQt4.cmake is executed before
# such an exported dependency file is processed.
#
+# Note that if using IMPORTED targets, the qtmain.lib static library is
+# automatically linked on Windows. To disable that globally, set the
+# QT4_NO_LINK_QTMAIN variable before finding Qt4. To disable that for a
+# particular executable, set the QT4_NO_LINK_QTMAIN target property to
+# True on the executable.
+#
# QT_INCLUDE_DIRS_NO_SYSTEM
# If this variable is set to TRUE, the Qt include directories
# in the QT_USE_FILE will NOT have the SYSTEM keyword set.
@@ -1009,7 +1015,14 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
# platform dependent libraries
if(Q_WS_WIN)
_QT4_ADJUST_LIB_VARS(qtmain)
+
_QT4_ADJUST_LIB_VARS(QAxServer)
+ set_property(TARGET Qt4::QAxServer PROPERTY
+ INTERFACE_QT4_NO_LINK_QTMAIN ON
+ )
+ set_property(TARGET Qt4::QAxServer APPEND PROPERTY
+ COMPATIBLE_INTERFACE_BOOL QT4_NO_LINK_QTMAIN)
+
_QT4_ADJUST_LIB_VARS(QAxContainer)
endif()
@@ -1049,6 +1062,21 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION)
_qt4_add_target_private_depends(phonon DBus)
endif()
+ if (WIN32 AND NOT QT4_NO_LINK_QTMAIN)
+ set(_isExe $<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>)
+ set(_isWin32 $<BOOL:$<TARGET_PROPERTY:WIN32_EXECUTABLE>>)
+ set(_isNotExcluded $<NOT:$<BOOL:$<TARGET_PROPERTY:QT4_NO_LINK_QTMAIN>>>)
+ set(_isPolicyNEW $<TARGET_POLICY:CMP0020>)
+ set_property(TARGET Qt4::QtCore APPEND PROPERTY
+ IMPORTED_LINK_INTERFACE_LIBRARIES
+ $<$<AND:${_isExe},${_isWin32},${_isNotExcluded},${_isPolicyNEW}>:Qt4::qtmain>
+ )
+ unset(_isExe)
+ unset(_isWin32)
+ unset(_isNotExcluded)
+ unset(_isPolicyNEW)
+ endif()
+
#######################################
#
# Check the executables of Qt
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index f77d17c..608c269 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 20130110)
+set(CMake_VERSION_TWEAK 20130129)
#set(CMake_VERSION_RC 1)
diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h
index b8889ac..be9f2ff 100644
--- a/Source/cmDocumentGeneratorExpressions.h
+++ b/Source/cmDocumentGeneratorExpressions.h
@@ -37,6 +37,7 @@
"target in the same buildsystem. Expands to the empty string " \
"otherwise.\n" \
" $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \
+ " $<TARGET_DEFINED:tgt> = '1' if tgt is a target, else '0'\n" \
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
" $<TARGET_SONAME_FILE:tgt> = file with soname (.so.3)\n" \
"where \"tgt\" is the name of a target. " \
@@ -46,9 +47,14 @@
" $<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" \
+ " $<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" \
"Boolean expressions:\n" \
" $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \
" $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \
@@ -59,7 +65,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 9533319..7147f86 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -62,6 +62,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
cmTarget* te = *tei;
this->GenerateImportTargetCode(os, te);
+ te->AppendBuildInterfaceIncludes();
+
ImportPropertyMap properties;
this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te,
@@ -70,20 +72,23 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te,
cmGeneratorExpression::BuildInterface,
properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
+ te, properties);
+ this->PopulateCompatibleInterfaceProperties(te, properties);
this->GenerateInterfaceProperties(te, os, properties);
}
- this->GenerateMissingTargetsCheckCode(os, missingTargets);
-
// Generate import file content for each configuration.
for(std::vector<std::string>::const_iterator
ci = this->Configurations.begin();
ci != this->Configurations.end(); ++ci)
{
- this->GenerateImportConfig(os, ci->c_str());
+ this->GenerateImportConfig(os, ci->c_str(), missingTargets);
}
+ this->GenerateMissingTargetsCheckCode(os, missingTargets);
+
return true;
}
@@ -91,7 +96,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
void
cmExportBuildFileGenerator
::GenerateImportTargetsConfig(std::ostream& os,
- const char* config, std::string const& suffix)
+ const char* config, std::string const& suffix,
+ std::vector<std::string> &missingTargets)
{
for(std::vector<cmTarget*>::const_iterator
tei = this->Exports->begin();
@@ -104,9 +110,12 @@ cmExportBuildFileGenerator
if(!properties.empty())
{
// Get the rest of the target details.
- std::vector<std::string> missingTargets;
this->SetImportDetailProperties(config, suffix,
target, properties, missingTargets);
+ this->SetImportLinkInterface(config, suffix,
+ cmGeneratorExpression::BuildInterface,
+ target, properties, missingTargets);
+
// TOOD: PUBLIC_HEADER_LOCATION
// This should wait until the build feature propagation stuff
@@ -115,7 +124,6 @@ cmExportBuildFileGenerator
// properties);
// Generate code in the export file.
- this->GenerateMissingTargetsCheckCode(os, missingTargets);
this->GenerateImportPropertyCode(os, config, target, properties);
}
}
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 726537b..5e1be16 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -44,7 +44,8 @@ protected:
virtual bool GenerateMainFile(std::ostream& os);
virtual void GenerateImportTargetsConfig(std::ostream& os,
const char* config,
- std::string const& suffix);
+ std::string const& suffix,
+ std::vector<std::string> &missingTargets);
virtual void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
cmMakefile* mf,
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 90c0c41..96e0aea 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmTarget.h"
#include "cmTargetExport.h"
#include "cmVersion.h"
+#include "cmComputeLinkInformation.h"
#include <cmsys/auto_ptr.hxx>
@@ -81,16 +82,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,14 +101,15 @@ bool cmExportFileGenerator::GenerateImportFile()
// End with the import file footer.
this->GenerateImportFooterCode(os);
- os << "CMAKE_POLICY(POP)\n";
+ os << "cmake_policy(POP)\n";
return result;
}
//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
- const char* config)
+ const char* config,
+ std::vector<std::string> &missingTargets)
{
// Construct the property configuration suffix.
std::string suffix = "_";
@@ -121,7 +123,19 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
}
// Generate the per-config target information.
- this->GenerateImportTargetsConfig(os, config, suffix);
+ this->GenerateImportTargetsConfig(os, config, suffix, missingTargets);
+}
+
+//----------------------------------------------------------------------------
+void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName,
+ cmTarget *target,
+ ImportPropertyMap &properties)
+{
+ const char *input = target->GetProperty(propName);
+ if (input)
+ {
+ properties[propName] = input;
+ }
}
//----------------------------------------------------------------------------
@@ -164,6 +178,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,
@@ -173,7 +266,7 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
{
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)
{
@@ -184,10 +277,90 @@ void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target,
}
//----------------------------------------------------------------------------
+bool
+cmExportFileGenerator::AddTargetNamespace(std::string &input,
+ cmTarget* target,
+ std::vector<std::string> &missingTargets)
+{
+ cmMakefile *mf = target->GetMakefile();
+
+ cmTarget *tgt = mf->FindTargetToUse(input.c_str());
+ if (!tgt)
+ {
+ return false;
+ }
+
+ if(tgt->IsImported())
+ {
+ return true;
+ }
+ if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
+ {
+ input = this->Namespace + input;
+ }
+ else
+ {
+ std::string namespacedTarget;
+ this->HandleMissingTarget(namespacedTarget, missingTargets,
+ mf, target, tgt);
+ if (!namespacedTarget.empty())
+ {
+ input = namespacedTarget;
+ }
+ }
+ return true;
+}
+
+//----------------------------------------------------------------------------
+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
cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
std::string &input,
cmTarget* target,
+ std::vector<std::string> &missingTargets,
+ FreeTargetsReplace replace)
+{
+ if (replace == NoReplaceFreeTargets)
+ {
+ this->ResolveTargetsInGeneratorExpression(input, target, missingTargets);
+ return;
+ }
+ std::vector<std::string> parts;
+ cmGeneratorExpression::Split(input, parts);
+
+ std::string sep;
+ input = "";
+ for(std::vector<std::string>::iterator li = parts.begin();
+ li != parts.end(); ++li)
+ {
+ if (!isGeneratorExpression(*li))
+ {
+ this->AddTargetNamespace(*li, target, missingTargets);
+ }
+ else
+ {
+ this->ResolveTargetsInGeneratorExpression(
+ *li,
+ target,
+ missingTargets);
+ }
+ input += sep + *li;
+ sep = ";";
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator::ResolveTargetsInGeneratorExpression(
+ std::string &input,
+ cmTarget* target,
std::vector<std::string> &missingTargets)
{
std::string::size_type pos = 0;
@@ -212,45 +385,17 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
continue;
}
- const std::string targetName = input.substr(nameStartPos,
+ std::string targetName = input.substr(nameStartPos,
commaPos - nameStartPos);
- pos = nameStartPos; // We're not going to replace the entire expression,
- // but only the target parameter.
- if (cmTarget *tgt = mf->FindTargetToUse(targetName.c_str()))
- {
- if(tgt->IsImported())
- {
- pos += targetName.size();
- }
- else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
- {
- input.replace(pos, targetName.size(),
- this->Namespace + targetName);
- pos += this->Namespace.size() + targetName.size();
- }
- else
- {
- std::string namespacedTarget;
- this->HandleMissingTarget(namespacedTarget, missingTargets,
- mf, target, tgt);
- if (!namespacedTarget.empty())
- {
- input.replace(pos, targetName.size(), namespacedTarget);
- pos += namespacedTarget.size();
- }
- }
- }
- else
+ if (!this->AddTargetNamespace(targetName, target, missingTargets))
{
errorString = "$<TARGET_PROPERTY:" + targetName + ",prop> requires "
"its first parameter to be a reachable target.";
- }
- lastPos = pos;
- if (!errorString.empty())
- {
break;
}
+ input.replace(nameStartPos, commaPos - nameStartPos, targetName);
+ lastPos = pos + targetName.size();
}
if (!errorString.empty())
{
@@ -267,51 +412,24 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
if (endPos == input.npos)
{
errorString = "$<TARGET_NAME:...> expression incomplete";
+ break;
}
- const std::string targetName = input.substr(nameStartPos,
+ std::string targetName = input.substr(nameStartPos,
endPos - nameStartPos);
- if(targetName.find("$<", lastPos) != input.npos)
+ if(targetName.find("$<") != input.npos)
{
errorString = "$<TARGET_NAME:...> requires its parameter to be a "
"literal.";
+ break;
}
- if (cmTarget *tgt = mf->FindTargetToUse(targetName.c_str()))
- {
- if(tgt->IsImported())
- {
- input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
- targetName);
- pos += sizeof("$<TARGET_NAME:") + targetName.size();
- }
- else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
- {
- input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
- this->Namespace + targetName);
- pos += sizeof("$<TARGET_NAME:") + targetName.size();
- }
- else
- {
- std::string namespacedTarget;
- this->HandleMissingTarget(namespacedTarget, missingTargets,
- mf, target, tgt);
- if (!namespacedTarget.empty())
- {
- input.replace(pos, sizeof("$<TARGET_NAME:") + targetName.size(),
- namespacedTarget);
- pos += sizeof("$<TARGET_NAME:") + targetName.size();
- }
- }
- }
- else
+ if (!this->AddTargetNamespace(targetName, target, missingTargets))
{
errorString = "$<TARGET_NAME:...> requires its parameter to be a "
"reachable target.";
- }
- lastPos = pos;
- if (!errorString.empty())
- {
break;
}
+ input.replace(pos, endPos - pos + 1, targetName);
+ lastPos = endPos;
}
if (!errorString.empty())
{
@@ -322,6 +440,64 @@ cmExportFileGenerator::ResolveTargetsInGeneratorExpressions(
//----------------------------------------------------------------------------
void
cmExportFileGenerator
+::SetImportLinkInterface(const char* config, std::string const& suffix,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
+ cmTarget* target, ImportPropertyMap& properties,
+ std::vector<std::string>& missingTargets)
+{
+ // Add the transitive link dependencies for this configuration.
+ cmTarget::LinkInterface const* iface = target->GetLinkInterface(config,
+ target);
+ if (!iface)
+ {
+ return;
+ }
+
+ if (iface->ImplementationIsInterface)
+ {
+ this->SetImportLinkProperty(suffix, target,
+ "IMPORTED_LINK_INTERFACE_LIBRARIES",
+ iface->Libraries, properties, missingTargets);
+ return;
+ }
+
+ const char *propContent;
+
+ if (const char *prop_suffixed = target->GetProperty(
+ ("LINK_INTERFACE_LIBRARIES" + suffix).c_str()))
+ {
+ propContent = prop_suffixed;
+ }
+ else if (const char *prop = target->GetProperty(
+ "LINK_INTERFACE_LIBRARIES"))
+ {
+ propContent = prop;
+ }
+ else
+ {
+ return;
+ }
+
+ if (!*propContent)
+ {
+ properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = "";
+ return;
+ }
+
+ std::string prepro = cmGeneratorExpression::Preprocess(propContent,
+ preprocessRule);
+ if (!prepro.empty())
+ {
+ this->ResolveTargetsInGeneratorExpressions(prepro, target,
+ missingTargets,
+ ReplaceFreeTargets);
+ properties["IMPORTED_LINK_INTERFACE_LIBRARIES" + suffix] = prepro;
+ }
+}
+
+//----------------------------------------------------------------------------
+void
+cmExportFileGenerator
::SetImportDetailProperties(const char* config, std::string const& suffix,
cmTarget* target, ImportPropertyMap& properties,
std::vector<std::string>& missingTargets
@@ -363,9 +539,7 @@ cmExportFileGenerator
this->SetImportLinkProperty(suffix, target,
"IMPORTED_LINK_INTERFACE_LANGUAGES",
iface->Languages, properties, missingTargets);
- this->SetImportLinkProperty(suffix, target,
- "IMPORTED_LINK_INTERFACE_LIBRARIES",
- iface->Libraries, properties, missingTargets);
+
this->SetImportLinkProperty(suffix, target,
"IMPORTED_LINK_DEPENDENT_LIBRARIES",
iface->SharedDeps, properties, missingTargets);
@@ -397,9 +571,6 @@ cmExportFileGenerator
return;
}
- // Get the makefile in which to lookup target information.
- cmMakefile* mf = target->GetMakefile();
-
// Construct the property value.
std::string link_libs;
const char* sep = "";
@@ -410,33 +581,9 @@ cmExportFileGenerator
link_libs += sep;
sep = ";";
- // Append this entry.
- if(cmTarget* tgt = mf->FindTargetToUse(li->c_str()))
- {
- // This is a target.
- if(tgt->IsImported())
- {
- // The target is imported (and therefore is not in the
- // export). Append the raw name.
- link_libs += *li;
- }
- else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
- {
- // The target is in the export. Append it with the export
- // namespace.
- link_libs += this->Namespace;
- link_libs += *li;
- }
- else
- {
- this->HandleMissingTarget(link_libs, missingTargets, mf, target, tgt);
- }
- }
- else
- {
- // Append the raw name.
- link_libs += *li;
- }
+ std::string temp = *li;
+ this->AddTargetNamespace(temp, target, missingTargets);
+ link_libs += temp;
}
// Store the property.
@@ -469,7 +616,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";
}
//----------------------------------------------------------------------------
@@ -478,7 +625,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";
}
@@ -486,31 +633,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";
}
//----------------------------------------------------------------------------
@@ -527,16 +674,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;
@@ -545,27 +692,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";
@@ -585,7 +732,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)
{
@@ -596,7 +743,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)
{
@@ -611,21 +758,29 @@ cmExportFileGenerator
void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os,
const std::vector<std::string>& missingTargets)
{
+ if (missingTargets.empty())
+ {
+ return;
+ }
os << "# Make sure the targets which have been exported in some other \n"
"# export set exist.\n";
+ std::set<std::string> emitted;
for(unsigned int i=0; i<missingTargets.size(); ++i)
{
- 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 \\\""
- << missingTargets[i] << "\\\" not found ! \")\n"
- << " ENDIF()\n"
- << "ENDIF()\n";
+ 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 "
+ << "\"Required imported target \\\"" << missingTargets[i]
+ << "\\\" not found ! \")\n"
+ << " else()\n"
+ << " message(FATAL_ERROR \"Required imported target \\\""
+ << missingTargets[i] << "\\\" not found ! \")\n"
+ << " endif()\n"
+ << "endif()\n";
+ }
}
os << "\n";
}
@@ -643,10 +798,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"
@@ -656,11 +811,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";
}
@@ -676,8 +831,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 7c58ad8..b39df0f 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -47,7 +47,8 @@ protected:
// Generate per-configuration target information to the given output
// stream.
- void GenerateImportConfig(std::ostream& os, const char* config);
+ void GenerateImportConfig(std::ostream& os, const char* config,
+ std::vector<std::string> &missingTargets);
// Methods to implement export file code generation.
void GenerateImportHeaderCode(std::ostream& os, const char* config = 0);
@@ -85,7 +86,8 @@ protected:
/** Each subclass knows where the target files are located. */
virtual void GenerateImportTargetsConfig(std::ostream& os,
const char* config,
- std::string const& suffix) = 0;
+ std::string const& suffix,
+ std::vector<std::string> &missingTargets) = 0;
/** Each subclass knows how to deal with a target that is missing from an
* export set. */
@@ -99,12 +101,27 @@ protected:
cmGeneratorExpression::PreprocessContext,
ImportPropertyMap &properties,
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);
+ void SetImportLinkInterface(const char* config, std::string const& suffix,
+ cmGeneratorExpression::PreprocessContext preprocessRule,
+ cmTarget* target, ImportPropertyMap& properties,
+ std::vector<std::string>& missingTargets);
+
+ enum FreeTargetsReplace {
+ ReplaceFreeTargets,
+ NoReplaceFreeTargets
+ };
+
void ResolveTargetsInGeneratorExpressions(std::string &input,
- cmTarget* target,
- std::vector<std::string> &missingTargets);
+ cmTarget* target,
+ std::vector<std::string> &missingTargets,
+ FreeTargetsReplace replace = NoReplaceFreeTargets);
// The namespace in which the exports are placed in the generated file.
std::string Namespace;
@@ -128,6 +145,13 @@ private:
cmGeneratorExpression::PreprocessContext,
ImportPropertyMap &properties,
std::vector<std::string> &missingTargets);
+
+ bool AddTargetNamespace(std::string &input, cmTarget* target,
+ std::vector<std::string> &missingTargets);
+
+ void ResolveTargetsInGeneratorExpression(std::string &input,
+ cmTarget* target,
+ std::vector<std::string> &missingTargets);
};
#endif
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index bc953c9..a35f5cf 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.";
@@ -89,39 +89,47 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
te,
cmGeneratorExpression::InstallInterface,
properties, missingTargets);
+ this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
+ te, properties);
+ this->PopulateCompatibleInterfaceProperties(te, properties);
this->GenerateInterfaceProperties(te, os, properties);
}
- this->GenerateMissingTargetsCheckCode(os, missingTargets);
// 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";
+ this->GenerateImportedFileCheckLoop(os);
+
// Generate an import file for each configuration.
bool result = true;
for(std::vector<std::string>::const_iterator
ci = this->Configurations.begin();
ci != this->Configurations.end(); ++ci)
{
- if(!this->GenerateImportFileConfig(ci->c_str()))
+ if(!this->GenerateImportFileConfig(ci->c_str(), missingTargets))
{
result = false;
}
}
+
+ this->GenerateMissingTargetsCheckCode(os, missingTargets);
+
return result;
}
//----------------------------------------------------------------------------
bool
-cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
+cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config,
+ std::vector<std::string> &missingTargets)
{
// Skip configurations not enabled for this export.
if(!this->IEGen->InstallsForConfig(config))
@@ -161,7 +169,7 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
this->GenerateImportHeaderCode(os, config);
// Generate the per-config target information.
- this->GenerateImportConfig(os, config);
+ this->GenerateImportConfig(os, config, missingTargets);
// End with the import file footer.
this->GenerateImportFooterCode(os);
@@ -176,7 +184,8 @@ cmExportInstallFileGenerator::GenerateImportFileConfig(const char* config)
void
cmExportInstallFileGenerator
::GenerateImportTargetsConfig(std::ostream& os,
- const char* config, std::string const& suffix)
+ 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.
@@ -185,12 +194,12 @@ cmExportInstallFileGenerator
{
std::string dest = installDest;
os << "# Compute the installation prefix relative to this file.\n"
- << "GET_FILENAME_COMPONENT(_IMPORT_PREFIX "
+ << "get_filename_component(_IMPORT_PREFIX "
<< "\"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n";
while(!dest.empty())
{
os <<
- "GET_FILENAME_COMPONENT(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
+ "get_filename_component(_IMPORT_PREFIX \"${_IMPORT_PREFIX}\" PATH)\n";
dest = cmSystemTools::GetFilenamePath(dest);
}
os << "\n";
@@ -225,10 +234,13 @@ cmExportInstallFileGenerator
if(!properties.empty())
{
// Get the rest of the target details.
- std::vector<std::string> missingTargets;
this->SetImportDetailProperties(config, suffix,
te->Target, properties, missingTargets);
+ this->SetImportLinkInterface(config, suffix,
+ cmGeneratorExpression::InstallInterface,
+ te->Target, properties, missingTargets);
+
// TOOD: PUBLIC_HEADER_LOCATION
// This should wait until the build feature propagation stuff
// is done. Then this can be a propagated include directory.
@@ -236,20 +248,17 @@ cmExportInstallFileGenerator
// properties);
// Generate code in the export file.
- this->GenerateMissingTargetsCheckCode(os, missingTargets);
this->GenerateImportPropertyCode(os, config, te->Target, properties);
this->GenerateImportedFileChecksCode(os, te->Target, properties,
importedLocations);
}
}
- this->GenerateImportedFileCheckLoop(os);
-
// Cleanup the import prefix variable.
if(!this->ImportPrefix.empty())
{
os << "# Cleanup temporary variables.\n"
- << "SET(_IMPORT_PREFIX)\n"
+ << "set(_IMPORT_PREFIX)\n"
<< "\n";
}
}
@@ -419,7 +428,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 "
@@ -437,7 +446,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 e719ecc..e187749 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -56,7 +56,8 @@ protected:
virtual bool GenerateMainFile(std::ostream& os);
virtual void GenerateImportTargetsConfig(std::ostream& os,
const char* config,
- std::string const& suffix);
+ std::string const& suffix,
+ std::vector<std::string> &missingTargets);
virtual void HandleMissingTarget(std::string& link_libs,
std::vector<std::string>& missingTargets,
cmMakefile* mf,
@@ -72,7 +73,8 @@ protected:
/** Generate a per-configuration file for the targets. */
- bool GenerateImportFileConfig(const char* config);
+ bool GenerateImportFileConfig(const char* config,
+ std::vector<std::string> &missingTargets);
/** Fill in properties indicating installed file locations. */
void SetImportLocationProperty(const char* config,
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/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 4063697..78ae8f2 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -148,6 +148,38 @@ cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression()
}
//----------------------------------------------------------------------------
+static std::string stripEmptyListElements(const std::string &input)
+{
+ std::string result;
+
+ const char *c = input.c_str();
+ bool skipSemiColons = true;
+ for ( ; *c; ++c)
+ {
+ if(c[0] == ';')
+ {
+ if(skipSemiColons)
+ {
+ continue;
+ }
+ skipSemiColons = true;
+ }
+ else
+ {
+ skipSemiColons = false;
+ }
+ result += *c;
+ }
+
+ if (!result.empty() && *(result.end() - 1) == ';')
+ {
+ result.resize(result.size() - 1);
+ }
+
+ return result;
+}
+
+//----------------------------------------------------------------------------
static std::string stripAllGeneratorExpressions(const std::string &input)
{
std::string result;
@@ -186,7 +218,7 @@ static std::string stripAllGeneratorExpressions(const std::string &input)
lastPos = pos;
}
result += input.substr(lastPos);
- return result;
+ return stripEmptyListElements(result);
}
//----------------------------------------------------------------------------
@@ -247,7 +279,68 @@ static std::string stripExportInterface(const std::string &input,
}
result += input.substr(lastPos);
- return result;
+ return stripEmptyListElements(result);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratorExpression::Split(const std::string &input,
+ std::vector<std::string> &output)
+{
+ std::string::size_type pos = 0;
+ std::string::size_type lastPos = pos;
+ while((pos = input.find("$<", lastPos)) != input.npos)
+ {
+ std::string part = input.substr(lastPos, pos - lastPos);
+ std::string preGenex;
+ if (!part.empty())
+ {
+ std::string::size_type startPos = input.rfind(";", pos);
+ if (startPos != pos - 1 && startPos >= lastPos)
+ {
+ part = input.substr(lastPos, startPos - lastPos);
+ preGenex = input.substr(startPos + 1, pos - startPos - 1);
+ }
+ cmSystemTools::ExpandListArgument(part.c_str(), output);
+ }
+ pos += 2;
+ int nestingLevel = 1;
+ const char *c = input.c_str() + pos;
+ const char * const cStart = c;
+ for ( ; *c; ++c)
+ {
+ if(c[0] == '$' && c[1] == '<')
+ {
+ ++nestingLevel;
+ ++c;
+ continue;
+ }
+ if(c[0] == '>')
+ {
+ --nestingLevel;
+ if (nestingLevel == 0)
+ {
+ break;
+ }
+ }
+ }
+ for ( ; *c; ++c)
+ {
+ // Capture the part after the genex and before the next ';'
+ if(c[0] == ';')
+ {
+ --c;
+ break;
+ }
+ }
+ const std::string::size_type traversed = (c - cStart) + 1;
+ output.push_back(preGenex + "$<" + input.substr(pos, traversed));
+ pos += traversed;
+ lastPos = pos;
+ }
+ if (lastPos < input.size())
+ {
+ cmSystemTools::ExpandListArgument(input.substr(lastPos), output);
+ }
}
//----------------------------------------------------------------------------
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index b58dde5..8f1aef6 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -59,6 +59,9 @@ public:
static std::string Preprocess(const std::string &input,
PreprocessContext context);
+ static void Split(const std::string &input,
+ std::vector<std::string> &output);
+
private:
cmGeneratorExpression(const cmGeneratorExpression &);
void operator=(const cmGeneratorExpression &);
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 2e5b5ae..269211b 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -106,3 +106,22 @@ 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);
+}
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index 48f26ed..3169291 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -35,6 +35,9 @@ struct cmGeneratorExpressionDAGChecker
void reportError(cmGeneratorExpressionContext *context,
const std::string &expr);
+
+ bool EvaluatingLinkLibraries();
+
private:
Result checkGraph() const;
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index f4e4131..0c61a12 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -289,6 +289,22 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
} configurationTestNode;
+static const struct TargetDefinedNode : public cmGeneratorExpressionNode
+{
+ TargetDefinedNode() {}
+
+ virtual int NumExpectedParameters() const { return 1; }
+
+ std::string Evaluate(const std::vector<std::string> &parameters,
+ cmGeneratorExpressionContext *context,
+ const GeneratorExpressionContent *,
+ cmGeneratorExpressionDAGChecker *) const
+ {
+ return context->Makefile->FindTargetToUse(parameters.front().c_str())
+ ? "1" : "0";
+ }
+} targetDefinedNode;
+
//----------------------------------------------------------------------------
static const char* targetPropertyTransitiveWhitelist[] = {
"INTERFACE_INCLUDE_DIRECTORIES"
@@ -426,6 +442,34 @@ 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")
+ {
+ return target->GetLinkInterfaceDependentBoolProperty(
+ "POSITION_INDEPENDENT_CODE", context->Config) ? "1" : "0";
+ }
+ if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
+ context->Config))
+ {
+ return target->GetLinkInterfaceDependentBoolProperty(
+ propertyName,
+ context->Config) ? "1" : "0";
+ }
+ if (target->IsLinkInterfaceDependentStringProperty(propertyName,
+ context->Config))
+ {
+ return target->GetLinkInterfaceDependentStringProperty(
+ propertyName,
+ context->Config);
+ }
+
return std::string();
}
@@ -472,6 +516,105 @@ 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();
+ }
+ 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;
+
+//----------------------------------------------------------------------------
template<bool linker, bool soname>
struct TargetFilesystemArtifactResultCreator
{
@@ -698,10 +841,14 @@ 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;
return 0;
}
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 d030aa7..f7eff21 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -941,19 +941,7 @@ void cmGlobalGenerator::Generate()
for ( tit = targets->begin(); tit != targets->end(); ++ tit )
{
- if (mf->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES"))
- {
- const char *binDir = mf->GetStartOutputDirectory();
- const char *srcDir = mf->GetStartDirectory();
- const std::string dirs = std::string(binDir ? binDir : "")
- + std::string(binDir ? ";" : "")
- + std::string(srcDir ? srcDir : "");
- if (!dirs.empty())
- {
- tit->second.AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
- ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
- }
- }
+ tit->second.AppendBuildInterfaceIncludes();
}
}
@@ -992,6 +980,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();
@@ -1075,7 +1064,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 2cfe4da..abe60c6 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1367,16 +1367,18 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(cmXCodeObject* buildPhases,
}
//----------------------------------------------------------------------------
-// This function removes each occurence of the flag and returns the last one
+// This function removes each occurrence of the flag and returns the last one
// (i.e., the dominant flag in GCC)
std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
std::string& flags)
{
std::string retFlag;
- std::string::size_type pos = flags.rfind(flag);
+ std::string::size_type lastOccurancePos = flags.rfind(flag);
bool saved = false;
- while(pos != flags.npos)
+ while(lastOccurancePos != flags.npos)
{
+ //increment pos, we use lastOccurancePos to reduce search space on next inc
+ std::string::size_type pos = lastOccurancePos;
if(pos == 0 || flags[pos-1]==' ')
{
while(pos < flags.size() && flags[pos] != ' ')
@@ -1388,9 +1390,12 @@ std::string cmGlobalXCodeGenerator::ExtractFlag(const char* flag,
flags[pos] = ' ';
pos++;
}
- }
saved = true;
- pos = flags.rfind(flag);
+ }
+ //decrement lastOccurancePos while making sure we don't loop around
+ //and become a very large positive number since size_type is unsigned
+ lastOccurancePos = lastOccurancePos == 0 ? 0 : lastOccurancePos-1;
+ lastOccurancePos = flags.rfind(flag,lastOccurancePos);
}
return retFlag;
}
@@ -1676,11 +1681,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..a32fc77 100644
--- a/Source/cmIncludeDirectoryCommand.h
+++ b/Source/cmIncludeDirectoryCommand.h
@@ -84,7 +84,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/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx
index 6c78ac4..617eb4e 100644
--- a/Source/cmLocalVisualStudio6Generator.cxx
+++ b/Source/cmLocalVisualStudio6Generator.cxx
@@ -1697,25 +1697,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 b432986..e7a1500 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/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/cmTarget.cxx b/Source/cmTarget.cxx
index 2cfb1bf..5669872 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -145,11 +145,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;
}
//----------------------------------------------------------------------------
@@ -892,6 +895,30 @@ void cmTarget::DefineProperties(cmake *cm)
"requirement for their INTERFACE_POSITION_INDEPENDENT_CODE property.");
cm->DefineProperty
+ ("COMPATIBLE_INTERFACE_BOOL", cmProperty::TARGET,
+ "Properties which must be compatible with their link interface",
+ "The COMPATIBLE_INTERFACE_BOOL property may contain a list of properties"
+ "for this target which must be consistent when evaluated as a boolean "
+ "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 consistent with each "
+ "other, and with the \"FOO\" property in this target. "
+ "Consistency in this sense has the meaning that if the property is set,"
+ "then it must have the same boolean value as all others, and if the "
+ "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 "
@@ -1485,6 +1512,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);
}
//----------------------------------------------------------------------------
@@ -1506,6 +1535,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();
}
//----------------------------------------------------------------------------
@@ -2233,6 +2269,14 @@ static std::string targetNameGenex(const char *lib)
}
//----------------------------------------------------------------------------
+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 cmTarget::AddLinkLibrary(cmMakefile& mf,
const char *target, const char* lib,
LinkLibraryType llt)
@@ -2247,13 +2291,19 @@ 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());
}
+ if (isGeneratorExpression(lib))
+ {
+ return;
+ }
+
cmTarget::LibraryID tmp;
tmp.first = lib;
tmp.second = llt;
@@ -2655,6 +2705,30 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
}
//----------------------------------------------------------------------------
+void cmTarget::AppendBuildInterfaceIncludes()
+{
+ if (this->BuildInterfaceIncludesAppended)
+ {
+ return;
+ }
+ this->BuildInterfaceIncludesAppended = true;
+
+ if (this->Makefile->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES"))
+ {
+ const char *binDir = this->Makefile->GetStartOutputDirectory();
+ const char *srcDir = this->Makefile->GetStartDirectory();
+ const std::string dirs = std::string(binDir ? binDir : "")
+ + std::string(binDir ? ";" : "")
+ + std::string(srcDir ? srcDir : "");
+ if (!dirs.empty())
+ {
+ this->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
+ ("$<BUILD_INTERFACE:" + dirs + ">").c_str());
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
bool before)
{
@@ -2688,11 +2762,17 @@ 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();
@@ -2727,14 +2807,43 @@ std::vector<std::string> cmTarget::GetIncludeDirectories(const char *config)
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.
@@ -4431,22 +4540,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 **)
+{
+ 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 *)
{
- bool propContent = this->GetPropertyAsBool(p.c_str());
- const bool explicitlySet = this->GetProperties()
+ 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;
@@ -4468,20 +4624,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
{
@@ -4499,15 +4657,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
{
@@ -4527,14 +4686,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
{
@@ -4559,6 +4719,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
@@ -4896,16 +5130,30 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
{
std::string linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
linkProp += suffix;
- if(const char* config_libs = this->GetProperty(linkProp.c_str()))
+
+ const char *propertyLibs = this->GetProperty(linkProp.c_str());
+
+ if(!propertyLibs)
{
- cmSystemTools::ExpandListArgument(config_libs,
- info.LinkInterface.Libraries);
+ linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
+ propertyLibs = this->GetProperty(linkProp.c_str());
}
- else if(const char* libs =
- this->GetProperty("IMPORTED_LINK_INTERFACE_LIBRARIES"))
+ if(propertyLibs)
{
- cmSystemTools::ExpandListArgument(libs,
- info.LinkInterface.Libraries);
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt,
+ this->GetName(),
+ linkProp, 0, 0);
+ cmSystemTools::ExpandListArgument(ge.Parse(propertyLibs)
+ ->Evaluate(this->Makefile,
+ desired_config.c_str(),
+ false,
+ headTarget,
+ this,
+ &dagChecker),
+ info.LinkInterface.Libraries);
}
}
@@ -5019,18 +5267,20 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
// An explicit list of interface libraries may be set for shared
// libraries and executables that export symbols.
const char* explicitLibraries = 0;
+ std::string linkIfaceProp;
if(this->GetType() == cmTarget::SHARED_LIBRARY ||
this->IsExecutableWithExports())
{
// Lookup the per-configuration property.
- std::string propName = "LINK_INTERFACE_LIBRARIES";
- propName += suffix;
- explicitLibraries = this->GetProperty(propName.c_str());
+ linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+ linkIfaceProp += suffix;
+ explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
// If not set, try the generic property.
if(!explicitLibraries)
{
- explicitLibraries = this->GetProperty("LINK_INTERFACE_LIBRARIES");
+ linkIfaceProp = "LINK_INTERFACE_LIBRARIES";
+ explicitLibraries = this->GetProperty(linkIfaceProp.c_str());
}
}
@@ -5048,7 +5298,16 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
if(explicitLibraries)
{
// The interface libraries have been explicitly set.
- cmSystemTools::ExpandListArgument(explicitLibraries, iface.Libraries);
+ cmListFileBacktrace lfbt;
+ cmGeneratorExpression ge(lfbt);
+ cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(),
+ linkIfaceProp, 0, 0);
+ cmSystemTools::ExpandListArgument(ge.Parse(explicitLibraries)->Evaluate(
+ this->Makefile,
+ config,
+ false,
+ headTarget,
+ this, &dagChecker), iface.Libraries);
if(this->GetType() == cmTarget::SHARED_LIBRARY)
{
@@ -5091,6 +5350,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
// The link implementation is the default link interface.
LinkImplementation const* impl = this->GetLinkImplementation(config,
headTarget);
+ iface.ImplementationIsInterface = true;
iface.Libraries = impl->Libraries;
iface.WrongConfigLibraries = impl->WrongConfigLibraries;
if(this->GetType() == cmTarget::STATIC_LIBRARY)
@@ -5272,6 +5532,107 @@ 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)
+{
+ const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
+
+ std::set<cmStdString> emitted;
+
+ for(cmComputeLinkInformation::ItemVector::const_iterator li =
+ deps.begin();
+ li != deps.end(); ++li)
+ {
+ if (!li->Target)
+ {
+ continue;
+ }
+
+ checkPropertyConsistency<bool>(this, li->Target,
+ "COMPATIBLE_INTERFACE_BOOL",
+ emitted, config, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ checkPropertyConsistency<const char *>(this, li->Target,
+ "COMPATIBLE_INTERFACE_STRING",
+ emitted, config, 0);
+ if (cmSystemTools::GetErrorOccuredFlag())
+ {
+ return;
+ }
+ }
+}
+
//----------------------------------------------------------------------------
cmComputeLinkInformation*
cmTarget::GetLinkInformation(const char* config, cmTarget *head)
@@ -5296,6 +5657,11 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head)
// Store the information for this configuration.
cmTargetLinkInformationMap::value_type entry(key, info);
i = this->LinkInformation.insert(entry).first;
+
+ if (info)
+ {
+ this->CheckPropertyCompatibility(info, config);
+ }
}
return i->second;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 1188a6a..cf2d4c4 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
*/
@@ -258,7 +262,9 @@ public:
// Needed only for OLD behavior of CMP0003.
std::vector<std::string> WrongConfigLibraries;
- LinkInterface(): Multiplicity(0) {}
+ bool ImplementationIsInterface;
+
+ LinkInterface(): Multiplicity(0), ImplementationIsInterface(false) {}
};
/** Get the link interface for the given configuration. Returns 0
@@ -424,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
@@ -488,15 +496,24 @@ public:
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
bool before = false);
+ void AppendBuildInterfaceIncludes();
+
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);
private:
/**
* A list of direct dependencies. Use in conjunction with DependencyMap.
@@ -606,9 +623,11 @@ private:
bool DLLPlatform;
bool IsApple;
bool IsImportedTarget;
+ bool DebugIncludesDone;
mutable std::map<cmStdString, std::set<std::string> >
LinkDependentProperties;
mutable std::set<std::string> LinkImplicitNullProperties;
+ bool BuildInterfaceIncludesAppended;
// Cache target output paths for each configuration.
struct OutputInfo;
@@ -624,6 +643,8 @@ private:
cmTarget *head);
cmTargetLinkInformationMap LinkInformation;
+ void CheckPropertyCompatibility(cmComputeLinkInformation *info,
+ const char* config);
bool ComputeLinkInterface(const char* config, LinkInterface& iface,
cmTarget *head);
@@ -649,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..683eff6 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());
}
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
index 707610e..d49b9e8 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 "
@@ -69,14 +69,16 @@ public:
"INTERFACE_COMPILE_DEFINITIONS from. "
"Repeated calls for the same <target> append items in the order called."
"\n"
+ "Arguments to target_compile_definitions may use \"generator "
+ "expressions\" with the syntax \"$<...>\". "
+ CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
;
}
cmTypeMacro(cmTargetCompileDefinitionsCommand, cmCommand);
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,
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index 18e2cba..aeba468 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());
}
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index c1957d6..5a5f859 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 "
@@ -73,14 +73,16 @@ public:
"directories must be absolute paths, not relative paths. "
"Repeated calls for the same <target> append items in the order called."
"\n"
+ "Arguments to target_include_directories may use \"generator "
+ "expressions\" with the syntax \"$<...>\". "
+ CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
;
}
cmTypeMacro(cmTargetIncludeDirectoriesCommand, cmCommand);
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,
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index 0705fb4..f42b0f6 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] << "\" "
@@ -261,16 +257,6 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
// 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)
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index 8e5823c..3da3950 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -13,6 +13,7 @@
#define cmTargetLinkLibrariesCommand_h
#include "cmCommand.h"
+#include "cmDocumentGeneratorExpressions.h"
/** \class cmTargetLinkLibrariesCommand
* \brief Specify a list of libraries to link into executables.
@@ -92,7 +93,9 @@ 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_link_libraries(<target> LINK_INTERFACE_LIBRARIES\n"
" [[debug|optimized|general] <lib>] ...)\n"
@@ -141,6 +144,12 @@ public:
"However, if two archives are really so interdependent they should "
"probably be combined into a single archive."
")"
+ "\n"
+ "Arguments to target_link_libraries may use \"generator expressions\" "
+ "with the syntax \"$<...>\". Note however, that generator expressions "
+ "will not be used in OLD handling of CMP0003 or CMP0004."
+ "\n"
+ CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS
;
}
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 69aaf17..e1eb1d2 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -66,6 +66,14 @@ bool cmTargetPropCommandBase
}
//----------------------------------------------------------------------------
+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);
+}
+
+//----------------------------------------------------------------------------
bool cmTargetPropCommandBase
::ProcessContentArgs(std::vector<std::string> const& args,
unsigned int &argIndex, bool prepend)
@@ -80,9 +88,9 @@ 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;
}
@@ -105,6 +113,10 @@ bool cmTargetPropCommandBase
content += sep + "$<TARGET_PROPERTY:" + args[i]
+ ",INTERFACE_" + this->Property + ">";
}
+ else if(isGeneratorExpression(args[i]))
+ {
+ content += sep + args[i];
+ }
else if (!this->HandleNonTargetArg(content, sep, args[i], args[0]))
{
return false;
diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h
index 90e3bbb..15a78c9 100644
--- a/Source/cmTargetPropCommandBase.h
+++ b/Source/cmTargetPropCommandBase.h
@@ -14,6 +14,7 @@
#define cmTargetPropCommandBase_h
#include "cmCommand.h"
+#include "cmDocumentGeneratorExpressions.h"
class cmTarget;
@@ -31,8 +32,7 @@ public:
const char *prop, ArgumentFlags flags = NO_FLAGS);
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,
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 42b7f79..fa73658 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -3302,6 +3302,12 @@ int cmake::ExecuteLinkScript(std::vector<std::string>& args)
int result = 0;
while(result == 0 && cmSystemTools::GetLineFromStream(fin, command))
{
+ // Skip empty command lines.
+ if(command.find_first_not_of(" \t") == command.npos)
+ {
+ continue;
+ }
+
// Setup this command line.
const char* cmd[2] = {command.c_str(), 0};
cmsysProcess_SetCommand(cp, cmd);
@@ -3555,6 +3561,13 @@ void cmake::DefineProperty(const char *name, cmProperty::ScopeType scope,
chained);
}
+bool cmake::GetIsPropertyDefined(const char *name,
+ cmProperty::ScopeType scope)
+{
+ return this->PropertyDefinitions[scope].find(name) !=
+ this->PropertyDefinitions[scope].end();
+}
+
cmPropertyDefinition *cmake
::GetPropertyDefinition(const char *name,
cmProperty::ScopeType scope)
@@ -4384,6 +4397,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/cmake.h b/Source/cmake.h
index e5aa076..f6fe0d6 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -341,6 +341,8 @@ class cmake
bool chain = false,
const char *variableGroup = 0);
+ bool GetIsPropertyDefined(const char *name, cmProperty::ScopeType scope);
+
// get property definition
cmPropertyDefinition *GetPropertyDefinition
(const char *name, cmProperty::ScopeType scope);
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 6bfcab0..124b8ac 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -574,6 +574,8 @@ IF(KWSYS_USE_SystemTools)
ENDIF()
IF(KWSYS_USE_SystemInformation)
+ SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ COMPILE_DEFINITIONS SIZEOF_VOID_P=${CMAKE_SIZEOF_VOID_P})
IF(NOT CYGWIN)
INCLUDE(CheckIncludeFiles)
CHECK_INCLUDE_FILES("sys/types.h;ifaddrs.h" KWSYS_SYS_HAS_IFADDRS_H)
@@ -603,6 +605,13 @@ IF(KWSYS_USE_SystemInformation)
COMPILE_DEFINITIONS KWSYS_SYS_HAS_MPCTL_H=1)
ENDIF()
ENDIF()
+ IF(CMAKE_SYSTEM MATCHES "BSD")
+ CHECK_INCLUDE_FILES("machine/cpu.h" KWSYS_SYS_HAS_MACHINE_CPU_H)
+ IF(KWSYS_SYS_HAS_MACHINE_CPU_H)
+ SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ COMPILE_DEFINITIONS KWSYS_SYS_HAS_MACHINE_CPU_H=1)
+ ENDIF()
+ ENDIF()
IF(KWSYS_LFS_AVAILABLE AND NOT KWSYS_LFS_DISABLE)
SET(KWSYS_PLATFORM_CXX_TEST_DEFINES -DKWSYS_HAS_LFS=1)
ENDIF()
@@ -631,6 +640,20 @@ IF(KWSYS_USE_SystemInformation)
SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_CXX_HAS__ATOI64=1)
ENDIF()
+ IF(BORLAND)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM
+ "Checking whether Borland CXX compiler supports assembler instructions" DIRECT)
+ IF(KWSYS_CXX_HAS_BORLAND_ASM)
+ SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM=1)
+ KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_BORLAND_ASM_CPUID
+ "Checking whether Borland CXX compiler supports CPUID assembler instruction" DIRECT)
+ IF(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
+ SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY
+ COMPILE_DEFINITIONS KWSYS_CXX_HAS_BORLAND_ASM_CPUID=1)
+ ENDIF()
+ ENDIF()
+ ENDIF()
IF(KWSYS_USE___INT64)
SET_PROPERTY(SOURCE SystemInformation.cxx testSystemInformation.cxx APPEND PROPERTY
COMPILE_DEFINITIONS KWSYS_USE___INT64=1)
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 83838af..2db1254 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -418,9 +418,10 @@ int kwsysProcess_AddCommand(kwsysProcess* cp, char const* const* command)
parse it. */
newCommands[cp->NumberOfCommands] =
kwsysSystem_Parse_CommandForUnix(*command, 0);
- if(!newCommands[cp->NumberOfCommands])
+ if(!newCommands[cp->NumberOfCommands] ||
+ !newCommands[cp->NumberOfCommands][0])
{
- /* Out of memory. */
+ /* Out of memory or no command parsed. */
free(newCommands);
return 0;
}
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 0460b29..b20d724 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -91,6 +91,10 @@ typedef int siginfo_t;
# include <sys/sysctl.h>
#endif
+#if defined(KWSYS_SYS_HAS_MACHINE_CPU_H)
+# include <machine/cpu.h>
+#endif
+
#if defined(__DragonFly__)
# include <sys/sysctl.h>
#endif
@@ -198,7 +202,7 @@ typedef struct rlimit ResourceLimitType;
#define USE_CPUID_INTRINSICS 0
#endif
-#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS
+#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS || defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
# define USE_CPUID 1
#else
# define USE_CPUID 0
@@ -220,6 +224,7 @@ static bool call_cpuid(int select, int result[4])
return true;
#else
int tmp[4];
+#if defined(_MSC_VER)
// Use SEH to determine CPUID presence
__try {
_asm {
@@ -258,7 +263,24 @@ static bool call_cpuid(int select, int result[4])
return false;
}
- memcpy(result, tmp, sizeof(tmp));
+ memcpy(result, tmp, sizeof(tmp));
+#elif defined(KWSYS_CXX_HAS_BORLAND_ASM_CPUID)
+ unsigned int a, b, c, d;
+ __asm {
+ mov EAX, select;
+ cpuid
+ mov a, EAX;
+ mov b, EBX;
+ mov c, ECX;
+ mov d, EDX;
+ }
+
+ result[0] = a;
+ result[1] = b;
+ result[2] = c;
+ result[3] = d;
+#endif
+
// The cpuid instruction succeeded.
return true;
#endif
@@ -428,7 +450,7 @@ protected:
int CPUCount();
unsigned char LogicalCPUPerPhysicalCPU();
unsigned char GetAPICId();
- unsigned int IsHyperThreadingSupported();
+ bool IsHyperThreadingSupported();
static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int);
// For Linux and Cygwin, /proc/cpuinfo formats are slightly different
@@ -452,7 +474,8 @@ protected:
kwsys_stl::string SysCtlBuffer;
// For Solaris
- bool QuerySolarisInfo();
+ bool QuerySolarisMemory();
+ bool QuerySolarisProcessor();
kwsys_stl::string ParseValueFromKStat(const char* arguments);
kwsys_stl::string RunProcess(kwsys_stl::vector<const char*> args);
@@ -477,9 +500,11 @@ protected:
//For AIX
bool QueryAIXMemory();
+ bool QueryProcessorBySysconf();
bool QueryProcessor();
// Evaluate the memory information.
+ bool QueryMemoryBySysconf();
bool QueryMemory();
size_t TotalVirtualMemory;
size_t AvailableVirtualMemory;
@@ -1283,7 +1308,7 @@ void SystemInformationImplementation::RunCPUCheck()
#elif defined(__APPLE__)
this->ParseSysCtl();
#elif defined (__SVR4) && defined (__sun)
- this->QuerySolarisInfo();
+ this->QuerySolarisProcessor();
#elif defined(__HAIKU__)
this->QueryHaikuInfo();
#elif defined(__QNX__)
@@ -1309,7 +1334,7 @@ void SystemInformationImplementation::RunMemoryCheck()
#if defined(__APPLE__)
this->ParseSysCtl();
#elif defined (__SVR4) && defined (__sun)
- this->QuerySolarisInfo();
+ this->QuerySolarisMemory();
#elif defined(__HAIKU__)
this->QueryHaikuInfo();
#elif defined(__QNX__)
@@ -3012,7 +3037,7 @@ bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile()
return true;
}
-bool SystemInformationImplementation::QueryProcessor()
+bool SystemInformationImplementation::QueryProcessorBySysconf()
{
#if defined(_SC_NPROC_ONLN) && !defined(_SC_NPROCESSORS_ONLN)
// IRIX names this slightly different
@@ -3026,7 +3051,7 @@ bool SystemInformationImplementation::QueryProcessor()
return false;
}
- this->NumberOfPhysicalCPU = c;
+ this->NumberOfPhysicalCPU = static_cast<unsigned int>(c);
this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU;
return true;
@@ -3035,6 +3060,11 @@ bool SystemInformationImplementation::QueryProcessor()
#endif
}
+bool SystemInformationImplementation::QueryProcessor()
+{
+ return this->QueryProcessorBySysconf();
+}
+
/**
Get total system RAM in units of KiB.
*/
@@ -3555,8 +3585,7 @@ bool SystemInformationImplementation::QueryAIXMemory()
#endif
}
-/** Query for the memory status */
-bool SystemInformationImplementation::QueryMemory()
+bool SystemInformationImplementation::QueryMemoryBySysconf()
{
#if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
// Assume the mmap() granularity as returned by _SC_PAGESIZE is also
@@ -3593,6 +3622,12 @@ bool SystemInformationImplementation::QueryMemory()
#endif
}
+/** Query for the memory status */
+bool SystemInformationImplementation::QueryMemory()
+{
+ return this->QueryMemoryBySysconf();
+}
+
/** */
size_t SystemInformationImplementation::GetTotalVirtualMemory()
{
@@ -3725,8 +3760,13 @@ unsigned char SystemInformationImplementation::LogicalCPUPerPhysicalCPU(void)
/** Works only for windows */
-unsigned int SystemInformationImplementation::IsHyperThreadingSupported()
+bool SystemInformationImplementation::IsHyperThreadingSupported()
{
+ if (this->Features.ExtendedFeatures.SupportsHyperthreading)
+ {
+ return true;
+ }
+
#if USE_CPUID
int Regs[4] = { 0, 0, 0, 0 },
VendorId[4] = { 0, 0, 0, 0 };
@@ -3744,13 +3784,15 @@ unsigned int SystemInformationImplementation::IsHyperThreadingSupported()
if (((Regs[0] & FAMILY_ID) == PENTIUM4_ID) || (Regs[0] & EXT_FAMILY_ID))
{
- if (VendorId[1] == 'uneG')
+ if (VendorId[1] == 0x756e6547) // 'uneG'
{
- if (VendorId[3] == 'Ieni')
+ if (VendorId[3] == 0x49656e69) // 'Ieni'
{
- if (VendorId[2] == 'letn')
+ if (VendorId[2] == 0x6c65746e) // 'letn'
{
- return(Regs[3] & HT_BIT); // Genuine Intel with hyper-Threading technology
+ // Genuine Intel with hyper-Threading technology
+ this->Features.ExtendedFeatures.SupportsHyperthreading = ((Regs[3] & HT_BIT) != 0);
+ return this->Features.ExtendedFeatures.SupportsHyperthreading;
}
}
}
@@ -4000,6 +4042,81 @@ bool SystemInformationImplementation::ParseSysCtl()
len = sizeof(value);
err = sysctlbyname("machdep.cpu.model", &value, &len, NULL, 0);
this->ChipID.Model = static_cast< int >( value );
+
+ // Chip Stepping
+ len = sizeof(value);
+ value = 0;
+ err = sysctlbyname("machdep.cpu.stepping", &value, &len, NULL, 0);
+ if (!err)
+ {
+ this->ChipID.Revision = static_cast< int >( value );
+ }
+
+ // feature string
+ char *buf = 0;
+ size_t allocSize = 128;
+
+ err = 0;
+ len = 0;
+
+ // sysctlbyname() will return with err==0 && len==0 if the buffer is too small
+ while (err == 0 && len == 0)
+ {
+ delete[] buf;
+ allocSize *= 2;
+ buf = new char[allocSize];
+ if (!buf)
+ {
+ break;
+ }
+ buf[0] = ' ';
+ len = allocSize - 2; // keep space for leading and trailing space
+ err = sysctlbyname("machdep.cpu.features", buf + 1, &len, NULL, 0);
+ }
+ if (!err && buf && len)
+ {
+ // now we can match every flags as space + flag + space
+ buf[len + 1] = ' ';
+ kwsys_stl::string cpuflags(buf, len + 2);
+
+ if ((cpuflags.find(" FPU ")!=kwsys_stl::string::npos))
+ {
+ this->Features.HasFPU = true;
+ }
+ if ((cpuflags.find(" TSC ")!=kwsys_stl::string::npos))
+ {
+ this->Features.HasTSC = true;
+ }
+ if ((cpuflags.find(" MMX ")!=kwsys_stl::string::npos))
+ {
+ this->Features.HasMMX = true;
+ }
+ if ((cpuflags.find(" SSE ")!=kwsys_stl::string::npos))
+ {
+ this->Features.HasSSE = true;
+ }
+ if ((cpuflags.find(" SSE2 ")!=kwsys_stl::string::npos))
+ {
+ this->Features.HasSSE2 = true;
+ }
+ if ((cpuflags.find(" APIC ")!=kwsys_stl::string::npos))
+ {
+ this->Features.HasAPIC = true;
+ }
+ if ((cpuflags.find(" CMOV ")!=kwsys_stl::string::npos))
+ {
+ this->Features.HasCMOV = true;
+ }
+ if ((cpuflags.find(" MTRR ")!=kwsys_stl::string::npos))
+ {
+ this->Features.HasMTRR = true;
+ }
+ if ((cpuflags.find(" ACPI ")!=kwsys_stl::string::npos))
+ {
+ this->Features.HasACPI = true;
+ }
+ }
+ delete[] buf;
}
// brand string
@@ -4059,13 +4176,12 @@ kwsys_stl::string SystemInformationImplementation::RunProcess(kwsys_stl::vector<
char* data = NULL;
int length;
double timeout = 255;
+ int pipe; // pipe id as returned by kwsysProcess_WaitForData()
- while(kwsysProcess_WaitForData(gp,&data,&length,&timeout)) // wait for 1s
+ while( ( pipe = kwsysProcess_WaitForData(gp,&data,&length,&timeout),
+ (pipe == kwsysProcess_Pipe_STDOUT || pipe == kwsysProcess_Pipe_STDERR) ) ) // wait for 1s
{
- for(int i=0;i<length;i++)
- {
- buffer += data[i];
- }
+ buffer.append(data, length);
}
kwsysProcess_WaitForExit(gp, 0);
@@ -4173,16 +4289,40 @@ kwsys_stl::string SystemInformationImplementation::ParseValueFromKStat(const cha
return value;
}
-
/** Querying for system information from Solaris */
-bool SystemInformationImplementation::QuerySolarisInfo()
+bool SystemInformationImplementation::QuerySolarisMemory()
{
- // Parse values
- this->NumberOfPhysicalCPU = static_cast<unsigned int>(
- atoi(this->ParseValueFromKStat("-n syste_misc -s ncpus").c_str()));
- this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU;
- this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = 1;
+#if defined (__SVR4) && defined (__sun)
+ // Solaris allows querying this value by sysconf, but if this is
+ // a 32 bit process on a 64 bit host the returned memory will be
+ // limited to 4GiB. So if this is a 32 bit process or if the sysconf
+ // method fails use the kstat interface.
+#if SIZEOF_VOID_P == 8
+ if (this->QueryMemoryBySysconf())
+ {
+ return true;
+ }
+#endif
+
+ char* tail;
+ unsigned long totalMemory =
+ strtoul(this->ParseValueFromKStat("-s physmem").c_str(),&tail,0);
+ this->TotalPhysicalMemory = totalMemory/128;
+
+ return true;
+#else
+ return false;
+#endif
+}
+bool SystemInformationImplementation::QuerySolarisProcessor()
+{
+ if (!this->QueryProcessorBySysconf())
+ {
+ return false;
+ }
+
+ // Parse values
this->CPUSpeedInMHz = static_cast<float>(atoi(this->ParseValueFromKStat("-s clock_MHz").c_str()));
// Chip family
@@ -4199,20 +4339,6 @@ bool SystemInformationImplementation::QuerySolarisInfo()
this->FindManufacturer();
}
- // Cache size
- this->Features.L1CacheSize = 0;
- this->Features.L2CacheSize = 0;
-
- char* tail;
- unsigned long totalMemory =
- strtoul(this->ParseValueFromKStat("-s physmem").c_str(),&tail,0);
- this->TotalPhysicalMemory = totalMemory/128;
-
- // Undefined values (for now at least)
- this->TotalVirtualMemory = 0;
- this->AvailablePhysicalMemory = 0;
- this->AvailableVirtualMemory = 0;
-
return true;
}
@@ -4424,6 +4550,45 @@ bool SystemInformationImplementation::QueryBSDProcessor()
this->CPUSpeedInMHz = (float) k;
#endif
+#if defined(CPU_SSE)
+ ctrl[0] = CTL_MACHDEP;
+ ctrl[1] = CPU_SSE;
+
+ if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0)
+ {
+ return false;
+ }
+
+ this->Features.HasSSE = (k > 0);
+#endif
+
+#if defined(CPU_SSE2)
+ ctrl[0] = CTL_MACHDEP;
+ ctrl[1] = CPU_SSE2;
+
+ if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0)
+ {
+ return false;
+ }
+
+ this->Features.HasSSE2 = (k > 0);
+#endif
+
+#if defined(CPU_CPUVENDOR)
+ ctrl[0] = CTL_MACHDEP;
+ ctrl[1] = CPU_CPUVENDOR;
+ char vbuf[25];
+ ::memset(vbuf, 0, sizeof(vbuf));
+ sz = sizeof(vbuf) - 1;
+ if (sysctl(ctrl, 2, vbuf, &sz, NULL, 0) != 0)
+ {
+ return false;
+ }
+
+ this->ChipID.Vendor = vbuf;
+ this->FindManufacturer();
+#endif
+
return true;
#else
return false;
diff --git a/Source/kwsys/kwsysPlatformTestsCXX.cxx b/Source/kwsys/kwsysPlatformTestsCXX.cxx
index ae58703..48976c4 100644
--- a/Source/kwsys/kwsysPlatformTestsCXX.cxx
+++ b/Source/kwsys/kwsysPlatformTestsCXX.cxx
@@ -580,3 +580,30 @@ int main()
}
}
#endif
+
+#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM
+int main()
+{
+ int a = 1;
+ __asm {
+ xor EBX, EBX;
+ mov a, EBX;
+ }
+
+ return a;
+}
+#endif
+
+#ifdef TEST_KWSYS_CXX_HAS_BORLAND_ASM_CPUID
+int main()
+{
+ int a = 0;
+ __asm {
+ xor EAX, EAX;
+ cpuid;
+ mov a, EAX;
+ }
+
+ return a;
+}
+#endif
diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
index 84a23ef..3eca7fc 100644
--- a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt
@@ -12,15 +12,12 @@ target_compile_definitions(target_compile_definitions
INTERFACE MY_INTERFACE_DEFINE
)
-add_library(importedlib UNKNOWN IMPORTED)
-target_compile_definitions(importedlib
- INTERFACE MY_IMPORTEDINTERFACE_DEFINE
-)
-
add_executable(consumer
"${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp"
)
target_compile_definitions(consumer
PRIVATE target_compile_definitions importedlib
+ $<$<TARGET_DEFINED:notdefined>:SHOULD_NOT_BE_DEFINED>
+ $<$<TARGET_DEFINED:target_compile_definitions>:SHOULD_BE_DEFINED>
)
diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
index e3788dd..f835b6c 100644
--- a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
+++ b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp
@@ -11,8 +11,12 @@
#error Expected MY_INTERFACE_DEFINE
#endif
-#ifndef MY_IMPORTEDINTERFACE_DEFINE
-#error Expected MY_IMPORTEDINTERFACE_DEFINE
+#ifdef SHOULD_NOT_BE_DEFINED
+#error Unexpected SHOULD_NOT_BE_DEFINED
+#endif
+
+#ifndef SHOULD_BE_DEFINED
+#error Expected SHOULD_BE_DEFINED
#endif
int main() { return 0; }
diff --git a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
index a0f2ee0..e190161 100644
--- a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt
@@ -11,9 +11,6 @@ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/publicinclude/publicinclude.h" "#define
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude/interfaceinclude.h" "#define INTERFACEINCLUDE_DEFINE\n")
-file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude/importedinterfaceinclude.h" "#define IMPORTEDINTERFACEINCLUDE_DEFINE\n")
-
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/poison")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/poison/common.h" "#error Should not be included\n")
@@ -33,12 +30,12 @@ target_include_directories(target_include_directories
PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/poison"
)
target_include_directories(target_include_directories
- BEFORE PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/cure"
+ BEFORE PUBLIC "$<$<TARGET_DEFINED:target_include_directories>:${CMAKE_CURRENT_BINARY_DIR}/cure>"
)
-add_library(importedlib UNKNOWN IMPORTED)
-target_include_directories(importedlib
- INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude"
+# Has no effect because the target is not defined:
+target_include_directories(target_include_directories
+ BEFORE PUBLIC "$<$<TARGET_DEFINED:notdefined>:${CMAKE_CURRENT_BINARY_DIR}/poison>"
)
add_executable(consumer
@@ -46,5 +43,5 @@ add_executable(consumer
)
target_include_directories(consumer
- PRIVATE target_include_directories importedlib
+ PRIVATE target_include_directories
)
diff --git a/Tests/CMakeCommands/target_include_directories/consumer.cpp b/Tests/CMakeCommands/target_include_directories/consumer.cpp
index 6fd61d5..5d88488 100644
--- a/Tests/CMakeCommands/target_include_directories/consumer.cpp
+++ b/Tests/CMakeCommands/target_include_directories/consumer.cpp
@@ -2,7 +2,6 @@
#include "common.h"
#include "publicinclude.h"
#include "interfaceinclude.h"
-#include "importedinterfaceinclude.h"
#ifdef PRIVATEINCLUDE_DEFINE
#error Unexpected PRIVATEINCLUDE_DEFINE
@@ -16,10 +15,6 @@
#error Expected INTERFACEINCLUDE_DEFINE
#endif
-#ifndef IMPORTEDINTERFACEINCLUDE_DEFINE
-#error Expected IMPORTEDINTERFACEINCLUDE_DEFINE
-#endif
-
#ifndef CURE_DEFINE
#error Expected CURE_DEFINE
#endif
diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
index 746d30c..1d0e342 100644
--- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
+++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt
@@ -29,9 +29,6 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_library(depA SHARED depA.cpp)
generate_export_header(depA)
-add_library(importedlib UNKNOWN IMPORTED)
-target_link_libraries(importedlib LINK_INTERFACE_LIBRARIES depA)
-
add_library(depB SHARED depB.cpp)
generate_export_header(depB)
@@ -80,3 +77,13 @@ assert_property(targetA LINK_INTERFACE_LIBRARIES "")
add_library(depIfaceOnly SHARED EXCLUDE_FROM_ALL depIfaceOnly.cpp)
generate_export_header(depIfaceOnly)
set_property(TARGET depB APPEND PROPERTY LINK_INTERFACE_LIBRARIES depIfaceOnly)
+
+add_library(depD SHARED depD.cpp)
+generate_export_header(depD)
+set_property(TARGET depD APPEND PROPERTY
+ LINK_INTERFACE_LIBRARIES
+ $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:depA>
+)
+
+add_executable(targetB targetB.cpp)
+target_link_libraries(targetB depD)
diff --git a/Tests/CMakeCommands/target_link_libraries/depD.cpp b/Tests/CMakeCommands/target_link_libraries/depD.cpp
new file mode 100644
index 0000000..b02c76c
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depD.cpp
@@ -0,0 +1,13 @@
+
+#include "depD.h"
+
+int DepD::foo()
+{
+ return 0;
+}
+
+DepA DepD::getA()
+{
+ DepA a;
+ return a;
+}
diff --git a/Tests/CMakeCommands/target_link_libraries/depD.h b/Tests/CMakeCommands/target_link_libraries/depD.h
new file mode 100644
index 0000000..d24ff5f
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/depD.h
@@ -0,0 +1,11 @@
+
+#include "depd_export.h"
+
+#include "depA.h"
+
+struct DEPD_EXPORT DepD
+{
+ int foo();
+
+ DepA getA();
+};
diff --git a/Tests/CMakeCommands/target_link_libraries/targetB.cpp b/Tests/CMakeCommands/target_link_libraries/targetB.cpp
new file mode 100644
index 0000000..063d63a
--- /dev/null
+++ b/Tests/CMakeCommands/target_link_libraries/targetB.cpp
@@ -0,0 +1,10 @@
+
+#include "depD.h"
+
+int main(int argc, char **argv)
+{
+ DepD d;
+ DepA a = d.getA();
+
+ return d.foo() + a.foo();
+}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 2f7df01..0c75892 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -216,6 +216,7 @@ if(BUILD_TESTING)
ADD_TEST_MACRO(PolicyScope PolicyScope)
ADD_TEST_MACRO(EmptyLibrary EmptyLibrary)
ADD_TEST_MACRO(CompileDefinitions CompileDefinitions)
+ ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
set_tests_properties(EmptyLibrary PROPERTIES
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target:test")
ADD_TEST_MACRO(CrossCompile CrossCompile)
diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt
index d34d4a6..b049995 100644
--- a/Tests/CMakeTests/CMakeLists.txt
+++ b/Tests/CMakeTests/CMakeLists.txt
@@ -4,7 +4,8 @@ set(CMAKE_EXECUTABLE "${CMake_BIN_DIR}/cmake")
macro(AddCMakeTest TestName PreArgs)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${TestName}Test.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" @ONLY IMMEDIATE)
- add_test(CMake.${TestName} ${CMAKE_EXECUTABLE} ${PreArgs}
+ add_test(NAME CMake.${TestName}
+ COMMAND ${CMAKE_EXECUTABLE} ${PreArgs}
-P "${CMAKE_CURRENT_BINARY_DIR}/${TestName}Test.cmake" ${ARGN})
endmacro()
@@ -28,7 +29,7 @@ AddCMakeTest(String "")
AddCMakeTest(Math "")
AddCMakeTest(CMakeMinimumRequired "")
AddCMakeTest(CompilerIdVendor "")
-AddCMakeTest(ProcessorCount "")
+AddCMakeTest(ProcessorCount "-DKWSYS_TEST_EXE=$<TARGET_FILE:cmsysTestsCxx>")
AddCMakeTest(PushCheckState "")
AddCMakeTest(While "")
diff --git a/Tests/CMakeTests/ProcessorCountTest.cmake.in b/Tests/CMakeTests/ProcessorCountTest.cmake.in
index 98f6ab1..f92dcc4 100644
--- a/Tests/CMakeTests/ProcessorCountTest.cmake.in
+++ b/Tests/CMakeTests/ProcessorCountTest.cmake.in
@@ -9,10 +9,17 @@ message("### 3. ProcessorCount(...) function call is emitting output that it sho
message("processor_count='${processor_count}'")
execute_process(
- COMMAND "@CMAKE_BINARY_DIR@/Source/kwsys/$ENV{CMAKE_CONFIG_TYPE}/cmsysTestsCxx"
+ COMMAND "${KWSYS_TEST_EXE}"
testSystemInformation
OUTPUT_VARIABLE tsi_out
- ERROR_VARIABLE tsi_err)
+ ERROR_VARIABLE tsi_err
+ RESULT_VARIABLE tsi_res
+)
+if (tsi_res)
+ message("executing \"${KWSYS_TEST_EXE}\" failed")
+ message(FATAL_ERROR "output: ${tsi_res}")
+endif ()
+
string(REGEX REPLACE "(.*)GetNumberOfPhysicalCPU:.([0-9]*)(.*)" "\\2"
system_info_processor_count "${tsi_out}")
diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt
new file mode 100644
index 0000000..259b5a1
--- /dev/null
+++ b/Tests/CompatibleInterface/CMakeLists.txt
@@ -0,0 +1,57 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+project(CompatibleInterface)
+
+include(GenerateExportHeader)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_library(iface1 empty.cpp)
+set_property(TARGET iface1 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_BOOL
+ BOOL_PROP1
+ BOOL_PROP2
+ BOOL_PROP3
+ BOOL_PROP4
+)
+set_property(TARGET iface1 APPEND PROPERTY
+ COMPATIBLE_INTERFACE_STRING
+ STRING_PROP1
+ STRING_PROP2
+ STRING_PROP3
+)
+
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON)
+set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON)
+set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1)
+set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2)
+
+add_executable(CompatibleInterface main.cpp)
+target_link_libraries(CompatibleInterface iface1)
+
+set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON)
+set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON)
+set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2)
+set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3)
+
+target_compile_definitions(CompatibleInterface
+ PRIVATE
+ $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP1>>:BOOL_PROP1>
+ $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP2>>:BOOL_PROP2>
+ $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP3>>:BOOL_PROP3>
+ $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP1>,prop1>:STRING_PROP1>
+ $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP2>,prop2>:STRING_PROP2>
+ $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3>
+)
+
+
+add_library(iface2 SHARED iface2.cpp)
+generate_export_header(iface2)
+
+# For the LINK_LIBRARIES and related properties, we should not evaluate
+# properties defined only in the interface - they should be implicitly zero
+set_property(TARGET iface2
+ APPEND PROPERTY
+ LINK_INTERFACE_LIBRARIES $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP4>>:nonexistant>
+)
+target_link_libraries(CompatibleInterface iface2)
diff --git a/Tests/CompatibleInterface/empty.cpp b/Tests/CompatibleInterface/empty.cpp
new file mode 100644
index 0000000..0032329
--- /dev/null
+++ b/Tests/CompatibleInterface/empty.cpp
@@ -0,0 +1 @@
+// no content
diff --git a/Tests/CompatibleInterface/iface2.cpp b/Tests/CompatibleInterface/iface2.cpp
new file mode 100644
index 0000000..a9b5015
--- /dev/null
+++ b/Tests/CompatibleInterface/iface2.cpp
@@ -0,0 +1,7 @@
+
+#include "iface2.h"
+
+int Iface2::foo()
+{
+ return 0;
+}
diff --git a/Tests/CompatibleInterface/iface2.h b/Tests/CompatibleInterface/iface2.h
new file mode 100644
index 0000000..ef4ebee
--- /dev/null
+++ b/Tests/CompatibleInterface/iface2.h
@@ -0,0 +1,13 @@
+
+#ifndef IFACE2_H
+#define IFACE2_H
+
+#include "iface2_export.h"
+
+class IFACE2_EXPORT Iface2
+{
+public:
+ int foo();
+};
+
+#endif
diff --git a/Tests/CompatibleInterface/main.cpp b/Tests/CompatibleInterface/main.cpp
new file mode 100644
index 0000000..f5e6e38
--- /dev/null
+++ b/Tests/CompatibleInterface/main.cpp
@@ -0,0 +1,32 @@
+
+#ifndef BOOL_PROP1
+#error Expected BOOL_PROP1
+#endif
+
+#ifndef BOOL_PROP2
+#error Expected BOOL_PROP2
+#endif
+
+#ifndef BOOL_PROP3
+#error Expected BOOL_PROP3
+#endif
+
+#ifndef STRING_PROP1
+#error Expected STRING_PROP1
+#endif
+
+#ifndef STRING_PROP2
+#error Expected STRING_PROP2
+#endif
+
+#ifndef STRING_PROP3
+#error Expected STRING_PROP3
+#endif
+
+#include "iface2.h"
+
+int main(int argc, char **argv)
+{
+ Iface2 if2;
+ return if2.foo();
+}
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index 569845a..eecfd6a 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -158,6 +158,56 @@ set_property(TARGET testLibRequired APPEND PROPERTY
$<INSTALL_INTERFACE:InstallOnly_DEFINE>
)
+include(GenerateExportHeader)
+
+add_library(testSharedLibRequired SHARED testSharedLibRequired.cpp)
+generate_export_header(testSharedLibRequired)
+set_property(TARGET testSharedLibRequired
+ PROPERTY
+ INTERFACE_POSITION_INDEPENDENT_CODE ON
+)
+set_property(TARGET testSharedLibRequired APPEND PROPERTY
+ INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
+)
+set_property(TARGET testSharedLibRequired APPEND PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+set_property(TARGET testSharedLibRequired
+ APPEND PROPERTY
+ COMPATIBLE_INTERFACE_BOOL CUSTOM_PROP
+)
+set_property(TARGET testSharedLibRequired
+ PROPERTY
+ INTERFACE_CUSTOM_PROP ON
+)
+set_property(TARGET testSharedLibRequired
+ APPEND PROPERTY
+ COMPATIBLE_INTERFACE_STRING CUSTOM_STRING
+)
+set_property(TARGET testSharedLibRequired
+ PROPERTY
+ INTERFACE_CUSTOM_STRING testcontent
+)
+
+add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp)
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+ INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}"
+)
+generate_export_header(testSharedLibDepends)
+
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES
+ $<TARGET_PROPERTY:testSharedLibRequired,INTERFACE_INCLUDE_DIRECTORIES>
+)
+set_property(TARGET testSharedLibDepends APPEND PROPERTY
+ LINK_INTERFACE_LIBRARIES
+ $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:$<TARGET_NAME:testSharedLibRequired>>
+)
+
+# LINK_PRIVATE because the LINK_INTERFACE_LIBRARIES is specified above.
+target_link_libraries(testSharedLibDepends LINK_PRIVATE testSharedLibRequired)
+
install(TARGETS testLibRequired
testLibIncludeRequired1
testLibIncludeRequired2
@@ -165,10 +215,11 @@ install(TARGETS testLibRequired
testLibIncludeRequired4
testLibIncludeRequired5
testLibIncludeRequired6
+ testSharedLibRequired
EXPORT RequiredExp DESTINATION lib )
install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredConfig.cmake DESTINATION lib/cmake/testLibRequired)
-install(TARGETS testLibDepends EXPORT DependsExp DESTINATION lib )
+install(TARGETS testLibDepends testSharedLibDepends EXPORT DependsExp DESTINATION lib )
install(EXPORT DependsExp FILE testLibDependsConfig.cmake DESTINATION lib/cmake/testLibDepends)
@@ -216,9 +267,12 @@ if(WIN32)
install(TARGETS testLib5 RUNTIME DESTINATION bin)
endif()
+add_subdirectory(sublib) # For CMAKE_BUILD_INTERFACE_INCLUDES test.
+
# Export from build tree.
export(TARGETS testExe1 testLib1 testLib2 testLib3
- testExe2libImp testLib3Imp testLib3ImpDep
+ testExe2libImp testLib3Imp testLib3ImpDep subdirlib
+ testSharedLibRequired testSharedLibDepends
NAMESPACE bld_
FILE ExportBuildTree.cmake
)
diff --git a/Tests/ExportImport/Export/sublib/CMakeLists.txt b/Tests/ExportImport/Export/sublib/CMakeLists.txt
new file mode 100644
index 0000000..2d11040
--- /dev/null
+++ b/Tests/ExportImport/Export/sublib/CMakeLists.txt
@@ -0,0 +1,6 @@
+
+set(CMAKE_BUILD_INTERFACE_INCLUDES ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+add_library(subdirlib SHARED subdir.cpp)
+generate_export_header(subdirlib)
diff --git a/Tests/ExportImport/Export/sublib/subdir.cpp b/Tests/ExportImport/Export/sublib/subdir.cpp
new file mode 100644
index 0000000..35b0743
--- /dev/null
+++ b/Tests/ExportImport/Export/sublib/subdir.cpp
@@ -0,0 +1,7 @@
+
+#include "subdir.h"
+
+int SubDirObject::foo()
+{
+ return 0;
+}
diff --git a/Tests/ExportImport/Export/sublib/subdir.h b/Tests/ExportImport/Export/sublib/subdir.h
new file mode 100644
index 0000000..3a4b73d
--- /dev/null
+++ b/Tests/ExportImport/Export/sublib/subdir.h
@@ -0,0 +1,12 @@
+
+#ifndef SUBDIR_H
+#define SUBDIR_H
+
+#include "subdirlib_export.h"
+
+struct SUBDIRLIB_EXPORT SubDirObject
+{
+ int foo();
+};
+
+#endif
diff --git a/Tests/ExportImport/Export/testSharedLibDepends.cpp b/Tests/ExportImport/Export/testSharedLibDepends.cpp
new file mode 100644
index 0000000..e279207
--- /dev/null
+++ b/Tests/ExportImport/Export/testSharedLibDepends.cpp
@@ -0,0 +1,8 @@
+
+#include "testSharedLibDepends.h"
+
+int TestSharedLibDepends::foo()
+{
+ TestSharedLibRequired req;
+ return req.foo();
+}
diff --git a/Tests/ExportImport/Export/testSharedLibDepends.h b/Tests/ExportImport/Export/testSharedLibDepends.h
new file mode 100644
index 0000000..b93143a
--- /dev/null
+++ b/Tests/ExportImport/Export/testSharedLibDepends.h
@@ -0,0 +1,14 @@
+
+#ifndef TESTSHAREDLIBDEPENDS_H
+#define TESTSHAREDLIBDEPENDS_H
+
+#include "testsharedlibdepends_export.h"
+
+#include "testSharedLibRequired.h"
+
+struct TESTSHAREDLIBDEPENDS_EXPORT TestSharedLibDepends
+{
+ int foo();
+};
+
+#endif
diff --git a/Tests/ExportImport/Export/testSharedLibRequired.cpp b/Tests/ExportImport/Export/testSharedLibRequired.cpp
new file mode 100644
index 0000000..1ac34aa
--- /dev/null
+++ b/Tests/ExportImport/Export/testSharedLibRequired.cpp
@@ -0,0 +1,7 @@
+
+#include "testSharedLibRequired.h"
+
+int TestSharedLibRequired::foo()
+{
+ return 0;
+}
diff --git a/Tests/ExportImport/Export/testSharedLibRequired.h b/Tests/ExportImport/Export/testSharedLibRequired.h
new file mode 100644
index 0000000..edaddd4
--- /dev/null
+++ b/Tests/ExportImport/Export/testSharedLibRequired.h
@@ -0,0 +1,12 @@
+
+#ifndef TESTSHAREDLIBREQUIRED_H
+#define TESTSHAREDLIBREQUIRED_H
+
+#include "testsharedlibrequired_export.h"
+
+struct TESTSHAREDLIBREQUIRED_EXPORT TestSharedLibRequired
+{
+ int foo();
+};
+
+#endif
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index b77562e..187c48a 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -157,13 +157,50 @@ endif()
# Test that dependent imported targets have usable
# INTERFACE_COMPILE_DEFINITIONS and INTERFACE_INCLUDE_DIRECTORIES
-add_library(deps_iface deps_iface.cpp)
-target_link_libraries(deps_iface testLibsDepends)
-set_property(TARGET deps_iface APPEND PROPERTY
- COMPILE_DEFINITIONS
- $<TARGET_PROPERTY:testLibDepends,INTERFACE_COMPILE_DEFINITIONS>
+add_executable(deps_iface deps_iface.c)
+target_link_libraries(deps_iface testLibDepends)
+target_include_directories(deps_iface PRIVATE testLibDepends)
+target_compile_definitions(deps_iface PRIVATE testLibDepends)
+
+add_executable(deps_shared_iface deps_shared_iface.cpp)
+target_link_libraries(deps_shared_iface testSharedLibDepends)
+target_include_directories(deps_shared_iface PRIVATE testSharedLibDepends)
+target_compile_definitions(deps_shared_iface
+ PRIVATE
+ testSharedLibDepends
+ $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
+ $<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
+ $<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
)
-set_property(TARGET deps_iface APPEND PROPERTY
- INCLUDE_DIRECTORIES
- $<TARGET_PROPERTY:testLibDepends,INTERFACE_INCLUDE_DIRECTORIES>
+
+if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag(-fPIE run_pic_test)
+else()
+ if (CMAKE_CXX_COMPILER_ID MATCHES "PGI"
+ OR CMAKE_CXX_COMPILER_ID MATCHES "PathScale"
+ OR CMAKE_SYSTEM_NAME MATCHES "IRIX64"
+ OR CMAKE_CXX_COMPILER_ID MATCHES "Intel")
+ set(run_pic_test 0)
+ else()
+ set(run_pic_test 1)
+ endif()
+endif()
+
+if (run_pic_test)
+ target_compile_definitions(deps_shared_iface PRIVATE CHECK_PIC_WORKS)
+endif()
+
+#-----------------------------------------------------------------------------
+# Test that targets imported from the build tree have their dependencies
+# evaluated correctly. The above already tests the same for the install tree.
+
+add_executable(deps_shared_iface2 deps_shared_iface.cpp)
+target_link_libraries(deps_shared_iface2 bld_testSharedLibDepends bld_subdirlib)
+target_include_directories(deps_shared_iface2 PRIVATE bld_testSharedLibDepends bld_subdirlib)
+target_compile_definitions(deps_shared_iface2
+ PRIVATE bld_testSharedLibDepends TEST_SUBDIR_LIB
+ $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:PIC_PROPERTY_IS_ON>
+ $<$<BOOL:$<TARGET_PROPERTY:CUSTOM_PROP>>:CUSTOM_PROPERTY_IS_ON>
+ $<$<STREQUAL:$<TARGET_PROPERTY:CUSTOM_STRING>,testcontent>:CUSTOM_STRING_IS_MATCH>
)
diff --git a/Tests/ExportImport/Import/A/deps_iface.cpp b/Tests/ExportImport/Import/A/deps_iface.c
index 7190b92..e73ca26 100644
--- a/Tests/ExportImport/Import/A/deps_iface.cpp
+++ b/Tests/ExportImport/Import/A/deps_iface.c
@@ -18,7 +18,7 @@
extern int testLibDepends(void);
-int main(int,char **)
+int main()
{
return testLibDepends();
}
diff --git a/Tests/ExportImport/Import/A/deps_shared_iface.cpp b/Tests/ExportImport/Import/A/deps_shared_iface.cpp
new file mode 100644
index 0000000..2f0e74a
--- /dev/null
+++ b/Tests/ExportImport/Import/A/deps_shared_iface.cpp
@@ -0,0 +1,41 @@
+
+
+#include "testSharedLibDepends.h"
+
+#ifdef CHECK_PIC_WORKS
+#if defined(__ELF__) && !defined(__PIC__) && !defined(__PIE__)
+#error Expected by INTERFACE_POSITION_INDEPENDENT_CODE property of dependency
+#endif
+#endif
+
+#ifndef PIC_PROPERTY_IS_ON
+#error Expected PIC_PROPERTY_IS_ON
+#endif
+
+#ifndef CUSTOM_PROPERTY_IS_ON
+#error Expected CUSTOM_PROPERTY_IS_ON
+#endif
+
+#ifndef CUSTOM_STRING_IS_MATCH
+#error Expected CUSTOM_STRING_IS_MATCH
+#endif
+
+#ifdef TEST_SUBDIR_LIB
+#include "subdir.h"
+#endif
+
+int main(int,char **)
+{
+ TestSharedLibDepends dep;
+ TestSharedLibRequired req;
+
+#ifdef TEST_SUBDIR_LIB
+ SubDirObject sdo;
+#endif
+
+ return dep.foo() + req.foo()
+#ifdef TEST_SUBDIR_LIB
+ + sdo.foo()
+#endif
+ ;
+}
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
index e24a979..602ff0f 100644
--- a/Tests/ExternalProject/CMakeLists.txt
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -50,6 +50,8 @@ if(NOT DEFINED can_build_tutorial_step5)
endif()
endif()
+add_custom_target(NonExternalProjectTarget
+ COMMAND ${CMAKE_COMMAND} -E echo NonExternalProjectTarget)
# Empty projects that test all the known ExternalProject_Add argument key words:
#
@@ -94,7 +96,7 @@ ExternalProject_Add(${proj}
CVS_REPOSITORY ""
CVS_MODULE ""
CVS_TAG ""
- DEPENDS "MinimalNoOpProject"
+ DEPENDS "MinimalNoOpProject" NonExternalProjectTarget
DOWNLOAD_COMMAND ""
INSTALL_COMMAND ""
PATCH_COMMAND ""
diff --git a/Tests/Qt4Targets/CMakeLists.txt b/Tests/Qt4Targets/CMakeLists.txt
index 9bd7a64..d3aba74 100644
--- a/Tests/Qt4Targets/CMakeLists.txt
+++ b/Tests/Qt4Targets/CMakeLists.txt
@@ -2,15 +2,16 @@ cmake_minimum_required(VERSION 2.8)
project(Qt4Targets)
+cmake_policy(SET CMP0020 NEW)
+
find_package(Qt4 REQUIRED)
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
add_executable(Qt4Targets WIN32 main.cpp)
target_link_libraries(Qt4Targets Qt4::QtGui)
-if (WIN32)
- target_link_libraries(Qt4Targets Qt4::qtmain)
-endif()
-
set_property(TARGET Qt4Targets APPEND PROPERTY
INCLUDE_DIRECTORIES
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_INCLUDE_DIRECTORIES>
@@ -19,3 +20,21 @@ set_property(TARGET Qt4Targets APPEND PROPERTY
COMPILE_DEFINITIONS
$<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_COMPILE_DEFINITIONS>
)
+
+if (WIN32)
+ if (TARGET Qt4::QAxServer)
+ add_executable(activeqtexe WIN32 activeqtexe.cpp)
+ set_property(TARGET activeqtexe PROPERTY QT4_NO_LINK_QTMAIN ON)
+ target_link_libraries(activeqtexe Qt4::QAxServer Qt4::QtGui)
+ set_property(TARGET activeqtexe APPEND PROPERTY
+ INCLUDE_DIRECTORIES
+ $<TARGET_PROPERTY:Qt4::QAxServer,INTERFACE_INCLUDE_DIRECTORIES>
+ $<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_INCLUDE_DIRECTORIES>
+ )
+ set_property(TARGET activeqtexe APPEND PROPERTY
+ COMPILE_DEFINITIONS
+ $<TARGET_PROPERTY:Qt4::QAxServer,INTERFACE_COMPILE_DEFINITIONS>
+ $<TARGET_PROPERTY:Qt4::QtGui,INTERFACE_COMPILE_DEFINITIONS>
+ )
+ endif()
+endif()
diff --git a/Tests/Qt4Targets/activeqtexe.cpp b/Tests/Qt4Targets/activeqtexe.cpp
new file mode 100644
index 0000000..d4a9121
--- /dev/null
+++ b/Tests/Qt4Targets/activeqtexe.cpp
@@ -0,0 +1,36 @@
+
+#include <QApplication>
+
+#ifndef QT_QAXSERVER_LIB
+#error Expected QT_QAXSERVER_LIB
+#endif
+
+#include <QAxFactory>
+
+class MyObject : public QObject
+{
+ Q_OBJECT
+public:
+ MyObject(QObject *parent = 0)
+ : QObject(parent)
+ {
+ }
+};
+
+QAXFACTORY_DEFAULT(MyObject,
+ "{4dc3f340-a6f7-44e4-a79b-3e9217685fbd}",
+ "{9ee49617-7d5c-441a-b833-4b068d41d751}",
+ "{13eca64b-ee2a-4f3c-aa04-5d9d975779a7}",
+ "{ce947ee3-0403-4fdc-895a-4fe779344b46}",
+ "{8de435ce-8d2a-46ac-b3b3-cb800d0547c7}");
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QAxFactory::isServer();
+
+ return app.exec();
+}
+
+#include "activeqtexe.moc"
diff --git a/Tests/QtAutomoc/CMakeLists.txt b/Tests/QtAutomoc/CMakeLists.txt
index 5e3686d..855fcf0 100644
--- a/Tests/QtAutomoc/CMakeLists.txt
+++ b/Tests/QtAutomoc/CMakeLists.txt
@@ -13,11 +13,14 @@ add_definitions(-DFOO -DSomeDefine="Barx")
# enable relaxed mode so automoc can handle all the special cases:
set(CMAKE_AUTOMOC_RELAXED_MODE TRUE)
-# create an executable and a library target, both requiring automoc:
+# create an executable and two library targets, each requiring automoc:
add_library(codeeditorLib STATIC codeeditor.cpp)
-add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp xyz.cpp yaf.cpp private_slot.cpp)
+add_library(privateSlot OBJECT private_slot.cpp)
-set_target_properties(foo codeeditorLib PROPERTIES AUTOMOC TRUE)
+add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp
+ xyz.cpp yaf.cpp $<TARGET_OBJECTS:privateSlot>)
+
+set_target_properties(foo codeeditorLib privateSlot PROPERTIES AUTOMOC TRUE)
target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} )
diff --git a/Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt b/Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-NEW-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt
new file mode 100644
index 0000000..a21cb6a
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-NEW-stderr.txt
@@ -0,0 +1,2 @@
+ Target "foo" links to item " bar " which has leading or trailing
+ whitespace. This is now an error according to policy CMP0004.
diff --git a/Tests/RunCMake/CMP0004/CMP0004-NEW.cmake b/Tests/RunCMake/CMP0004/CMP0004-NEW.cmake
new file mode 100644
index 0000000..7c61961
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-NEW.cmake
@@ -0,0 +1,9 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+cmake_policy(SET CMP0004 NEW)
+
+add_library(foo SHARED empty.cpp)
+add_library(bar SHARED empty.cpp)
+
+target_link_libraries(foo "$<1: bar >")
diff --git a/Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt b/Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-OLD-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt
new file mode 100644
index 0000000..782e45c
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-OLD-stderr.txt
@@ -0,0 +1,2 @@
+ Target "bat" links to item " bar " which has leading or trailing
+ whitespace. This is now an error according to policy CMP0004.
diff --git a/Tests/RunCMake/CMP0004/CMP0004-OLD.cmake b/Tests/RunCMake/CMP0004/CMP0004-OLD.cmake
new file mode 100644
index 0000000..d6ed72c
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-OLD.cmake
@@ -0,0 +1,21 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+cmake_policy(SET CMP0004 OLD)
+
+add_library(foo SHARED empty.cpp)
+add_library(bar SHARED empty.cpp)
+add_library(bing SHARED empty.cpp)
+add_library(bung SHARED empty.cpp)
+
+cmake_policy(SET CMP0004 NEW)
+
+add_library(bat SHARED empty.cpp)
+
+target_link_libraries(foo "$<1: bar >")
+target_link_libraries(bing "$<$<NOT:$<TARGET_POLICY:CMP0004>>: bar >")
+target_link_libraries(bung "$<$<TARGET_POLICY:CMP0004>: bar >")
+
+# The line below causes the error because the policy is NEW when bat
+# is created.
+target_link_libraries(bat "$<1: bar >")
diff --git a/Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-WARN-stderr.txt
diff --git a/Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt b/Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-policy-genex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt b/Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt
new file mode 100644
index 0000000..eed53e7
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-policy-genex-stderr.txt
@@ -0,0 +1,2 @@
+ Target "foo" links to item " bat " which has leading or trailing
+ whitespace. This is now an error according to policy CMP0004.
diff --git a/Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake b/Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake
new file mode 100644
index 0000000..eab680a
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMP0004-policy-genex.cmake
@@ -0,0 +1,14 @@
+
+cmake_minimum_required(VERSION 2.8)
+
+cmake_policy(SET CMP0004 NEW)
+
+add_library(foo SHARED empty.cpp)
+add_library(bar SHARED empty.cpp)
+add_library(bat SHARED empty.cpp)
+
+# The negation here avoids the error.
+target_link_libraries(foo "$<$<NOT:$<TARGET_POLICY:CMP0004>>: bar >")
+
+# The below line causes the error.
+target_link_libraries(foo "$<$<TARGET_POLICY:CMP0004>: bat >")
diff --git a/Tests/RunCMake/CMP0004/CMakeLists.txt b/Tests/RunCMake/CMP0004/CMakeLists.txt
new file mode 100644
index 0000000..e8db6b0
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CMP0004/RunCMakeTest.cmake b/Tests/RunCMake/CMP0004/RunCMakeTest.cmake
new file mode 100644
index 0000000..950d0ed
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/RunCMakeTest.cmake
@@ -0,0 +1,5 @@
+include(RunCMake)
+
+run_cmake(CMP0004-OLD)
+run_cmake(CMP0004-NEW)
+run_cmake(CMP0004-policy-genex)
diff --git a/Tests/RunCMake/CMP0004/empty.cpp b/Tests/RunCMake/CMP0004/empty.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/CMP0004/empty.cpp
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 9b133b2..35b9a43 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -53,12 +53,14 @@ add_RunCMake_test(ObjectLibrary)
if(NOT WIN32)
add_RunCMake_test(PositionIndependentCode)
endif()
+add_RunCMake_test(CompatibleInterface)
add_RunCMake_test(build_command)
add_RunCMake_test(find_package)
add_RunCMake_test(include)
add_RunCMake_test(include_directories)
add_RunCMake_test(list)
+add_RunCMake_test(CMP0004)
if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]")
add_RunCMake_test(include_external_msproject)
diff --git a/Tests/RunCMake/CompatibleInterface/CMakeLists.txt b/Tests/RunCMake/CompatibleInterface/CMakeLists.txt
new file mode 100644
index 0000000..68dd8d6
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 2.8)
+project(${RunCMake_TEST} CXX)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt
new file mode 100644
index 0000000..1a925b6
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" has property "INCLUDE_DIRECTORIES" listed in its
+ COMPATIBLE_INTERFACE_BOOL property. This is not allowed. Only
+ user-defined properties may appear listed in the COMPATIBLE_INTERFACE_BOOL
+ property.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake
new file mode 100644
index 0000000..5feb4d5
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-builtin-prop.cmake
@@ -0,0 +1,11 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL INCLUDE_DIRECTORIES)
+set_property(TARGET foo PROPERTY INTERFACE_INCLUDE_DIRECTORIES ON)
+set_property(TARGET bar PROPERTY INTERFACE_INCLUDE_DIRECTORIES ON)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES OFF)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt
new file mode 100644
index 0000000..0476da9
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error: Property SOMEPROP on target "user" does
+not match the INTERFACE_SOMEPROP property requirement
+of dependency "foo".
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake
new file mode 100644
index 0000000..90543e8
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depend-self.cmake
@@ -0,0 +1,11 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP ON)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY SOMEPROP OFF)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt
new file mode 100644
index 0000000..d885c09
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error: The INTERFACE_SOMEPROP property of "bar" does
+not agree with the value of SOMEPROP already determined
+for "user".
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake
new file mode 100644
index 0000000..69be796
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatch-depends.cmake
@@ -0,0 +1,10 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP OFF)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt
new file mode 100644
index 0000000..8556ee0
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error: Property SOMEPROP on target "user" is
+implied to be FALSE because it was used to determine the link libraries
+already. The INTERFACE_SOMEPROP property on
+dependency "foo" is in conflict.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake
new file mode 100644
index 0000000..ccfad0a
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceBool-mismatched-use.cmake
@@ -0,0 +1,9 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP ON)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,prop>:bar>)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt
new file mode 100644
index 0000000..6a293b4
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop-stderr.txt
@@ -0,0 +1,5 @@
+CMake Error in CMakeLists.txt:
+ Target "foo" has property "INCLUDE_DIRECTORIES" listed in its
+ COMPATIBLE_INTERFACE_STRING property. This is not allowed. Only
+ user-defined properties may appear listed in the
+ COMPATIBLE_INTERFACE_STRING property.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake
new file mode 100644
index 0000000..5221a12
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-builtin-prop.cmake
@@ -0,0 +1,11 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING INCLUDE_DIRECTORIES)
+set_property(TARGET foo PROPERTY INTERFACE_INCLUDE_DIRECTORIES foo_inc)
+set_property(TARGET bar PROPERTY INTERFACE_INCLUDE_DIRECTORIES bar_inc)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY INCLUDE_DIRECTORIES bar_inc)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt
new file mode 100644
index 0000000..0476da9
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error: Property SOMEPROP on target "user" does
+not match the INTERFACE_SOMEPROP property requirement
+of dependency "foo".
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake
new file mode 100644
index 0000000..187f29f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depend-self.cmake
@@ -0,0 +1,11 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP prop)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP prop)
+
+add_executable(user main.cpp)
+set_property(TARGET user PROPERTY SOMEPROP different)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt
new file mode 100644
index 0000000..d885c09
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends-stderr.txt
@@ -0,0 +1,3 @@
+CMake Error: The INTERFACE_SOMEPROP property of "bar" does
+not agree with the value of SOMEPROP already determined
+for "user".
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake
new file mode 100644
index 0000000..73cc3fc
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatch-depends.cmake
@@ -0,0 +1,10 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP foo)
+set_property(TARGET bar PROPERTY INTERFACE_SOMEPROP bar)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo bar)
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt
new file mode 100644
index 0000000..723daec
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error: Property SOMEPROP on target "user" is
+implied to be empty because it was used to determine the link libraries
+already. The INTERFACE_SOMEPROP property on
+dependency "foo" is in conflict.
diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake
new file mode 100644
index 0000000..af3ce8f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-mismatched-use.cmake
@@ -0,0 +1,9 @@
+
+add_library(foo UNKNOWN IMPORTED)
+add_library(bar UNKNOWN IMPORTED)
+
+set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMEPROP)
+set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP prop)
+
+add_executable(user main.cpp)
+target_link_libraries(user foo $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,prop>:bar>)
diff --git a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake
new file mode 100644
index 0000000..922ad7f
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake
@@ -0,0 +1,10 @@
+include(RunCMake)
+
+run_cmake(InterfaceBool-mismatch-depends)
+run_cmake(InterfaceBool-mismatch-depend-self)
+run_cmake(InterfaceBool-mismatched-use)
+run_cmake(InterfaceBool-builtin-prop)
+run_cmake(InterfaceString-mismatch-depends)
+run_cmake(InterfaceString-mismatch-depend-self)
+run_cmake(InterfaceString-mismatched-use)
+run_cmake(InterfaceString-builtin-prop)
diff --git a/Tests/RunCMake/CompatibleInterface/main.cpp b/Tests/RunCMake/CompatibleInterface/main.cpp
new file mode 100644
index 0000000..65eddcf
--- /dev/null
+++ b/Tests/RunCMake/CompatibleInterface/main.cpp
@@ -0,0 +1,5 @@
+
+int main(int argc, char **argv)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt b/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt
index 948def1..736fe69 100644
--- a/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt
+++ b/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt
@@ -1,37 +1,30 @@
-CMake Warning at DebugIncludes.cmake:8 \(include_directories\):
- Used includes:
+CMake Debug Log at DebugIncludes.cmake:8 \(include_directories\):
+ Used includes for target lll:
\* .*/Tests/RunCMake/include_directories/one
-
-Call Stack \(most recent call first\):
- CMakeLists.txt:3 \(include\)
-+
-CMake Warning at DebugIncludes.cmake:8 \(include_directories\):
- Used includes:
-
\* .*/Tests/RunCMake/include_directories/two
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
-CMake Warning at DebugIncludes.cmake:13 \(set_property\):
- Used includes:
+CMake Debug Log at DebugIncludes.cmake:13 \(set_property\):
+ Used includes for target lll:
\* .*/Tests/RunCMake/include_directories/three
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
-CMake Warning at DebugIncludes.cmake:18 \(include_directories\):
- Used includes:
+CMake Debug Log at DebugIncludes.cmake:18 \(include_directories\):
+ Used includes for target lll:
\* .*/Tests/RunCMake/include_directories/four
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
+
-CMake Warning at DebugIncludes.cmake:25 \(set_property\):
- Used includes:
+CMake Debug Log at DebugIncludes.cmake:25 \(set_property\):
+ Used includes for target lll:
\* .*/Tests/RunCMake/include_directories/five
\* .*/Tests/RunCMake/include_directories/six
diff --git a/Tests/VSExternalInclude/Lib1/CMakeLists.txt b/Tests/VSExternalInclude/Lib1/CMakeLists.txt
index 1cb01c5..9dfac86 100644
--- a/Tests/VSExternalInclude/Lib1/CMakeLists.txt
+++ b/Tests/VSExternalInclude/Lib1/CMakeLists.txt
@@ -1,3 +1,4 @@
+set(CMAKE_SUPPRESS_REGENERATION 1)
project(LIB1)
set(SOURCES lib1.cpp)
diff --git a/Tests/VSExternalInclude/Lib2/CMakeLists.txt b/Tests/VSExternalInclude/Lib2/CMakeLists.txt
index f726c3f..f451354 100644
--- a/Tests/VSExternalInclude/Lib2/CMakeLists.txt
+++ b/Tests/VSExternalInclude/Lib2/CMakeLists.txt
@@ -1,3 +1,4 @@
+set(CMAKE_SUPPRESS_REGENERATION 1)
project(VSEXTERNAL_LIB2)
include_directories(${VSEXTERNAL_LIB2_SOURCE_DIR}/../Lib1)