diff options
68 files changed, 853 insertions, 160 deletions
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 45fc936..623b708 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 20130121) +set(CMake_VERSION_TWEAK 20130123) #set(CMake_VERSION_RC 1) diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index fa21907..c2bf423 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -50,6 +50,10 @@ " $<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_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" \ diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 61e130d..7147f86 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -74,6 +74,7 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); + this->PopulateCompatibleInterfaceProperties(te, properties); this->GenerateInterfaceProperties(te, os, properties); } diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 4a7c6f9..ef1fc5f 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,7 +101,7 @@ bool cmExportFileGenerator::GenerateImportFile() // End with the import file footer. this->GenerateImportFooterCode(os); - os << "CMAKE_POLICY(POP)\n"; + os << "cmake_policy(POP)\n"; return result; } @@ -177,6 +178,79 @@ 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); + } +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::PopulateCompatibleInterfaceProperties( + cmTarget *target, + ImportPropertyMap &properties) +{ + this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_BOOL", + target, properties); + + std::set<std::string> ifaceProperties; + + getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", 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, @@ -186,7 +260,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) { @@ -536,7 +610,7 @@ void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os, void cmExportFileGenerator::GenerateImportFooterCode(std::ostream& os) { os << "# Commands beyond this point should not need to know the version.\n" - << "SET(CMAKE_IMPORT_FILE_VERSION)\n"; + << "set(CMAKE_IMPORT_FILE_VERSION)\n"; } //---------------------------------------------------------------------------- @@ -545,7 +619,7 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os) // Store an import file format version. This will let us change the // format later while still allowing old import files to work. os << "# Commands may need to know the format version.\n" - << "SET(CMAKE_IMPORT_FILE_VERSION 1)\n" + << "set(CMAKE_IMPORT_FILE_VERSION 1)\n" << "\n"; } @@ -553,31 +627,31 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os) void cmExportFileGenerator::GenerateExpectedTargetsCode(std::ostream& os, const std::string &expectedTargets) { - os << "SET(_targetsDefined)\n" - "SET(_targetsNotDefined)\n" - "SET(_expectedTargets)\n" - "FOREACH(_expectedTarget " << expectedTargets << ")\n" - " LIST(APPEND _expectedTargets ${_expectedTarget})\n" - " IF(NOT TARGET ${_expectedTarget})\n" - " LIST(APPEND _targetsNotDefined ${_expectedTarget})\n" - " ENDIF(NOT TARGET ${_expectedTarget})\n" - " IF(TARGET ${_expectedTarget})\n" - " LIST(APPEND _targetsDefined ${_expectedTarget})\n" - " ENDIF(TARGET ${_expectedTarget})\n" - "ENDFOREACH(_expectedTarget)\n" - "IF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n" - " SET(CMAKE_IMPORT_FILE_VERSION)\n" - " CMAKE_POLICY(POP)\n" - " RETURN()\n" - "ENDIF(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n" - "IF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n" - " MESSAGE(FATAL_ERROR \"Some (but not all) targets in this export " + os << "set(_targetsDefined)\n" + "set(_targetsNotDefined)\n" + "set(_expectedTargets)\n" + "foreach(_expectedTarget " << expectedTargets << ")\n" + " list(APPEND _expectedTargets ${_expectedTarget})\n" + " if(NOT TARGET ${_expectedTarget})\n" + " list(APPEND _targetsNotDefined ${_expectedTarget})\n" + " endif()\n" + " if(TARGET ${_expectedTarget})\n" + " list(APPEND _targetsDefined ${_expectedTarget})\n" + " endif()\n" + "endforeach()\n" + "if(\"${_targetsDefined}\" STREQUAL \"${_expectedTargets}\")\n" + " set(CMAKE_IMPORT_FILE_VERSION)\n" + " cmake_policy(POP)\n" + " return()\n" + "endif()\n" + "if(NOT \"${_targetsDefined}\" STREQUAL \"\")\n" + " message(FATAL_ERROR \"Some (but not all) targets in this export " "set were already defined.\\nTargets Defined: ${_targetsDefined}\\n" "Targets not yet defined: ${_targetsNotDefined}\\n\")\n" - "ENDIF(NOT \"${_targetsDefined}\" STREQUAL \"\")\n" - "UNSET(_targetsDefined)\n" - "UNSET(_targetsNotDefined)\n" - "UNSET(_expectedTargets)\n" + "endif()\n" + "unset(_targetsDefined)\n" + "unset(_targetsNotDefined)\n" + "unset(_expectedTargets)\n" "\n\n"; } //---------------------------------------------------------------------------- @@ -594,16 +668,16 @@ cmExportFileGenerator switch(target->GetType()) { case cmTarget::EXECUTABLE: - os << "ADD_EXECUTABLE(" << targetName << " IMPORTED)\n"; + os << "add_executable(" << targetName << " IMPORTED)\n"; break; case cmTarget::STATIC_LIBRARY: - os << "ADD_LIBRARY(" << targetName << " STATIC IMPORTED)\n"; + os << "add_library(" << targetName << " STATIC IMPORTED)\n"; break; case cmTarget::SHARED_LIBRARY: - os << "ADD_LIBRARY(" << targetName << " SHARED IMPORTED)\n"; + os << "add_library(" << targetName << " SHARED IMPORTED)\n"; break; case cmTarget::MODULE_LIBRARY: - os << "ADD_LIBRARY(" << targetName << " MODULE IMPORTED)\n"; + os << "add_library(" << targetName << " MODULE IMPORTED)\n"; break; default: // should never happen break; @@ -612,27 +686,27 @@ cmExportFileGenerator // Mark the imported executable if it has exports. if(target->IsExecutableWithExports()) { - os << "SET_PROPERTY(TARGET " << targetName + os << "set_property(TARGET " << targetName << " PROPERTY ENABLE_EXPORTS 1)\n"; } // Mark the imported library if it is a framework. if(target->IsFrameworkOnApple()) { - os << "SET_PROPERTY(TARGET " << targetName + os << "set_property(TARGET " << targetName << " PROPERTY FRAMEWORK 1)\n"; } // Mark the imported executable if it is an application bundle. if(target->IsAppBundleOnApple()) { - os << "SET_PROPERTY(TARGET " << targetName + os << "set_property(TARGET " << targetName << " PROPERTY MACOSX_BUNDLE 1)\n"; } if (target->IsCFBundleOnApple()) { - os << "SET_PROPERTY(TARGET " << targetName + os << "set_property(TARGET " << targetName << " PROPERTY BUNDLE 1)\n"; } os << "\n"; @@ -652,7 +726,7 @@ cmExportFileGenerator // Set the import properties. os << "# Import target \"" << targetName << "\" for configuration \"" << config << "\"\n"; - os << "SET_PROPERTY(TARGET " << targetName + os << "set_property(TARGET " << targetName << " APPEND PROPERTY IMPORTED_CONFIGURATIONS "; if(config && *config) { @@ -663,7 +737,7 @@ cmExportFileGenerator os << "NOCONFIG"; } os << ")\n"; - os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n"; + os << "set_target_properties(" << targetName << " PROPERTIES\n"; for(ImportPropertyMap::const_iterator pi = properties.begin(); pi != properties.end(); ++pi) { @@ -689,17 +763,17 @@ void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os, { if (emitted.insert(missingTargets[i]).second) { - os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n" - << " IF(CMAKE_FIND_PACKAGE_NAME)\n" - << " SET( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n" - << " SET( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE " + os << "if(NOT TARGET \"" << missingTargets[i] << "\" )\n" + << " if(CMAKE_FIND_PACKAGE_NAME)\n" + << " set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n" + << " set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE " << "\"Required imported target \\\"" << missingTargets[i] << "\\\" not found ! \")\n" - << " ELSE()\n" - << " MESSAGE(FATAL_ERROR \"Required imported target \\\"" + << " else()\n" + << " message(FATAL_ERROR \"Required imported target \\\"" << missingTargets[i] << "\\\" not found ! \")\n" - << " ENDIF()\n" - << "ENDIF()\n"; + << " endif()\n" + << "endif()\n"; } } os << "\n"; @@ -718,10 +792,10 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os) // on SUSE with a mysql pkg-config file, which claimed everything is fine, // but the development package was not installed.). os << "# Loop over all imported files and verify that they actually exist\n" - "FOREACH(target ${_IMPORT_CHECK_TARGETS} )\n" - " FOREACH(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n" - " IF(NOT EXISTS \"${file}\" )\n" - " MESSAGE(FATAL_ERROR \"The imported target \\\"${target}\\\"" + "foreach(target ${_IMPORT_CHECK_TARGETS} )\n" + " foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n" + " if(NOT EXISTS \"${file}\" )\n" + " message(FATAL_ERROR \"The imported target \\\"${target}\\\"" " references the file\n" " \\\"${file}\\\"\n" "but this file does not exist. Possible reasons include:\n" @@ -731,11 +805,11 @@ cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os) " \\\"${CMAKE_CURRENT_LIST_FILE}\\\"\n" "but not all the files it references.\n" "\")\n" - " ENDIF()\n" - " ENDFOREACH()\n" - " UNSET(_IMPORT_CHECK_FILES_FOR_${target})\n" - "ENDFOREACH()\n" - "UNSET(_IMPORT_CHECK_TARGETS)\n" + " endif()\n" + " endforeach()\n" + " unset(_IMPORT_CHECK_FILES_FOR_${target})\n" + "endforeach()\n" + "unset(_IMPORT_CHECK_TARGETS)\n" "\n"; } @@ -751,8 +825,8 @@ cmExportFileGenerator std::string targetName = this->Namespace; targetName += target->GetName(); - os << "LIST(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n" - "LIST(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " "; + os << "list(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n" + "list(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " "; for(std::set<std::string>::const_iterator li = importedLocations.begin(); li != importedLocations.end(); diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index eb3f3c3..b39df0f 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -103,6 +103,8 @@ protected: std::vector<std::string> &missingTargets); void PopulateInterfaceProperty(const char *propName, cmTarget *target, ImportPropertyMap &properties); + void PopulateCompatibleInterfaceProperties(cmTarget *target, + ImportPropertyMap &properties); void GenerateInterfaceProperties(cmTarget *target, std::ostream& os, const ImportPropertyMap &properties); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 965f63d..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."; @@ -91,6 +91,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) properties, missingTargets); this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); + this->PopulateCompatibleInterfaceProperties(te, properties); this->GenerateInterfaceProperties(te, os, properties); } @@ -98,12 +99,12 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) // Now load per-configuration properties for them. os << "# Load information for each installed configuration.\n" - << "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n" - << "FILE(GLOB CONFIG_FILES \"${_DIR}/" + << "get_filename_component(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n" + << "file(GLOB CONFIG_FILES \"${_DIR}/" << this->GetConfigImportFileGlob() << "\")\n" - << "FOREACH(f ${CONFIG_FILES})\n" - << " INCLUDE(${f})\n" - << "ENDFOREACH(f)\n" + << "foreach(f ${CONFIG_FILES})\n" + << " include(${f})\n" + << "endforeach()\n" << "\n"; this->GenerateImportedFileCheckLoop(os); @@ -193,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"; @@ -257,7 +258,7 @@ cmExportInstallFileGenerator if(!this->ImportPrefix.empty()) { os << "# Cleanup temporary variables.\n" - << "SET(_IMPORT_PREFIX)\n" + << "set(_IMPORT_PREFIX)\n" << "\n"; } } @@ -427,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 " @@ -445,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/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/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 2e5b5ae..057f4c3 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -106,3 +106,16 @@ cmGeneratorExpressionDAGChecker::checkGraph() const } return DAG; } + +//---------------------------------------------------------------------------- +bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries() +{ + const cmGeneratorExpressionDAGChecker *top = this; + const cmGeneratorExpressionDAGChecker *parent = this->Parent; + while (parent) + { + parent = parent->Parent; + top = parent; + } + return top->Property == "LINK_LIBRARIES"; +} 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 8e40815a..c468c39 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -442,6 +442,27 @@ 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"; + } + return std::string(); } @@ -488,6 +509,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> ¶meters, + 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 { @@ -714,6 +834,8 @@ 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") diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index d2baf53..f7eff21 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -980,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(); @@ -1063,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..0681ce5 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; } 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/cmMakefile.cxx b/Source/cmMakefile.cxx index b432986..4721e4c 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); + } } //---------------------------------------------------------------------------- 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/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/cmTarget.cxx b/Source/cmTarget.cxx index 815da40..2b912f3 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -145,12 +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; } //---------------------------------------------------------------------------- @@ -1499,6 +1501,8 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->Makefile->GetPolicyStatus(cmPolicies::CMP0004); this->PolicyStatusCMP0008 = this->Makefile->GetPolicyStatus(cmPolicies::CMP0008); + this->PolicyStatusCMP0020 = + this->Makefile->GetPolicyStatus(cmPolicies::CMP0020); } //---------------------------------------------------------------------------- @@ -1520,6 +1524,13 @@ void cmTarget::ClearLinkMaps() this->Internal->LinkImplMap.clear(); this->Internal->LinkInterfaceMap.clear(); this->Internal->LinkClosureMap.clear(); + for (cmTargetLinkInformationMap::const_iterator it + = this->LinkInformation.begin(); + it != this->LinkInformation.end(); ++it) + { + delete it->second; + } + this->LinkInformation.clear(); } //---------------------------------------------------------------------------- @@ -2269,8 +2280,9 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, cmTarget *tgt = this->Makefile->FindTargetToUse(lib); const bool isNonImportedTarget = tgt && !tgt->IsImported(); - std::string libName = isNonImportedTarget ? targetNameGenex(lib) - : std::string(lib); + const std::string libName = (isNonImportedTarget && llt != GENERAL) + ? targetNameGenex(lib) + : std::string(lib); this->AppendProperty("LINK_LIBRARIES", this->GetDebugGeneratorExpressions(libName, llt).c_str()); @@ -2739,11 +2751,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(); @@ -2778,8 +2796,8 @@ 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; @@ -4533,6 +4551,7 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, "INTERFACE_" << p << " property requirement\nof " "dependency \"" << li->Target->GetName() << "\".\n"; cmSystemTools::Error(e.str().c_str()); + break; } else { @@ -4559,6 +4578,7 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, "INTERFACE_" << p << " property on\ndependency \"" << li->Target->GetName() << "\" is in conflict.\n"; cmSystemTools::Error(e.str().c_str()); + break; } else { @@ -4586,6 +4606,7 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, "of " << p << " already determined\nfor \"" << this->GetName() << "\".\n"; cmSystemTools::Error(e.str().c_str()); + break; } else { @@ -4610,6 +4631,53 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, } //---------------------------------------------------------------------------- +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); +} + +//---------------------------------------------------------------------------- void cmTarget::GetLanguages(std::set<cmStdString>& languages) const { for(std::vector<cmSourceFile*>::const_iterator @@ -5422,14 +5490,14 @@ cmTarget::GetLinkInformation(const char* config, cmTarget *head) info = 0; } + // Store the information for this configuration. + cmTargetLinkInformationMap::value_type entry(key, info); + i = this->LinkInformation.insert(entry).first; + if (info) { this->CheckPropertyCompatibility(info, config); } - - // Store the information for this configuration. - cmTargetLinkInformationMap::value_type entry(key, info); - i = this->LinkInformation.insert(entry).first; } return i->second; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 69a00c1..9909bae 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 */ @@ -495,6 +499,8 @@ public: void GetLinkDependentTargetsForProperty(const std::string &p, std::set<std::string> &targets); bool IsNullImpliedByLinkLibraries(const std::string &p); + bool IsLinkInterfaceDependentBoolProperty(const std::string &p, + const char *config); void AddLinkDependentTargetsForProperties( const std::map<cmStdString, cmStdString> &map); @@ -610,6 +616,7 @@ private: bool DLLPlatform; bool IsApple; bool IsImportedTarget; + bool DebugIncludesDone; mutable std::map<cmStdString, std::set<std::string> > LinkDependentProperties; mutable std::set<std::string> LinkImplicitNullProperties; @@ -656,6 +663,7 @@ private: cmPolicies::PolicyStatus PolicyStatusCMP0003; cmPolicies::PolicyStatus PolicyStatusCMP0004; cmPolicies::PolicyStatus PolicyStatusCMP0008; + cmPolicies::PolicyStatus PolicyStatusCMP0020; // Internal representation details. friend class cmTargetInternals; diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx index c79c16f..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) @@ -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/cmake.cxx b/Source/cmake.cxx index 2eecfba..932c996 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -4394,6 +4394,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/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt index 486bca0..e190161 100644 --- a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt +++ b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt @@ -30,7 +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>" +) + +# 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 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/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt new file mode 100644 index 0000000..d0eb60f --- /dev/null +++ b/Tests/CompatibleInterface/CMakeLists.txt @@ -0,0 +1,28 @@ + +cmake_minimum_required(VERSION 2.8) + +project(CompatibleInterface) + +add_library(iface1 empty.cpp) +set_property(TARGET iface1 APPEND PROPERTY + COMPATIBLE_INTERFACE_BOOL + BOOL_PROP1 + BOOL_PROP2 + BOOL_PROP3 +) + +set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON) +set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON) + +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) + +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> +) 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/main.cpp b/Tests/CompatibleInterface/main.cpp new file mode 100644 index 0000000..b7c6638 --- /dev/null +++ b/Tests/CompatibleInterface/main.cpp @@ -0,0 +1,17 @@ + +#ifndef BOOL_PROP1 +#error Expected BOOL_PROP1 +#endif + +#ifndef BOOL_PROP2 +#error Expected BOOL_PROP2 +#endif + +#ifndef BOOL_PROP3 +#error Expected BOOL_PROP3 +#endif + +int main(int argc, char **argv) +{ + return 0; +} diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index dd615d1..5992293 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -173,6 +173,15 @@ 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 +) + add_library(testSharedLibDepends SHARED testSharedLibDepends.cpp) set_property(TARGET testSharedLibDepends APPEND PROPERTY diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 4812e7e..4df5771 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -165,7 +165,12 @@ 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) +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> +) if (APPLE OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") include(CheckCXXCompilerFlag) @@ -194,4 +199,6 @@ 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> ) diff --git a/Tests/ExportImport/Import/A/deps_shared_iface.cpp b/Tests/ExportImport/Import/A/deps_shared_iface.cpp index 43f832a..a33f200 100644 --- a/Tests/ExportImport/Import/A/deps_shared_iface.cpp +++ b/Tests/ExportImport/Import/A/deps_shared_iface.cpp @@ -8,6 +8,14 @@ #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 + #ifdef TEST_SUBDIR_LIB #include "subdir.h" #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/RunCMakeTest.cmake b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake new file mode 100644 index 0000000..ba8917b --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake @@ -0,0 +1,6 @@ +include(RunCMake) + +run_cmake(InterfaceBool-mismatch-depends) +run_cmake(InterfaceBool-mismatch-depend-self) +run_cmake(InterfaceBool-mismatched-use) +run_cmake(InterfaceBool-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) |