diff options
Diffstat (limited to 'Source')
25 files changed, 602 insertions, 448 deletions
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 341a925..2928c3c 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 12) -set(CMake_VERSION_TWEAK 20131024) +set(CMake_VERSION_TWEAK 20131026) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 725810b..448d8d1 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -170,6 +170,16 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration() } } + if(GetOption("CPACK_PACKAGE_VENDOR") == 0) + { + std::string defaultVendor = "Humanity"; + SetOption("CPACK_PACKAGE_VENDOR", defaultVendor.c_str()); + + cmCPackLogger(cmCPackLog::LOG_VERBOSE, + "CPACK_PACKAGE_VENDOR implicitly set to " << defaultVendor << " . " + << std::endl); + } + return true; } @@ -368,117 +378,49 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() featureDefinitions.AddAttribute("Id", "ProductFeature"); featureDefinitions.AddAttribute("Title", Name); featureDefinitions.AddAttribute("Level", "1"); - featureDefinitions.EndElement(); + featureDefinitions.EndElement("Feature"); featureDefinitions.BeginElement("FeatureRef"); featureDefinitions.AddAttribute("Id", "ProductFeature"); + std::vector<std::string> cpackPackageExecutablesList; const char *cpackPackageExecutables = GetOption("CPACK_PACKAGE_EXECUTABLES"); - std::vector<std::string> cpackPkgExecutables; - std::string regKey; - if ( cpackPackageExecutables ) + if(cpackPackageExecutables) { - cmSystemTools::ExpandListArgument(cpackPackageExecutables, - cpackPkgExecutables); - if ( cpackPkgExecutables.size() % 2 != 0 ) - { - cmCPackLogger(cmCPackLog::LOG_ERROR, - "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and " - "<icon name>." << std::endl); - cpackPkgExecutables.clear(); - } - - const char *cpackVendor = GetOption("CPACK_PACKAGE_VENDOR"); - const char *cpackPkgName = GetOption("CPACK_PACKAGE_NAME"); - if (!cpackVendor || !cpackPkgName) - { - cmCPackLogger(cmCPackLog::LOG_WARNING, "CPACK_PACKAGE_VENDOR and " - "CPACK_PACKAGE_NAME must be defined for shortcut creation" - << std::endl); - cpackPkgExecutables.clear(); - } - else - { - regKey = std::string("Software/") + cpackVendor + "/" + cpackPkgName; - } + cmSystemTools::ExpandListArgument(cpackPackageExecutables, + cpackPackageExecutablesList); + if(cpackPackageExecutablesList.size() % 2 != 0 ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "CPACK_PACKAGE_EXECUTABLES should contain pairs of <executable> and " + "<text label>." << std::endl); + return false; + } } - std::vector<std::string> dirIdExecutables; AddDirectoryAndFileDefinitons( toplevel, "INSTALL_ROOT", directoryDefinitions, fileDefinitions, featureDefinitions, - cpackPkgExecutables, dirIdExecutables); - - directoryDefinitions.EndElement(); - directoryDefinitions.EndElement(); + cpackPackageExecutablesList); - if (dirIdExecutables.size() > 0 && dirIdExecutables.size() % 3 == 0) + if(!CreateStartMenuShortcuts( + directoryDefinitions, fileDefinitions, featureDefinitions)) { - fileDefinitions.BeginElement("DirectoryRef"); - fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); - fileDefinitions.BeginElement("Component"); - fileDefinitions.AddAttribute("Id", "SHORTCUT"); - fileDefinitions.AddAttribute("Guid", "*"); + return false; + } - std::vector<std::string>::iterator it; - for ( it = dirIdExecutables.begin() ; - it != dirIdExecutables.end(); - ++it) - { - std::string fileName = *it++; - std::string iconName = *it++; - std::string directoryId = *it; - - fileDefinitions.BeginElement("Shortcut"); - - // the iconName is more likely to contain blanks early on - std::string shortcutName = fileName; - - std::string::size_type const dotPos = shortcutName.find('.'); - if(std::string::npos == dotPos) - { shortcutName = shortcutName.substr(0, dotPos); } - fileDefinitions.AddAttribute("Id", "SHORTCUT_" + shortcutName); - fileDefinitions.AddAttribute("Name", iconName); - std::string target = "[" + directoryId + "]" + fileName; - fileDefinitions.AddAttribute("Target", target); - fileDefinitions.AddAttribute("WorkingDirectory", directoryId); - fileDefinitions.EndElement(); - } - fileDefinitions.BeginElement("Shortcut"); - fileDefinitions.AddAttribute("Id", "UNINSTALL"); - std::string pkgName = GetOption("CPACK_PACKAGE_NAME"); - fileDefinitions.AddAttribute("Name", "Uninstall " + pkgName); - fileDefinitions.AddAttribute("Description", "Uninstalls " + pkgName); - fileDefinitions.AddAttribute("Target", "[SystemFolder]msiexec.exe"); - fileDefinitions.AddAttribute("Arguments", "/x [ProductCode]"); - fileDefinitions.EndElement(); - fileDefinitions.BeginElement("RemoveFolder"); - fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); - fileDefinitions.AddAttribute("On", "uninstall"); - fileDefinitions.EndElement(); - fileDefinitions.BeginElement("RegistryValue"); - fileDefinitions.AddAttribute("Root", "HKCU"); - fileDefinitions.AddAttribute("Key", regKey); - fileDefinitions.AddAttribute("Name", "installed"); - fileDefinitions.AddAttribute("Type", "integer"); - fileDefinitions.AddAttribute("Value", "1"); - fileDefinitions.AddAttribute("KeyPath", "yes"); - - featureDefinitions.BeginElement("ComponentRef"); - featureDefinitions.AddAttribute("Id", "SHORTCUT"); - featureDefinitions.EndElement(); - directoryDefinitions.BeginElement("Directory"); - directoryDefinitions.AddAttribute("Id", "ProgramMenuFolder"); - directoryDefinitions.BeginElement("Directory"); - directoryDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); - const char *startMenuFolder = GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); - directoryDefinitions.AddAttribute("Name", startMenuFolder); - } + featureDefinitions.EndElement("FeatureRef"); + featureDefinitions.EndElement("Fragment"); + fileDefinitions.EndElement("Fragment"); - featureDefinitions.EndElement(); - featureDefinitions.EndElement(); - fileDefinitions.EndElement(); - directoryDefinitions.EndElement(); + for(size_t i = 1; i < install_root.size(); ++i) + { + directoryDefinitions.EndElement("Directory"); + } + + directoryDefinitions.EndElement("Directory"); + directoryDefinitions.EndElement("Directory"); + directoryDefinitions.EndElement("Fragment"); std::string wixTemplate = FindTemplate("WIX.template.in"); if(GetOption("CPACK_WIX_TEMPLATE") != 0) @@ -508,6 +450,106 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() return true; } +bool cmCPackWIXGenerator::CreateStartMenuShortcuts( + cmWIXSourceWriter& directoryDefinitions, + cmWIXSourceWriter& fileDefinitions, + cmWIXSourceWriter& featureDefinitions) +{ + if(shortcutMap.empty()) + { + return true; + } + + std::string cpackVendor; + if(!RequireOption("CPACK_PACKAGE_VENDOR", cpackVendor)) + { + return false; + } + + std::string cpackPackageName; + if(!RequireOption("CPACK_PACKAGE_NAME", cpackPackageName)) + { + return false; + } + + fileDefinitions.BeginElement("DirectoryRef"); + fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); + fileDefinitions.BeginElement("Component"); + fileDefinitions.AddAttribute("Id", "SHORTCUT"); + fileDefinitions.AddAttribute("Guid", "*"); + + for(shortcut_map_t::const_iterator + i = shortcutMap.begin(); i != shortcutMap.end(); ++i) + { + std::string const& id = i->first; + cmWIXShortcut const& shortcut = i->second; + + std::string shortcutId = std::string("CM_S") + id; + std::string fileId = std::string("CM_F") + id; + + fileDefinitions.BeginElement("Shortcut"); + fileDefinitions.AddAttribute("Id", shortcutId); + fileDefinitions.AddAttribute("Name", shortcut.textLabel); + std::string target = "[#" + fileId + "]"; + fileDefinitions.AddAttribute("Target", target); + fileDefinitions.AddAttribute("WorkingDirectory", + shortcut.workingDirectoryId); + fileDefinitions.EndElement("Shortcut"); + } + + CreateUninstallShortcut(cpackPackageName, fileDefinitions); + + fileDefinitions.BeginElement("RemoveFolder"); + fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); + fileDefinitions.AddAttribute("On", "uninstall"); + fileDefinitions.EndElement("RemoveFolder"); + + std::string registryKey = + std::string("Software/") + cpackVendor + "/" + cpackPackageName; + + fileDefinitions.BeginElement("RegistryValue"); + fileDefinitions.AddAttribute("Root", "HKCU"); + fileDefinitions.AddAttribute("Key", registryKey); + fileDefinitions.AddAttribute("Name", "installed"); + fileDefinitions.AddAttribute("Type", "integer"); + fileDefinitions.AddAttribute("Value", "1"); + fileDefinitions.AddAttribute("KeyPath", "yes"); + fileDefinitions.EndElement("RegistryValue"); + + fileDefinitions.EndElement("Component"); + fileDefinitions.EndElement("DirectoryRef"); + + featureDefinitions.BeginElement("ComponentRef"); + featureDefinitions.AddAttribute("Id", "SHORTCUT"); + featureDefinitions.EndElement("ComponentRef"); + + directoryDefinitions.BeginElement("Directory"); + directoryDefinitions.AddAttribute("Id", "ProgramMenuFolder"); + + directoryDefinitions.BeginElement("Directory"); + directoryDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER"); + const char *startMenuFolder = GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"); + directoryDefinitions.AddAttribute("Name", startMenuFolder); + directoryDefinitions.EndElement("Directory"); + + directoryDefinitions.EndElement("Directory"); + + return true; +} + +void cmCPackWIXGenerator::CreateUninstallShortcut( + std::string const& packageName, + cmWIXSourceWriter& fileDefinitions) +{ + fileDefinitions.BeginElement("Shortcut"); + fileDefinitions.AddAttribute("Id", "UNINSTALL"); + fileDefinitions.AddAttribute("Name", "Uninstall " + packageName); + fileDefinitions.AddAttribute("Description", "Uninstalls " + packageName); + fileDefinitions.AddAttribute("Target", "[SystemFolder]msiexec.exe"); + fileDefinitions.AddAttribute("Arguments", "/x [ProductCode]"); + fileDefinitions.EndElement("Shortcut"); +} + bool cmCPackWIXGenerator::CreateLicenseFile() { std::string licenseSourceFilename; @@ -561,8 +603,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions, - const std::vector<std::string>& pkgExecutables, - std::vector<std::string>& dirIdExecutables) + const std::vector<std::string>& packageExecutables) { cmsys::Directory dir; dir.Load(topdir.c_str()); @@ -596,9 +637,9 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( directoryDefinitions, fileDefinitions, featureDefinitions, - pkgExecutables, - dirIdExecutables); - directoryDefinitions.EndElement(); + packageExecutables); + + directoryDefinitions.EndElement("Directory"); } else { @@ -617,28 +658,25 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( fileDefinitions.AddAttribute("Source", fullPath); fileDefinitions.AddAttribute("KeyPath", "yes"); - fileDefinitions.EndElement(); - fileDefinitions.EndElement(); - fileDefinitions.EndElement(); + fileDefinitions.EndElement("File"); + fileDefinitions.EndElement("Component"); + fileDefinitions.EndElement("DirectoryRef"); featureDefinitions.BeginElement("ComponentRef"); featureDefinitions.AddAttribute("Id", componentId); - featureDefinitions.EndElement(); + featureDefinitions.EndElement("ComponentRef"); - std::vector<std::string>::const_iterator it; - for (it = pkgExecutables.begin() ; - it != pkgExecutables.end() ; - ++it) + for(size_t j = 0; j < packageExecutables.size(); ++j) { - std::string execName = *it++; - std::string iconName = *it; + std::string const& executableName = packageExecutables[j++]; + std::string const& textLabel = packageExecutables[j]; - if (cmSystemTools::LowerCase(fileName) == - cmSystemTools::LowerCase(execName) + ".exe") + if(cmSystemTools::LowerCase(fileName) == + cmSystemTools::LowerCase(executableName) + ".exe") { - dirIdExecutables.push_back(fileName); - dirIdExecutables.push_back(iconName); - dirIdExecutables.push_back(directoryId); + cmWIXShortcut &shortcut = shortcutMap[id]; + shortcut.textLabel= textLabel; + shortcut.workingDirectoryId = directoryId; } } } diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h index eac69fe..c96ad5a 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.h +++ b/Source/CPack/WiX/cmCPackWIXGenerator.h @@ -18,6 +18,12 @@ #include <string> #include <map> +struct cmWIXShortcut +{ + std::string textLabel; + std::string workingDirectoryId; +}; + class cmWIXSourceWriter; /** \class cmCPackWIXGenerator @@ -56,6 +62,7 @@ protected: private: typedef std::map<std::string, std::string> id_map_t; typedef std::map<std::string, size_t> ambiguity_map_t; + typedef std::map<std::string, cmWIXShortcut> shortcut_map_t; bool InitializeWiXConfiguration(); @@ -71,6 +78,15 @@ private: bool CreateWiXSourceFiles(); + bool CreateStartMenuShortcuts( + cmWIXSourceWriter& directoryDefinitions, + cmWIXSourceWriter& fileDefinitions, + cmWIXSourceWriter& featureDefinitions); + + void CreateUninstallShortcut( + std::string const& packageName, + cmWIXSourceWriter& fileDefinitions); + void AppendUserSuppliedExtraSources(); void AppendUserSuppliedExtraObjects(std::ostream& stream); @@ -89,9 +105,7 @@ private: cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions, - const std::vector<std::string>& pkgExecutables, - std::vector<std::string>& dirIdExecutables - ); + const std::vector<std::string>& pkgExecutables); bool RequireOption(const std::string& name, std::string& value) const; @@ -118,6 +132,7 @@ private: std::vector<std::string> wixSources; id_map_t pathToIdMap; ambiguity_map_t idAmbiguityCounter; + shortcut_map_t shortcutMap; }; #endif diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx index af7ba80..214b8ac 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx @@ -21,7 +21,8 @@ cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger, bool isIncludeFile): Logger(logger), file(filename.c_str()), - state(DEFAULT) + state(DEFAULT), + sourceFilename(filename) { WriteXMLDeclaration(); @@ -39,10 +40,15 @@ cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger, cmWIXSourceWriter::~cmWIXSourceWriter() { - while(elements.size()) + if(elements.size() > 1) { - EndElement(); + cmCPackLogger(cmCPackLog::LOG_ERROR, + elements.size() - 1 << " WiX elements were still open when closing '" << + sourceFilename << "'" << std::endl); + return; } + + EndElement(elements.back()); } void cmWIXSourceWriter::BeginElement(const std::string& name) @@ -60,12 +66,22 @@ void cmWIXSourceWriter::BeginElement(const std::string& name) state = BEGIN; } -void cmWIXSourceWriter::EndElement() +void cmWIXSourceWriter::EndElement(std::string const& name) { if(elements.empty()) { cmCPackLogger(cmCPackLog::LOG_ERROR, - "can not end WiX element with no open elements" << std::endl); + "can not end WiX element with no open elements in '" << + sourceFilename << "'" << std::endl); + return; + } + + if(elements.back() != name) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "WiX element <" << elements.back() << + "> can not be closed by </" << name << "> in '" << + sourceFilename << "'" << std::endl); return; } @@ -173,6 +189,9 @@ std::string cmWIXSourceWriter::EscapeAttributeValue( case '<': result += "<"; break; + case '>': + result += ">"; + break; case '&': result +="&"; break; diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h index 1dafc1f..0c7803c 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.h +++ b/Source/CPack/WiX/cmWIXSourceWriter.h @@ -32,7 +32,7 @@ public: void BeginElement(const std::string& name); - void EndElement(); + void EndElement(const std::string& name); void AddProcessingInstruction( const std::string& target, const std::string& content); @@ -62,6 +62,8 @@ private: State state; std::vector<std::string> elements; + + std::string sourceFilename; }; #endif diff --git a/Source/cmAddCustomTargetCommand.cxx b/Source/cmAddCustomTargetCommand.cxx index 4eba886..2a683a4 100644 --- a/Source/cmAddCustomTargetCommand.cxx +++ b/Source/cmAddCustomTargetCommand.cxx @@ -25,17 +25,12 @@ bool cmAddCustomTargetCommand // Check the target name. if(args[0].find_first_of("/\\") != args[0].npos) { - if(!this->Makefile->NeedBackwardsCompatibility(2,2)) - { - cmOStringStream e; - e << "called with invalid target name \"" << args[0] - << "\". Target names may not contain a slash. " - << "Use ADD_CUSTOM_COMMAND to generate files. " - << "Set CMAKE_BACKWARDS_COMPATIBILITY to 2.2 " - << "or lower to skip this check."; - this->SetError(e.str().c_str()); - return false; - } + cmOStringStream e; + e << "called with invalid target name \"" << args[0] + << "\". Target names may not contain a slash. " + << "Use ADD_CUSTOM_COMMAND to generate files."; + this->SetError(e.str().c_str()); + return false; } // Accumulate one command line at a time. diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx index 49c585f..6e2ca64 100644 --- a/Source/cmCMakeMinimumRequired.cxx +++ b/Source/cmCMakeMinimumRequired.cxx @@ -114,6 +114,9 @@ bool cmCMakeMinimumRequired if (required_major < 2 || (required_major == 2 && required_minor < 4)) { + this->Makefile->IssueMessage( + cmake::AUTHOR_WARNING, + "Compatibility with CMake < 2.4 is not supported by CMake >= 3.0."); this->Makefile->SetPolicyVersion("2.4"); } else diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index e52ddef..f8ec642 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -74,10 +74,6 @@ bool cmConfigureFileCommand this->CopyOnly = false; this->EscapeQuotes = false; - // for CMake 2.0 and earlier CONFIGURE_FILE defaults to the FinalPass, - // after 2.0 it only does InitialPass - this->Immediate = !this->Makefile->NeedBackwardsCompatibility(2,0); - this->AtOnly = false; for(unsigned int i=2;i < args.size();++i) { @@ -101,32 +97,19 @@ bool cmConfigureFileCommand } else if(args[i] == "IMMEDIATE") { - this->Immediate = true; + /* Ignore legacy option. */ } } - // If we were told to copy the file immediately, then do it on the - // first pass (now). - if(this->Immediate) + if ( !this->ConfigureFile() ) { - if ( !this->ConfigureFile() ) - { - this->SetError("Problem configuring file"); - return false; - } + this->SetError("Problem configuring file"); + return false; } return true; } -void cmConfigureFileCommand::FinalPass() -{ - if(!this->Immediate) - { - this->ConfigureFile(); - } -} - int cmConfigureFileCommand::ConfigureFile() { return this->Makefile->ConfigureFile( diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h index 605b58b..86de92c 100644 --- a/Source/cmConfigureFileCommand.h +++ b/Source/cmConfigureFileCommand.h @@ -41,9 +41,6 @@ public: */ virtual bool IsScriptable() const { return true; } - virtual void FinalPass(); - virtual bool HasFinalPass() const { return !this->Immediate; } - private: int ConfigureFile(); @@ -53,7 +50,6 @@ private: std::string OutputFile; bool CopyOnly; bool EscapeQuotes; - bool Immediate; bool AtOnly; }; diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index b01e499..65f1cc6 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -411,6 +411,12 @@ void getCompatibleInterfaceProperties(cmTarget *target, getPropertyContents(li->Target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties); + getPropertyContents(li->Target, + "COMPATIBLE_INTERFACE_NUMBER_MIN", + ifaceProperties); + getPropertyContents(li->Target, + "COMPATIBLE_INTERFACE_NUMBER_MAX", + ifaceProperties); } } @@ -423,11 +429,19 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties( target, properties); this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_STRING", target, properties); + this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_NUMBER_MIN", + target, properties); + this->PopulateInterfaceProperty("COMPATIBLE_INTERFACE_NUMBER_MAX", + target, properties); std::set<std::string> ifaceProperties; getPropertyContents(target, "COMPATIBLE_INTERFACE_BOOL", ifaceProperties); getPropertyContents(target, "COMPATIBLE_INTERFACE_STRING", ifaceProperties); + getPropertyContents(target, "COMPATIBLE_INTERFACE_NUMBER_MIN", + ifaceProperties); + getPropertyContents(target, "COMPATIBLE_INTERFACE_NUMBER_MAX", + ifaceProperties); getCompatibleInterfaceProperties(target, ifaceProperties, 0); diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index c1e7b1e..ae15ee7 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -28,11 +28,6 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) return false; } - // CMake versions below 2.3 did not search all these extra - // locations. Preserve compatibility unless a modern argument is - // passed. - bool compatibility = this->Makefile->NeedBackwardsCompatibility(2,3); - // copy argsIn into args so it can be modified, // in the process extract the DOC "documentation" size_t size = argsIn.size(); @@ -112,7 +107,6 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) else if (args[j] == "PATH_SUFFIXES") { doing = DoingPathSuffixes; - compatibility = false; newStyle = true; } else if (args[j] == "NAMES_PER_DIR") @@ -136,7 +130,6 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) else if (this->CheckCommonArgument(args[j])) { doing = DoingNone; - compatibility = false; // Some common arguments were accidentally supported by CMake // 2.4 and 2.6.0 in the short-hand form of the command, so we // must support it even though it is not documented. @@ -159,17 +152,6 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn) } } - // Now that arguments have been parsed check the compatibility - // setting. If we need to be compatible with CMake 2.2 and earlier - // do not add the CMake system paths. It is safe to add the CMake - // environment paths and system environment paths because that - // existed in 2.2. It is safe to add the CMake user variable paths - // because the user or project has explicitly set them. - if(compatibility) - { - this->NoCMakeSystemPath = true; - } - if(this->VariableDocumentation.size() == 0) { this->VariableDocumentation = "Where can "; diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index aeca39a..12f04d6 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -24,32 +24,6 @@ #include <StorageDefs.h> #endif -void cmFindPackageNeedBackwardsCompatibility(const std::string& variable, - int access_type, void*, const char* newValue, - const cmMakefile*) -{ - (void)newValue; -#ifdef CMAKE_BUILD_WITH_CMAKE - if(access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS) - { - std::string message = "An attempt was made to access a variable: "; - message += variable; - message += - " that has not been defined. This variable is created by the " - "FIND_PACKAGE command. CMake version 1.6 always converted the " - "variable name to upper-case, but this behavior is no longer the " - "case. To fix this you might need to set the cache value of " - "CMAKE_BACKWARDS_COMPATIBILITY to 1.6 or less. If you are writing a " - "CMake listfile, you should change the variable reference to use " - "the case of the argument to FIND_PACKAGE."; - cmSystemTools::Error(message.c_str()); - } -#else - (void)variable; - (void)access_type; -#endif -} - //---------------------------------------------------------------------------- cmFindPackageCommand::cmFindPackageCommand() { @@ -128,11 +102,6 @@ bool cmFindPackageCommand std::set<std::string> requiredComponents; std::set<std::string> optionalComponents; - // Check ancient compatibility. - this->Compatibility_1_6 = - this->Makefile->GetLocalGenerator() - ->NeedBackwardsCompatibility(1, 6); - // Always search directly in a generated path. this->SearchPathSuffixes.push_back(""); @@ -154,7 +123,6 @@ bool cmFindPackageCommand else if(args[i] == "EXACT") { this->VersionExact = true; - this->Compatibility_1_6 = false; doing = DoingNone; } else if(args[i] == "MODULE") @@ -179,75 +147,63 @@ bool cmFindPackageCommand } else if(args[i] == "COMPONENTS") { - this->Compatibility_1_6 = false; doing = DoingComponents; } else if(args[i] == "OPTIONAL_COMPONENTS") { - this->Compatibility_1_6 = false; doing = DoingOptionalComponents; } else if(args[i] == "NAMES") { configArgs.insert(i); - this->Compatibility_1_6 = false; doing = DoingNames; } else if(args[i] == "PATHS") { configArgs.insert(i); - this->Compatibility_1_6 = false; doing = DoingPaths; } else if(args[i] == "HINTS") { configArgs.insert(i); - this->Compatibility_1_6 = false; doing = DoingHints; } else if(args[i] == "PATH_SUFFIXES") { configArgs.insert(i); - this->Compatibility_1_6 = false; doing = DoingPathSuffixes; } else if(args[i] == "CONFIGS") { configArgs.insert(i); - this->Compatibility_1_6 = false; doing = DoingConfigs; } else if(args[i] == "NO_POLICY_SCOPE") { this->PolicyScope = false; - this->Compatibility_1_6 = false; doing = DoingNone; } else if(args[i] == "NO_CMAKE_PACKAGE_REGISTRY") { this->NoUserRegistry = true; configArgs.insert(i); - this->Compatibility_1_6 = false; doing = DoingNone; } else if(args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY") { this->NoSystemRegistry = true; configArgs.insert(i); - this->Compatibility_1_6 = false; doing = DoingNone; } else if(args[i] == "NO_CMAKE_BUILDS_PATH") { this->NoBuilds = true; configArgs.insert(i); - this->Compatibility_1_6 = false; doing = DoingNone; } else if(this->CheckCommonArgument(args[i])) { configArgs.insert(i); - this->Compatibility_1_6 = false; doing = DoingNone; } else if((doing == DoingComponents) || (doing == DoingOptionalComponents)) @@ -642,24 +598,9 @@ bool cmFindPackageCommand::HandlePackageMode() std::string upperFound = cmSystemTools::UpperCase(this->Name); upperDir += "_DIR"; upperFound += "_FOUND"; - if(upperDir == this->Variable) - { - this->Compatibility_1_6 = false; - } // Try to find the config file. const char* def = this->Makefile->GetDefinition(this->Variable.c_str()); - if(this->Compatibility_1_6 && cmSystemTools::IsOff(def)) - { - // Use the setting of the old name of the variable to provide the - // value of the new. - const char* oldDef = this->Makefile->GetDefinition(upperDir.c_str()); - if(!cmSystemTools::IsOff(oldDef)) - { - this->Makefile->AddDefinition(this->Variable.c_str(), oldDef); - def = this->Makefile->GetDefinition(this->Variable.c_str()); - } - } // Try to load the config file if the directory is known bool fileFound = false; @@ -881,43 +822,6 @@ bool cmFindPackageCommand::HandlePackageMode() this->Makefile->RemoveDefinition(fileVar.c_str()); } - // Handle some ancient compatibility stuff. - if(this->Compatibility_1_6) - { - // Listfiles will be looking for the capitalized version of the - // name. Provide it. - this->Makefile->AddDefinition - (upperDir.c_str(), - this->Makefile->GetDefinition(this->Variable.c_str())); - this->Makefile->AddDefinition - (upperFound.c_str(), - this->Makefile->GetDefinition(foundVar.c_str())); - } - -#ifdef CMAKE_BUILD_WITH_CMAKE - if(!(upperDir == this->Variable)) - { - if(this->Compatibility_1_6) - { - // Listfiles may use the capitalized version of the name. - // Remove any previously added watch. - this->Makefile->GetVariableWatch()->RemoveWatch( - upperDir.c_str(), - cmFindPackageNeedBackwardsCompatibility - ); - } - else - { - // Listfiles should not be using the capitalized version of the - // name. Add a watch to warn the user. - this->Makefile->GetVariableWatch()->AddWatch( - upperDir.c_str(), - cmFindPackageNeedBackwardsCompatibility - ); - } - } -#endif - std::string consideredConfigsVar = this->Name; consideredConfigsVar += "_CONSIDERED_CONFIGS"; std::string consideredVersionsVar = this->Name; diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h index 1ed0710..7ceebb2 100644 --- a/Source/cmFindPackageCommand.h +++ b/Source/cmFindPackageCommand.h @@ -117,7 +117,6 @@ private: unsigned int RequiredCMakeVersion; bool Quiet; bool Required; - bool Compatibility_1_6; bool UseConfigFiles; bool UseFindModules; bool NoUserRegistry; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 33863f4..f92c18e 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -980,10 +980,54 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode context->Config); return propContent ? propContent : ""; } + if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMinProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMaxProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } return linkedTargetsContent; } + if (!target->IsImported() + && dagCheckerParent && !dagCheckerParent->EvaluatingLinkLibraries()) + { + if (target->IsLinkInterfaceDependentNumberMinProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMinProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + if (target->IsLinkInterfaceDependentNumberMaxProperty(propertyName, + context->Config)) + { + context->HadContextSensitiveCondition = true; + const char *propContent = + target->GetLinkInterfaceDependentNumberMaxProperty( + propertyName, + context->Config); + return propContent ? propContent : ""; + } + } for (size_t i = 1; i < cmArraySize(targetPropertyTransitiveWhitelist); ++i) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index fb205be..e26f59f 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -624,29 +624,6 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages, { cmSystemTools::RemoveFile(compilerLangFile.c_str()); } - else - { - // load backwards compatibility stuff for C and CXX - // for old versions of CMake ListFiles C and CXX had some - // backwards compatibility files they have to load - // These files have a bunch of try compiles in them so - // should only be done - if (mf->NeedBackwardsCompatibility(1,4)) - { - if(strcmp(lang, "C") == 0) - { - ifpath = - mf->GetModulesFile("CMakeBackwardCompatibilityC.cmake"); - mf->ReadListFile(0,ifpath.c_str()); - } - if(strcmp(lang, "CXX") == 0) - { - ifpath = - mf->GetModulesFile("CMakeBackwardCompatibilityCXX.cmake"); - mf->ReadListFile(0,ifpath.c_str()); - } - } - } } // end if in try compile } // end need test language // Store the shared library flags so that we can satisfy CMP0018 diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 3dde19f..edf80e6 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1412,13 +1412,6 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, includeBinaryDir = true; } - // CMake versions below 2.0 would add the source tree to the -I path - // automatically. Preserve compatibility. - if(this->NeedBackwardsCompatibility(1,9)) - { - includeSourceDir = true; - } - // Hack for VTK 4.0 - 4.4 which depend on the old behavior but do // not set the backwards compatibility level automatically. const char* vtkSourceDir = @@ -3071,7 +3064,7 @@ cmLocalGenerator // Decide whether this language wants to replace the source // extension with the object extension. For CMake 2.4 // compatibility do this by default. - bool replaceExt = this->NeedBackwardsCompatibility(2, 4); + bool replaceExt = this->NeedBackwardsCompatibility_2_4(); if(!replaceExt) { if(const char* lang = source.GetLanguage()) @@ -3318,9 +3311,7 @@ unsigned int cmLocalGenerator::GetBackwardsCompatibility() } //---------------------------------------------------------------------------- -bool cmLocalGenerator::NeedBackwardsCompatibility(unsigned int major, - unsigned int minor, - unsigned int patch) +bool cmLocalGenerator::NeedBackwardsCompatibility_2_4() { // Check the policy to decide whether to pay attention to this // variable. @@ -3348,7 +3339,7 @@ bool cmLocalGenerator::NeedBackwardsCompatibility(unsigned int major, // equal to or lower than the given version. unsigned int actual_compat = this->GetBackwardsCompatibility(); return (actual_compat && - actual_compat <= CMake_VERSION_ENCODE(major, minor, patch)); + actual_compat <= CMake_VERSION_ENCODE(2, 4, 255)); } //---------------------------------------------------------------------------- diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 10f0b1a..21700e9 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -324,9 +324,7 @@ public: /** * Test whether compatibility is set to a given version or lower. */ - bool NeedBackwardsCompatibility(unsigned int major, - unsigned int minor, - unsigned int patch = 0xFFu); + bool NeedBackwardsCompatibility_2_4(); /** * Generate a Mac OS X application bundle Info.plist file. diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 13c43fa..ade4252 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -799,22 +799,6 @@ void cmMakefile::SetLocalGenerator(cmLocalGenerator* lg) this->CheckSystemVars = this->GetCMakeInstance()->GetCheckSystemVars(); } -bool cmMakefile::NeedBackwardsCompatibility(unsigned int major, - unsigned int minor, - unsigned int patch) -{ - if(this->LocalGenerator) - { - return - this->LocalGenerator->NeedBackwardsCompatibility(major, minor, patch); - } - else - { - return false; - } -} - - namespace { struct file_not_persistent @@ -871,13 +855,15 @@ void cmMakefile::ConfigureFinalPass() this->FinalPass(); const char* oldValue = this->GetDefinition("CMAKE_BACKWARDS_COMPATIBILITY"); - if (oldValue && atof(oldValue) <= 1.2) + if (oldValue && cmSystemTools::VersionCompare( + cmSystemTools::OP_LESS, oldValue, "2.4")) { - cmSystemTools::Error("You have requested backwards compatibility " - "with CMake version 1.2 or earlier. This version " - "of CMake only supports backwards compatibility " - "with CMake 1.4 or later. For compatibility with " - "1.2 or earlier please use CMake 2.0"); + this->IssueMessage( + cmake::FATAL_ERROR, + "You have set CMAKE_BACKWARDS_COMPATIBILITY to a CMake version less " + "than 2.4. This version of CMake only supports backwards compatibility " + "with CMake 2.4 or later. For compatibility with older versions please " + "use any CMake 2.8.x release or lower."); } for (cmTargets::iterator l = this->Targets.begin(); l != this->Targets.end(); l++) @@ -1456,8 +1442,6 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target, this->GetCMakeInstance()->GetGlobalGenerator()->FindTarget(0,lib); if(tgt) { - // CMake versions below 2.4 allowed linking to modules. - bool allowModules = this->NeedBackwardsCompatibility(2,2); // if it is not a static or shared library then you can not link to it if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) || (tgt->GetType() == cmTarget::SHARED_LIBRARY) || @@ -1470,24 +1454,7 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target, << " may not be linked into another target. " << "One may link only to STATIC or SHARED libraries, or " << "to executables with the ENABLE_EXPORTS property set."; - // in older versions of cmake linking to modules was allowed - if( tgt->GetType() == cmTarget::MODULE_LIBRARY ) - { - e << "\n" - << "If you are developing a new project, re-organize it to avoid " - << "linking to modules. " - << "If you are just trying to build an existing project, " - << "set CMAKE_BACKWARDS_COMPATIBILITY to 2.2 or lower to allow " - << "linking to modules."; - } - // if no modules are allowed then this is always an error - if(!allowModules || - // if we allow modules but the type is not a module then it is - // still an error - (allowModules && tgt->GetType() != cmTarget::MODULE_LIBRARY)) - { - this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); - } + this->IssueMessage(cmake::FATAL_ERROR, e.str().c_str()); } } i->second.AddLinkLibrary( *this, target, lib, llt ); diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index ca82336..918c8bf 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -146,13 +146,6 @@ public: { return this->LocalGenerator;} /** - * Test whether compatibility is set to a given version or lower. - */ - bool NeedBackwardsCompatibility(unsigned int major, - unsigned int minor, - unsigned int patch = 0xFFu); - - /** * Help enforce global target name uniqueness. */ bool EnforceUniqueName(std::string const& name, std::string& msg, diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index c05de17..ab822d3 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -357,15 +357,9 @@ bool cmPolicies::ApplyPolicyVersion(cmMakefile *mf, if (majorVer < 2 || (majorVer == 2 && minorVer < 4)) { mf->IssueMessage(cmake::FATAL_ERROR, - "An attempt was made to set the policy version of CMake to something " - "earlier than \"2.4\". " - "In CMake 2.4 and below backwards compatibility was handled with the " - "CMAKE_BACKWARDS_COMPATIBILITY variable. " - "In order to get compatibility features supporting versions earlier " - "than 2.4 set policy CMP0001 to OLD to tell CMake to check the " - "CMAKE_BACKWARDS_COMPATIBILITY variable. " - "One way to do this is to set the policy version to 2.4 exactly." - ); + "Compatibility with CMake < 2.4 is not supported by CMake >= 3.0. " + "For compatibility with older versions please use any CMake 2.8.x " + "release or lower."); return false; } diff --git a/Source/cmStandardIncludes.h b/Source/cmStandardIncludes.h index 6c77144..18d017d 100644 --- a/Source/cmStandardIncludes.h +++ b/Source/cmStandardIncludes.h @@ -377,7 +377,8 @@ static thisClass* SafeDownCast(cmObject *c) \ return 0;\ } -#if defined(_MSC_VER) && _MSC_VER < 1300 +#if defined(_MSC_VER) && _MSC_VER < 1300 \ + || defined(__GNUC__) && __GNUC__ < 3 #define cmArrayBegin(a) a #define cmArraySize(a) (sizeof(a)/sizeof(*a)) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ad4ae0c..ea0b504 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -985,15 +985,20 @@ void cmTarget::MergeLinkLibraries( cmMakefile& mf, i += this->PrevLinkedLibraries.size(); for( ; i != libs.end(); ++i ) { + const char *lib = i->first.c_str(); // We call this so that the dependencies get written to the cache - this->AddLinkLibrary( mf, selfname, i->first.c_str(), i->second ); + this->AddLinkLibrary( mf, selfname, lib, i->second ); if (this->GetType() == cmTarget::STATIC_LIBRARY) { - this->AppendProperty("INTERFACE_LINK_LIBRARIES", - ("$<LINK_ONLY:" + - this->GetDebugGeneratorExpressions(i->first.c_str(), i->second) + - ">").c_str()); + std::string configLib = this->GetDebugGeneratorExpressions(lib, + i->second); + if (cmGeneratorExpression::IsValidTargetName(lib) + || cmGeneratorExpression::Find(lib) != std::string::npos) + { + configLib = "$<LINK_ONLY:" + configLib + ">"; + } + this->AppendProperty("INTERFACE_LINK_LIBRARIES", configLib.c_str()); } } this->PrevLinkedLibraries = libs; @@ -4450,26 +4455,107 @@ const char *getTypedProperty<const char *>(cmTarget *tgt, const char *prop, return tgt->GetProperty(prop); } +enum CompatibleType +{ + BoolType, + StringType, + NumberMinType, + NumberMaxType +}; + //---------------------------------------------------------------------------- template<typename PropertyType> -bool consistentProperty(PropertyType lhs, PropertyType rhs); +PropertyType consistentProperty(PropertyType lhs, PropertyType rhs, + CompatibleType t); //---------------------------------------------------------------------------- template<> -bool consistentProperty(bool lhs, bool rhs) +bool consistentProperty(bool lhs, bool rhs, CompatibleType) { return lhs == rhs; } //---------------------------------------------------------------------------- +const char * consistentStringProperty(const char *lhs, const char *rhs) +{ + return strcmp(lhs, rhs) == 0 ? lhs : 0; +} + +#if defined(_MSC_VER) && _MSC_VER <= 1200 +template<typename T> const T& +cmMaximum(const T& l, const T& r) {return l > r ? l : r;} +template<typename T> const T& +cmMinimum(const T& l, const T& r) {return l < r ? l : r;} +#else +#define cmMinimum std::min +#define cmMaximum std::max +#endif + +//---------------------------------------------------------------------------- +const char * consistentNumberProperty(const char *lhs, const char *rhs, + CompatibleType t) +{ + double lnum; + double rnum; + if(sscanf(lhs, "%lg", &lnum) != 1 || + sscanf(rhs, "%lg", &rnum) != 1) + { + return 0; + } + + if (t == NumberMaxType) + { + return cmMaximum(lnum, rnum) == lnum ? lhs : rhs; + } + else + { + return cmMinimum(lnum, rnum) == lnum ? lhs : rhs; + } +} + +//---------------------------------------------------------------------------- template<> -bool consistentProperty(const char *lhs, const char *rhs) +const char* consistentProperty(const char *lhs, const char *rhs, + CompatibleType t) { if (!lhs && !rhs) - return true; - if (!lhs || !rhs) - return false; - return strcmp(lhs, rhs) == 0; + { + return ""; + } + if (!lhs) + { + return rhs ? rhs : ""; + } + if (!rhs) + { + return lhs ? lhs : ""; + } + switch(t) + { + case BoolType: + assert(!"consistentProperty for strings called with BoolType"); + return 0; + case StringType: + return consistentStringProperty(lhs, rhs); + case NumberMinType: + case NumberMaxType: + return consistentNumberProperty(lhs, rhs, t); + } + assert(!"Unreachable!"); + return 0; +} + +template<typename PropertyType> +PropertyType impliedValue(PropertyType); +template<> +bool impliedValue<bool>(bool) +{ + return false; +} +template<> +const char* impliedValue<const char*>(const char*) +{ + return ""; } //---------------------------------------------------------------------------- @@ -4478,6 +4564,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt, const std::string &p, const char *config, const char *defaultValue, + CompatibleType t, PropertyType *) { PropertyType propContent = getTypedProperty<PropertyType>(tgt, p.c_str(), @@ -4523,7 +4610,9 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt, { if (ifaceIsSet) { - if (!consistentProperty(propContent, ifacePropContent)) + PropertyType consistent = consistentProperty(propContent, + ifacePropContent, t); + if (!consistent) { cmOStringStream e; e << "Property " << p << " on target \"" @@ -4536,6 +4625,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt, else { // Agree + propContent = consistent; continue; } } @@ -4547,9 +4637,12 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt, } else if (impliedByUse) { + propContent = impliedValue<PropertyType>(propContent); if (ifaceIsSet) { - if (!consistentProperty(propContent, ifacePropContent)) + PropertyType consistent = consistentProperty(propContent, + ifacePropContent, t); + if (!consistent) { cmOStringStream e; e << "Property " << p << " on target \"" @@ -4563,6 +4656,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt, else { // Agree + propContent = consistent; continue; } } @@ -4578,7 +4672,9 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt, { if (propInitialized) { - if (!consistentProperty(propContent, ifacePropContent)) + PropertyType consistent = consistentProperty(propContent, + ifacePropContent, t); + if (!consistent) { cmOStringStream e; e << "The INTERFACE_" << p << " property of \"" @@ -4591,6 +4687,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget *tgt, else { // Agree. + propContent = consistent; continue; } } @@ -4615,7 +4712,7 @@ bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, const char *config) { return checkInterfacePropertyCompatibility<bool>(this, p, config, "FALSE", - 0); + BoolType, 0); } //---------------------------------------------------------------------------- @@ -4626,7 +4723,32 @@ const char * cmTarget::GetLinkInterfaceDependentStringProperty( return checkInterfacePropertyCompatibility<const char *>(this, p, config, - "empty", 0); + "empty", + StringType, 0); +} + +//---------------------------------------------------------------------------- +const char * cmTarget::GetLinkInterfaceDependentNumberMinProperty( + const std::string &p, + const char *config) +{ + return checkInterfacePropertyCompatibility<const char *>(this, + p, + config, + "empty", + NumberMinType, 0); +} + +//---------------------------------------------------------------------------- +const char * cmTarget::GetLinkInterfaceDependentNumberMaxProperty( + const std::string &p, + const char *config) +{ + return checkInterfacePropertyCompatibility<const char *>(this, + p, + config, + "empty", + NumberMaxType, 0); } //---------------------------------------------------------------------------- @@ -4698,6 +4820,30 @@ bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p, } //---------------------------------------------------------------------------- +bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p, + const char *config) +{ + if (this->TargetTypeValue == OBJECT_LIBRARY) + { + return false; + } + return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MIN", + config); +} + +//---------------------------------------------------------------------------- +bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p, + const char *config) +{ + if (this->TargetTypeValue == OBJECT_LIBRARY) + { + return false; + } + return isLinkDependentProperty(this, p, "COMPATIBLE_INTERFACE_NUMBER_MAX", + config); +} + +//---------------------------------------------------------------------------- void cmTarget::GetLanguages(std::set<cmStdString>& languages) const { for(std::vector<cmSourceFile*>::const_iterator @@ -5376,11 +5522,9 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface, // There is no implicit link interface for executables or modules // so if none was explicitly set then there is no link interface. - // Note that CMake versions 2.2 and below allowed linking to modules. - bool canLinkModules = this->Makefile->NeedBackwardsCompatibility(2,2); if(!explicitLibraries && (this->GetType() == cmTarget::EXECUTABLE || - (this->GetType() == cmTarget::MODULE_LIBRARY && !canLinkModules))) + (this->GetType() == cmTarget::MODULE_LIBRARY))) { return false; } @@ -5677,23 +5821,39 @@ template<typename PropertyType> PropertyType getLinkInterfaceDependentProperty(cmTarget *tgt, const std::string prop, const char *config, + CompatibleType, PropertyType *); template<> bool getLinkInterfaceDependentProperty(cmTarget *tgt, - const std::string prop, - const char *config, bool *) + const std::string prop, + const char *config, + CompatibleType, bool *) { return tgt->GetLinkInterfaceDependentBoolProperty(prop, config); } template<> const char * getLinkInterfaceDependentProperty(cmTarget *tgt, - const std::string prop, - const char *config, - const char **) + const std::string prop, + const char *config, + CompatibleType t, + const char **) { - return tgt->GetLinkInterfaceDependentStringProperty(prop, config); + switch(t) + { + case BoolType: + assert(!"String compatibility check function called for boolean"); + return 0; + case StringType: + return tgt->GetLinkInterfaceDependentStringProperty(prop, config); + case NumberMinType: + return tgt->GetLinkInterfaceDependentNumberMinProperty(prop, config); + case NumberMaxType: + return tgt->GetLinkInterfaceDependentNumberMaxProperty(prop, config); + } + assert(!"Unreachable!"); + return 0; } //---------------------------------------------------------------------------- @@ -5702,6 +5862,7 @@ void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee, const char *propName, std::set<cmStdString> &emitted, const char *config, + CompatibleType t, PropertyType *) { const char *prop = dependee->GetProperty(propName); @@ -5734,7 +5895,7 @@ void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee, if(emitted.insert(*pi).second) { getLinkInterfaceDependentProperty<PropertyType>(depender, *pi, config, - 0); + t, 0); if (cmSystemTools::GetErrorOccuredFlag()) { return; @@ -5743,6 +5904,50 @@ void checkPropertyConsistency(cmTarget *depender, cmTarget *dependee, } } +static cmStdString intersect(const std::set<cmStdString> &s1, + const std::set<cmStdString> &s2) +{ + std::set<cmStdString> intersect; + std::set_intersection(s1.begin(),s1.end(), + s2.begin(),s2.end(), + std::inserter(intersect,intersect.begin())); + if (!intersect.empty()) + { + return *intersect.begin(); + } + return ""; +} +static cmStdString intersect(const std::set<cmStdString> &s1, + const std::set<cmStdString> &s2, + const std::set<cmStdString> &s3) +{ + cmStdString result; + result = intersect(s1, s2); + if (!result.empty()) + return result; + result = intersect(s1, s3); + if (!result.empty()) + return result; + return intersect(s2, s3); +} +static cmStdString intersect(const std::set<cmStdString> &s1, + const std::set<cmStdString> &s2, + const std::set<cmStdString> &s3, + const std::set<cmStdString> &s4) +{ + cmStdString result; + result = intersect(s1, s2); + if (!result.empty()) + return result; + result = intersect(s1, s3); + if (!result.empty()) + return result; + result = intersect(s1, s4); + if (!result.empty()) + return result; + return intersect(s2, s3, s4); +} + //---------------------------------------------------------------------------- void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, const char* config) @@ -5751,6 +5956,8 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, std::set<cmStdString> emittedBools; std::set<cmStdString> emittedStrings; + std::set<cmStdString> emittedMinNumbers; + std::set<cmStdString> emittedMaxNumbers; for(cmComputeLinkInformation::ItemVector::const_iterator li = deps.begin(); @@ -5763,35 +5970,84 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, checkPropertyConsistency<bool>(this, li->Target, "COMPATIBLE_INTERFACE_BOOL", - emittedBools, config, 0); + emittedBools, config, BoolType, 0); if (cmSystemTools::GetErrorOccuredFlag()) { return; } checkPropertyConsistency<const char *>(this, li->Target, "COMPATIBLE_INTERFACE_STRING", - emittedStrings, config, 0); + emittedStrings, config, + StringType, 0); + if (cmSystemTools::GetErrorOccuredFlag()) + { + return; + } + checkPropertyConsistency<const char *>(this, li->Target, + "COMPATIBLE_INTERFACE_NUMBER_MIN", + emittedMinNumbers, config, + NumberMinType, 0); + if (cmSystemTools::GetErrorOccuredFlag()) + { + return; + } + checkPropertyConsistency<const char *>(this, li->Target, + "COMPATIBLE_INTERFACE_NUMBER_MAX", + emittedMaxNumbers, config, + NumberMaxType, 0); if (cmSystemTools::GetErrorOccuredFlag()) { return; } } - for(std::set<cmStdString>::const_iterator li = emittedBools.begin(); - li != emittedBools.end(); ++li) + std::string prop = intersect(emittedBools, + emittedStrings, + emittedMinNumbers, + emittedMaxNumbers); + + if (!prop.empty()) { - const std::set<cmStdString>::const_iterator si = emittedStrings.find(*li); - if (si != emittedStrings.end()) + std::set<std::string> props; + std::set<cmStdString>::const_iterator i = emittedBools.find(prop); + if (i != emittedBools.end()) { - cmOStringStream e; - e << "Property \"" << *li << "\" appears in both the " - "COMPATIBLE_INTERFACE_BOOL and the COMPATIBLE_INTERFACE_STRING " - "property in the dependencies of target \"" << this->GetName() << - "\". This is not allowed. A property may only require compatibility " - "in a boolean interpretation or a string interpretation, but not both."; - this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); - break; + props.insert("COMPATIBLE_INTERFACE_BOOL"); + } + i = emittedStrings.find(prop); + if (i != emittedStrings.end()) + { + props.insert("COMPATIBLE_INTERFACE_STRING"); + } + i = emittedMinNumbers.find(prop); + if (i != emittedMinNumbers.end()) + { + props.insert("COMPATIBLE_INTERFACE_NUMBER_MIN"); + } + i = emittedMaxNumbers.find(prop); + if (i != emittedMaxNumbers.end()) + { + props.insert("COMPATIBLE_INTERFACE_NUMBER_MAX"); } + + std::string propsString = *props.begin(); + props.erase(props.begin()); + while (props.size() > 1) + { + propsString += ", " + *props.begin(); + props.erase(props.begin()); + } + if (props.size() == 1) + { + propsString += " and the " + *props.begin(); + } + cmOStringStream e; + e << "Property \"" << prop << "\" appears in both the " + << propsString << + " property in the dependencies of target \"" << this->GetName() << + "\". This is not allowed. A property may only require compatibility " + "in a boolean interpretation or a string interpretation, but not both."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); } } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index e8f4e08..9d62f5f 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -536,12 +536,20 @@ public: const char *config); bool IsLinkInterfaceDependentStringProperty(const std::string &p, const char *config); + bool IsLinkInterfaceDependentNumberMinProperty(const std::string &p, + const char *config); + bool IsLinkInterfaceDependentNumberMaxProperty(const std::string &p, + const char *config); bool GetLinkInterfaceDependentBoolProperty(const std::string &p, const char *config); const char *GetLinkInterfaceDependentStringProperty(const std::string &p, const char *config); + const char *GetLinkInterfaceDependentNumberMinProperty(const std::string &p, + const char *config); + const char *GetLinkInterfaceDependentNumberMaxProperty(const std::string &p, + const char *config); std::string GetDebugGeneratorExpressions(const std::string &value, cmTarget::LinkLibraryType llt); diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index 0707c62..9add198 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -395,10 +395,15 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib, { if (this->Target->GetType() == cmTarget::STATIC_LIBRARY) { + std::string configLib = this->Target + ->GetDebugGeneratorExpressions(lib, llt); + if (cmGeneratorExpression::IsValidTargetName(lib) + || cmGeneratorExpression::Find(lib) != std::string::npos) + { + configLib = "$<LINK_ONLY:" + configLib + ">"; + } this->Target->AppendProperty("INTERFACE_LINK_LIBRARIES", - ("$<LINK_ONLY:" + - this->Target->GetDebugGeneratorExpressions(lib, llt) + - ">").c_str()); + configLib.c_str()); } // Not a 'public' or 'interface' library. Do not add to interface // property. diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 6822fe1..186d4e6 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -99,30 +99,6 @@ static bool cmakeCheckStampFile(const char* stampName); static bool cmakeCheckStampList(const char* stampName); -void cmNeedBackwardsCompatibility(const std::string& variable, - int access_type, void*, const char*, const cmMakefile*) -{ -#ifdef CMAKE_BUILD_WITH_CMAKE - if (access_type == cmVariableWatch::UNKNOWN_VARIABLE_READ_ACCESS) - { - std::string message = "An attempt was made to access a variable: "; - message += variable; - message += - " that has not been defined. Some variables were always defined " - "by CMake in versions prior to 1.6. To fix this you might need to set " - "the cache value of CMAKE_BACKWARDS_COMPATIBILITY to 1.4 or less. If " - "you are writing a CMakeLists file, (or have already set " - "CMAKE_BACKWARDS_COMPATIBILITY to 1.4 or less) then you probably need " - "to include a CMake module to test for the feature this variable " - "defines."; - cmSystemTools::Error(message.c_str()); - } -#else - (void)variable; - (void)access_type; -#endif -} - void cmWarnUnusedCliWarning(const std::string& variable, int, void* ctx, const char*, const cmMakefile*) { @@ -169,12 +145,6 @@ cmake::cmake() #ifdef CMAKE_BUILD_WITH_CMAKE this->VariableWatch = new cmVariableWatch; - this->VariableWatch->AddWatch("CMAKE_WORDS_BIGENDIAN", - cmNeedBackwardsCompatibility); - this->VariableWatch->AddWatch("CMAKE_SIZEOF_INT", - cmNeedBackwardsCompatibility); - this->VariableWatch->AddWatch("CMAKE_X_LIBS", - cmNeedBackwardsCompatibility); #endif this->AddDefaultGenerators(); |