From 51da766a6d85397f9244f5ec426091848d9318ff Mon Sep 17 00:00:00 2001 From: David Golub Date: Wed, 9 May 2012 14:56:36 -0400 Subject: [PATCH 001/170] CPack/NSIS: Fix compatibility issues with prerelease NSIS (#13202) --- Modules/NSIS.template.in | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Modules/NSIS.template.in b/Modules/NSIS.template.in index ffc425e67..59a444bde 100644 --- a/Modules/NSIS.template.in +++ b/Modules/NSIS.template.in @@ -37,6 +37,9 @@ ;Set compression SetCompressor @CPACK_NSIS_COMPRESSOR@ + ;Require administrator access + RequestExecutionLevel admin + @CPACK_NSIS_DEFINES@ !include Sections.nsh @@ -119,7 +122,7 @@ Var AR_RegFlags "exit_${SecName}:" !macroend -!macro RemoveSection SecName +!macro RemoveSection_CPack SecName ; This macro is used to call section's Remove_... macro ;from the uninstaller. ;Input: section index constant name specified in Section command. @@ -841,7 +844,7 @@ Section "Uninstall" DeleteRegKey SHCTX "Software\@CPACK_PACKAGE_VENDOR@\@CPACK_PACKAGE_INSTALL_REGISTRY_KEY@" ; Removes all optional components - !insertmacro SectionList "RemoveSection" + !insertmacro SectionList "RemoveSection_CPack" !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP From 6ff730a4983d15f3e115a919eb18d866f8c65507 Mon Sep 17 00:00:00 2001 From: David Golub Date: Wed, 9 May 2012 15:33:44 -0400 Subject: [PATCH 002/170] CPack/NSIS: Add support for 64-bit NSIS (#13203) --- Source/CPack/cmCPackGeneratorFactory.cxx | 2 ++ Source/CPack/cmCPackNSISGenerator.cxx | 18 +++++++++++++++++- Source/CPack/cmCPackNSISGenerator.h | 7 ++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index 37ff46041..eba1ef92d 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -61,6 +61,8 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() { this->RegisterGenerator("NSIS", "Null Soft Installer", cmCPackNSISGenerator::CreateGenerator); + this->RegisterGenerator("NSIS64", "Null Soft Installer (64-bit)", + cmCPackNSISGenerator::CreateGenerator64); } #ifdef __CYGWIN__ if (cmCPackCygwinBinaryGenerator::CanGenerate()) diff --git a/Source/CPack/cmCPackNSISGenerator.cxx b/Source/CPack/cmCPackNSISGenerator.cxx index fdbae3504..9f86ea272 100644 --- a/Source/CPack/cmCPackNSISGenerator.cxx +++ b/Source/CPack/cmCPackNSISGenerator.cxx @@ -33,8 +33,9 @@ #endif //---------------------------------------------------------------------- -cmCPackNSISGenerator::cmCPackNSISGenerator() +cmCPackNSISGenerator::cmCPackNSISGenerator(bool nsis64) { + Nsis64 = nsis64; } //---------------------------------------------------------------------- @@ -359,6 +360,21 @@ int cmCPackNSISGenerator::InitializeInternal() bool gotRegValue = false; #ifdef _WIN32 + if (Nsis64) + { + if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS\\Unicode", nsisPath, + cmsys::SystemTools::KeyWOW64_64) ) + { + gotRegValue = true; + } + if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue( + "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", nsisPath, + cmsys::SystemTools::KeyWOW64_64) ) + { + gotRegValue = true; + } + } if ( !gotRegValue && cmsys::SystemTools::ReadRegistryValue( "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS\\Unicode", nsisPath, cmsys::SystemTools::KeyWOW64_32) ) diff --git a/Source/CPack/cmCPackNSISGenerator.h b/Source/CPack/cmCPackNSISGenerator.h index 82248546f..e46fbdab7 100644 --- a/Source/CPack/cmCPackNSISGenerator.h +++ b/Source/CPack/cmCPackNSISGenerator.h @@ -27,10 +27,13 @@ class cmCPackNSISGenerator : public cmCPackGenerator public: cmCPackTypeMacro(cmCPackNSISGenerator, cmCPackGenerator); + static cmCPackGenerator* CreateGenerator64() + { return new cmCPackNSISGenerator(true); } + /** * Construct generator */ - cmCPackNSISGenerator(); + cmCPackNSISGenerator(bool nsis64 = false); virtual ~cmCPackNSISGenerator(); protected: @@ -77,6 +80,8 @@ protected: /// Translations any newlines found in the string into \\r\\n, so that the /// resulting string can be used within NSIS. static std::string TranslateNewlines(std::string str); + + bool Nsis64; }; #endif From 14861f88d2e33edc53ab00f92dfaaf860f9d4084 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Mon, 19 Nov 2012 20:56:26 +0100 Subject: [PATCH 003/170] VS: Remove TargetMachine for linker when checking compiler id If the TargetMachine isn't defined the linker will choose the correct target depending on the input file. This helps us later with additional compiler platforms for WinCE. --- Modules/CMakeDetermineCompilerId.cmake | 3 --- Modules/CompilerId/VS-7.vcproj.in | 1 - 2 files changed, 4 deletions(-) diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 906a5e7ba..dd2bcd2dd 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -124,16 +124,13 @@ Id flags: ${testflags} set(ext dsp) endif() if("${vs_arch}" STREQUAL "Win64") - set(id_machine_7 17) set(id_machine_10 MachineX64) set(id_arch x64) elseif("${vs_arch}" STREQUAL "IA64") - set(id_machine_7 5) set(id_machine_10 MachineIA64) set(id_arch ia64) else() set(id_machine_6 x86) - set(id_machine_7 1) set(id_machine_10 MachineX86) set(id_arch Win32) endif() diff --git a/Modules/CompilerId/VS-7.vcproj.in b/Modules/CompilerId/VS-7.vcproj.in index 71bf64de2..bcb18a5b7 100644 --- a/Modules/CompilerId/VS-7.vcproj.in +++ b/Modules/CompilerId/VS-7.vcproj.in @@ -37,7 +37,6 @@ LinkIncremental="1" GenerateDebugInformation="false" SubSystem="1" - TargetMachine="@id_machine_7@" /> Date: Tue, 20 Nov 2012 21:59:40 +0100 Subject: [PATCH 004/170] Ninja: encode LINK_FLAGS to handle bash variables Bug 13560 --- Source/cmNinjaNormalTargetGenerator.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 853bc1220..65967a517 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -439,6 +439,9 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() this->GetGeneratorTarget()); this->AddModuleDefinitionFlag(vars["LINK_FLAGS"]); + vars["LINK_FLAGS"] = cmGlobalNinjaGenerator + ::EncodeLiteral(vars["LINK_FLAGS"]); + vars["LINK_PATH"] = frameworkPath + linkPath; // Compute architecture specific link flags. Yes, these go into a different From d8a59ea4b370eaf4a5b6162631af9e272fdb24b4 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sat, 27 Oct 2012 16:16:17 +0200 Subject: [PATCH 005/170] Port cmGeneratorExpression to cmTarget from cmGeneratorTarget. Following from the discussion here: http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/3615/focus=5170 (Re: Generator expressisons in target properties, 26 Oct 12:10) we can't split cmTarget API for linking into cmGeneratorTarget. In the future we will probably also need to move the include and compile definitions API back to cmTarget so that it can be used by export(). --- Source/cmGeneratorExpression.cxx | 2 +- Source/cmGeneratorExpression.h | 3 +-- Source/cmGeneratorExpressionEvaluator.cxx | 4 ++-- Source/cmGeneratorExpressionEvaluator.h | 3 +-- Source/cmGeneratorTarget.cxx | 4 ++-- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 7d8df3733..32bf941eb 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -68,7 +68,7 @@ cmGeneratorExpression::~cmGeneratorExpression() //---------------------------------------------------------------------------- const char *cmCompiledGeneratorExpression::Evaluate( cmMakefile* mf, const char* config, bool quiet, - cmGeneratorTarget *target, + cmTarget *target, cmGeneratorExpressionDAGChecker *dagChecker) const { if (!this->NeedsParsing) diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 29d3f444f..ea3e7d03b 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -20,7 +20,6 @@ #include class cmTarget; -class cmGeneratorTarget; class cmMakefile; class cmListFileBacktrace; @@ -68,7 +67,7 @@ class cmCompiledGeneratorExpression public: const char* Evaluate(cmMakefile* mf, const char* config, bool quiet = false, - cmGeneratorTarget *target = 0, + cmTarget *target = 0, cmGeneratorExpressionDAGChecker *dagChecker = 0) const; /** Get set of targets found during evaluations. */ diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 2e123a4d9..c60900034 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -287,7 +287,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode cmsys::RegularExpression propertyNameValidator; propertyNameValidator.compile("^[A-Za-z0-9_]+$"); - cmGeneratorTarget* target = context->Target; + cmTarget* target = context->Target; std::string propertyName = *parameters.begin(); if (parameters.size() == 2) { @@ -320,7 +320,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode "Target name not supported."); return std::string(); } - target = context->Makefile->FindGeneratorTargetToUse( + target = context->Makefile->FindTargetToUse( targetName.c_str()); if (!target) diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 04a2acdc6..d37337ef5 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -18,7 +18,6 @@ #include "cmListFileCache.h" class cmTarget; -class cmGeneratorTarget; //---------------------------------------------------------------------------- struct cmGeneratorExpressionContext @@ -27,7 +26,7 @@ struct cmGeneratorExpressionContext std::set Targets; cmMakefile *Makefile; const char *Config; - cmGeneratorTarget *Target; + cmTarget *Target; bool Quiet; bool HadError; }; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 19b55c62c..a68abca2f 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -308,7 +308,7 @@ std::vector cmGeneratorTarget::GetIncludeDirectories( .Evaluate(this->Makefile, config, false, - this, + this->Target, &dagChecker), includes); @@ -356,6 +356,6 @@ std::string cmGeneratorTarget::GetCompileDefinitions(const char *config) return ge.Parse(prop).Evaluate(this->Makefile, config, false, - this, + this->Target, &dagChecker); } From ddc052052b05d6daea0791efd2e1b97a9349a5e9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 21 Nov 2012 00:56:36 +0100 Subject: [PATCH 006/170] Always use the auto_ptr from cmsys. This is for consistency throughout cmake. The cmsys version exists becaues uses of auto_ptr types as return types does not work with some implementations in ancient compilers. --- Source/CPack/cmCPackGenerator.cxx | 3 +-- Source/CPack/cpack.cxx | 3 +-- Source/CTest/cmCTestTestHandler.cxx | 3 +-- Source/cmGraphVizWriter.cxx | 4 +--- Source/cmLocalUnixMakefileGenerator3.cxx | 1 - Source/cmMakefileLibraryTargetGenerator.cxx | 2 -- Source/cmSystemTools.cxx | 1 - Source/cmake.cxx | 18 ++++++++---------- 8 files changed, 12 insertions(+), 23 deletions(-) diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 6317fa031..7cc152269 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -23,7 +23,6 @@ #include #include -#include // auto_ptr #include #if defined(__HAIKU__) @@ -696,7 +695,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( cm.SetProgressCallback(cmCPackGeneratorProgress, this); cmGlobalGenerator gg; gg.SetCMakeInstance(&cm); - std::auto_ptr lg(gg.CreateLocalGenerator()); + cmsys::auto_ptr lg(gg.CreateLocalGenerator()); cmMakefile *mf = lg->GetMakefile(); std::string realInstallDirectory = tempInstallDirectory; if ( !installSubDirectory.empty() && installSubDirectory != "/" ) diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index b6035854e..0ba732269 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -27,7 +27,6 @@ #include #include -#include // auto_ptr //---------------------------------------------------------------------------- static const char * cmDocumentationName[][3] = @@ -276,7 +275,7 @@ int main (int argc, char *argv[]) cminst.RemoveUnscriptableCommands(); cmGlobalGenerator cmgg; cmgg.SetCMakeInstance(&cminst); - std::auto_ptr cmlg(cmgg.CreateLocalGenerator()); + cmsys::auto_ptr cmlg(cmgg.CreateLocalGenerator()); cmMakefile* globalMF = cmlg->GetMakefile(); bool cpackConfigFileSpecified = true; diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx index b796b8373..e7491bba3 100644 --- a/Source/CTest/cmCTestTestHandler.cxx +++ b/Source/CTest/cmCTestTestHandler.cxx @@ -32,7 +32,6 @@ #include #include -#include // auto_ptr #include //---------------------------------------------------------------------- @@ -1547,7 +1546,7 @@ void cmCTestTestHandler::GetListOfTests() cmake cm; cmGlobalGenerator gg; gg.SetCMakeInstance(&cm); - std::auto_ptr lg(gg.CreateLocalGenerator()); + cmsys::auto_ptr lg(gg.CreateLocalGenerator()); cmMakefile *mf = lg->GetMakefile(); mf->AddDefinition("CTEST_CONFIGURATION_TYPE", this->CTest->GetConfigType().c_str()); diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx index 15bad5265..4816da9ea 100644 --- a/Source/cmGraphVizWriter.cxx +++ b/Source/cmGraphVizWriter.cxx @@ -15,8 +15,6 @@ #include "cmGlobalGenerator.h" #include "cmGeneratedFileStream.h" -#include - static const char* getShapeForTarget(const cmTarget* target) @@ -67,7 +65,7 @@ void cmGraphVizWriter::ReadSettings(const char* settingsFileName, cmake cm; cmGlobalGenerator ggi; ggi.SetCMakeInstance(&cm); - std::auto_ptr lg(ggi.CreateLocalGenerator()); + cmsys::auto_ptr lg(ggi.CreateLocalGenerator()); cmMakefile *mf = lg->GetMakefile(); const char* inFileName = settingsFileName; diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx index 820d25a9d..d629e7135 100644 --- a/Source/cmLocalUnixMakefileGenerator3.cxx +++ b/Source/cmLocalUnixMakefileGenerator3.cxx @@ -32,7 +32,6 @@ #include -#include // auto_ptr #include //---------------------------------------------------------------------------- diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx index e7004d668..5b4e4d774 100644 --- a/Source/cmMakefileLibraryTargetGenerator.cxx +++ b/Source/cmMakefileLibraryTargetGenerator.cxx @@ -19,8 +19,6 @@ #include "cmTarget.h" #include "cmake.h" -#include // auto_ptr - //---------------------------------------------------------------------------- cmMakefileLibraryTargetGenerator ::cmMakefileLibraryTargetGenerator(cmTarget* target): diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 89f03f62c..22b6aec08 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -52,7 +52,6 @@ #endif #if defined(CMAKE_BUILD_WITH_CMAKE) -# include // auto_ptr # include # include "cmCryptoHash.h" #endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 1ec88fb86..1424a1132 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -110,8 +110,6 @@ #include // struct stat -#include // auto_ptr - static bool cmakeCheckStampFile(const char* stampName); static bool cmakeCheckStampList(const char* stampName); @@ -519,7 +517,7 @@ void cmake::ReadListFile(const std::vector& args, // read in the list file to fill the cache if(path) { - std::auto_ptr lg(gg->CreateLocalGenerator()); + cmsys::auto_ptr lg(gg->CreateLocalGenerator()); lg->GetMakefile()->SetHomeOutputDirectory (cmSystemTools::GetCurrentWorkingDirectory().c_str()); lg->GetMakefile()->SetStartOutputDirectory @@ -558,7 +556,7 @@ bool cmake::FindPackage(const std::vector& args) this->SetGlobalGenerator(gg); // read in the list file to fill the cache - std::auto_ptr lg(gg->CreateLocalGenerator()); + cmsys::auto_ptr lg(gg->CreateLocalGenerator()); cmMakefile* mf = lg->GetMakefile(); mf->SetHomeOutputDirectory (cmSystemTools::GetCurrentWorkingDirectory().c_str()); @@ -1654,7 +1652,7 @@ int cmake::ExecuteCMakeCommand(std::vector& args) if(cmGlobalGenerator* ggd = cm.CreateGlobalGenerator(gen.c_str())) { cm.SetGlobalGenerator(ggd); - std::auto_ptr lgd(ggd->CreateLocalGenerator()); + cmsys::auto_ptr lgd(ggd->CreateLocalGenerator()); lgd->GetMakefile()->SetStartDirectory(startDir.c_str()); lgd->GetMakefile()->SetStartOutputDirectory(startOutDir.c_str()); lgd->GetMakefile()->MakeStartDirectoriesCurrent(); @@ -2794,7 +2792,7 @@ int cmake::CheckBuildSystem() cmake cm; cmGlobalGenerator gg; gg.SetCMakeInstance(&cm); - std::auto_ptr lg(gg.CreateLocalGenerator()); + cmsys::auto_ptr lg(gg.CreateLocalGenerator()); cmMakefile* mf = lg->GetMakefile(); if(!mf->ReadListFile(0, this->CheckBuildSystemArgument.c_str()) || cmSystemTools::GetErrorOccuredFlag()) @@ -2820,11 +2818,11 @@ int cmake::CheckBuildSystem() } // Create the generator and use it to clear the dependencies. - std::auto_ptr + cmsys::auto_ptr ggd(this->CreateGlobalGenerator(genName)); if(ggd.get()) { - std::auto_ptr lgd(ggd->CreateLocalGenerator()); + cmsys::auto_ptr lgd(ggd->CreateLocalGenerator()); lgd->ClearDependencies(mf, verbose); } } @@ -3067,7 +3065,7 @@ void cmake::MarkCliAsUsed(const std::string& variable) void cmake::GenerateGraphViz(const char* fileName) const { #ifdef CMAKE_BUILD_WITH_CMAKE - std::auto_ptr gvWriter( + cmsys::auto_ptr gvWriter( new cmGraphVizWriter(this->GetGlobalGenerator()->GetLocalGenerators())); std::string settingsFile = this->GetHomeOutputDirectory(); @@ -4466,7 +4464,7 @@ int cmake::Build(const std::string& dir, std::cerr << "Error: could find generator in Cache\n"; return 1; } - std::auto_ptr gen( + cmsys::auto_ptr gen( this->CreateGlobalGenerator(it.GetValue())); std::string output; std::string projName; From d5cf644ac2e3f035d2d3413dd98aa0d46f9f27eb Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 1 Nov 2012 10:16:56 +0100 Subject: [PATCH 007/170] Split link information processing into two steps. The first step can be ported to use the generator expression API, while the second can not. This is for compatibility with CMP0003. --- Source/cmTarget.cxx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 7c62ea8f1..214b09972 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -4707,14 +4707,24 @@ void cmTarget::ComputeLinkImplementation(const char* config, { continue; } - if(li->second == cmTarget::GENERAL || li->second == linkType) { // The entry is meant for this configuration. impl.Libraries.push_back(item); } - else + } + + LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries(); + for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin(); + li != oldllibs.end(); ++li) + { + if(li->second != cmTarget::GENERAL && li->second != linkType) { + std::string item = this->CheckCMP0004(li->first); + if(item == this->GetName() || item.empty()) + { + continue; + } // Support OLD behavior for CMP0003. impl.WrongConfigLibraries.push_back(item); } From 0bbae6f95f55f23b758780f771bf4dd560ac2c07 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 5 Nov 2012 16:14:02 +0100 Subject: [PATCH 008/170] Revert "Move GetLinkInformation to cmGeneratorTarget" As we can't move all linking related code from cmTarget, it makes sense to reverse the move in some cases. This reverts commit 4f5384e75c6a00d110d3fa3f555a3f6a4f31bb46. --- Source/cmGeneratorTarget.cxx | 38 ---------------- Source/cmGeneratorTarget.h | 6 --- Source/cmGlobalXCodeGenerator.cxx | 3 +- Source/cmInstallTargetGenerator.cxx | 30 ++----------- Source/cmInstallTargetGenerator.h | 5 +-- Source/cmLocalGenerator.cxx | 2 +- Source/cmLocalVisualStudio6Generator.cxx | 4 +- Source/cmLocalVisualStudio7Generator.cxx | 8 +--- Source/cmMakefileTargetGenerator.cxx | 6 +-- Source/cmNinjaTargetGenerator.cxx | 2 +- Source/cmTarget.cxx | 50 ++++++++++++++++++++++ Source/cmTarget.h | 14 ++++++ Source/cmVisualStudio10TargetGenerator.cxx | 2 +- 13 files changed, 78 insertions(+), 92 deletions(-) diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index a68abca2f..de8b5e369 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -14,14 +14,11 @@ #include "cmTarget.h" #include "cmMakefile.h" #include "cmLocalGenerator.h" -#include "cmComputeLinkInformation.h" #include "cmGlobalGenerator.h" #include "cmSourceFile.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionDAGChecker.h" -#include - //---------------------------------------------------------------------------- cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t) { @@ -32,15 +29,6 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t) this->LookupObjectLibraries(); } -cmGeneratorTarget::~cmGeneratorTarget() -{ - for(std::map::iterator i - = LinkInformation.begin(); i != LinkInformation.end(); ++i) - { - delete i->second; - } -} - //---------------------------------------------------------------------------- int cmGeneratorTarget::GetType() const { @@ -220,32 +208,6 @@ void cmGeneratorTarget::UseObjectLibraries(std::vector& objs) } } -//---------------------------------------------------------------------------- -cmComputeLinkInformation* -cmGeneratorTarget::GetLinkInformation(const char* config) -{ - // Lookup any existing information for this configuration. - std::map::iterator - i = this->LinkInformation.find(config?config:""); - if(i == this->LinkInformation.end()) - { - // Compute information for this configuration. - cmComputeLinkInformation* info = - new cmComputeLinkInformation(this->Target, config); - if(!info || !info->Compute()) - { - delete info; - info = 0; - } - - // Store the information for this configuration. - std::map::value_type - entry(config?config:"", info); - i = this->LinkInformation.insert(entry).first; - } - return i->second; -} - //---------------------------------------------------------------------------- void cmGeneratorTarget::GetAppleArchs(const char* config, std::vector& archVec) diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h index a29a9f904..6f5ecb7e9 100644 --- a/Source/cmGeneratorTarget.h +++ b/Source/cmGeneratorTarget.h @@ -14,7 +14,6 @@ #include "cmStandardIncludes.h" -class cmComputeLinkInformation; class cmCustomCommand; class cmGlobalGenerator; class cmLocalGenerator; @@ -26,7 +25,6 @@ class cmGeneratorTarget { public: cmGeneratorTarget(cmTarget*); - ~cmGeneratorTarget(); int GetType() const; const char *GetName() const; @@ -60,10 +58,6 @@ public: void UseObjectLibraries(std::vector& objs); - std::map LinkInformation; - - cmComputeLinkInformation* GetLinkInformation(const char* config); - void GetAppleArchs(const char* config, std::vector& archVec); diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 4ef2f5736..9bbeeaf6f 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -2649,8 +2649,7 @@ void cmGlobalXCodeGenerator } // Compute the link library and directory information. - cmGeneratorTarget* gtgt = this->GetGeneratorTarget(cmtarget); - cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName); + cmComputeLinkInformation* pcli = cmtarget->GetLinkInformation(configName); if(!pcli) { continue; diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx index 347ad3ec5..5f9b6585e 100644 --- a/Source/cmInstallTargetGenerator.cxx +++ b/Source/cmInstallTargetGenerator.cxx @@ -16,7 +16,6 @@ #include "cmLocalGenerator.h" #include "cmMakefile.h" #include "cmake.h" -#include "cmGeneratorTarget.h" #include @@ -27,8 +26,7 @@ cmInstallTargetGenerator std::vector const& configurations, const char* component, bool optional): cmInstallGenerator(dest, configurations, component), Target(&t), - ImportLibrary(implib), FilePermissions(file_permissions), - Optional(optional), GeneratorTarget(0) + ImportLibrary(implib), FilePermissions(file_permissions), Optional(optional) { this->ActionsPerConfig = true; this->NamelinkMode = NamelinkModeNone; @@ -486,17 +484,6 @@ void cmInstallTargetGenerator::PostReplacementTweaks(std::ostream& os, this->AddStripRule(os, indent, file); } -void cmInstallTargetGenerator::CreateGeneratorTarget() -{ - if (!this->GeneratorTarget) - { - this->GeneratorTarget = this->Target->GetMakefile() - ->GetLocalGenerator() - ->GetGlobalGenerator() - ->GetGeneratorTarget(this->Target); - } -} - //---------------------------------------------------------------------------- void cmInstallTargetGenerator @@ -520,13 +507,10 @@ cmInstallTargetGenerator return; } - this->CreateGeneratorTarget(); - // Build a map of build-tree install_name to install-tree install_name for // shared libraries linked to this target. std::map install_name_remap; - if(cmComputeLinkInformation* cli = - this->GeneratorTarget->GetLinkInformation(config)) + if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config)) { std::set const& sharedLibs = cli->GetSharedLibrariesLinked(); for(std::set::const_iterator j = sharedLibs.begin(); @@ -624,12 +608,9 @@ cmInstallTargetGenerator return; } - this->CreateGeneratorTarget(); - // Get the link information for this target. // It can provide the RPATH. - cmComputeLinkInformation* cli = - this->GeneratorTarget->GetLinkInformation(config); + cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config); if(!cli) { return; @@ -658,12 +639,9 @@ cmInstallTargetGenerator return; } - this->CreateGeneratorTarget(); - // Get the link information for this target. // It can provide the RPATH. - cmComputeLinkInformation* cli = - this->GeneratorTarget->GetLinkInformation(config); + cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config); if(!cli) { return; diff --git a/Source/cmInstallTargetGenerator.h b/Source/cmInstallTargetGenerator.h index cab3e9065..8cf72f975 100644 --- a/Source/cmInstallTargetGenerator.h +++ b/Source/cmInstallTargetGenerator.h @@ -14,8 +14,7 @@ #include "cmInstallGenerator.h" #include "cmTarget.h" - -class cmGeneratorTarget; +#include "cmGeneratorTarget.h" /** \class cmInstallTargetGenerator * \brief Generate target installation rules. @@ -94,8 +93,6 @@ protected: void AddRanlibRule(std::ostream& os, Indent const& indent, const std::string& toDestDirPath); - void CreateGeneratorTarget(); - cmTarget* Target; bool ImportLibrary; std::string FilePermissions; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 4952a8ce9..377cd091f 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1671,7 +1671,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, { cmOStringStream fout; const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"); - cmComputeLinkInformation* pcli = tgt.GetLinkInformation(config); + cmComputeLinkInformation* pcli = tgt.Target->GetLinkInformation(config); if(!pcli) { return; diff --git a/Source/cmLocalVisualStudio6Generator.cxx b/Source/cmLocalVisualStudio6Generator.cxx index 9497e3146..6c78ac47e 100644 --- a/Source/cmLocalVisualStudio6Generator.cxx +++ b/Source/cmLocalVisualStudio6Generator.cxx @@ -1785,10 +1785,8 @@ void cmLocalVisualStudio6Generator const std::string extraOptions, std::string& options) { - cmGeneratorTarget* gt = - this->GlobalGenerator->GetGeneratorTarget(&target); // Compute the link information for this configuration. - cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName); + cmComputeLinkInformation* pcli = target.GetLinkInformation(configName); if(!pcli) { return; diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index d954a5290..afd30f3bf 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -1076,9 +1076,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, targetNameImport, targetNamePDB, configName); // Compute the link library and directory information. - cmGeneratorTarget* gt = - this->GlobalGenerator->GetGeneratorTarget(&target); - cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName); + cmComputeLinkInformation* pcli = target.GetLinkInformation(configName); if(!pcli) { return; @@ -1163,9 +1161,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, targetNameImport, targetNamePDB, configName); // Compute the link library and directory information. - cmGeneratorTarget* gt = - this->GlobalGenerator->GetGeneratorTarget(&target); - cmComputeLinkInformation* pcli = gt->GetLinkInformation(configName); + cmComputeLinkInformation* pcli = target.GetLinkInformation(configName); if(!pcli) { return; diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 3d02d6a04..2b89c794b 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1017,8 +1017,7 @@ void cmMakefileTargetGenerator::WriteTargetDependRules() << "SET(CMAKE_TARGET_LINKED_INFO_FILES\n"; std::set emitted; const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); - if(cmComputeLinkInformation* cli = - this->GeneratorTarget->GetLinkInformation(cfg)) + if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) { cmComputeLinkInformation::ItemVector const& items = cli->GetItems(); for(cmComputeLinkInformation::ItemVector::const_iterator @@ -1594,8 +1593,7 @@ void cmMakefileTargetGenerator // Loop over all library dependencies. const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); - if(cmComputeLinkInformation* cli = - this->GeneratorTarget->GetLinkInformation(cfg)) + if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) { std::vector const& libDeps = cli->GetDepends(); for(std::vector::const_iterator j = libDeps.begin(); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 0f1015208..5b1dfc881 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -257,7 +257,7 @@ cmNinjaDeps cmNinjaTargetGenerator::ComputeLinkDeps() const return cmNinjaDeps(); cmComputeLinkInformation* cli = - this->GeneratorTarget->GetLinkInformation(this->GetConfigName()); + this->Target->GetLinkInformation(this->GetConfigName()); if(!cli) return cmNinjaDeps(); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 214b09972..be20464da 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -15,6 +15,7 @@ #include "cmSourceFile.h" #include "cmLocalGenerator.h" #include "cmGlobalGenerator.h" +#include "cmComputeLinkInformation.h" #include "cmDocumentCompileDefinitions.h" #include "cmDocumentGeneratorExpressions.h" #include "cmDocumentLocationUndefined.h" @@ -4813,6 +4814,32 @@ std::string cmTarget::CheckCMP0004(std::string const& item) return lib; } +//---------------------------------------------------------------------------- +cmComputeLinkInformation* +cmTarget::GetLinkInformation(const char* config) +{ + // Lookup any existing information for this configuration. + std::map::iterator + i = this->LinkInformation.find(config?config:""); + if(i == this->LinkInformation.end()) + { + // Compute information for this configuration. + cmComputeLinkInformation* info = + new cmComputeLinkInformation(this, config); + if(!info || !info->Compute()) + { + delete info; + info = 0; + } + + // Store the information for this configuration. + std::map::value_type + entry(config?config:"", info); + i = this->LinkInformation.insert(entry).first; + } + return i->second; +} + //---------------------------------------------------------------------------- std::string cmTarget::GetFrameworkDirectory(const char* config) { @@ -4870,6 +4897,29 @@ std::string cmTarget::GetMacContentDirectory(const char* config, return fpath; } +//---------------------------------------------------------------------------- +cmTargetLinkInformationMap +::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived() +{ + // Ideally cmTarget instances should never be copied. However until + // we can make a sweep to remove that, this copy constructor avoids + // allowing the resources (LinkInformation) from getting copied. In + // the worst case this will lead to extra cmComputeLinkInformation + // instances. We also enforce in debug mode that the map be emptied + // when copied. + static_cast(r); + assert(r.empty()); +} + +//---------------------------------------------------------------------------- +cmTargetLinkInformationMap::~cmTargetLinkInformationMap() +{ + for(derived::iterator i = this->begin(); i != this->end(); ++i) + { + delete i->second; + } +} + //---------------------------------------------------------------------------- cmTargetInternalPointer::cmTargetInternalPointer() { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index e442d259a..9efd638f8 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -22,8 +22,18 @@ class cmake; class cmMakefile; class cmSourceFile; class cmGlobalGenerator; +class cmComputeLinkInformation; class cmListFileBacktrace; +struct cmTargetLinkInformationMap: + public std::map +{ + typedef std::map derived; + cmTargetLinkInformationMap() {} + cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r); + ~cmTargetLinkInformationMap(); +}; + class cmTargetInternals; class cmTargetInternalPointer { @@ -392,6 +402,8 @@ public: std::string GetInstallNameDirForInstallTree(const char* config, bool for_xcode = false); + cmComputeLinkInformation* GetLinkInformation(const char* config); + // Get the properties cmPropertyMap &GetProperties() { return this->Properties; }; @@ -584,6 +596,8 @@ private: ImportInfo const* GetImportInfo(const char* config); void ComputeImportInfo(std::string const& desired_config, ImportInfo& info); + cmTargetLinkInformationMap LinkInformation; + bool ComputeLinkInterface(const char* config, LinkInterface& iface); void ComputeLinkImplementation(const char* config, diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index d3b395098..ec9c125a9 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1430,7 +1430,7 @@ cmVisualStudio10TargetGenerator::ComputeLinkOptions(std::string const& config) // Replace spaces in libs with ; cmSystemTools::ReplaceString(libs, " ", ";"); cmComputeLinkInformation* pcli = - this->GeneratorTarget->GetLinkInformation(config.c_str()); + this->Target->GetLinkInformation(config.c_str()); if(!pcli) { cmSystemTools::Error From 078e35defbe6e0ee3b216dd2e83ca85d49920fc3 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 21 Nov 2012 10:23:17 -0500 Subject: [PATCH 009/170] NMake: Add a test to demonstrate EmptyDepends issue (#13392) --- Tests/CMakeLists.txt | 2 ++ Tests/EmptyDepends/CMakeLists.txt | 15 +++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 Tests/EmptyDepends/CMakeLists.txt diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index f2a198cff..7dc26439f 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -573,6 +573,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommand") + ADD_TEST_MACRO(EmptyDepends ${CMAKE_CTEST_COMMAND}) + add_test(CustomCommandWorkingDirectory ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/CustomCommandWorkingDirectory" diff --git a/Tests/EmptyDepends/CMakeLists.txt b/Tests/EmptyDepends/CMakeLists.txt new file mode 100644 index 000000000..a24382cea --- /dev/null +++ b/Tests/EmptyDepends/CMakeLists.txt @@ -0,0 +1,15 @@ +cmake_minimum_required(VERSION 2.8) +project(EmptyDepends) + +include(CTest) + +set(extra_dep) + +add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/qrc_my.cxx + COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_BINARY_DIR}/qrc_my.cxx" + DEPENDS "${extra_dep}" "${CMAKE_BINARY_DIR}/my.qrc") + +add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/my.qrc + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/my.qrc) + +add_library(qrc SHARED ${CMAKE_BINARY_DIR}/qrc_my.cxx) From 7ae7d6650344f7a36216af8424abbf0b834688d1 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 21 Nov 2012 11:23:14 -0500 Subject: [PATCH 010/170] NMake: Fix problem with empty DEPENDS args (#13392) add_custom_command can have empty DEPENDS arguments, which was triggering invalid makefile generation for the NMake Makefiles generator. We were mistakenly emitting the build directory appended with "/" plus the empty string... which was then translated to a string ending in \" in build.make... which nmake choked on. The solution is not to emit any dependency when the input DEPENDS is the empty string. Return early from GetRealDependency in this empty input case. --- Source/cmLocalGenerator.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 4952a8ce9..d48f43a91 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1875,6 +1875,14 @@ bool cmLocalGenerator::GetRealDependency(const char* inName, // modify the name so stripping down to just the file name should // produce the target name in this case. std::string name = cmSystemTools::GetFilenameName(inName); + + // If the input name is the empty string, there is no real + // dependency. Short-circuit the other checks: + if(name == "") + { + return false; + } + if(cmSystemTools::GetFilenameLastExtension(name) == ".exe") { name = cmSystemTools::GetFilenameWithoutLastExtension(name); From 00e96808aa3729a6b385818643249ea2130cbef1 Mon Sep 17 00:00:00 2001 From: Clemens Heppner Date: Sun, 28 Oct 2012 09:54:26 +0100 Subject: [PATCH 011/170] CMake: source_group needs to check its own regex after its children (#13611) Otherwise, regexes that descend into sub-folders do not get grouped correctly. --- Source/cmSourceGroup.cxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx index 4fd98518b..f09976f44 100644 --- a/Source/cmSourceGroup.cxx +++ b/Source/cmSourceGroup.cxx @@ -182,10 +182,6 @@ cmSourceGroup *cmSourceGroup::MatchChildrenRegex(const char *name) std::vector::iterator end = this->Internal->GroupChildren.end(); - if(this->MatchesRegex(name)) - { - return this; - } for(;iter!=end; ++iter) { cmSourceGroup *result = iter->MatchChildrenRegex(name); @@ -194,6 +190,11 @@ cmSourceGroup *cmSourceGroup::MatchChildrenRegex(const char *name) return result; } } + if(this->MatchesRegex(name)) + { + return this; + } + return 0; } From 51af1da3d21b95540888d585fccdaa8d68d1fdd8 Mon Sep 17 00:00:00 2001 From: David Cole Date: Fri, 23 Nov 2012 11:41:58 -0500 Subject: [PATCH 012/170] CMake: Remove "/STACK:10000000" from default linker flags (#12437) Modern apps that use multiple threads do NOT want 10 Megabytes of RAM per thread being used for each thread's stack... Just leave off the /STACK: argument, and let the compiler use a reasonable default value for the stack size. If existing single-threaded apps require the /STACK: argument because they do need a very large stack size, they can add the flag in their own CMakeLists files. --- Modules/Platform/Windows-Intel.cmake | 2 +- Modules/Platform/Windows-MSVC.cmake | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/Platform/Windows-Intel.cmake b/Modules/Platform/Windows-Intel.cmake index 58da8c56d..8a9d630f6 100644 --- a/Modules/Platform/Windows-Intel.cmake +++ b/Modules/Platform/Windows-Intel.cmake @@ -50,7 +50,7 @@ elseif(MSVC_CXX_ARCHITECTURE_ID) elseif(MSVC_Fortran_ARCHITECTURE_ID) set(_MACHINE_ARCH_FLAG "/machine:${MSVC_Fortran_ARCHITECTURE_ID}") endif() -set (CMAKE_EXE_LINKER_FLAGS_INIT "/STACK:10000000 /INCREMENTAL:YES ${_MACHINE_ARCH_FLAG}") +set (CMAKE_EXE_LINKER_FLAGS_INIT "/INCREMENTAL:YES ${_MACHINE_ARCH_FLAG}") set (CMAKE_EXE_LINKER_FLAGS_DEBUG_INIT "/debug") set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO_INIT "/debug") diff --git a/Modules/Platform/Windows-MSVC.cmake b/Modules/Platform/Windows-MSVC.cmake index 32dd54631..5cbf9ee6b 100644 --- a/Modules/Platform/Windows-MSVC.cmake +++ b/Modules/Platform/Windows-MSVC.cmake @@ -165,7 +165,7 @@ set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}") # executable linker flags set (CMAKE_LINK_DEF_FILE_FLAG "/DEF:") -# set the stack size and the machine type +# set the machine type set(_MACHINE_ARCH_FLAG ${MSVC_C_ARCHITECTURE_ID}) if(NOT _MACHINE_ARCH_FLAG) set(_MACHINE_ARCH_FLAG ${MSVC_CXX_ARCHITECTURE_ID}) @@ -178,7 +178,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "WindowsCE") endif() endif() set (CMAKE_EXE_LINKER_FLAGS_INIT - "${CMAKE_EXE_LINKER_FLAGS_INIT} /STACK:10000000 /machine:${_MACHINE_ARCH_FLAG}") + "${CMAKE_EXE_LINKER_FLAGS_INIT} /machine:${_MACHINE_ARCH_FLAG}") # add /debug and /INCREMENTAL:YES to DEBUG and RELWITHDEBINFO also add pdbtype # on versions that support it From 6aa02d24c74b249a1883ccdb9a87de86368c6575 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sun, 25 Nov 2012 00:01:07 -0500 Subject: [PATCH 013/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 60514b70e..42b4807bd 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 20121124) +set(CMake_VERSION_TWEAK 20121125) #set(CMake_VERSION_RC 1) From e5748521206e1f240d495d1ec3b2ccd31611f081 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Mon, 26 Nov 2012 00:01:06 -0500 Subject: [PATCH 014/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 42b4807bd..b77883e30 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 20121125) +set(CMake_VERSION_TWEAK 20121126) #set(CMake_VERSION_RC 1) From a7be25341836e928f471f5fd79a1c3473e491eb6 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Sun, 25 Nov 2012 15:15:34 +0100 Subject: [PATCH 015/170] FindGettext: fix overwriting result with empty variable (#13691) Remove stray line left by commit 656ab19b (FindGettext: remove code duplicating FPHSA checks, 2012-09-08). --- Modules/FindGettext.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/Modules/FindGettext.cmake b/Modules/FindGettext.cmake index f1c78ae6d..1a6bd39dd 100644 --- a/Modules/FindGettext.cmake +++ b/Modules/FindGettext.cmake @@ -209,5 +209,3 @@ function(GETTEXT_PROCESS_PO_FILES _lang) add_dependencies(pofiles ${uniqueTargetName}) endfunction() - -set(GETTEXT_FOUND ${Gettext_FOUND}) From f180b24ef43d48fcec265656ee73ab9130fe39bd Mon Sep 17 00:00:00 2001 From: Alan Witkowski Date: Mon, 26 Nov 2012 09:08:14 -0500 Subject: [PATCH 016/170] FindBullet: Search in per-config dirs on Windows (#13738) Bullet for windows installs in these per-config paths. --- Modules/FindBullet.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/FindBullet.cmake b/Modules/FindBullet.cmake index 1c4a9dec4..1a27fc32b 100644 --- a/Modules/FindBullet.cmake +++ b/Modules/FindBullet.cmake @@ -33,6 +33,8 @@ macro(_FIND_BULLET_LIBRARY _var) ${ARGN} HINTS ${BULLET_ROOT} + ${BULLET_ROOT}/lib/Release + ${BULLET_ROOT}/lib/Debug ${BULLET_ROOT}/out/release8/libs ${BULLET_ROOT}/out/debug8/libs PATH_SUFFIXES lib From d41d4d3d61275414958831bc3d5a45f74b1f2339 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Tue, 20 Nov 2012 11:33:34 +0100 Subject: [PATCH 017/170] VS: Add CMAKE_VS_PLATFORM_NAME definition to cmMakefile When adding more platforms to the Visual Studio generators a simple regular expressing can not handle all cases anymore. This new define holds the name of the Visual Studio target platform. --- Modules/CMakeDetermineCompilerId.cmake | 13 +++++++------ Source/cmGlobalVisualStudio8Generator.cxx | 7 +++++++ Source/cmGlobalVisualStudio8Generator.h | 2 ++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index dd2bcd2dd..05430a6a5 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -107,11 +107,14 @@ Id flags: ${testflags} ") # Compile the compiler identification source. - if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)( .NET)?( 200[358])? *((Win64|IA64|ARM))?") + if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)") set(vs_version ${CMAKE_MATCH_1}) - set(vs_arch ${CMAKE_MATCH_4}) + set(id_arch ${CMAKE_VS_PLATFORM_NAME}) set(id_lang "${lang}") set(id_cl cl.exe) + if(NOT id_arch) + set(id_arch Win32) + endif() if(NOT "${vs_version}" VERSION_LESS 10) set(v 10) set(ext vcxproj) @@ -123,16 +126,14 @@ Id flags: ${testflags} set(v 6) set(ext dsp) endif() - if("${vs_arch}" STREQUAL "Win64") + if("${id_arch}" STREQUAL "x64") set(id_machine_10 MachineX64) - set(id_arch x64) - elseif("${vs_arch}" STREQUAL "IA64") + elseif("${id_arch}" STREQUAL "Itanium") set(id_machine_10 MachineIA64) set(id_arch ia64) else() set(id_machine_6 x86) set(id_machine_10 MachineX86) - set(id_arch Win32) endif() if(CMAKE_VS_PLATFORM_TOOLSET) set(id_toolset "${CMAKE_VS_PLATFORM_TOOLSET}") diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 855727b7b..8ab97b5b8 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -98,6 +98,13 @@ cmLocalGenerator *cmGlobalVisualStudio8Generator::CreateLocalGenerator() return lg; } +//---------------------------------------------------------------------------- +void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf) +{ + cmGlobalVisualStudio71Generator::AddPlatformDefinitions(mf); + mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName()); +} + //---------------------------------------------------------------------------- // ouput standard header for dsw file void cmGlobalVisualStudio8Generator::WriteSLNHeader(std::ostream& fout) diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index f68bb9ee1..a39c26d91 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -38,6 +38,8 @@ public: ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); + virtual void AddPlatformDefinitions(cmMakefile* mf); + /** * Override Configure and Generate to add the build-system check * target. From 332dc09d0de3b427eac8a36c3b0c1339daf7179c Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Tue, 20 Nov 2012 12:18:43 +0100 Subject: [PATCH 018/170] VS: Add static method to get the base of the registry --- Source/cmGlobalVisualStudioGenerator.cxx | 11 +++++++++-- Source/cmGlobalVisualStudioGenerator.h | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index a51735154..67d6f8075 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -32,10 +32,17 @@ cmGlobalVisualStudioGenerator::~cmGlobalVisualStudioGenerator() //---------------------------------------------------------------------------- std::string cmGlobalVisualStudioGenerator::GetRegistryBase() +{ + return cmGlobalVisualStudioGenerator::GetRegistryBase( + this->GetIDEVersion()); +} + +//---------------------------------------------------------------------------- +std::string cmGlobalVisualStudioGenerator::GetRegistryBase( + const char* version) { std::string key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\"; - key += this->GetIDEVersion(); - return key; + return key + version; } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index 7258e313e..65ba24fcd 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -65,6 +65,9 @@ public: /** Get the top-level registry key for this VS version. */ std::string GetRegistryBase(); + /** Get the top-level registry key for the given VS version. */ + static std::string GetRegistryBase(const char* version); + /** Return true if the generated build tree may contain multiple builds. i.e. "Can I build Debug and Release in the same tree?" */ virtual bool IsMultiConfig() { return true; } From 102521b6b3172e32b2985c53eadc6eaebe90245d Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Tue, 20 Nov 2012 11:37:32 +0100 Subject: [PATCH 019/170] VS: Change variable type of ArchitectureId from const char* to string --- Source/cmGlobalVisualStudio10Generator.cxx | 3 +-- Source/cmGlobalVisualStudio8Generator.cxx | 4 ++-- Source/cmGlobalVisualStudioGenerator.cxx | 4 ++-- Source/cmGlobalVisualStudioGenerator.h | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index c218c97ec..d9920366b 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -144,8 +144,7 @@ void cmGlobalVisualStudio10Generator ::EnableLanguage(std::vectorconst & lang, cmMakefile *mf, bool optional) { - if(!strcmp(this->ArchitectureId, "Itanium") || - !strcmp(this->ArchitectureId, "x64")) + if(this->ArchitectureId == "Itanium" || this->ArchitectureId == "x64") { if(this->IsExpressEdition() && !this->Find64BitTools(mf)) { diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 8ab97b5b8..be1bedc76 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -79,11 +79,11 @@ cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator( //---------------------------------------------------------------------------- const char* cmGlobalVisualStudio8Generator::GetPlatformName() const { - if (!strcmp(this->ArchitectureId, "X86")) + if (this->ArchitectureId == "X86") { return "Win32"; } - return this->ArchitectureId; + return this->ArchitectureId.c_str(); } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx index 67d6f8075..808664d44 100644 --- a/Source/cmGlobalVisualStudioGenerator.cxx +++ b/Source/cmGlobalVisualStudioGenerator.cxx @@ -499,8 +499,8 @@ void cmGlobalVisualStudioGenerator::ComputeVSTargetDepends(cmTarget& target) //---------------------------------------------------------------------------- void cmGlobalVisualStudioGenerator::AddPlatformDefinitions(cmMakefile* mf) { - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId); + mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId.c_str()); + mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId.c_str()); if(this->AdditionalPlatformDefinition) { diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index 65ba24fcd..f9715ab9f 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -101,7 +101,7 @@ protected: std::string GetUtilityDepend(cmTarget* target); typedef std::map UtilityDependsMap; UtilityDependsMap UtilityDepends; - const char* ArchitectureId; + std::string ArchitectureId; const char* AdditionalPlatformDefinition; private: From 6920fed652339ca6b45d98769c88a8c341e507b8 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Tue, 20 Nov 2012 12:16:09 +0100 Subject: [PATCH 020/170] VS: Change variable type of Name from const char* to string --- Source/cmGlobalVisualStudio8Generator.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index a39c26d91..8163d6a3e 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -28,7 +28,7 @@ public: static cmGlobalGeneratorFactory* NewFactory(); ///! Get the name for the generator. - virtual const char* GetName() const {return this->Name;} + virtual const char* GetName() const {return this->Name.c_str();} const char* GetPlatformName() const; @@ -82,7 +82,7 @@ protected: virtual void WriteProjectDepends(std::ostream& fout, const char* name, const char* path, cmTarget &t); - const char* Name; + std::string Name; private: class Factory; From 2118a2016f69f3c7cdb711eaaa2f6ca9374103ce Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Tue, 20 Nov 2012 12:38:06 +0100 Subject: [PATCH 021/170] VS: Support setting correct subsystem and entry point for WinCE WinCE has only one SubSystem. So the WIN32_EXECUTABLE property must be handled via the EntryPointSymbol in the vcproj files. --- Source/cmGlobalVisualStudioGenerator.h | 3 +++ Source/cmLocalVisualStudio7Generator.cxx | 20 +++++++++++++++++--- Source/cmLocalVisualStudio7Generator.h | 1 + 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Source/cmGlobalVisualStudioGenerator.h b/Source/cmGlobalVisualStudioGenerator.h index f9715ab9f..9d811706b 100644 --- a/Source/cmGlobalVisualStudioGenerator.h +++ b/Source/cmGlobalVisualStudioGenerator.h @@ -72,6 +72,9 @@ public: i.e. "Can I build Debug and Release in the same tree?" */ virtual bool IsMultiConfig() { return true; } + /** Return true if building for Windows CE */ + virtual bool TargetsWindowsCE() const { return false; } + class TargetSet: public std::set {}; struct TargetCompare { diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index d954a5290..665ef3b35 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -229,6 +229,9 @@ void cmLocalVisualStudio7Generator this->FortranProject = static_cast(this->GlobalGenerator) ->TargetIsFortranOnly(target); + this->WindowsCEProject = + static_cast(this->GlobalGenerator) + ->TargetsWindowsCE(); // Intel Fortran for VS10 uses VS9 format ".vfproj" files. VSVersion realVersion = this->Version; @@ -1173,6 +1176,8 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, cmComputeLinkInformation& cli = *pcli; const char* linkLanguage = cli.GetLinkLanguage(); + bool isWin32Executable = target.GetPropertyAsBool("WIN32_EXECUTABLE"); + // Compute the variable name to lookup standard libraries for this // language. std::string standardLibsVar = "CMAKE_"; @@ -1220,15 +1225,24 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout, { fout << "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n"; } - if ( target.GetPropertyAsBool("WIN32_EXECUTABLE") ) + if ( this->WindowsCEProject ) + { + fout << "\t\t\t\tSubSystem=\"9\"\n" + << "\t\t\t\tEntryPointSymbol=\"" + << (isWin32Executable ? "WinMainCRTStartup" : "mainACRTStartup") + << "\"\n"; + } + else if ( this->FortranProject ) { fout << "\t\t\t\tSubSystem=\"" - << (this->FortranProject? "subSystemWindows" : "2") << "\"\n"; + << (isWin32Executable ? "subSystemWindows" : "subSystemConsole") + << "\"\n"; } else { fout << "\t\t\t\tSubSystem=\"" - << (this->FortranProject? "subSystemConsole" : "1") << "\"\n"; + << (isWin32Executable ? "2" : "1") + << "\"\n"; } std::string stackVar = "CMAKE_"; stackVar += linkLanguage; diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 95db2cc8c..5a1d208ef 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -122,6 +122,7 @@ private: cmVS7FlagTable const* ExtraFlagTable; std::string ModuleDefinitionFile; bool FortranProject; + bool WindowsCEProject; std::string PlatformName; // Win32 or x64 cmLocalVisualStudio7GeneratorInternals* Internal; }; From 37c34d7d7b7b32c0f6c00acbb3375c79e42a5587 Mon Sep 17 00:00:00 2001 From: David Cole Date: Mon, 26 Nov 2012 06:22:52 -0500 Subject: [PATCH 022/170] CMake: Fix infinite loop untarring corrupt tar file Suggested-by: Robert Maynard --- Source/cmSystemTools.cxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 89f03f62c..544f7e43e 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1932,6 +1932,7 @@ bool extract_tar(const char* outFileName, bool verbose, { cmSystemTools::Error("Problem with archive_read_next_header(): ", archive_error_string(a)); + break; } if (verbose && extract) { @@ -1954,6 +1955,7 @@ bool extract_tar(const char* outFileName, bool verbose, cmSystemTools::Error( "Problem with archive_write_disk_set_options(): ", archive_error_string(ext)); + break; } r = archive_write_header(ext, entry); @@ -1963,6 +1965,7 @@ bool extract_tar(const char* outFileName, bool verbose, archive_error_string(ext)); cmSystemTools::Error("Current file:", archive_entry_pathname(entry)); + break; } else { @@ -1972,6 +1975,7 @@ bool extract_tar(const char* outFileName, bool verbose, { cmSystemTools::Error("Problem with archive_write_finish_entry(): ", archive_error_string(ext)); + break; } } } @@ -1982,8 +1986,7 @@ bool extract_tar(const char* outFileName, bool verbose, } archive_read_close(a); archive_read_finish(a); - return true; - + return r == ARCHIVE_EOF || r == ARCHIVE_OK; } } #endif From 1d3b35fd8a59c6f987b4caab17330955dbaf32bc Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 26 Nov 2012 13:04:20 -0500 Subject: [PATCH 023/170] CMake 2.8.10.2 --- ChangeLog.manual | 14 ++++++++++++++ Source/CMakeVersion.cmake | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog.manual b/ChangeLog.manual index aa5534812..90c91629e 100644 --- a/ChangeLog.manual +++ b/ChangeLog.manual @@ -1,3 +1,17 @@ +Changes in CMake 2.8.10.2 (since 2.8.10.1) +---------------------------------------------- +Alex Neundorf (1): + Automoc: fix regression #13667, broken build in phonon + +Brad King (1): + Initialize IMPORTED GLOBAL targets on reconfigure (#13702) + +David Cole (1): + CMake: Fix infinite loop untarring corrupt tar file + +Rolf Eike Beer (1): + FindGettext: fix overwriting result with empty variable (#13691) + Changes in CMake 2.8.10.1 (since 2.8.10) ---------------------------------------------- Brad King (5): diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 29ac436eb..c59c618e2 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 1) +set(CMake_VERSION_TWEAK 2) #set(CMake_VERSION_RC 3) From e593f8a1cf8d8f757e6630148a37dc77cdf8eaf1 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Mon, 26 Nov 2012 20:46:36 +0100 Subject: [PATCH 024/170] FindBISON: Add support for the Win flex-bison distribution Search for win_bison too. --- Modules/FindBISON.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake index a0afd344c..4a3e68c68 100644 --- a/Modules/FindBISON.cmake +++ b/Modules/FindBISON.cmake @@ -47,7 +47,7 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -find_program(BISON_EXECUTABLE bison DOC "path to the bison executable") +find_program(BISON_EXECUTABLE NAMES bison win_bison DOC "path to the bison executable") mark_as_advanced(BISON_EXECUTABLE) if(BISON_EXECUTABLE) From df293368933ce5698f62a359e3f2d244a60c33be Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Mon, 26 Nov 2012 22:22:39 +0100 Subject: [PATCH 025/170] FindFLEX: Add support for the Win flex-bison distribution Search for win_flex too and improve version parsing. --- Modules/FindFLEX.cmake | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Modules/FindFLEX.cmake b/Modules/FindFLEX.cmake index daae94fad..79a3a1e6c 100644 --- a/Modules/FindFLEX.cmake +++ b/Modules/FindFLEX.cmake @@ -63,7 +63,7 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -find_program(FLEX_EXECUTABLE flex DOC "path to the flex executable") +find_program(FLEX_EXECUTABLE NAMES flex win_flex DOC "path to the flex executable") mark_as_advanced(FLEX_EXECUTABLE) find_library(FL_LIBRARY NAMES fl @@ -93,10 +93,12 @@ if(FLEX_EXECUTABLE) else() # older versions of flex printed "/full/path/to/executable version X.Y" # newer versions use "basename(executable) X.Y" - get_filename_component(FLEX_EXE_NAME "${FLEX_EXECUTABLE}" NAME) - string(REGEX REPLACE "^.*${FLEX_EXE_NAME}\"? (version )?([0-9]+[^ ]*)( .*)?$" "\\2" + get_filename_component(FLEX_EXE_NAME_WE "${FLEX_EXECUTABLE}" NAME_WE) + get_filename_component(FLEX_EXE_EXT "${FLEX_EXECUTABLE}" EXT) + string(REGEX REPLACE "^.*${FLEX_EXE_NAME_WE}(${FLEX_EXE_EXT})?\"? (version )?([0-9]+[^ ]*)( .*)?$" "\\3" FLEX_VERSION "${FLEX_version_output}") - unset(FLEX_EXE_NAME) + unset(FLEX_EXE_EXT) + unset(FLEX_EXE_NAME_WE) endif() #============================================================ From b96f6fc2aabed8a77cd45c0f87af7abb6a687576 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 26 Nov 2012 16:44:56 -0500 Subject: [PATCH 026/170] Teach find_(path|file) about Linux multiarch (#13742) Implement support for multiarch include directories as specified here: https://wiki.ubuntu.com/MultiarchCross Generalize the multiarch feature added in commit b41ad3b3 (Teach find_(library|package) about Linux multiarch, 2011-06-08) to the find_path and find_file commands. Teach them to search /include/ whenever they would search /include. --- Source/cmFindBase.cxx | 4 ++-- Source/cmFindPathCommand.cxx | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx index 1de3982f4..7ce003216 100644 --- a/Source/cmFindBase.cxx +++ b/Source/cmFindBase.cxx @@ -360,13 +360,13 @@ void cmFindBase::AddPrefixPaths(std::vector const& in_paths, { dir += "/"; } - if(subdir == "lib") + if(subdir == "include" || subdir == "lib") { const char* arch = this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE"); if(arch && *arch) { - this->AddPathInternal(dir+"lib/"+arch, pathType); + this->AddPathInternal(dir+subdir+"/"+arch, pathType); } } std::string add = dir + subdir; diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx index 952492463..6a432984d 100644 --- a/Source/cmFindPathCommand.cxx +++ b/Source/cmFindPathCommand.cxx @@ -45,8 +45,10 @@ void cmFindPathCommand::GenerateDocumentation() "SEARCH_XXX", "file in a directory"); cmSystemTools::ReplaceString(this->GenericDocumentation, "XXX_SUBDIR", "include"); - cmSystemTools::ReplaceString(this->GenericDocumentation, - "XXX_EXTRA_PREFIX_ENTRY", ""); + cmSystemTools::ReplaceString( + this->GenericDocumentation, + "XXX_EXTRA_PREFIX_ENTRY", + " /include/ if CMAKE_LIBRARY_ARCHITECTURE is set, and\n"); cmSystemTools::ReplaceString(this->GenericDocumentation, "CMAKE_FIND_ROOT_PATH_MODE_XXX", "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE"); From ee96dc76864b899684d62b51edd87d3083e80168 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 26 Nov 2012 22:42:00 +0100 Subject: [PATCH 027/170] Genex: Extract a method to parse parameters. --- Source/cmGeneratorExpressionEvaluator.cxx | 21 ++++++++++++++++++--- Source/cmGeneratorExpressionEvaluator.h | 8 ++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 2e123a4d9..23f641d64 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -677,6 +677,23 @@ std::string GeneratorExpressionContent::Evaluate( } std::vector parameters; + this->EvaluateParameters(node, identifier, context, dagChecker, parameters); + if (context->HadError) + { + return std::string(); + } + + return node->Evaluate(parameters, context, this, dagChecker); +} + +//---------------------------------------------------------------------------- +std::string GeneratorExpressionContent::EvaluateParameters( + const cmGeneratorExpressionNode *node, + const std::string &identifier, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + std::vector ¶meters) const +{ { std::vector >::const_iterator pit = this->ParamChildren.begin(); @@ -732,10 +749,8 @@ std::string GeneratorExpressionContent::Evaluate( { reportError(context, this->GetOriginalExpression(), "$<" + identifier + "> expression requires at least one parameter."); - return std::string(); } - - return node->Evaluate(parameters, context, this, dagChecker); + return std::string(); } //---------------------------------------------------------------------------- diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 04a2acdc6..642a02ee5 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -33,6 +33,7 @@ struct cmGeneratorExpressionContext }; struct cmGeneratorExpressionDAGChecker; +struct cmGeneratorExpressionNode; //---------------------------------------------------------------------------- struct cmGeneratorExpressionEvaluator @@ -117,6 +118,13 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator ~GeneratorExpressionContent(); +private: + std::string EvaluateParameters(const cmGeneratorExpressionNode *node, + const std::string &identifier, + cmGeneratorExpressionContext *context, + cmGeneratorExpressionDAGChecker *dagChecker, + std::vector ¶meters) const; + private: std::vector IdentifierChildren; std::vector > ParamChildren; From da1d9bac63d486d430b0c61ee8d3928f8d09ab26 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 26 Nov 2012 17:01:43 -0500 Subject: [PATCH 028/170] Test find_path multiarch support (#13742) --- Tests/CMakeOnly/CMakeLists.txt | 1 + Tests/CMakeOnly/find_path/CMakeLists.txt | 31 +++++++++++++++++++ .../find_path/include/arch/test1arch.h | 0 Tests/CMakeOnly/find_path/include/test1.h | 0 4 files changed, 32 insertions(+) create mode 100644 Tests/CMakeOnly/find_path/CMakeLists.txt create mode 100644 Tests/CMakeOnly/find_path/include/arch/test1arch.h create mode 100644 Tests/CMakeOnly/find_path/include/test1.h diff --git a/Tests/CMakeOnly/CMakeLists.txt b/Tests/CMakeOnly/CMakeLists.txt index 1b4ebc425..be7ddbc21 100644 --- a/Tests/CMakeOnly/CMakeLists.txt +++ b/Tests/CMakeOnly/CMakeLists.txt @@ -32,6 +32,7 @@ add_CMakeOnly_test(SelectLibraryConfigurations) add_CMakeOnly_test(TargetScope) add_CMakeOnly_test(find_library) +add_CMakeOnly_test(find_path) add_test(CMakeOnly.ProjectInclude ${CMAKE_CMAKE_COMMAND} -DTEST=ProjectInclude diff --git a/Tests/CMakeOnly/find_path/CMakeLists.txt b/Tests/CMakeOnly/find_path/CMakeLists.txt new file mode 100644 index 000000000..0e64ed467 --- /dev/null +++ b/Tests/CMakeOnly/find_path/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 2.8) +project(FindPathTest NONE) + +set(CMAKE_FIND_DEBUG_MODE 1) + +macro(test_find_path expected) + unset(HDR CACHE) + find_path(HDR ${ARGN} + NO_CMAKE_ENVIRONMENT_PATH + NO_SYSTEM_ENVIRONMENT_PATH + ) + if(HDR) + # Convert to relative path for comparison to expected location. + file(RELATIVE_PATH REL_HDR "${CMAKE_CURRENT_SOURCE_DIR}" "${HDR}") + + # Check and report failure. + if(NOT "${REL_HDR}" STREQUAL "${expected}") + message(SEND_ERROR "Header ${expected} found as [${REL_HDR}]") + elseif(CMAKE_FIND_DEBUG_MODE) + message(STATUS "Header ${expected} found as [${REL_HDR}]") + endif() + else() + message(SEND_ERROR "Header ${expected} NOT FOUND") + endif() +endmacro() + +set(CMAKE_SYSTEM_PREFIX_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +set(CMAKE_LIBRARY_ARCHITECTURE arch) + +test_find_path(include NAMES test1.h) +test_find_path(include/arch NAMES test1arch.h) diff --git a/Tests/CMakeOnly/find_path/include/arch/test1arch.h b/Tests/CMakeOnly/find_path/include/arch/test1arch.h new file mode 100644 index 000000000..e69de29bb diff --git a/Tests/CMakeOnly/find_path/include/test1.h b/Tests/CMakeOnly/find_path/include/test1.h new file mode 100644 index 000000000..e69de29bb From 075e0daabc4068f0a67c073dfceaf2796ba0ae15 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Tue, 27 Nov 2012 00:01:05 -0500 Subject: [PATCH 029/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index b77883e30..be8259ddd 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 20121126) +set(CMake_VERSION_TWEAK 20121127) #set(CMake_VERSION_RC 1) From 6fe4fcba787e4e27a4863faa28aa41ae11026d6b Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Tue, 20 Nov 2012 13:12:27 +0100 Subject: [PATCH 030/170] VS: Add parser for WCE.VCPlatform.config to read WinCE platforms Parse the WCE.VCPlatform.config file, which contains the installed WindowsCE SDKs in XML format, and add possibility to generate Visual Studio generators for them. --- Source/CMakeLists.txt | 2 + Source/cmGlobalVisualStudio8Generator.cxx | 55 ++++++-- Source/cmGlobalVisualStudio8Generator.h | 6 + Source/cmGlobalVisualStudio9Generator.cxx | 63 +++++++--- Source/cmGlobalVisualStudio9Generator.h | 1 + Source/cmVisualStudioWCEPlatformParser.cxx | 139 +++++++++++++++++++++ Source/cmVisualStudioWCEPlatformParser.h | 55 ++++++++ 7 files changed, 297 insertions(+), 24 deletions(-) create mode 100644 Source/cmVisualStudioWCEPlatformParser.cxx create mode 100644 Source/cmVisualStudioWCEPlatformParser.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index fa174bc2f..4de20c900 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -353,6 +353,8 @@ if (WIN32) cmLocalVisualStudio7Generator.h cmLocalVisualStudioGenerator.cxx cmLocalVisualStudioGenerator.h + cmVisualStudioWCEPlatformParser.h + cmVisualStudioWCEPlatformParser.cxx cmWin32ProcessExecution.cxx cmWin32ProcessExecution.h ) diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index be1bedc76..39b31a0c7 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -13,32 +13,57 @@ #include "cmGlobalVisualStudio8Generator.h" #include "cmLocalVisualStudio7Generator.h" #include "cmMakefile.h" +#include "cmVisualStudioWCEPlatformParser.h" #include "cmake.h" #include "cmGeneratedFileStream.h" -static const char vs8Win32generatorName[] = "Visual Studio 8 2005"; -static const char vs8Win64generatorName[] = "Visual Studio 8 2005 Win64"; +static const char vs8generatorName[] = "Visual Studio 8 2005"; class cmGlobalVisualStudio8Generator::Factory : public cmGlobalGeneratorFactory { public: virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const { - if(!strcmp(name, vs8Win32generatorName)) + if(strstr(name, vs8generatorName) != name) + { + return 0; + } + + const char* p = name + sizeof(vs8generatorName) - 1; + if(p[0] == '\0') { return new cmGlobalVisualStudio8Generator( - vs8Win32generatorName, NULL, NULL); + name, NULL, NULL); } - if(!strcmp(name, vs8Win64generatorName)) + + if(p[0] != ' ') + { + return 0; + } + + ++p; + + if(!strcmp(p, "Win64")) { return new cmGlobalVisualStudio8Generator( - vs8Win64generatorName, "x64", "CMAKE_FORCE_WIN64"); + name, "x64", "CMAKE_FORCE_WIN64"); } - return 0; + + cmVisualStudioWCEPlatformParser parser(p); + parser.ParseVersion("8.0"); + if (!parser.Found()) + { + return 0; + } + + cmGlobalVisualStudio8Generator* ret = new cmGlobalVisualStudio8Generator( + name, parser.GetArchitectureFamily(), NULL); + ret->WindowsCEVersion = parser.GetOSVersion(); + return ret; } virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = "Visual Studio 8 2005"; + entry.Name = vs8generatorName; entry.Brief = "Generates Visual Studio 8 2005 project files."; entry.Full = "It is possible to append a space followed by the platform name " @@ -48,8 +73,18 @@ public: } virtual void GetGenerators(std::vector& names) const { - names.push_back(vs8Win32generatorName); - names.push_back(vs8Win64generatorName); } + names.push_back(vs8generatorName); + names.push_back(vs8generatorName + std::string(" Win64")); + cmVisualStudioWCEPlatformParser parser; + parser.ParseVersion("8.0"); + const std::vector& availablePlatforms = + parser.GetAvailablePlatforms(); + for(std::vector::const_iterator i = + availablePlatforms.begin(); i != availablePlatforms.end(); ++i) + { + names.push_back("Visual Studio 8 2005 " + *i); + } + } }; //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 8163d6a3e..08674cda3 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -64,6 +64,10 @@ public: LinkLibraryDependencies and link to .sln dependencies. */ virtual bool NeedLinkLibraryDependencies(cmTarget& target); + /** Return true if building for Windows CE */ + virtual bool TargetsWindowsCE() const { + return !this->WindowsCEVersion.empty(); } + protected: virtual const char* GetIDEVersion() { return "8.0"; } @@ -83,8 +87,10 @@ protected: const char* path, cmTarget &t); std::string Name; + std::string WindowsCEVersion; private: class Factory; + friend class Factory; }; #endif diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx index 87599efd3..dbe093e4a 100644 --- a/Source/cmGlobalVisualStudio9Generator.cxx +++ b/Source/cmGlobalVisualStudio9Generator.cxx @@ -13,37 +13,62 @@ #include "cmGlobalVisualStudio9Generator.h" #include "cmLocalVisualStudio7Generator.h" #include "cmMakefile.h" +#include "cmVisualStudioWCEPlatformParser.h" #include "cmake.h" -static const char vs9Win32generatorName[] = "Visual Studio 9 2008"; -static const char vs9Win64generatorName[] = "Visual Studio 8 2005 Win64"; -static const char vs9IA64generatorName[] = "Visual Studio 9 2008 IA64"; +static const char vs9generatorName[] = "Visual Studio 9 2008"; class cmGlobalVisualStudio9Generator::Factory : public cmGlobalGeneratorFactory { public: virtual cmGlobalGenerator* CreateGlobalGenerator(const char* name) const { - if(!strcmp(name, vs9Win32generatorName)) + if(strstr(name, vs9generatorName) != name) + { + return 0; + } + + const char* p = name + sizeof(vs9generatorName) - 1; + if(p[0] == '\0') { return new cmGlobalVisualStudio9Generator( - vs9Win32generatorName, NULL, NULL); + name, NULL, NULL); } - if(!strcmp(name, vs9Win64generatorName)) + + if(p[0] != ' ') + { + return 0; + } + + ++p; + + if(!strcmp(p, "IA64")) { return new cmGlobalVisualStudio9Generator( - vs9Win64generatorName, "x64", "CMAKE_FORCE_WIN64"); + name, "Itanium", "CMAKE_FORCE_IA64"); } - if(!strcmp(name, vs9IA64generatorName)) + + if(!strcmp(p, "Win64")) { return new cmGlobalVisualStudio9Generator( - vs9IA64generatorName, "Itanium", "CMAKE_FORCE_IA64"); + name, "x64", "CMAKE_FORCE_WIN64"); } - return 0; + + cmVisualStudioWCEPlatformParser parser(p); + parser.ParseVersion("9.0"); + if (!parser.Found()) + { + return 0; + } + + cmGlobalVisualStudio9Generator* ret = new cmGlobalVisualStudio9Generator( + name, parser.GetArchitectureFamily(), NULL); + ret->WindowsCEVersion = parser.GetOSVersion(); + return ret; } virtual void GetDocumentation(cmDocumentationEntry& entry) const { - entry.Name = "Visual Studio 9 2008"; + entry.Name = vs9generatorName; entry.Brief = "Generates Visual Studio 9 2008 project files."; entry.Full = "It is possible to append a space followed by the platform name " @@ -53,9 +78,19 @@ public: } virtual void GetGenerators(std::vector& names) const { - names.push_back(vs9Win32generatorName); - names.push_back(vs9Win64generatorName); - names.push_back(vs9IA64generatorName); } + names.push_back(vs9generatorName); + names.push_back(vs9generatorName + std::string(" Win64")); + names.push_back(vs9generatorName + std::string(" IA64")); + cmVisualStudioWCEPlatformParser parser; + parser.ParseVersion("9.0"); + const std::vector& availablePlatforms = + parser.GetAvailablePlatforms(); + for(std::vector::const_iterator i = + availablePlatforms.begin(); i != availablePlatforms.end(); ++i) + { + names.push_back("Visual Studio 9 2008 " + *i); + } + } }; //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudio9Generator.h b/Source/cmGlobalVisualStudio9Generator.h index f05d3773d..1310a93ac 100644 --- a/Source/cmGlobalVisualStudio9Generator.h +++ b/Source/cmGlobalVisualStudio9Generator.h @@ -55,5 +55,6 @@ protected: virtual const char* GetIDEVersion() { return "9.0"; } private: class Factory; + friend class Factory; }; #endif diff --git a/Source/cmVisualStudioWCEPlatformParser.cxx b/Source/cmVisualStudioWCEPlatformParser.cxx new file mode 100644 index 000000000..0afcf678e --- /dev/null +++ b/Source/cmVisualStudioWCEPlatformParser.cxx @@ -0,0 +1,139 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmVisualStudioWCEPlatformParser.h" +#include "cmGlobalVisualStudioGenerator.h" +#include "cmXMLParser.h" + +int cmVisualStudioWCEPlatformParser::ParseVersion(const char* version) +{ + std::string vskey = cmGlobalVisualStudioGenerator::GetRegistryBase(version); + vskey += "\\Setup\\VS;ProductDir"; + + std::string vsInstallPath; + if(!cmSystemTools::ReadRegistryValue(vskey.c_str(), vsInstallPath)) + { + return 0; + } + cmSystemTools::ConvertToUnixSlashes(vsInstallPath); + + const std::string configFilename = + vsInstallPath + "/VC/vcpackages/WCE.VCPlatform.config"; + + return this->ParseFile(configFilename.c_str()); +} + +std::string cmVisualStudioWCEPlatformParser::GetOSVersion() const +{ + if (this->OSMinorVersion.empty()) + { + return OSMajorVersion; + } + + return OSMajorVersion + "." + OSMinorVersion; +} + +const char* cmVisualStudioWCEPlatformParser::GetArchitectureFamily() const +{ + std::map::const_iterator it = + this->Macros.find("ARCHFAM"); + if (it != this->Macros.end()) + { + return it->second.c_str(); + } + + return 0; +} + +void cmVisualStudioWCEPlatformParser::StartElement(const char* name, + const char** attributes) +{ + if(this->FoundRequiredName) + { + return; + } + + this->CharacterData = ""; + + if(strcmp(name, "PlatformData") == 0) + { + this->PlatformName = ""; + this->OSMajorVersion = ""; + this->OSMinorVersion = ""; + this->Macros.clear(); + } + + if(strcmp(name, "Macro") == 0) + { + std::string macroName; + std::string macroValue; + + for(const char** attr = attributes; *attr; attr += 2) + { + if(strcmp(attr[0], "Name") == 0) + { + macroName = attr[1]; + } + else if(strcmp(attr[0], "Value") == 0) + { + macroValue = attr[1]; + } + } + + if(!macroName.empty()) + { + this->Macros[macroName] = macroValue; + } + } +} + +void cmVisualStudioWCEPlatformParser::EndElement(const char* name) +{ + if(!this->RequiredName) + { + if(strcmp(name, "PlatformName") == 0) + { + this->AvailablePlatforms.push_back(this->CharacterData); + } + return; + } + + if(this->FoundRequiredName) + { + return; + } + + if(strcmp(name, "PlatformName") == 0) + { + this->PlatformName = this->CharacterData; + } + else if(strcmp(name, "OSMajorVersion") == 0) + { + this->OSMajorVersion = this->CharacterData; + } + else if(strcmp(name, "OSMinorVersion") == 0) + { + this->OSMinorVersion = this->CharacterData; + } + else if(strcmp(name, "Platform") == 0) + { + if(this->PlatformName == this->RequiredName) + { + this->FoundRequiredName = true; + } + } +} + +void cmVisualStudioWCEPlatformParser::CharacterDataHandler(const char* data, + int length) +{ + this->CharacterData.append(data, length); +} diff --git a/Source/cmVisualStudioWCEPlatformParser.h b/Source/cmVisualStudioWCEPlatformParser.h new file mode 100644 index 000000000..28061fd23 --- /dev/null +++ b/Source/cmVisualStudioWCEPlatformParser.h @@ -0,0 +1,55 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmVisualStudioWCEPlatformParser_h +#define cmVisualStudioWCEPlatformParser_h +#include "cmStandardIncludes.h" + +#include "cmXMLParser.h" + +// This class is used to parse XML with configuration +// of installed SDKs in system +class cmVisualStudioWCEPlatformParser : public cmXMLParser +{ +public: + cmVisualStudioWCEPlatformParser(const char* name = NULL) + : RequiredName(name) + , FoundRequiredName(false) + { + } + + int ParseVersion(const char* version); + + bool Found() const {return this->FoundRequiredName;} + const char* GetArchitectureFamily() const; + std::string GetOSVersion() const; + const std::vector& GetAvailablePlatforms() const { + return this->AvailablePlatforms; } + +protected: + virtual void StartElement(const char* name, const char** attributes); + void EndElement(const char* name); + void CharacterDataHandler(const char* data, int length); + +private: + std::string CharacterData; + + std::string PlatformName; + std::string OSMajorVersion; + std::string OSMinorVersion; + std::map Macros; + std::vector AvailablePlatforms; + + const char* RequiredName; + bool FoundRequiredName; +}; + +#endif From 038df9e49e6fcb54d6f6a1bcfb09f6a0e5ec0c2e Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Tue, 20 Nov 2012 13:16:36 +0100 Subject: [PATCH 031/170] VS: Allow setting the name of the target platform Since the name for a target platform is independent of its cpu architecture an additional option is required to set it correctly. --- Source/cmGlobalVisualStudio8Generator.cxx | 5 +++++ Source/cmGlobalVisualStudio8Generator.h | 1 + Source/cmGlobalVisualStudio9Generator.cxx | 1 + 3 files changed, 7 insertions(+) diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 39b31a0c7..a482d4695 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -58,6 +58,7 @@ public: cmGlobalVisualStudio8Generator* ret = new cmGlobalVisualStudio8Generator( name, parser.GetArchitectureFamily(), NULL); + ret->PlatformName = p; ret->WindowsCEVersion = parser.GetOSVersion(); return ret; } @@ -114,6 +115,10 @@ cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator( //---------------------------------------------------------------------------- const char* cmGlobalVisualStudio8Generator::GetPlatformName() const { + if (!this->PlatformName.empty()) + { + return this->PlatformName.c_str(); + } if (this->ArchitectureId == "X86") { return "Win32"; diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 08674cda3..4dd2b4ba2 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -87,6 +87,7 @@ protected: const char* path, cmTarget &t); std::string Name; + std::string PlatformName; std::string WindowsCEVersion; private: diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx index dbe093e4a..2082384e6 100644 --- a/Source/cmGlobalVisualStudio9Generator.cxx +++ b/Source/cmGlobalVisualStudio9Generator.cxx @@ -63,6 +63,7 @@ public: cmGlobalVisualStudio9Generator* ret = new cmGlobalVisualStudio9Generator( name, parser.GetArchitectureFamily(), NULL); + ret->PlatformName = p; ret->WindowsCEVersion = parser.GetOSVersion(); return ret; } From 40c36c9f7bd101185b06ddf2aee079ccbe7634d3 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Tue, 20 Nov 2012 13:37:50 +0100 Subject: [PATCH 032/170] VS: Make DetermineCompilerId working with WinCE too Add a dummy mainCRTStartup() function, since the linker searches for it instead of main() and set the CMAKE_SYSTEM_* variables depending on the MSVC_C_ARCHITECTURE_ID and CMAKE_VS_WINCE_VERSION variables. --- Modules/CMakeCCompilerId.c.in | 4 ++++ Modules/CMakeCXXCompilerId.cpp.in | 4 ++++ Modules/CMakeDetermineCompilerId.cmake | 3 +++ Modules/CMakeDetermineSystem.cmake | 6 ++++++ Modules/CompilerId/VS-7.vcproj.in | 2 +- Source/cmGlobalVisualStudio8Generator.cxx | 6 ++++++ 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index 2d76c7a34..3d1380c6d 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -228,3 +228,7 @@ int main(int argc, char* argv[]) return require; } #endif + +#ifdef ADD_MAINCRTSTARTUP +void mainCRTStartup() {} +#endif diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index 5e70a4196..142a5c5ab 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -210,3 +210,7 @@ int main(int argc, char* argv[]) (void)argv; return require; } + +#ifdef ADD_MAINCRTSTARTUP +extern "C" void mainCRTStartup() {} +#endif diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 05430a6a5..43469eaad 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -140,6 +140,9 @@ Id flags: ${testflags} else() set(id_toolset "") endif() + if(CMAKE_VS_WINCE_VERSION) + set(id_definitions "ADD_MAINCRTSTARTUP") + endif() if("${CMAKE_MAKE_PROGRAM}" MATCHES "[Mm][Ss][Bb][Uu][Ii][Ll][Dd]") set(build /p:Configuration=Debug /p:Platform=@id_arch@ /p:VisualStudioVersion=${vs_version}.0) elseif("${CMAKE_MAKE_PROGRAM}" MATCHES "[Mm][Ss][Dd][Ee][Vv]") diff --git a/Modules/CMakeDetermineSystem.cmake b/Modules/CMakeDetermineSystem.cmake index cd3344756..c7f9c32a7 100644 --- a/Modules/CMakeDetermineSystem.cmake +++ b/Modules/CMakeDetermineSystem.cmake @@ -106,6 +106,12 @@ if(CMAKE_SYSTEM_NAME) set(CMAKE_CROSSCOMPILING TRUE) endif() set(PRESET_CMAKE_SYSTEM_NAME TRUE) +elseif(CMAKE_VS_WINCE_VERSION) + set(CMAKE_SYSTEM_NAME "WindowsCE") + set(CMAKE_SYSTEM_VERSION "${CMAKE_VS_WINCE_VERSION}") + set(CMAKE_SYSTEM_PROCESSOR "${MSVC_C_ARCHITECTURE_ID}") + set(CMAKE_CROSSCOMPILING TRUE) + set(PRESET_CMAKE_SYSTEM_NAME TRUE) else() set(CMAKE_SYSTEM_NAME "${CMAKE_HOST_SYSTEM_NAME}") set(CMAKE_SYSTEM_VERSION "${CMAKE_HOST_SYSTEM_VERSION}") diff --git a/Modules/CompilerId/VS-7.vcproj.in b/Modules/CompilerId/VS-7.vcproj.in index bcb18a5b7..b1449e4ac 100644 --- a/Modules/CompilerId/VS-7.vcproj.in +++ b/Modules/CompilerId/VS-7.vcproj.in @@ -24,7 +24,7 @@ AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName()); + + if(this->TargetsWindowsCE()) + { + mf->AddDefinition("CMAKE_VS_WINCE_VERSION", + this->WindowsCEVersion.c_str()); + } } //---------------------------------------------------------------------------- From 3a1006e41fd7be22c415d1de45364f0c8ff4b697 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Fri, 14 Sep 2012 12:06:57 +0200 Subject: [PATCH 033/170] VS: Added "Deploy" at project configuration for WindowsCE targets --- Source/cmGlobalVisualStudio71Generator.cxx | 2 +- Source/cmGlobalVisualStudio71Generator.h | 2 +- Source/cmGlobalVisualStudio7Generator.cxx | 6 +++--- Source/cmGlobalVisualStudio7Generator.h | 2 +- Source/cmGlobalVisualStudio8Generator.cxx | 11 ++++++++++- Source/cmGlobalVisualStudio8Generator.h | 2 +- 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Source/cmGlobalVisualStudio71Generator.cxx b/Source/cmGlobalVisualStudio71Generator.cxx index db584b804..2494f559c 100644 --- a/Source/cmGlobalVisualStudio71Generator.cxx +++ b/Source/cmGlobalVisualStudio71Generator.cxx @@ -277,7 +277,7 @@ void cmGlobalVisualStudio71Generator // executables to the libraries it uses are also done here void cmGlobalVisualStudio71Generator ::WriteProjectConfigurations( - std::ostream& fout, const char* name, + std::ostream& fout, const char* name, cmTarget::TargetType, const std::set& configsPartOfDefaultBuild, const char* platformMapping) { diff --git a/Source/cmGlobalVisualStudio71Generator.h b/Source/cmGlobalVisualStudio71Generator.h index e9cab0683..6d91f97fc 100644 --- a/Source/cmGlobalVisualStudio71Generator.h +++ b/Source/cmGlobalVisualStudio71Generator.h @@ -63,7 +63,7 @@ protected: virtual void WriteProjectDepends(std::ostream& fout, const char* name, const char* path, cmTarget &t); virtual void WriteProjectConfigurations( - std::ostream& fout, const char* name, + std::ostream& fout, const char* name, cmTarget::TargetType type, const std::set& configsPartOfDefaultBuild, const char* platformMapping = NULL); virtual void WriteExternalProject(std::ostream& fout, diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index b82a4f46f..71d79a170 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -247,7 +247,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( std::set allConfigurations(this->Configurations.begin(), this->Configurations.end()); this->WriteProjectConfigurations( - fout, target->GetName(), + fout, target->GetName(), target->GetType(), allConfigurations, target->GetProperty("VS_PLATFORM_MAPPING")); } else @@ -259,7 +259,7 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations( target->GetProperty("GENERATOR_FILE_NAME"); if (vcprojName) { - this->WriteProjectConfigurations(fout, vcprojName, + this->WriteProjectConfigurations(fout, vcprojName, target->GetType(), configsPartOfDefaultBuild); } } @@ -587,7 +587,7 @@ cmGlobalVisualStudio7Generator // executables to the libraries it uses are also done here void cmGlobalVisualStudio7Generator ::WriteProjectConfigurations( - std::ostream& fout, const char* name, + std::ostream& fout, const char* name, cmTarget::TargetType, const std::set& configsPartOfDefaultBuild, const char* platformMapping) { diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index 9eb9687d7..6e786201b 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -108,7 +108,7 @@ protected: virtual void WriteProjectDepends(std::ostream& fout, const char* name, const char* path, cmTarget &t); virtual void WriteProjectConfigurations( - std::ostream& fout, const char* name, + std::ostream& fout, const char* name, cmTarget::TargetType type, const std::set& configsPartOfDefaultBuild, const char* platformMapping = NULL); virtual void WriteSLNGlobalSections(std::ostream& fout, diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 21c82b771..864e8db02 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -374,7 +374,7 @@ cmGlobalVisualStudio8Generator void cmGlobalVisualStudio8Generator ::WriteProjectConfigurations( - std::ostream& fout, const char* name, + std::ostream& fout, const char* name, cmTarget::TargetType type, const std::set& configsPartOfDefaultBuild, const char* platformMapping) { @@ -395,6 +395,15 @@ cmGlobalVisualStudio8Generator << (platformMapping ? platformMapping : this->GetPlatformName()) << "\n"; } + bool needsDeploy = (type == cmTarget::EXECUTABLE || + type == cmTarget::SHARED_LIBRARY); + if(this->TargetsWindowsCE() && needsDeploy) + { + fout << "\t\t{" << guid << "}." << *i + << "|" << this->GetPlatformName() << ".Deploy.0 = " << *i << "|" + << (platformMapping ? platformMapping : this->GetPlatformName()) + << "\n"; + } } } diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 4dd2b4ba2..bcbd7a0bd 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -79,7 +79,7 @@ protected: virtual void WriteSLNHeader(std::ostream& fout); virtual void WriteSolutionConfigurations(std::ostream& fout); virtual void WriteProjectConfigurations( - std::ostream& fout, const char* name, + std::ostream& fout, const char* name, cmTarget::TargetType type, const std::set& configsPartOfDefaultBuild, const char* platformMapping = NULL); virtual bool ComputeTargetDepends(); From 07749e3705cfc0105399c4a7a8349ec9f83ba39c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 26 Nov 2012 22:43:13 +0100 Subject: [PATCH 034/170] Genex: Ensure that $<0:...> has a parameter. --- Source/cmGeneratorExpressionEvaluator.cxx | 16 ++++++++++++++++ .../GeneratorExpression/BadZero-result.txt | 1 + .../GeneratorExpression/BadZero-stderr.txt | 8 ++++++++ Tests/RunCMake/GeneratorExpression/BadZero.cmake | 4 ++++ .../GeneratorExpression/RunCMakeTest.cmake | 1 + 5 files changed, 30 insertions(+) create mode 100644 Tests/RunCMake/GeneratorExpression/BadZero-result.txt create mode 100644 Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt create mode 100644 Tests/RunCMake/GeneratorExpression/BadZero.cmake diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 23f641d64..3c2f7c5fa 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -66,6 +66,8 @@ static const struct ZeroNode : public cmGeneratorExpressionNode virtual bool GeneratesContent() const { return false; } + virtual bool AcceptsSingleArbitraryContentParameter() const { return true; } + std::string Evaluate(const std::vector &, cmGeneratorExpressionContext *, const GeneratorExpressionContent *, @@ -642,6 +644,20 @@ std::string GeneratorExpressionContent::Evaluate( if (!node->GeneratesContent()) { + if (node->AcceptsSingleArbitraryContentParameter()) + { + if (this->ParamChildren.empty()) + { + reportError(context, this->GetOriginalExpression(), + "$<" + identifier + "> expression requires a parameter."); + } + } + else + { + std::vector parameters; + this->EvaluateParameters(node, identifier, context, dagChecker, + parameters); + } return std::string(); } diff --git a/Tests/RunCMake/GeneratorExpression/BadZero-result.txt b/Tests/RunCMake/GeneratorExpression/BadZero-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadZero-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt new file mode 100644 index 000000000..ce044828b --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at BadZero.cmake:2 \(add_custom_target\): + Error evaluating generator expression: + + \$<0> + + \$<0> expression requires a parameter. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/BadZero.cmake b/Tests/RunCMake/GeneratorExpression/BadZero.cmake new file mode 100644 index 000000000..295ab0e20 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadZero.cmake @@ -0,0 +1,4 @@ + +add_custom_target(check ALL COMMAND check + $<0> + VERBATIM) diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake index 18a47ae00..992ba792f 100644 --- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake @@ -5,3 +5,4 @@ run_cmake(BadOR) run_cmake(BadAND) run_cmake(BadNOT) run_cmake(BadStrEqual) +run_cmake(BadZero) From b581be07672e08cce4c29fa279b250d8e9c7aaba Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 26 Nov 2012 22:44:13 +0100 Subject: [PATCH 035/170] Genex: Don't segfault on $ Treat the comma as part of the identifier here. It will later not resolve to a generator expression and the user gets a proper error message. --- Source/cmGeneratorExpressionParser.cxx | 10 +++++++++- Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt | 9 +++++++++ Tests/RunCMake/GeneratorExpression/BadZero.cmake | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Source/cmGeneratorExpressionParser.cxx b/Source/cmGeneratorExpressionParser.cxx index 7a8fc510d..a619cecd0 100644 --- a/Source/cmGeneratorExpressionParser.cxx +++ b/Source/cmGeneratorExpressionParser.cxx @@ -88,7 +88,15 @@ void cmGeneratorExpressionParser::ParseGeneratorExpression( while(this->it->TokenType != cmGeneratorExpressionToken::EndExpression && this->it->TokenType != cmGeneratorExpressionToken::ColonSeparator) { - this->ParseContent(identifier); + if (this->it->TokenType == cmGeneratorExpressionToken::CommaSeparator) + { + extendText(identifier, this->it); + ++this->it; + } + else + { + this->ParseContent(identifier); + } if (this->it == this->Tokens.end()) { break; diff --git a/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt index ce044828b..40db4ae88 100644 --- a/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt +++ b/Tests/RunCMake/GeneratorExpression/BadZero-stderr.txt @@ -6,3 +6,12 @@ CMake Error at BadZero.cmake:2 \(add_custom_target\): \$<0> expression requires a parameter. Call Stack \(most recent call first\): CMakeLists.txt:3 \(include\) ++ +CMake Error at BadZero.cmake:2 \(add_custom_target\): + Error evaluating generator expression: + + \$<0,> + + Expression did not evaluate to a known generator expression +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/BadZero.cmake b/Tests/RunCMake/GeneratorExpression/BadZero.cmake index 295ab0e20..559a9fa3d 100644 --- a/Tests/RunCMake/GeneratorExpression/BadZero.cmake +++ b/Tests/RunCMake/GeneratorExpression/BadZero.cmake @@ -1,4 +1,5 @@ add_custom_target(check ALL COMMAND check $<0> + $<0,> VERBATIM) From 1ed04648519f8dad60dbe6c1b3952429a011eb4b Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Wed, 28 Nov 2012 00:01:06 -0500 Subject: [PATCH 036/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index be8259ddd..a7afa52cd 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 20121127) +set(CMake_VERSION_TWEAK 20121128) #set(CMake_VERSION_RC 1) From 223850576b070f66a5eec5340b7eefa8ecf7b5de Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 28 Nov 2012 12:11:52 -0500 Subject: [PATCH 037/170] Watcom: Avoid prompt from wmake about dll with no exports... ...by simply building a STATIC lib for the test, instead of a SHARED one. Fixes test timeout on the Watcom dashboards. --- Tests/EmptyDepends/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/EmptyDepends/CMakeLists.txt b/Tests/EmptyDepends/CMakeLists.txt index a24382cea..832d9dce6 100644 --- a/Tests/EmptyDepends/CMakeLists.txt +++ b/Tests/EmptyDepends/CMakeLists.txt @@ -12,4 +12,4 @@ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/qrc_my.cxx add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/my.qrc COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/my.qrc) -add_library(qrc SHARED ${CMAKE_BINARY_DIR}/qrc_my.cxx) +add_library(qrc STATIC ${CMAKE_BINARY_DIR}/qrc_my.cxx) From d5ac791366595be307896e9894c66815c1e1eb2f Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Thu, 29 Nov 2012 00:01:01 -0500 Subject: [PATCH 038/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a7afa52cd..824de7e9e 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 20121128) +set(CMake_VERSION_TWEAK 20121129) #set(CMake_VERSION_RC 1) From 4809cadfe82316b648de50471169b4da9ef101e2 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Thu, 29 Nov 2012 09:21:18 +0100 Subject: [PATCH 039/170] FPHSA: don't succeed if only checking for XX_FOUND (#13755) This fixes issue #13755. FPHSA(XX DEFAULT_MSG XX_FOUND) always succeeded due to the way how the XX_FOUND variable was set. It was preset to TRUE, and then reset to FALSE if something was missing (...which had the effect that XX_FOUND itself was already preset when FPHSA checked whether XX_FOUND is set) Now XX_FOUND is unset first, and only later on set to TRUE. Alex --- Modules/FindPackageHandleStandardArgs.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Modules/FindPackageHandleStandardArgs.cmake b/Modules/FindPackageHandleStandardArgs.cmake index 5549d1464..e89e9a97d 100644 --- a/Modules/FindPackageHandleStandardArgs.cmake +++ b/Modules/FindPackageHandleStandardArgs.cmake @@ -187,8 +187,8 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) # user knows better what went wrong (#6375) set(MISSING_VARS "") set(DETAILS "") - set(${_NAME_UPPER}_FOUND TRUE) # check if all passed variables are valid + unset(${_NAME_UPPER}_FOUND) foreach(_CURRENT_VAR ${FPHSA_REQUIRED_VARS}) if(NOT ${_CURRENT_VAR}) set(${_NAME_UPPER}_FOUND FALSE) @@ -197,6 +197,9 @@ function(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FIRST_ARG) set(DETAILS "${DETAILS}[${${_CURRENT_VAR}}]") endif() endforeach() + if(NOT "${${_NAME_UPPER}_FOUND}" STREQUAL "FALSE") + set(${_NAME_UPPER}_FOUND TRUE) + endif() # component handling unset(FOUND_COMPONENTS_MSG) From 587b7b6f5ec252906e8d595d895e334680e341c9 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 28 Nov 2012 17:01:25 -0500 Subject: [PATCH 040/170] Tests: Use the right path to CPack value for running CPack tests These tests were not running properly on Visual Studio or Xcode dashboards before this commit because of the "Debug" or "Release" sub-directory. The scripts already have CMAKE_CPACK_COMMAND since the correct CMake executable is used to run the scripts, so just use that, rather than passing down an incorrect path to the CPack executable. --- Tests/CMakeLists.txt | 3 --- .../CPackComponentsForAll/RunCPackVerifyResult.cmake | 11 +++++------ Tests/CPackTestAllGenerators/RunCPack.cmake | 8 ++------ 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 7dc26439f..e8fa7c6aa 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -744,7 +744,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ # ACTIVE_CPACK_GENERATORS variable # now contains the list of 'active generators' set(CPackComponentsForAll_EXTRA_OPTIONS) - set(CPackRun_CPackCommand "-DCPackCommand=${CMAKE_CPACK_COMMAND}") # set up list of CPack generators list(APPEND GENLST "ZIP") if(APPLE) @@ -784,7 +783,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --graphviz=CPackComponentsForAll.dot --test-command ${CMAKE_CMAKE_COMMAND} "-DCPackComponentsForAll_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}" - "${CPackRun_CPackCommand}" "${CPackRun_CPackGen}" "${CPackRun_CPackComponentWay}" -P "${CMake_SOURCE_DIR}/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake") @@ -819,7 +817,6 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --test-command ${CMAKE_CMAKE_COMMAND} -D dir=${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators - -D cpack=${CMAKE_CPACK_COMMAND} -P ${CMake_SOURCE_DIR}/Tests/CPackTestAllGenerators/RunCPack.cmake ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators") diff --git a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake index 9a022c580..0b6d07d97 100644 --- a/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake +++ b/Tests/CPackComponentsForAll/RunCPackVerifyResult.cmake @@ -9,11 +9,10 @@ endif() if(NOT CPackGen) message(FATAL_ERROR "CPackGen not set") endif() -get_filename_component(CPACK_LOCATION ${CMAKE_COMMAND} PATH) -set(CPackCommand "${CPACK_LOCATION}/cpack") -message("cpack = ${CPackCommand}") -if(NOT CPackCommand) - message(FATAL_ERROR "CPackCommand not set") + +message("CMAKE_CPACK_COMMAND = ${CMAKE_CPACK_COMMAND}") +if(NOT CMAKE_CPACK_COMMAND) + message(FATAL_ERROR "CMAKE_CPACK_COMMAND not set") endif() if(NOT CPackComponentWay) @@ -92,7 +91,7 @@ endif() message("config_args = ${config_args}") message("config_verbose = ${config_verbose}") -execute_process(COMMAND ${CPackCommand} ${config_verbose} -G ${CPackGen} ${config_args} +execute_process(COMMAND ${CMAKE_CPACK_COMMAND} ${config_verbose} -G ${CPackGen} ${config_args} RESULT_VARIABLE CPack_result OUTPUT_VARIABLE CPack_output ERROR_VARIABLE CPack_error diff --git a/Tests/CPackTestAllGenerators/RunCPack.cmake b/Tests/CPackTestAllGenerators/RunCPack.cmake index e0c241ec4..952d5f4ae 100644 --- a/Tests/CPackTestAllGenerators/RunCPack.cmake +++ b/Tests/CPackTestAllGenerators/RunCPack.cmake @@ -1,14 +1,10 @@ -if(NOT DEFINED cpack) - message(FATAL_ERROR "cpack not defined") -endif() - if(NOT DEFINED dir) message(FATAL_ERROR "dir not defined") endif() # Analyze 'cpack --help' output for list of available generators: # -execute_process(COMMAND ${cpack} --help +execute_process(COMMAND ${CMAKE_CPACK_COMMAND} --help RESULT_VARIABLE result OUTPUT_VARIABLE stdout ERROR_VARIABLE stderr @@ -43,7 +39,7 @@ message(STATUS "CPack generators='${generators}'") foreach(g ${generators}) message(STATUS "Calling cpack -G ${g}...") - execute_process(COMMAND ${cpack} -G ${g} + execute_process(COMMAND ${CMAKE_CPACK_COMMAND} -G ${g} RESULT_VARIABLE result OUTPUT_VARIABLE stdout ERROR_VARIABLE stderr From 965358fcf64cf1a3693bcdd66f723729e0614ef6 Mon Sep 17 00:00:00 2001 From: Mathias Gaunard Date: Fri, 30 Nov 2012 02:21:35 +0100 Subject: [PATCH 041/170] enable CTEST_USE_LAUNCHERS with Ninja too --- Modules/CTestUseLaunchers.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CTestUseLaunchers.cmake b/Modules/CTestUseLaunchers.cmake index 6731d3754..24f5f2e16 100644 --- a/Modules/CTestUseLaunchers.cmake +++ b/Modules/CTestUseLaunchers.cmake @@ -35,7 +35,7 @@ if(NOT DEFINED CTEST_USE_LAUNCHERS AND DEFINED ENV{CTEST_USE_LAUNCHERS_DEFAULT}) CACHE INTERNAL "CTEST_USE_LAUNCHERS initial value from ENV") endif() -if(NOT "${CMAKE_GENERATOR}" MATCHES "Make") +if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja") set(CTEST_USE_LAUNCHERS 0) endif() From 9fc2e20244a2c8b01c23cd06031388aa85e50117 Mon Sep 17 00:00:00 2001 From: Mathias Gaunard Date: Fri, 30 Nov 2012 03:38:25 +0100 Subject: [PATCH 042/170] Ninja: fix usage of cldeps with ctest launchers --- Source/cmNinjaTargetGenerator.cxx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 5b1dfc881..15842e44f 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -423,17 +423,19 @@ cmNinjaTargetGenerator std::vector compileCmds; cmSystemTools::ExpandListArgument(compileCmd, compileCmds); + if(useClDeps) + { + std::string cmdPrefix = clDepsBinary + lang + " $in \"$DEP_FILE\" $out " + + clShowPrefix + clBinary; + compileCmds.front().insert(0, cmdPrefix); + } + for (std::vector::iterator i = compileCmds.begin(); i != compileCmds.end(); ++i) this->GetLocalGenerator()->ExpandRuleVariables(*i, vars); - std::string cmdLine; - if(useClDeps) - { - cmdLine = clDepsBinary + lang + " $in \"$DEP_FILE\" $out " + - clShowPrefix + clBinary; - } - cmdLine += this->GetLocalGenerator()->BuildCommandLine(compileCmds); + std::string cmdLine = + this->GetLocalGenerator()->BuildCommandLine(compileCmds); // Write the rule for compiling file of the given language. From e0af55a5f4cd84db1cc5a3517e730ea8c6332f45 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Fri, 30 Nov 2012 00:01:04 -0500 Subject: [PATCH 043/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 824de7e9e..5139b58c5 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 20121129) +set(CMake_VERSION_TWEAK 20121130) #set(CMake_VERSION_RC 1) From bf2ddceb4e55b2b9e3fb749fbee6126340f73f07 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 30 Nov 2012 09:26:09 +0100 Subject: [PATCH 044/170] Generate an early-return guard in target Export files. Previously it was necessary for writers of Config files which incude exported target files to write the guard themselves, but this was not immediately obvious or documented. Options for them would be to use a variable, or an INHERITED directory property in an effort to avoid accidental name clashes in all contexts in which find_package can be used. Getting this right requires boiler plate code, so generate a simpler check automatically instead. --- Source/cmExportBuildFileGenerator.cxx | 14 +++++++++++ Source/cmExportFileGenerator.cxx | 31 +++++++++++++++++++++++++ Source/cmExportFileGenerator.h | 2 ++ Source/cmExportInstallFileGenerator.cxx | 14 +++++++++++ 4 files changed, 61 insertions(+) diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index fb3f39fe6..cd6a7ab9e 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -22,6 +22,20 @@ cmExportBuildFileGenerator::cmExportBuildFileGenerator() //---------------------------------------------------------------------------- bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) { + { + std::string expectedTargets; + std::string sep; + for(std::vector::const_iterator + tei = this->Exports->begin(); + tei != this->Exports->end(); ++tei) + { + expectedTargets += sep + this->Namespace + (*tei)->GetName(); + sep = " "; + } + + this->GenerateExpectedTargetsCode(os, expectedTargets); + } + // Create all the imported targets. for(std::vector::const_iterator tei = this->Exports->begin(); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 8dffae43a..3f738ccde 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -286,6 +286,37 @@ void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os) << "\n"; } +//---------------------------------------------------------------------------- +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 " + "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" + "\n\n"; +} //---------------------------------------------------------------------------- void cmExportFileGenerator diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 70bc65de5..4a75c52d5 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -63,6 +63,8 @@ protected: void GenerateMissingTargetsCheckCode(std::ostream& os, const std::vector& missingTargets); + void GenerateExpectedTargetsCode(std::ostream& os, + const std::string &expectedTargets); // Collect properties with detailed information about targets beyond // their location on disk. diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 784173172..6ba7d9fc2 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -39,6 +39,20 @@ std::string cmExportInstallFileGenerator::GetConfigImportFileGlob() //---------------------------------------------------------------------------- bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { + { + std::string expectedTargets; + std::string sep; + for(std::vector::const_iterator + tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); + tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) + { + expectedTargets += sep + this->Namespace + (*tei)->Target->GetName(); + sep = " "; + } + + this->GenerateExpectedTargetsCode(os, expectedTargets); + } + // Create all the imported targets. for(std::vector::const_iterator tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); From dce54b103af0ee1627de9e0cf04a5e390442a929 Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Thu, 29 Nov 2012 16:36:20 +0100 Subject: [PATCH 045/170] Add command to generate environment for a Windows CE SDK --- Source/cmVisualStudioWCEPlatformParser.cxx | 48 +++++++++++++++++++--- Source/cmVisualStudioWCEPlatformParser.h | 13 ++++++ Source/cmake.cxx | 36 ++++++++++++++++ Source/cmake.h | 2 + 4 files changed, 93 insertions(+), 6 deletions(-) diff --git a/Source/cmVisualStudioWCEPlatformParser.cxx b/Source/cmVisualStudioWCEPlatformParser.cxx index 0afcf678e..b302246ea 100644 --- a/Source/cmVisualStudioWCEPlatformParser.cxx +++ b/Source/cmVisualStudioWCEPlatformParser.cxx @@ -15,18 +15,23 @@ int cmVisualStudioWCEPlatformParser::ParseVersion(const char* version) { - std::string vskey = cmGlobalVisualStudioGenerator::GetRegistryBase(version); - vskey += "\\Setup\\VS;ProductDir"; + const std::string registryBase = + cmGlobalVisualStudioGenerator::GetRegistryBase(version); + const std::string vckey = registryBase + "\\Setup\\VC;ProductDir"; + const std::string vskey = registryBase + "\\Setup\\VS;ProductDir"; - std::string vsInstallPath; - if(!cmSystemTools::ReadRegistryValue(vskey.c_str(), vsInstallPath)) + if(!cmSystemTools::ReadRegistryValue(vckey.c_str(), this->VcInstallDir) || + !cmSystemTools::ReadRegistryValue(vskey.c_str(), this->VsInstallDir)) { return 0; } - cmSystemTools::ConvertToUnixSlashes(vsInstallPath); + cmSystemTools::ConvertToUnixSlashes(this->VcInstallDir); + cmSystemTools::ConvertToUnixSlashes(this->VsInstallDir); + this->VcInstallDir.append("/"); + this->VsInstallDir.append("/"); const std::string configFilename = - vsInstallPath + "/VC/vcpackages/WCE.VCPlatform.config"; + this->VcInstallDir + "vcpackages/WCE.VCPlatform.config"; return this->ParseFile(configFilename.c_str()); } @@ -93,6 +98,24 @@ void cmVisualStudioWCEPlatformParser::StartElement(const char* name, this->Macros[macroName] = macroValue; } } + else if(strcmp(name, "Directories") == 0) + { + for(const char** attr = attributes; *attr; attr += 2) + { + if(strcmp(attr[0], "Include") == 0) + { + this->Include = attr[1]; + } + else if(strcmp(attr[0], "Library") == 0) + { + this->Library = attr[1]; + } + else if(strcmp(attr[0], "Path") == 0) + { + this->Path = attr[1]; + } + } + } } void cmVisualStudioWCEPlatformParser::EndElement(const char* name) @@ -137,3 +160,16 @@ void cmVisualStudioWCEPlatformParser::CharacterDataHandler(const char* data, { this->CharacterData.append(data, length); } + +std::string cmVisualStudioWCEPlatformParser::FixPaths( + const std::string& paths) const +{ + std::string ret = paths; + cmSystemTools::ReplaceString(ret, "$(PATH)", "%PATH%"); + cmSystemTools::ReplaceString(ret, "$(VCInstallDir)", VcInstallDir.c_str()); + cmSystemTools::ReplaceString(ret, "$(VSInstallDir)", VsInstallDir.c_str()); + cmSystemTools::ReplaceString(ret, "\\", "/"); + cmSystemTools::ReplaceString(ret, "//", "/"); + cmSystemTools::ReplaceString(ret, "/", "\\"); + return ret; +} diff --git a/Source/cmVisualStudioWCEPlatformParser.h b/Source/cmVisualStudioWCEPlatformParser.h index 28061fd23..466e1dd43 100644 --- a/Source/cmVisualStudioWCEPlatformParser.h +++ b/Source/cmVisualStudioWCEPlatformParser.h @@ -31,6 +31,12 @@ public: bool Found() const {return this->FoundRequiredName;} const char* GetArchitectureFamily() const; std::string GetOSVersion() const; + std::string GetIncludeDirectories() const { + return this->FixPaths(this->Include); } + std::string GetLibraryDirectories() const { + return this->FixPaths(this->Library); } + std::string GetPathDirectories() const { + return this->FixPaths(this->Path); } const std::vector& GetAvailablePlatforms() const { return this->AvailablePlatforms; } @@ -40,8 +46,13 @@ protected: void CharacterDataHandler(const char* data, int length); private: + std::string FixPaths(const std::string& paths) const; + std::string CharacterData; + std::string Include; + std::string Library; + std::string Path; std::string PlatformName; std::string OSMajorVersion; std::string OSMinorVersion; @@ -50,6 +61,8 @@ private: const char* RequiredName; bool FoundRequiredName; + std::string VcInstallDir; + std::string VsInstallDir; }; #endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 1424a1132..fba4860fd 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -82,6 +82,7 @@ #if defined(CMAKE_HAVE_VS_GENERATORS) #include "cmCallVisualStudioMacro.h" +#include "cmVisualStudioWCEPlatformParser.h" #endif #if !defined(CMAKE_BOOT_MINGW) @@ -1143,6 +1144,10 @@ void CMakeCommandUsage(const char* program) << "Available on Windows only:\n" << " comspec - on windows 9x use this for RunCommand\n" << " delete_regv key - delete registry value\n" + << " env_vs8_wince sdkname - displays a batch file which sets the " + "environment for the provided Windows CE SDK installed in VS2005\n" + << " env_vs9_wince sdkname - displays a batch file which sets the " + "environment for the provided Windows CE SDK installed in VS2008\n" << " write_regv key value - write registry value\n" #else << "Available on UNIX only:\n" @@ -1808,6 +1813,14 @@ int cmake::ExecuteCMakeCommand(std::vector& args) } return cmWin32ProcessExecution::Windows9xHack(command.c_str()); } + else if (args[1] == "env_vs8_wince" && args.size() == 3) + { + return cmake::WindowsCEEnvironment("8.0", args[2]); + } + else if (args[1] == "env_vs9_wince" && args.size() == 3) + { + return cmake::WindowsCEEnvironment("9.0", args[2]); + } #endif } @@ -4001,6 +4014,29 @@ static bool cmakeCheckStampList(const char* stampList) return true; } +//---------------------------------------------------------------------------- +int cmake::WindowsCEEnvironment(const char* version, const std::string& name) +{ +#if defined(CMAKE_HAVE_VS_GENERATORS) + cmVisualStudioWCEPlatformParser parser(name.c_str()); + parser.ParseVersion(version); + if (parser.Found()) + { + std::cout << "@echo off" << std::endl; + std::cout << "echo Environment Selection: " << name << std::endl; + std::cout << "set PATH=" << parser.GetPathDirectories() << std::endl; + std::cout << "set INCLUDE=" << parser.GetIncludeDirectories() <& args); static int ExecuteLinkScript(std::vector& args); + static int WindowsCEEnvironment(const char* version, + const std::string& name); static int VisualStudioLink(std::vector& args, int type); static int VisualStudioLinkIncremental(std::vector& args, int type, From 6a6a6f36707f9588249990eb2d67e414d2eebd38 Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Thu, 29 Nov 2012 18:20:11 -0500 Subject: [PATCH 046/170] libarchive: fixed undefined left shift with signed ints caught by clang's -fsanitize=shift. A small unsigned int was promoted, according to C's regular promotion rules, to a signed int, it was then left shifted. This sometimes pushed a 1 into the sign bit, which is undefined behaviour. Fixed by using unsigned temporaries. --- .../cmlibarchive/libarchive/archive_endian.h | 36 ++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/Utilities/cmlibarchive/libarchive/archive_endian.h b/Utilities/cmlibarchive/libarchive/archive_endian.h index bbf58fd10..3c039f702 100644 --- a/Utilities/cmlibarchive/libarchive/archive_endian.h +++ b/Utilities/cmlibarchive/libarchive/archive_endian.h @@ -64,7 +64,13 @@ archive_be16dec(const void *pp) { unsigned char const *p = (unsigned char const *)pp; - return ((p[0] << 8) | p[1]); + /* Store into unsigned temporaries before left shifting, to avoid + promotion to signed int and then left shifting into the sign bit, + which is undefined behaviour. */ + unsigned int p1 = p[1]; + unsigned int p0 = p[0]; + + return ((p0 << 8) | p1); } static inline uint32_t @@ -72,7 +78,15 @@ archive_be32dec(const void *pp) { unsigned char const *p = (unsigned char const *)pp; - return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); + /* Store into unsigned temporaries before left shifting, to avoid + promotion to signed int and then left shifting into the sign bit, + which is undefined behaviour. */ + unsigned int p3 = p[3]; + unsigned int p2 = p[2]; + unsigned int p1 = p[1]; + unsigned int p0 = p[0]; + + return ((p0 << 24) | (p1 << 16) | (p2 << 8) | p3); } static inline uint64_t @@ -88,7 +102,13 @@ archive_le16dec(const void *pp) { unsigned char const *p = (unsigned char const *)pp; - return ((p[1] << 8) | p[0]); + /* Store into unsigned temporaries before left shifting, to avoid + promotion to signed int and then left shifting into the sign bit, + which is undefined behaviour. */ + unsigned int p1 = p[1]; + unsigned int p0 = p[0]; + + return ((p1 << 8) | p0); } static inline uint32_t @@ -96,7 +116,15 @@ archive_le32dec(const void *pp) { unsigned char const *p = (unsigned char const *)pp; - return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); + /* Store into unsigned temporaries before left shifting, to avoid + promotion to signed int and then left shifting into the sign bit, + which is undefined behaviour. */ + unsigned int p3 = p[3]; + unsigned int p2 = p[2]; + unsigned int p1 = p[1]; + unsigned int p0 = p[0]; + + return ((p3 << 24) | (p2 << 16) | (p1 << 8) | p0); } static inline uint64_t From 5bf9fd8253ec804498c0f3339c4d706cab3673ea Mon Sep 17 00:00:00 2001 From: Patrick Gansterer Date: Fri, 30 Nov 2012 14:14:27 +0100 Subject: [PATCH 047/170] VS: Set the correct SubSystem when determinating the CompilerId Some WinCE linker only work when the subsystem is set to WINDOWSCE. --- Modules/CMakeDetermineCompilerId.cmake | 3 +++ Modules/CompilerId/VS-7.vcproj.in | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 43469eaad..40e4f5aac 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -142,6 +142,9 @@ Id flags: ${testflags} endif() if(CMAKE_VS_WINCE_VERSION) set(id_definitions "ADD_MAINCRTSTARTUP") + set(id_subsystem 9) + else() + set(id_subsystem 1) endif() if("${CMAKE_MAKE_PROGRAM}" MATCHES "[Mm][Ss][Bb][Uu][Ii][Ll][Dd]") set(build /p:Configuration=Debug /p:Platform=@id_arch@ /p:VisualStudioVersion=${vs_version}.0) diff --git a/Modules/CompilerId/VS-7.vcproj.in b/Modules/CompilerId/VS-7.vcproj.in index b1449e4ac..5b68e8637 100644 --- a/Modules/CompilerId/VS-7.vcproj.in +++ b/Modules/CompilerId/VS-7.vcproj.in @@ -36,7 +36,7 @@ Name="VCLinkerTool" LinkIncremental="1" GenerateDebugInformation="false" - SubSystem="1" + SubSystem="@id_subsystem@" /> Date: Fri, 30 Nov 2012 15:15:06 +0100 Subject: [PATCH 048/170] VS: Add the entry point when compiling for WindowsCE Set the entry point to mainACRTStartup to make sure that main() can be found when linking the application to check the compiler. --- Modules/CMakeCCompilerId.c.in | 4 ---- Modules/CMakeCXXCompilerId.cpp.in | 4 ---- Modules/CMakeDetermineCompilerId.cmake | 2 +- Modules/CompilerId/VS-7.vcproj.in | 2 +- 4 files changed, 2 insertions(+), 10 deletions(-) diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index 3d1380c6d..2d76c7a34 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -228,7 +228,3 @@ int main(int argc, char* argv[]) return require; } #endif - -#ifdef ADD_MAINCRTSTARTUP -void mainCRTStartup() {} -#endif diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index 142a5c5ab..5e70a4196 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -210,7 +210,3 @@ int main(int argc, char* argv[]) (void)argv; return require; } - -#ifdef ADD_MAINCRTSTARTUP -extern "C" void mainCRTStartup() {} -#endif diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 40e4f5aac..609f35bf7 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -141,7 +141,7 @@ Id flags: ${testflags} set(id_toolset "") endif() if(CMAKE_VS_WINCE_VERSION) - set(id_definitions "ADD_MAINCRTSTARTUP") + set(id_entrypoint "mainACRTStartup") set(id_subsystem 9) else() set(id_subsystem 1) diff --git a/Modules/CompilerId/VS-7.vcproj.in b/Modules/CompilerId/VS-7.vcproj.in index 5b68e8637..3e2b34a62 100644 --- a/Modules/CompilerId/VS-7.vcproj.in +++ b/Modules/CompilerId/VS-7.vcproj.in @@ -24,7 +24,6 @@ Date: Fri, 30 Nov 2012 15:17:50 +0100 Subject: [PATCH 049/170] VS: Ignore LIBC.lib when linking the CompilerId executables Some Windows CE linkers want to link against LIBC.lib, but can not find them. Since they are not required we can simply ignore it. --- Modules/CompilerId/VS-7.vcproj.in | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/CompilerId/VS-7.vcproj.in b/Modules/CompilerId/VS-7.vcproj.in index 3e2b34a62..fa48cadb3 100644 --- a/Modules/CompilerId/VS-7.vcproj.in +++ b/Modules/CompilerId/VS-7.vcproj.in @@ -34,6 +34,7 @@ Date: Sat, 1 Dec 2012 00:01:08 -0500 Subject: [PATCH 050/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 5139b58c5..776b62466 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 20121130) +set(CMake_VERSION_TWEAK 20121201) #set(CMake_VERSION_RC 1) From cb15efc370f935aa23e9cc597bf04948ed6907ae Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sun, 2 Dec 2012 00:01:05 -0500 Subject: [PATCH 051/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 776b62466..e02a13c29 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 20121201) +set(CMake_VERSION_TWEAK 20121202) #set(CMake_VERSION_RC 1) From 981629f701c598f58115445456ee733077beae8d Mon Sep 17 00:00:00 2001 From: Benjamin Eikel Date: Sun, 2 Dec 2012 14:32:47 +0100 Subject: [PATCH 052/170] Swap linking order of SDLmain and SDL (#0013769) --- Modules/FindSDL.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake index f2e9f25f5..fec142ed5 100644 --- a/Modules/FindSDL.cmake +++ b/Modules/FindSDL.cmake @@ -122,7 +122,7 @@ if(SDL_LIBRARY_TEMP) if(SDLMAIN_LIBRARY AND NOT SDL_BUILDING_LIBRARY) list(FIND SDL_LIBRARY_TEMP "${SDLMAIN_LIBRARY}" _SDL_MAIN_INDEX) if(_SDL_MAIN_INDEX EQUAL -1) - list(APPEND SDL_LIBRARY_TEMP "${SDLMAIN_LIBRARY}") + set(SDL_LIBRARY_TEMP "${SDLMAIN_LIBRARY}" ${SDL_LIBRARY_TEMP}) endif() unset(_SDL_MAIN_INDEX) endif() From 538af1642561565f6d2674430005bb5dd6370ebb Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Mon, 3 Dec 2012 00:01:06 -0500 Subject: [PATCH 053/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index e02a13c29..942c0d04e 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 20121202) +set(CMake_VERSION_TWEAK 20121203) #set(CMake_VERSION_RC 1) From 691ac05d4049619407b6ff0b89207c5c77e21ae0 Mon Sep 17 00:00:00 2001 From: Clinton Stimpson Date: Mon, 3 Dec 2012 08:00:07 -0700 Subject: [PATCH 054/170] Qt4: Add SYSTEM option to include_directories. Thanks to Scott Bailey and Benjamin Kloster. --- Modules/FindQt4.cmake | 4 ++++ Modules/UseQt4.cmake | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index b42247a1c..00e86e8e8 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -65,6 +65,10 @@ # is much more flexible, but requires that FindQt4.cmake is executed before # such an exported dependency file is processed. # +# 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. +# # There are also some files that need processing by some Qt tools such as moc # and uic. Listed below are macros that may be used to process those files. # diff --git a/Modules/UseQt4.cmake b/Modules/UseQt4.cmake index e8166f4fc..f05a3d5f3 100644 --- a/Modules/UseQt4.cmake +++ b/Modules/UseQt4.cmake @@ -25,7 +25,11 @@ if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS QT_NO_DEBUG) endif() -include_directories(${QT_INCLUDE_DIR}) +if(QT_INCLUDE_DIRS_NO_SYSTEM) + include_directories(${QT_INCLUDE_DIR}) +else(QT_INCLUDE_DIRS_NO_SYSTEM) + include_directories(SYSTEM ${QT_INCLUDE_DIR}) +endif(QT_INCLUDE_DIRS_NO_SYSTEM) set(QT_LIBRARIES "") set(QT_LIBRARIES_PLUGINS "") @@ -89,7 +93,11 @@ foreach(module QT3SUPPORT QTOPENGL QTASSISTANT QTDESIGNER QTMOTIF QTNSPLUGIN if(QT_USE_${module}) string(REPLACE "QT" "" qt_module_def "${module}") add_definitions(-DQT_${qt_module_def}_LIB) - include_directories(${QT_${module}_INCLUDE_DIR}) + if(QT_INCLUDE_DIRS_NO_SYSTEM) + include_directories(${QT_${module}_INCLUDE_DIR}) + else(QT_INCLUDE_DIRS_NO_SYSTEM) + include_directories(SYSTEM ${QT_${module}_INCLUDE_DIR}) + endif(QT_INCLUDE_DIRS_NO_SYSTEM) endif() set(QT_LIBRARIES ${QT_LIBRARIES} ${QT_${module}_LIBRARY}) set(QT_LIBRARIES_PLUGINS ${QT_LIBRARIES_PLUGINS} ${QT_${module}_PLUGINS}) From 85baac1503c638756211ba07c4c25128e6d3d845 Mon Sep 17 00:00:00 2001 From: Nils Gladitz Date: Wed, 3 Oct 2012 16:08:49 +0200 Subject: [PATCH 055/170] CPack: Add a WiX Generator (#11575) This new CPack generator produces an *.msi installer file. Requires having the WiX Toolset installed in order to work properly. Download the WiX Toolset installer "WiX36.exe" here: http://wix.codeplex.com/releases/view/93929 --- CMakeCPackOptions.cmake.in | 24 + Modules/CPack.cmake | 7 +- Modules/CPackWIX.cmake | 83 +++ Modules/WIX.template.in | 31 + Source/CMakeLists.txt | 8 + Source/CPack/WiX/cmCPackWIXGenerator.cxx | 568 ++++++++++++++++++ Source/CPack/WiX/cmCPackWIXGenerator.h | 101 ++++ .../CPack/WiX/cmWIXRichTextFormatWriter.cxx | 137 +++++ Source/CPack/WiX/cmWIXRichTextFormatWriter.h | 46 ++ Source/CPack/WiX/cmWIXSourceWriter.cxx | 188 ++++++ Source/CPack/WiX/cmWIXSourceWriter.h | 67 +++ Source/CPack/cmCPackGeneratorFactory.cxx | 11 + Tests/CMakeLists.txt | 23 + Tests/CPackWiXGenerator/CMakeLists.txt | 73 +++ .../RunCPackVerifyResult.cmake | 72 +++ Tests/CPackWiXGenerator/file with spaces.h | 0 Tests/CPackWiXGenerator/mylib.cpp | 7 + Tests/CPackWiXGenerator/mylib.h | 1 + Tests/CPackWiXGenerator/mylibapp.cpp | 6 + 19 files changed, 1452 insertions(+), 1 deletion(-) create mode 100644 Modules/CPackWIX.cmake create mode 100644 Modules/WIX.template.in create mode 100644 Source/CPack/WiX/cmCPackWIXGenerator.cxx create mode 100644 Source/CPack/WiX/cmCPackWIXGenerator.h create mode 100644 Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx create mode 100644 Source/CPack/WiX/cmWIXRichTextFormatWriter.h create mode 100644 Source/CPack/WiX/cmWIXSourceWriter.cxx create mode 100644 Source/CPack/WiX/cmWIXSourceWriter.h create mode 100644 Tests/CPackWiXGenerator/CMakeLists.txt create mode 100644 Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake create mode 100644 Tests/CPackWiXGenerator/file with spaces.h create mode 100644 Tests/CPackWiXGenerator/mylib.cpp create mode 100644 Tests/CPackWiXGenerator/mylib.h create mode 100644 Tests/CPackWiXGenerator/mylibapp.cpp diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in index 3a72eaa5c..47dad49c2 100644 --- a/CMakeCPackOptions.cmake.in +++ b/CMakeCPackOptions.cmake.in @@ -51,3 +51,27 @@ if("${CPACK_GENERATOR}" STREQUAL "PackageMaker") set(CPACK_PACKAGE_DEFAULT_LOCATION "/usr") endif() endif() + +if("${CPACK_GENERATOR}" STREQUAL "WIX") + # Reset CPACK_PACKAGE_VERSION to deal with WiX restriction. + # But the file names still use the full CMake_VERSION value: + set(CPACK_PACKAGE_FILE_NAME + "${CPACK_PACKAGE_NAME}-@CMake_VERSION@-${CPACK_SYSTEM_NAME}") + set(CPACK_SOURCE_PACKAGE_FILE_NAME + "${CPACK_PACKAGE_NAME}-@CMake_VERSION@-Source") + + if(NOT CPACK_WIX_SIZEOF_VOID_P) + set(CPACK_WIX_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@") + endif() + + set(CPACK_PACKAGE_VERSION + "@CMake_VERSION_MAJOR@.@CMake_VERSION_MINOR@.@CMake_VERSION_PATCH@") + # WIX installers require at most a 4 component version number, where + # each component is an integer between 0 and 65534 inclusive + set(tweak "@CMake_VERSION_TWEAK@") + if(tweak MATCHES "^[0-9]+$") + if(tweak GREATER 0 AND tweak LESS 65535) + set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.${tweak}") + endif() + endif() +endif() diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 6886ed9fd..42d3c0c39 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -438,6 +438,7 @@ if(NOT CPACK_GENERATOR) endif() else() option(CPACK_BINARY_NSIS "Enable to build NSIS packages" ON) + option(CPACK_BINARY_WIX "Enable to build WiX packages" OFF) option(CPACK_BINARY_ZIP "Enable to build ZIP packages" OFF) endif() @@ -453,6 +454,7 @@ if(NOT CPACK_GENERATOR) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TGZ TGZ) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TBZ2 TBZ2) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TZ TZ) + cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_WIX WIX) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_ZIP ZIP) endif() @@ -483,7 +485,7 @@ endif() mark_as_advanced(CPACK_BINARY_CYGWIN CPACK_BINARY_PACKAGEMAKER CPACK_BINARY_OSXX11 CPACK_BINARY_STGZ CPACK_BINARY_TGZ CPACK_BINARY_TBZ2 CPACK_BINARY_DEB CPACK_BINARY_RPM CPACK_BINARY_TZ - CPACK_BINARY_NSIS CPACK_BINARY_ZIP CPACK_BINARY_BUNDLE + CPACK_BINARY_NSIS CPACK_BINARY_WIX CPACK_BINARY_ZIP CPACK_BINARY_BUNDLE CPACK_SOURCE_CYGWIN CPACK_SOURCE_TBZ2 CPACK_SOURCE_TGZ CPACK_SOURCE_TZ CPACK_SOURCE_ZIP CPACK_BINARY_DRAGNDROP) @@ -522,6 +524,9 @@ cpack_set_if_not_set(CPACK_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") cpack_set_if_not_set(CPACK_NSIS_INSTALLER_ICON_CODE "") cpack_set_if_not_set(CPACK_NSIS_INSTALLER_MUI_ICON_CODE "") +# WiX specific variables +cpack_set_if_not_set(CPACK_WIX_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}") + if(DEFINED CPACK_COMPONENTS_ALL) if(CPACK_MONOLITHIC_INSTALL) message("CPack warning: both CPACK_COMPONENTS_ALL and CPACK_MONOLITHIC_INSTALL have been set.\nDefaulting to a monolithic installation.") diff --git a/Modules/CPackWIX.cmake b/Modules/CPackWIX.cmake new file mode 100644 index 000000000..f278953dd --- /dev/null +++ b/Modules/CPackWIX.cmake @@ -0,0 +1,83 @@ +##section Variables specific to CPack WiX generator +##end +##module +# - CPack WiX generator specific options +# +# The following variables are specific to the installers built +# on Windows using WiX. +##end +##variable +# CPACK_WIX_UPGRADE_GUID - Upgrade GUID (Product/@UpgradeCode) +# +# Will be automatically generated unless explicitly provided. +# +# It should be explicitly set to a constant generated +# gloabally unique identifier (GUID) to allow your installers +# to replace existing installations that use the same GUID. +# +# You may for example explicitly set this variable in +# your CMakeLists.txt to the value that has been generated per default. +# You should not use GUIDs that you did not generate yourself or which may +# belong to other projects. +# +# A GUID shall have the following fixed length syntax: +# XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX +# (each X represents an uppercase hexadecimal digit) +##end +##variable +# CPACK_WIX_PRODUCT_GUID - Product GUID (Product/@Id) +# +# Will be automatically generated unless explicitly provided. +# +# If explicitly provided this will set the Product Id of your installer. +# +# The installer will abort if it detects a pre-existing installation that uses +# the same GUID. +# +# The GUID shall use the syntax described for CPACK_WIX_UPGRADE_GUID. +##end +##variable +# CPACK_WIX_LICENSE_RTF - RTF License File +# +# If CPACK_RESOURCE_FILE_LICENSE has an .rtf extension +# it is used as-is. +# +# If CPACK_RESOURCE_FILE_LICENSE has an .txt extension +# it is implicitly converted to RTF by the WiX Generator. +# +# With CPACK_WIX_LICENSE_RTF you can override the license file used +# by the WiX Generator in case CPACK_RESOURCE_FILE_LICENSE +# is in an unsupported format or the .txt -> .rtf +# conversion does not work as expected. +##end + +#============================================================================= +# Copyright 2012 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +if(NOT CPACK_WIX_ROOT) + file(TO_CMAKE_PATH "$ENV{WIX}" CPACK_WIX_ROOT) +endif() + +find_program(CPACK_WIX_CANDLE_EXECUTABLE candle + PATHS "${CPACK_WIX_ROOT}/bin") + +if(NOT CPACK_WIX_CANDLE_EXECUTABLE) + message(FATAL_ERROR "Could not find the WiX candle executable.") +endif() + +find_program(CPACK_WIX_LIGHT_EXECUTABLE light + PATHS "${CPACK_WIX_ROOT}/bin") + +if(NOT CPACK_WIX_LIGHT_EXECUTABLE) + message(FATAL_ERROR "Could not find the WiX light executable.") +endif() diff --git a/Modules/WIX.template.in b/Modules/WIX.template.in new file mode 100644 index 000000000..63fad7cb7 --- /dev/null +++ b/Modules/WIX.template.in @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 4de20c900..675f576f9 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -499,6 +499,14 @@ if(UNIX) ) endif() +if(WIN32) + set(CPACK_SRCS ${CPACK_SRCS} + CPack/WiX/cmCPackWIXGenerator.cxx + CPack/WiX/cmWIXSourceWriter.cxx + CPack/WiX/cmWIXRichTextFormatWriter.cxx + ) +endif() + if(APPLE) set(CPACK_SRCS ${CPACK_SRCS} CPack/cmCPackBundleGenerator.cxx diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx new file mode 100644 index 000000000..6e8c5ea0f --- /dev/null +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -0,0 +1,568 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmCPackWIXGenerator.h" + +#include +#include +#include +#include + +#include "cmWIXSourceWriter.h" +#include "cmWIXRichTextFormatWriter.h" + +#include +#include + +#include // for GUID generation + +int cmCPackWIXGenerator::InitializeInternal() +{ + componentPackageMethod = ONE_PACKAGE; + + return this->Superclass::InitializeInternal(); +} + +bool cmCPackWIXGenerator::RunWiXCommand(const std::string& command) +{ + std::string cpackTopLevel; + if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel)) + { + return false; + } + + std::string logFileName = cpackTopLevel + "/wix.log"; + + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "Running WiX command: " << command << std::endl); + + std::string output; + + int returnValue = 0; + bool status = cmSystemTools::RunSingleCommand(command.c_str(), &output, + &returnValue, 0, cmSystemTools::OUTPUT_NONE); + + std::ofstream logFile(logFileName.c_str(), std::ios::app); + logFile << command << std::endl; + logFile << output; + logFile.close(); + + if(!status || returnValue) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Problem running WiX candle. " + "Please check '" << logFileName << "' for errors." << std::endl); + + return false; + } + + return true; +} + +bool cmCPackWIXGenerator::RunCandleCommand( + const std::string& sourceFile, const std::string& objectFile) +{ + std::string executable; + if(!RequireOption("CPACK_WIX_CANDLE_EXECUTABLE", executable)) + { + return false; + } + + std::stringstream command; + command << QuotePath(executable); + command << " -nologo"; + command << " -arch " << GetArchitecture(); + command << " -out " << QuotePath(objectFile); + command << " " << QuotePath(sourceFile); + + return RunWiXCommand(command.str()); +} + +bool cmCPackWIXGenerator::RunLightCommand(const std::string& objectFiles) +{ + std::string executable; + if(!RequireOption("CPACK_WIX_LIGHT_EXECUTABLE", executable)) + { + return false; + } + + std::stringstream command; + command << QuotePath(executable); + command << " -nologo"; + command << " -out " << QuotePath(packageFileNames.at(0)); + command << " -ext WixUIExtension"; + command << " " << objectFiles; + + return RunWiXCommand(command.str()); +} + +int cmCPackWIXGenerator::PackageFiles() +{ + if(!PackageFilesImpl() || cmSystemTools::GetErrorOccuredFlag()) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Fatal WiX Generator Error" << std::endl); + return false; + } + + return true; +} + +bool cmCPackWIXGenerator::InitializeWiXConfiguration() +{ + if(!ReadListFile("CPackWIX.cmake")) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Error while executing CPackWIX.cmake" << std::endl); + return false; + } + + if(GetOption("CPACK_WIX_PRODUCT_GUID") == 0) + { + std::string guid = GenerateGUID(); + SetOption("CPACK_WIX_PRODUCT_GUID", guid.c_str()); + + cmCPackLogger(cmCPackLog::LOG_VERBOSE, + "CPACK_WIX_PRODUCT_GUID implicitly set to " << guid << " . " + << std::endl); + } + + if(GetOption("CPACK_WIX_UPGRADE_GUID") == 0) + { + std::string guid = GenerateGUID(); + SetOption("CPACK_WIX_UPGRADE_GUID", guid.c_str()); + + cmCPackLogger(cmCPackLog::LOG_WARNING, + "CPACK_WIX_UPGRADE_GUID implicitly set to " << guid << " . " + "Please refer to the documentation on how and why " + "you might want to set this explicitly." << std::endl); + } + + std::string cpackTopLevel; + if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel)) + { + return false; + } + + if(GetOption("CPACK_WIX_LICENSE_RTF") == 0) + { + std::string licenseFilename = cpackTopLevel + "/License.rtf"; + SetOption("CPACK_WIX_LICENSE_RTF", licenseFilename.c_str()); + + if(!CreateLicenseFile()) + { + return false; + } + } + + return true; +} + +bool cmCPackWIXGenerator::PackageFilesImpl() +{ + if(!InitializeWiXConfiguration()) + { + return false; + } + + if(!CreateWiXVariablesIncludeFile()) + { + return false; + } + + if(!CreateWiXSourceFiles()) + { + return false; + } + + std::stringstream objectFiles; + for(std::size_t i = 0; i < wixSources.size(); ++i) + { + const std::string& sourceFilename = wixSources[i]; + + std::string objectFilename = + cmSystemTools::GetFilenameWithoutExtension(sourceFilename) + ".wixobj"; + + if(!RunCandleCommand(sourceFilename, objectFilename)) + { + return false; + } + + objectFiles << " " << QuotePath(objectFilename); + } + + return RunLightCommand(objectFiles.str()); +} + +bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile() +{ + std::string cpackTopLevel; + if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel)) + { + return false; + } + + std::string includeFilename = + cpackTopLevel + "/cpack_variables.wxi"; + + cmWIXSourceWriter includeFile(Logger, includeFilename, true); + CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_GUID"); + CopyDefinition(includeFile, "CPACK_WIX_UPGRADE_GUID"); + CopyDefinition(includeFile, "CPACK_PACKAGE_VENDOR"); + CopyDefinition(includeFile, "CPACK_PACKAGE_NAME"); + CopyDefinition(includeFile, "CPACK_PACKAGE_VERSION"); + CopyDefinition(includeFile, "CPACK_WIX_LICENSE_RTF"); + + return true; +} + +void cmCPackWIXGenerator::CopyDefinition( + cmWIXSourceWriter &source, const std::string &name) +{ + const char* value = GetOption(name.c_str()); + if(value) + { + AddDefinition(source, name, value); + } +} + +void cmCPackWIXGenerator::AddDefinition(cmWIXSourceWriter& source, + const std::string& name, const std::string& value) +{ + std::stringstream tmp; + tmp << name << "=\"" << value << '"'; + + source.AddProcessingInstruction("define", + cmWIXSourceWriter::WindowsCodepageToUtf8(tmp.str())); +} + +bool cmCPackWIXGenerator::CreateWiXSourceFiles() +{ + std::string cpackTopLevel; + if(!RequireOption("CPACK_TOPLEVEL_DIRECTORY", cpackTopLevel)) + { + return false; + } + + std::string directoryDefinitionsFilename = + cpackTopLevel + "/directories.wxs"; + + wixSources.push_back(directoryDefinitionsFilename); + + cmWIXSourceWriter directoryDefinitions(Logger, directoryDefinitionsFilename); + directoryDefinitions.BeginElement("Fragment"); + + directoryDefinitions.BeginElement("Directory"); + directoryDefinitions.AddAttribute("Id", "TARGETDIR"); + directoryDefinitions.AddAttribute("Name", "SourceDir"); + + directoryDefinitions.BeginElement("Directory"); + if(GetArchitecture() == "x86") + { + directoryDefinitions.AddAttribute("Id", "ProgramFilesFolder"); + } + else + { + directoryDefinitions.AddAttribute("Id", "ProgramFiles64Folder"); + } + + std::vector install_root; + + std::string tmp; + if(!RequireOption("CPACK_PACKAGE_INSTALL_DIRECTORY", tmp)) + { + return false; + } + + cmSystemTools::SplitPath(tmp.c_str(), install_root); + + if(!install_root.empty() && install_root.back().empty()) + { + install_root.pop_back(); + } + + for(std::size_t i = 1; i < install_root.size(); ++i) + { + directoryDefinitions.BeginElement("Directory"); + + if(i == install_root.size() - 1) + { + directoryDefinitions.AddAttribute("Id", "INSTALL_ROOT"); + } + else + { + std::stringstream tmp; + tmp << "INSTALL_PREFIX_" << i; + directoryDefinitions.AddAttribute("Id", tmp.str()); + } + + directoryDefinitions.AddAttribute("Name", install_root[i]); + } + + std::size_t directoryCounter = 0; + std::size_t fileCounter = 0; + + std::string fileDefinitionsFilename = + cpackTopLevel + "/files.wxs"; + + wixSources.push_back(fileDefinitionsFilename); + + cmWIXSourceWriter fileDefinitions(Logger, fileDefinitionsFilename); + fileDefinitions.BeginElement("Fragment"); + + std::string featureDefinitionsFilename = + cpackTopLevel +"/features.wxs"; + + wixSources.push_back(featureDefinitionsFilename); + + cmWIXSourceWriter featureDefinitions(Logger, featureDefinitionsFilename); + featureDefinitions.BeginElement("Fragment"); + + featureDefinitions.BeginElement("Feature"); + featureDefinitions.AddAttribute("Id", "ProductFeature"); + featureDefinitions.AddAttribute("Title", Name); + featureDefinitions.AddAttribute("Level", "1"); + featureDefinitions.EndElement(); + + featureDefinitions.BeginElement("FeatureRef"); + featureDefinitions.AddAttribute("Id", "ProductFeature"); + + AddDirectoryAndFileDefinitons( + toplevel, "INSTALL_ROOT", + directoryDefinitions, fileDefinitions, featureDefinitions, + directoryCounter, fileCounter); + + featureDefinitions.EndElement(); + featureDefinitions.EndElement(); + fileDefinitions.EndElement(); + + for(std::size_t i = 1; i < install_root.size(); ++i) + { + directoryDefinitions.EndElement(); + } + + directoryDefinitions.EndElement(); + directoryDefinitions.EndElement(); + directoryDefinitions.EndElement(); + + std::string wixTemplate = FindTemplate("WIX.template.in"); + if(wixTemplate.empty()) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Could not find CPack WiX template file WIX.template.in" << std::endl); + return false; + } + + std::string mainSourceFilePath = cpackTopLevel + "/main.wxs"; + + if(!ConfigureFile(wixTemplate.c_str(), mainSourceFilePath .c_str())) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Failed creating '" << mainSourceFilePath << + "'' from template." << std::endl); + + return false; + } + + wixSources.push_back(mainSourceFilePath); + + return true; +} + +bool cmCPackWIXGenerator::CreateLicenseFile() +{ + std::string licenseSourceFilename; + if(!RequireOption("CPACK_RESOURCE_FILE_LICENSE", licenseSourceFilename)) + { + return false; + } + + std::string licenseDestinationFilename; + if(!RequireOption("CPACK_WIX_LICENSE_RTF", licenseDestinationFilename)) + { + return false; + } + + std::string extension = GetRightmostExtension(licenseSourceFilename); + + if(extension == ".rtf") + { + cmSystemTools::CopyAFile( + licenseSourceFilename.c_str(), + licenseDestinationFilename.c_str()); + } + else if(extension == ".txt") + { + cmWIXRichTextFormatWriter rtfWriter(licenseDestinationFilename); + + std::ifstream licenseSource(licenseSourceFilename.c_str()); + + std::string line; + while(std::getline(licenseSource, line)) + { + rtfWriter.AddText(line); + rtfWriter.AddText("\n"); + } + } + else + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "unsupported WiX License file extension '" << + extension << "'" << std::endl); + + return false; + } + + return true; +} + +void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( + const std::string& topdir, + const std::string& directoryId, + cmWIXSourceWriter& directoryDefinitions, + cmWIXSourceWriter& fileDefinitions, + cmWIXSourceWriter& featureDefinitions, + std::size_t& directoryCounter, + std::size_t& fileCounter) +{ + cmsys::Directory dir; + dir.Load(topdir.c_str()); + + for(std::size_t i = 0; i < dir.GetNumberOfFiles(); ++i) + { + std::string fileName = dir.GetFile(static_cast(i)); + + if(fileName == "." || fileName == "..") + { + continue; + } + + std::string fullPath = topdir + "/" + fileName; + + if(cmSystemTools::FileIsDirectory(fullPath.c_str())) + { + std::stringstream tmp; + tmp << "DIR_ID_" << ++directoryCounter; + std::string subDirectoryId = tmp.str(); + + directoryDefinitions.BeginElement("Directory"); + directoryDefinitions.AddAttribute("Id", subDirectoryId); + directoryDefinitions.AddAttribute("Name", fileName); + + AddDirectoryAndFileDefinitons( + fullPath, subDirectoryId, + directoryDefinitions, + fileDefinitions, + featureDefinitions, + directoryCounter, + fileCounter); + + directoryDefinitions.EndElement(); + } + else + { + std::stringstream tmp; + tmp << "_ID_" << ++fileCounter; + std::string idSuffix = tmp.str(); + + std::string componentId = std::string("CMP") + idSuffix; + std::string fileId = std::string("FILE") + idSuffix; + + fileDefinitions.BeginElement("DirectoryRef"); + fileDefinitions.AddAttribute("Id", directoryId); + + fileDefinitions.BeginElement("Component"); + fileDefinitions.AddAttribute("Id", componentId); + fileDefinitions.AddAttribute("Guid", "*"); + + fileDefinitions.BeginElement("File"); + fileDefinitions.AddAttribute("Id", fileId); + fileDefinitions.AddAttribute("Source", fullPath); + fileDefinitions.AddAttribute("KeyPath", "yes"); + + fileDefinitions.EndElement(); + fileDefinitions.EndElement(); + fileDefinitions.EndElement(); + + featureDefinitions.BeginElement("ComponentRef"); + featureDefinitions.AddAttribute("Id", componentId); + featureDefinitions.EndElement(); + } + } +} + +bool cmCPackWIXGenerator::RequireOption( + const std::string& name, std::string &value) const +{ + const char* tmp = GetOption(name.c_str()); + if(tmp) + { + value = tmp; + + return true; + } + else + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Required variable " << name << " not set" << std::endl); + + return false; + } +} + +std::string cmCPackWIXGenerator::GetArchitecture() const +{ + std::string void_p_size; + RequireOption("CPACK_WIX_SIZEOF_VOID_P", void_p_size); + + if(void_p_size == "8") + { + return "x64"; + } + else + { + return "x86"; + } +} + +std::string cmCPackWIXGenerator::GenerateGUID() +{ + UUID guid; + UuidCreate(&guid); + + RPC_CSTR tmp = 0; + UuidToStringA(&guid, &tmp); + + std::string result(reinterpret_cast(tmp)); + RpcStringFree(&tmp); + + return cmSystemTools::UpperCase(result); +} + +std::string cmCPackWIXGenerator::QuotePath(const std::string& path) +{ + return std::string("\"") + path + '"'; +} + +std::string cmCPackWIXGenerator::GetRightmostExtension( + const std::string& filename) +{ + std::string extension; + + std::string::size_type i = filename.rfind("."); + if(i != std::string::npos) + { + extension = filename.substr(i); + } + + return cmSystemTools::LowerCase(extension); +} diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h new file mode 100644 index 000000000..9fc9093cc --- /dev/null +++ b/Source/CPack/WiX/cmCPackWIXGenerator.h @@ -0,0 +1,101 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmCPackWIXGenerator_h +#define cmCPackWIXGenerator_h + +#include + +#include +#include + +class cmWIXSourceWriter; + +/** \class cmCPackWIXGenerator + * \brief A generator for WIX files + */ +class cmCPackWIXGenerator : public cmCPackGenerator +{ +public: + cmCPackTypeMacro(cmCPackWIXGenerator, cmCPackGenerator); + +protected: + virtual int InitializeInternal(); + + virtual int PackageFiles(); + + virtual const char* GetOutputExtension() + { + return ".msi"; + } + + virtual enum CPackSetDestdirSupport SupportsSetDestdir() const + { + return SETDESTDIR_UNSUPPORTED; + } + + virtual bool SupportsAbsoluteDestination() const + { + return false; + } + + virtual bool SupportsComponentInstallation() const + { + return false; + } + +private: + bool InitializeWiXConfiguration(); + + bool PackageFilesImpl(); + + bool CreateWiXVariablesIncludeFile(); + + void CopyDefinition( + cmWIXSourceWriter &source, const std::string &name); + + void AddDefinition(cmWIXSourceWriter& source, + const std::string& name, const std::string& value); + + bool CreateWiXSourceFiles(); + + bool CreateLicenseFile(); + + bool RunWiXCommand(const std::string& command); + + bool RunCandleCommand( + const std::string& sourceFile, const std::string& objectFile); + + bool RunLightCommand(const std::string& objectFiles); + + void AddDirectoryAndFileDefinitons(const std::string& topdir, + const std::string& directoryId, + cmWIXSourceWriter& directoryDefinitions, + cmWIXSourceWriter& fileDefinitions, + cmWIXSourceWriter& featureDefinitions, + std::size_t& directoryCounter, + std::size_t& fileCounter); + + bool RequireOption(const std::string& name, std::string& value) const; + + std::string GetArchitecture() const; + + static std::string GenerateGUID(); + + static std::string QuotePath(const std::string& path); + + static std::string GetRightmostExtension(const std::string& filename); + + std::vector wixSources; +}; + +#endif diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx new file mode 100644 index 000000000..07633443f --- /dev/null +++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx @@ -0,0 +1,137 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmWIXRichTextFormatWriter.h" + +#include + +cmWIXRichTextFormatWriter::cmWIXRichTextFormatWriter( + const std::string& filename): + file(filename.c_str(), std::ios::binary) +{ + StartGroup(); + WriteHeader(); + WriteDocumentPrefix(); +} + +cmWIXRichTextFormatWriter::~cmWIXRichTextFormatWriter() +{ + EndGroup(); + + /* I haven't seen this in the RTF spec but + * wordpad terminates its RTF like this */ + file << "\r\n"; + file.put(0); +} + +void cmWIXRichTextFormatWriter::AddText(const std::string& text) +{ + typedef unsigned char rtf_byte_t; + + for(std::size_t i = 0; i < text.size(); ++i) + { + rtf_byte_t c = rtf_byte_t(text[i]); + + switch(c) + { + case '\\': + file << "\\\\"; + break; + case '{': + file << "\\{"; + break; + case '}': + file << "\\}"; + break; + case '\n': + file << "\\par\r\n"; + break; + case '\r': + continue; + default: + { + if(c <= 0x7F) + { + file << c; + } + else + { + file << "[NON-ASCII-" << int(c) << "]"; + } + } + break; + } + } +} + +void cmWIXRichTextFormatWriter::WriteHeader() +{ + ControlWord("rtf1"); + ControlWord("ansi"); + ControlWord("ansicpg1252"); + ControlWord("deff0"); + ControlWord("deflang1031"); + + WriteFontTable(); + WriteGenerator(); +} + +void cmWIXRichTextFormatWriter::WriteFontTable() +{ + StartGroup(); + ControlWord("fonttbl"); + + StartGroup(); + ControlWord("f0"); + ControlWord("fswiss"); + ControlWord("fcharset0 Arial;"); + EndGroup(); + + EndGroup(); +} + +void cmWIXRichTextFormatWriter::WriteGenerator() +{ + StartGroup(); + NewControlWord("generator"); + file << " CPack WiX Generator (" << cmVersion::GetCMakeVersion() << ");"; + EndGroup(); +} + +void cmWIXRichTextFormatWriter::WriteDocumentPrefix() +{ + ControlWord("viewkind4"); + ControlWord("uc1"); + ControlWord("pard"); + ControlWord("f0"); + ControlWord("fs20"); +} + +void cmWIXRichTextFormatWriter::ControlWord(const std::string& keyword) +{ + file << "\\" << keyword; +} + +void cmWIXRichTextFormatWriter::NewControlWord(const std::string& keyword) +{ + file << "\\*\\" << keyword; +} + +void cmWIXRichTextFormatWriter::StartGroup() +{ + file.put('{'); +} + +void cmWIXRichTextFormatWriter::EndGroup() +{ + file.put('}'); +} diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.h b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h new file mode 100644 index 000000000..10b67c39f --- /dev/null +++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h @@ -0,0 +1,46 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2012 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmWIXRichTextFormatWriter_h +#define cmWIXRichTextFormatWriter_h + +#include + +/** \class cmWIXRichtTextFormatWriter + * \brief Helper class to generate Rich Text Format (RTF) documents + * from plain text (e.g. for license and welcome text) + */ +class cmWIXRichTextFormatWriter +{ +public: + cmWIXRichTextFormatWriter(const std::string& filename); + ~cmWIXRichTextFormatWriter(); + + void AddText(const std::string& text); + +private: + void WriteHeader(); + void WriteFontTable(); + void WriteGenerator(); + + void WriteDocumentPrefix(); + + void ControlWord(const std::string& keyword); + void NewControlWord(const std::string& keyword); + + void StartGroup(); + void EndGroup(); + + std::ofstream file; +}; + +#endif diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx new file mode 100644 index 000000000..cc00e5749 --- /dev/null +++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx @@ -0,0 +1,188 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmWIXSourceWriter.h" + +#include + +#include + +cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger, + const std::string& filename, + bool isIncludeFile): + Logger(logger), + file(filename.c_str()), + state(DEFAULT) +{ + WriteXMLDeclaration(); + + if(isIncludeFile) + { + BeginElement("Include"); + } + else + { + BeginElement("Wix"); + } + + AddAttribute("xmlns", "http://schemas.microsoft.com/wix/2006/wi"); +} + +cmWIXSourceWriter::~cmWIXSourceWriter() +{ + while(elements.size()) + { + EndElement(); + } +} + +void cmWIXSourceWriter::BeginElement(const std::string& name) +{ + if(state == BEGIN) + { + file << ">"; + } + + file << "\n"; + Indent(elements.size()); + file << "<" << name; + + elements.push_back(name); + state = BEGIN; +} + +void cmWIXSourceWriter::EndElement() +{ + if(elements.empty()) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "can not end WiX element with no open elements" << std::endl); + return; + } + + if(state == DEFAULT) + { + file << "\n"; + Indent(elements.size()-1); + file << ""; + } + else + { + file << "/>"; + } + + elements.pop_back(); + state = DEFAULT; +} + +void cmWIXSourceWriter::AddProcessingInstruction( + const std::string& target, const std::string& content) +{ + if(state == BEGIN) + { + file << ">"; + } + + file << "\n"; + Indent(elements.size()); + file << ""; + + state = DEFAULT; +} + +void cmWIXSourceWriter::AddAttribute( + const std::string& key, const std::string& value) +{ + std::string utf8 = WindowsCodepageToUtf8(value); + + file << " " << key << "=\"" << EscapeAttributeValue(utf8) << '"'; +} + +std::string cmWIXSourceWriter::WindowsCodepageToUtf8(const std::string& value) +{ + if(value.empty()) + { + return std::string(); + } + + int characterCount = MultiByteToWideChar( + CP_ACP, 0, value.c_str(), value.size(), 0, 0); + + if(characterCount == 0) + { + return std::string(); + } + + std::vector utf16(characterCount); + + MultiByteToWideChar( + CP_ACP, 0, value.c_str(), value.size(), &utf16[0], utf16.size()); + + int utf8ByteCount = + WideCharToMultiByte(CP_UTF8, 0, &utf16[0], utf16.size(), 0, 0, 0, 0); + + if(utf8ByteCount == 0) + { + return std::string(); + } + + std::vector utf8(utf8ByteCount); + + WideCharToMultiByte(CP_UTF8, 0, &utf16[0], utf16.size(), + &utf8[0], utf8.size(), 0, 0); + + return std::string(&utf8[0], utf8.size()); +} + + +void cmWIXSourceWriter::WriteXMLDeclaration() +{ + file << "" << std::endl; +} + +void cmWIXSourceWriter::Indent(std::size_t count) +{ + for(std::size_t i = 0; i < count; ++i) + { + file << " "; + } +} + +std::string cmWIXSourceWriter::EscapeAttributeValue( + const std::string& value) +{ + std::string result; + result.reserve(value.size()); + + char c = 0; + for(std::size_t i = 0 ; i < value.size(); ++i) + { + c = value[i]; + switch(c) + { + case '<': + result += "<"; + break; + case '&': + result +="&"; + break; + case '"': + result += """; + break; + default: + result += c; + break; + } + } + + return result; +} diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h new file mode 100644 index 000000000..582554d7d --- /dev/null +++ b/Source/CPack/WiX/cmWIXSourceWriter.h @@ -0,0 +1,67 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Kitware, Inc. + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmWIXSourceWriter_h +#define cmWIXSourceWriter_h + +#include +#include +#include + +#include + +/** \class cmWIXSourceWriter + * \brief Helper class to generate XML WiX source files + */ +class cmWIXSourceWriter +{ +public: + cmWIXSourceWriter(cmCPackLog* logger, + const std::string& filename, bool isIncludeFile = false); + + ~cmWIXSourceWriter(); + + void BeginElement(const std::string& name); + + void EndElement(); + + void AddProcessingInstruction( + const std::string& target, const std::string& content); + + void AddAttribute( + const std::string& key, const std::string& value); + + static std::string WindowsCodepageToUtf8(const std::string& value); + +private: + enum State + { + DEFAULT, + BEGIN + }; + + void WriteXMLDeclaration(); + + void Indent(std::size_t count); + + static std::string EscapeAttributeValue(const std::string& value); + + std::ofstream file; + + std::vector elements; + + State state; + + cmCPackLog* Logger; +}; + +#endif diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index eba1ef92d..557767391 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -19,6 +19,7 @@ #include "cmCPackZIPGenerator.h" #include "cmCPackSTGZGenerator.h" #include "cmCPackNSISGenerator.h" + #ifdef __APPLE__ # include "cmCPackDragNDropGenerator.h" # include "cmCPackBundleGenerator.h" @@ -37,6 +38,9 @@ # include "cmCPackRPMGenerator.h" #endif +#ifdef _WIN32 +# include "WiX/cmCPackWIXGenerator.h" +#endif #include "cmCPackLog.h" @@ -82,6 +86,13 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() this->RegisterGenerator("ZIP", "ZIP file format", cmCPackZIPGenerator::CreateGenerator); } +#ifdef _WIN32 + if (cmCPackWIXGenerator::CanGenerate()) + { + this->RegisterGenerator("WIX", "MSI file format via WiX tools", + cmCPackWIXGenerator::CreateGenerator); + } +#endif if (cmCPackTarBZip2Generator::CanGenerate()) { this->RegisterGenerator("TBZ2", "Tar BZip2 compression", diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 7dc26439f..2cef2fcfc 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -697,6 +697,29 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ endif() endif() + # On Windows run the CPackWiXGenerator test + # if the WiX Toolset seems to be available + if(WIN32) + file(TO_CMAKE_PATH "$ENV{WIX}" WIX_ROOT) + + find_program(WIX_LIGHT_EXECUTABLE light + PATHS "${WIX_ROOT}/bin" + DOC "WiX Toolset light.exe location") + + if(WIX_LIGHT_EXECUTABLE) + add_test(CPackWiXGenerator ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/CPackWiXGenerator" + "${CMake_BINARY_DIR}/Tests/CPackWiXGenerator" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project CPackWiXGenerator + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --test-command ${CMAKE_CMAKE_COMMAND} + "-DCPackWiXGenerator_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackWiXGenerator" + -P "${CMake_SOURCE_DIR}/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake") + endif() + endif() + if(CTEST_RUN_CPackComponents) set(CPackComponents_EXTRA_OPTIONS) if(APPLE) diff --git a/Tests/CPackWiXGenerator/CMakeLists.txt b/Tests/CPackWiXGenerator/CMakeLists.txt new file mode 100644 index 000000000..ce02f110d --- /dev/null +++ b/Tests/CPackWiXGenerator/CMakeLists.txt @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 2.8) + +project(CPackWiXGenerator) + +add_library(mylib mylib.cpp) + +add_executable(mylibapp mylibapp.cpp) +target_link_libraries(mylibapp mylib) + +install(TARGETS mylib + ARCHIVE + DESTINATION lib + COMPONENT libraries) + +install(TARGETS mylibapp + RUNTIME + DESTINATION bin + COMPONENT applications) + +install(FILES mylib.h "file with spaces.h" + DESTINATION include + COMPONENT headers) + +set(CPACK_GENERATOR "WIX") + +set(CPACK_PACKAGE_NAME "MyLib") +set(CPACK_PACKAGE_VENDOR "CMake.org") +set(CPACK_PACKAGE_CONTACT "somebody@cmake.org") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "MyLib - CPack Component Installation Example") + +set(CPACK_PACKAGE_VERSION_MAJOR "1") +set(CPACK_PACKAGE_VERSION_MINOR "0") +set(CPACK_PACKAGE_VERSION_PATCH "0") +set(CPACK_PACKAGE_INSTALL_DIRECTORY "CPack Component Example") + +set(CPACK_WIX_UPGRADE_GUID "BF20CE5E-7F7C-401D-8F7C-AB45E8D170E6") + +include(CPack) + +cpack_add_install_type(Full DISPLAY_NAME "Everything") +cpack_add_install_type(Developer) + +cpack_add_component_group(Runtime) + +cpack_add_component_group(Development + EXPANDED + DESCRIPTION "All of the tools you'll ever need to develop software") + +cpack_add_component(applications + DISPLAY_NAME "MyLib Application" + DESCRIPTION "An extremely useful application that makes use of MyLib" + GROUP Runtime + INSTALL_TYPES Full) + +cpack_add_component(documentation + DISPLAY_NAME "MyLib Documentation" + DESCRIPTION "The extensive suite of MyLib Application documentation files" + GROUP Runtime + INSTALL_TYPES Full) + +cpack_add_component(libraries + DISPLAY_NAME "Libraries" + DESCRIPTION "Static libraries used to build programs with MyLib" + GROUP Development + INSTALL_TYPES Developer Full) + +cpack_add_component(headers + DISPLAY_NAME "C++ Headers" + DESCRIPTION "C/C++ header files for use with MyLib" + GROUP Development + DEPENDS libraries + INSTALL_TYPES Developer Full) diff --git a/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake b/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake new file mode 100644 index 000000000..30e33cf22 --- /dev/null +++ b/Tests/CPackWiXGenerator/RunCPackVerifyResult.cmake @@ -0,0 +1,72 @@ +message(STATUS "=============================================================") +message(STATUS "CTEST_FULL_OUTPUT (Avoid ctest truncation of output)") +message(STATUS "") + +if(NOT CPackWiXGenerator_BINARY_DIR) + message(FATAL_ERROR "CPackWiXGenerator_BINARY_DIR not set") +endif() + +message(STATUS "CMAKE_COMMAND: ${CMAKE_COMMAND}") +message(STATUS "CMAKE_CPACK_COMMAND: ${CMAKE_CPACK_COMMAND}") +message(STATUS "CPackWiXGenerator_BINARY_DIR: ${CPackWiXGenerator_BINARY_DIR}") + +execute_process(COMMAND "${CMAKE_CPACK_COMMAND}" + RESULT_VARIABLE CPack_result + OUTPUT_VARIABLE CPack_output + ERROR_VARIABLE CPack_error + WORKING_DIRECTORY "${CPackWiXGenerator_BINARY_DIR}") + +if(CPack_result) + message(FATAL_ERROR "CPack execution went wrong!, CPack_output=${CPack_output}, CPack_error=${CPack_error}") +else () + message(STATUS "CPack_output=${CPack_output}") +endif() + +set(expected_file_mask "*.msi") +file(GLOB installer_file "${expected_file_mask}") + +message(STATUS "installer_file='${installer_file}'") +message(STATUS "expected_file_mask='${expected_file_mask}'") + +if(NOT installer_file) + message(FATAL_ERROR "installer_file does not exist.") +endif() + +function(run_wix_command command) + file(TO_CMAKE_PATH "$ENV{WIX}" WIX_ROOT) + set(WIX_PROGRAM "${WIX_ROOT}/bin/${command}.exe") + + if(NOT EXISTS "${WIX_PROGRAM}") + message(FATAL_ERROR "Failed to find WiX Tool: ${WIX_PROGRAM}") + endif() + + message(STATUS "Running WiX Tool: ${command} ${ARGN}") + + execute_process(COMMAND "${WIX_PROGRAM}" ${ARGN} + RESULT_VARIABLE WIX_result + OUTPUT_VARIABLE WIX_output + ERROR_VARIABLE WIX_output + WORKING_DIRECTORY "${CPackWiXGenerator_BINARY_DIR}") + + message(STATUS "${command} Output: \n${WIX_output}") + + if(WIX_result) + message(FATAL_ERROR "WiX ${command} failed: ${WIX_result}") + endif() +endfunction() + +file(GLOB WXS_SOURCE_FILES + "${CPackWiXGenerator_BINARY_DIR}/_CPack_Packages/*/WIX/*.wxs") + +if(NOT WXS_SOURCE_FILES) + message(FATAL_ERROR "Failed finding WiX source files to validate.") +endif() + +foreach(WXS_SOURCE_FILE IN LISTS WXS_SOURCE_FILES) + run_wix_command(wixcop "${WXS_SOURCE_FILE}") +endforeach() + +# error SMOK1076 : ICE61: This product should remove only older +# versions of itself. The Maximum version is not less +# than the current product. (1.0.0 1.0.0) +run_wix_command(smoke -nologo -wx -sw1076 "${installer_file}") diff --git a/Tests/CPackWiXGenerator/file with spaces.h b/Tests/CPackWiXGenerator/file with spaces.h new file mode 100644 index 000000000..e69de29bb diff --git a/Tests/CPackWiXGenerator/mylib.cpp b/Tests/CPackWiXGenerator/mylib.cpp new file mode 100644 index 000000000..8ddac198c --- /dev/null +++ b/Tests/CPackWiXGenerator/mylib.cpp @@ -0,0 +1,7 @@ +#include "mylib.h" +#include "stdio.h" + +void mylib_function() +{ + printf("This is mylib"); +} diff --git a/Tests/CPackWiXGenerator/mylib.h b/Tests/CPackWiXGenerator/mylib.h new file mode 100644 index 000000000..5d0a822db --- /dev/null +++ b/Tests/CPackWiXGenerator/mylib.h @@ -0,0 +1 @@ +void mylib_function(); diff --git a/Tests/CPackWiXGenerator/mylibapp.cpp b/Tests/CPackWiXGenerator/mylibapp.cpp new file mode 100644 index 000000000..a438ac77f --- /dev/null +++ b/Tests/CPackWiXGenerator/mylibapp.cpp @@ -0,0 +1,6 @@ +#include "mylib.h" + +int main() +{ + mylib_function(); +} From 0729ad476c94e2e8918e5fa9718a9173f8199e02 Mon Sep 17 00:00:00 2001 From: David Cole Date: Mon, 3 Dec 2012 13:16:35 -0500 Subject: [PATCH 056/170] CPack: Fix dashboard errors (#11575) Use same technique here with UuidToString as already found in cmGlobalVisualStudio7Generator::CreateGUID to avoid using a type that is not defined on older systems... (VS 7.0 and Borland) --- Source/CPack/WiX/cmCPackWIXGenerator.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 6e8c5ea0f..68ca60eea 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -539,8 +539,8 @@ std::string cmCPackWIXGenerator::GenerateGUID() UUID guid; UuidCreate(&guid); - RPC_CSTR tmp = 0; - UuidToStringA(&guid, &tmp); + unsigned char *tmp = 0; + UuidToString(&guid, &tmp); std::string result(reinterpret_cast(tmp)); RpcStringFree(&tmp); From ad0f73573fcc59c7c428ef5e529f8fec6a1cfbe6 Mon Sep 17 00:00:00 2001 From: David Cole Date: Mon, 3 Dec 2012 13:35:29 -0500 Subject: [PATCH 057/170] CPack: Fix dashboard warnings (#11575) Fix int vs. size_t conversion warnings that only showed up in the 64-bit builds. --- Source/CPack/WiX/cmWIXSourceWriter.cxx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx index cc00e5749..b890ccde2 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx @@ -115,7 +115,7 @@ std::string cmWIXSourceWriter::WindowsCodepageToUtf8(const std::string& value) } int characterCount = MultiByteToWideChar( - CP_ACP, 0, value.c_str(), value.size(), 0, 0); + CP_ACP, 0, value.c_str(), static_cast(value.size()), 0, 0); if(characterCount == 0) { @@ -125,10 +125,11 @@ std::string cmWIXSourceWriter::WindowsCodepageToUtf8(const std::string& value) std::vector utf16(characterCount); MultiByteToWideChar( - CP_ACP, 0, value.c_str(), value.size(), &utf16[0], utf16.size()); + CP_ACP, 0, value.c_str(), static_cast(value.size()), + &utf16[0], static_cast(utf16.size())); - int utf8ByteCount = - WideCharToMultiByte(CP_UTF8, 0, &utf16[0], utf16.size(), 0, 0, 0, 0); + int utf8ByteCount = WideCharToMultiByte( + CP_UTF8, 0, &utf16[0], static_cast(utf16.size()), 0, 0, 0, 0); if(utf8ByteCount == 0) { @@ -137,8 +138,8 @@ std::string cmWIXSourceWriter::WindowsCodepageToUtf8(const std::string& value) std::vector utf8(utf8ByteCount); - WideCharToMultiByte(CP_UTF8, 0, &utf16[0], utf16.size(), - &utf8[0], utf8.size(), 0, 0); + WideCharToMultiByte(CP_UTF8, 0, &utf16[0], static_cast(utf16.size()), + &utf8[0], static_cast(utf8.size()), 0, 0); return std::string(&utf8[0], utf8.size()); } From 7fa0f4b8703e08e958336b66f1b4f7db94ef4001 Mon Sep 17 00:00:00 2001 From: David Cole Date: Mon, 3 Dec 2012 13:53:43 -0500 Subject: [PATCH 058/170] VS11: Allow using folders with the VS11 Express Edition (#13770) Solution folders are supported as read-only in the VS11 Express Edition, so do not prohibit their use just because we detect the express edition (as we did in the VS10 generator). Inspired-by: Paris --- Source/cmGlobalGenerator.cxx | 2 +- Source/cmGlobalVisualStudio11Generator.cxx | 9 +++++++++ Source/cmGlobalVisualStudio11Generator.h | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 154e6298f..0f439e9cd 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -2047,7 +2047,7 @@ bool cmGlobalGenerator::UseFolderProperty() } // By default, this feature is OFF, since it is not supported in the - // Visual Studio Express editions: + // Visual Studio Express editions until VS11: // return false; } diff --git a/Source/cmGlobalVisualStudio11Generator.cxx b/Source/cmGlobalVisualStudio11Generator.cxx index ba30e18cb..b6d7d0452 100644 --- a/Source/cmGlobalVisualStudio11Generator.cxx +++ b/Source/cmGlobalVisualStudio11Generator.cxx @@ -93,3 +93,12 @@ cmLocalGenerator *cmGlobalVisualStudio11Generator::CreateLocalGenerator() lg->SetGlobalGenerator(this); return lg; } + +//---------------------------------------------------------------------------- +bool cmGlobalVisualStudio11Generator::UseFolderProperty() +{ + // Intentionally skip over the parent class implementation and call the + // grand-parent class's implementation. Folders are not supported by the + // Express editions in VS10 and earlier, but they are in VS11 Express. + return cmGlobalVisualStudio8Generator::UseFolderProperty(); +} diff --git a/Source/cmGlobalVisualStudio11Generator.h b/Source/cmGlobalVisualStudio11Generator.h index 8898c5d24..174f1ccb0 100644 --- a/Source/cmGlobalVisualStudio11Generator.h +++ b/Source/cmGlobalVisualStudio11Generator.h @@ -33,6 +33,7 @@ public: virtual std::string GetUserMacrosDirectory() { return ""; } protected: virtual const char* GetIDEVersion() { return "11.0"; } + bool UseFolderProperty(); private: class Factory; }; From 9d95dc3e23df8466cf333d552221dbc8c7640c12 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Tue, 4 Dec 2012 00:01:07 -0500 Subject: [PATCH 059/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 942c0d04e..1799905c6 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 20121203) +set(CMake_VERSION_TWEAK 20121204) #set(CMake_VERSION_RC 1) From 288f75edee99d6689f6651fe2ad00955d293d665 Mon Sep 17 00:00:00 2001 From: Amit Kulkarni Date: Mon, 3 Dec 2012 17:15:19 -0600 Subject: [PATCH 060/170] OpenBSD: Install shared libraries without executable permission --- Modules/Platform/OpenBSD.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/Platform/OpenBSD.cmake b/Modules/Platform/OpenBSD.cmake index df240e01b..53cabedde 100644 --- a/Modules/Platform/OpenBSD.cmake +++ b/Modules/Platform/OpenBSD.cmake @@ -16,3 +16,7 @@ if(NOT CMAKE_PLATFORM_RUNTIME_PATH) endif() set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_OPENBSD_VERSIONING 1) + +# OpenBSD policy requires that shared libraries be installed without +# executable permission. +set(CMAKE_INSTALL_SO_NO_EXE 1) From 6e7a3453b43897006cdd1b2587a3641fe3bd7731 Mon Sep 17 00:00:00 2001 From: Amit Kulkarni Date: Mon, 3 Dec 2012 17:23:10 -0600 Subject: [PATCH 061/170] OpenBSD: Add paths for Java 1.6.0/1.7.0 JRE/JDK --- Modules/CMakeDetermineJavaCompiler.cmake | 2 ++ Modules/FindJNI.cmake | 9 +++++++++ Modules/FindJava.cmake | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/Modules/CMakeDetermineJavaCompiler.cmake b/Modules/CMakeDetermineJavaCompiler.cmake index c4217f552..ae9f5fcaf 100644 --- a/Modules/CMakeDetermineJavaCompiler.cmake +++ b/Modules/CMakeDetermineJavaCompiler.cmake @@ -63,6 +63,8 @@ if(NOT CMAKE_Java_COMPILER) /usr/java/j2sdk1.4.2_09/bin /usr/lib/j2sdk1.5-sun/bin /opt/sun-jdk-1.5.0.04/bin + /usr/local/jdk-1.7.0/bin + /usr/local/jdk-1.6.0/bin ) # if no compiler has been specified yet, then look for one if(CMAKE_Java_COMPILER_INIT) diff --git a/Modules/FindJNI.cmake b/Modules/FindJNI.cmake index 0de3f7985..9d708ca15 100644 --- a/Modules/FindJNI.cmake +++ b/Modules/FindJNI.cmake @@ -120,6 +120,11 @@ JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES /usr/lib/jvm/default-java/jre/lib/{libarch} /usr/lib/jvm/default-java/jre/lib /usr/lib/jvm/default-java/lib + # OpenBSD specific paths for default JVM + /usr/local/jdk-1.7.0/jre/lib/{libarch} + /usr/local/jre-1.7.0/lib/{libarch} + /usr/local/jdk-1.6.0/jre/lib/{libarch} + /usr/local/jre-1.6.0/lib/{libarch} ) set(JAVA_JVM_LIBRARY_DIRECTORIES) @@ -153,6 +158,9 @@ set(JAVA_AWT_INCLUDE_DIRECTORIES /opt/sun-jdk-1.5.0.04/include # Debian specific path for default JVM /usr/lib/jvm/default-java/include + # OpenBSD specific path for default JVM + /usr/local/jdk-1.7.0/include + /usr/local/jdk-1.6.0/include ) foreach(JAVA_PROG "${JAVA_RUNTIME}" "${JAVA_COMPILE}" "${JAVA_ARCHIVE}") @@ -227,6 +235,7 @@ find_path(JAVA_INCLUDE_PATH2 jni_md.h ${JAVA_INCLUDE_PATH}/win32 ${JAVA_INCLUDE_PATH}/linux ${JAVA_INCLUDE_PATH}/freebsd + ${JAVA_INCLUDE_PATH}/openbsd ${JAVA_INCLUDE_PATH}/solaris ${JAVA_INCLUDE_PATH}/hp-ux ${JAVA_INCLUDE_PATH}/alpha diff --git a/Modules/FindJava.cmake b/Modules/FindJava.cmake index 1b4593d9c..2f02b7a4b 100644 --- a/Modules/FindJava.cmake +++ b/Modules/FindJava.cmake @@ -80,6 +80,8 @@ set(_JAVA_PATHS /usr/java/j2sdk1.4.2_09/bin /usr/lib/j2sdk1.5-sun/bin /opt/sun-jdk-1.5.0.04/bin + /usr/local/jdk-1.7.0/bin + /usr/local/jdk-1.6.0/bin ) find_program(Java_JAVA_EXECUTABLE NAMES java @@ -107,6 +109,7 @@ if(Java_JAVA_EXECUTABLE) # 2. OpenJDK 1.6 # 3. GCJ 1.5 # 4. Kaffe 1.4.2 + # 5. OpenJDK 1.7.x on OpenBSD if(var MATCHES "java version \"[0-9]+\\.[0-9]+\\.[0-9_.]+.*\".*") # This is most likely Sun / OpenJDK, or maybe GCJ-java compat layer string( REGEX REPLACE ".* version \"([0-9]+\\.[0-9]+\\.[0-9_.]+.*)\".*" @@ -115,6 +118,10 @@ if(Java_JAVA_EXECUTABLE) # Kaffe style string( REGEX REPLACE "java full version \"kaffe-([0-9]+\\.[0-9]+\\.[0-9_]+).*" "\\1" Java_VERSION_STRING "${var}" ) + elseif(var MATCHES "openjdk version \"[0-9]+\\.[0-9]+\\.[0-9_]+\".*") + # OpenJDK ver 1.7.x on OpenBSD + string( REGEX REPLACE "openjdk version \"([0-9]+\\.[0-9]+\\.[0-9_]+).*" + "\\1" Java_VERSION_STRING "${var}" ) else() if(NOT Java_FIND_QUIETLY) message(WARNING "regex not supported: ${var}. Please report") From 51c1119469ebf0e1c866711bd7acdf896fd74cf4 Mon Sep 17 00:00:00 2001 From: Amit Kulkarni Date: Mon, 3 Dec 2012 17:29:55 -0600 Subject: [PATCH 062/170] OpenBSD: Add path for Freetype under X.org --- Modules/FindFreetype.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/FindFreetype.cmake b/Modules/FindFreetype.cmake index cdb46beff..1df239904 100644 --- a/Modules/FindFreetype.cmake +++ b/Modules/FindFreetype.cmake @@ -46,6 +46,7 @@ find_path(FREETYPE_INCLUDE_DIR_ft2build ft2build.h HINTS ENV FREETYPE_DIR PATHS + /usr/X11R6 /usr/local/X11R6 /usr/local/X11 /usr/freeware @@ -56,6 +57,7 @@ find_path(FREETYPE_INCLUDE_DIR_freetype2 freetype/config/ftheader.h HINTS ENV FREETYPE_DIR PATHS + /usr/X11R6 /usr/local/X11R6 /usr/local/X11 /usr/freeware @@ -68,6 +70,7 @@ find_library(FREETYPE_LIBRARY ENV FREETYPE_DIR PATH_SUFFIXES lib PATHS + /usr/X11R6 /usr/local/X11R6 /usr/local/X11 /usr/freeware From 4a015f77e7be79bc02f6e3cb5b134cf29fbf4b49 Mon Sep 17 00:00:00 2001 From: Amit Kulkarni Date: Mon, 3 Dec 2012 17:38:49 -0600 Subject: [PATCH 063/170] OpenBSD: Add paths for Tcl/Tk 8.4/8.5 --- Modules/FindTCL.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Modules/FindTCL.cmake b/Modules/FindTCL.cmake index 2f84ae091..f649ddc56 100644 --- a/Modules/FindTCL.cmake +++ b/Modules/FindTCL.cmake @@ -82,6 +82,10 @@ set(TCLTK_POSSIBLE_LIB_PATHS "${TK_LIBRARY_PATH}" "${TCL_TCLSH_PATH_PARENT}/lib" "${TK_WISH_PATH_PARENT}/lib" + /usr/local/lib/tcl/tcl8.5 + /usr/local/lib/tcl/tk8.5 + /usr/local/lib/tcl/tcl8.4 + /usr/local/lib/tcl/tk8.4 ) if(WIN32) @@ -168,6 +172,10 @@ set(TCLTK_POSSIBLE_INCLUDE_PATHS /usr/include/tcl8.3 /usr/include/tcl8.2 /usr/include/tcl8.0 + /usr/local/include/tcl8.5 + /usr/local/include/tk8.5 + /usr/local/include/tcl8.4 + /usr/local/include/tk8.4 ) if(WIN32) From 2f49b71b65c7b595650ee61100430e37380bc948 Mon Sep 17 00:00:00 2001 From: Amit Kulkarni Date: Mon, 3 Dec 2012 17:42:10 -0600 Subject: [PATCH 064/170] OpenBSD: Add path for Lua 5.1 --- Modules/FindLua51.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/FindLua51.cmake b/Modules/FindLua51.cmake index eac25f526..2d7ed3d6c 100644 --- a/Modules/FindLua51.cmake +++ b/Modules/FindLua51.cmake @@ -28,7 +28,7 @@ find_path(LUA_INCLUDE_DIR lua.h HINTS ENV LUA_DIR - PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include + PATH_SUFFIXES include/lua51 include/lua5.1 include/lua-5.1 include/lua include PATHS ~/Library/Frameworks /Library/Frameworks From a74bd470a4d01cfa06710d039bb435b02682ac3f Mon Sep 17 00:00:00 2001 From: David Cole Date: Tue, 4 Dec 2012 14:37:41 -0500 Subject: [PATCH 065/170] CPack: Fix dashboard errors and warnings (#11575) ...revealed by the Nightly dashboard runs last night. Use "size_t" instead of "std::size_t" so that it compiles with Visual Studio 6, too. Fix warnings about shadowed "tmp" local variable and ordering of member variables vs. lines of code in the constructor initializer list. --- Source/CPack/WiX/cmCPackWIXGenerator.cxx | 22 +++++++++---------- Source/CPack/WiX/cmCPackWIXGenerator.h | 4 ++-- .../CPack/WiX/cmWIXRichTextFormatWriter.cxx | 2 +- Source/CPack/WiX/cmWIXSourceWriter.cxx | 6 ++--- Source/CPack/WiX/cmWIXSourceWriter.h | 8 +++---- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 68ca60eea..8b5862559 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -185,7 +185,7 @@ bool cmCPackWIXGenerator::PackageFilesImpl() } std::stringstream objectFiles; - for(std::size_t i = 0; i < wixSources.size(); ++i) + for(size_t i = 0; i < wixSources.size(); ++i) { const std::string& sourceFilename = wixSources[i]; @@ -290,7 +290,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() install_root.pop_back(); } - for(std::size_t i = 1; i < install_root.size(); ++i) + for(size_t i = 1; i < install_root.size(); ++i) { directoryDefinitions.BeginElement("Directory"); @@ -300,16 +300,16 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() } else { - std::stringstream tmp; - tmp << "INSTALL_PREFIX_" << i; - directoryDefinitions.AddAttribute("Id", tmp.str()); + std::stringstream ss; + ss << "INSTALL_PREFIX_" << i; + directoryDefinitions.AddAttribute("Id", ss.str()); } directoryDefinitions.AddAttribute("Name", install_root[i]); } - std::size_t directoryCounter = 0; - std::size_t fileCounter = 0; + size_t directoryCounter = 0; + size_t fileCounter = 0; std::string fileDefinitionsFilename = cpackTopLevel + "/files.wxs"; @@ -345,7 +345,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles() featureDefinitions.EndElement(); fileDefinitions.EndElement(); - for(std::size_t i = 1; i < install_root.size(); ++i) + for(size_t i = 1; i < install_root.size(); ++i) { directoryDefinitions.EndElement(); } @@ -431,13 +431,13 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons( cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions, - std::size_t& directoryCounter, - std::size_t& fileCounter) + size_t& directoryCounter, + size_t& fileCounter) { cmsys::Directory dir; dir.Load(topdir.c_str()); - for(std::size_t i = 0; i < dir.GetNumberOfFiles(); ++i) + for(size_t i = 0; i < dir.GetNumberOfFiles(); ++i) { std::string fileName = dir.GetFile(static_cast(i)); diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h index 9fc9093cc..0e95d70f6 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.h +++ b/Source/CPack/WiX/cmCPackWIXGenerator.h @@ -82,8 +82,8 @@ private: cmWIXSourceWriter& directoryDefinitions, cmWIXSourceWriter& fileDefinitions, cmWIXSourceWriter& featureDefinitions, - std::size_t& directoryCounter, - std::size_t& fileCounter); + size_t& directoryCounter, + size_t& fileCounter); bool RequireOption(const std::string& name, std::string& value) const; diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx index 07633443f..774c22c76 100644 --- a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx +++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx @@ -37,7 +37,7 @@ void cmWIXRichTextFormatWriter::AddText(const std::string& text) { typedef unsigned char rtf_byte_t; - for(std::size_t i = 0; i < text.size(); ++i) + for(size_t i = 0; i < text.size(); ++i) { rtf_byte_t c = rtf_byte_t(text[i]); diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx index b890ccde2..af7ba807f 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.cxx +++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx @@ -150,9 +150,9 @@ void cmWIXSourceWriter::WriteXMLDeclaration() file << "" << std::endl; } -void cmWIXSourceWriter::Indent(std::size_t count) +void cmWIXSourceWriter::Indent(size_t count) { - for(std::size_t i = 0; i < count; ++i) + for(size_t i = 0; i < count; ++i) { file << " "; } @@ -165,7 +165,7 @@ std::string cmWIXSourceWriter::EscapeAttributeValue( result.reserve(value.size()); char c = 0; - for(std::size_t i = 0 ; i < value.size(); ++i) + for(size_t i = 0 ; i < value.size(); ++i) { c = value[i]; switch(c) diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h index 582554d7d..1dafc1ff2 100644 --- a/Source/CPack/WiX/cmWIXSourceWriter.h +++ b/Source/CPack/WiX/cmWIXSourceWriter.h @@ -51,17 +51,17 @@ private: void WriteXMLDeclaration(); - void Indent(std::size_t count); + void Indent(size_t count); static std::string EscapeAttributeValue(const std::string& value); - std::ofstream file; + cmCPackLog* Logger; - std::vector elements; + std::ofstream file; State state; - cmCPackLog* Logger; + std::vector elements; }; #endif From 7c2891daebc971380c1945b5976937eebbf4b79e Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Wed, 5 Dec 2012 00:01:05 -0500 Subject: [PATCH 066/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 1799905c6..a97bf61ec 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 20121204) +set(CMake_VERSION_TWEAK 20121205) #set(CMake_VERSION_RC 1) From 711e2b3b5c674d4f754b5b214d511be6ce7e8f4d Mon Sep 17 00:00:00 2001 From: Nils Gladitz Date: Fri, 5 Oct 2012 21:55:07 +0200 Subject: [PATCH 067/170] CMake: Add TIMESTAMP subcommand to string and file commands --- Source/cmBootstrapCommands.cxx | 1 + Source/cmFileCommand.cxx | 57 ++++++++ Source/cmFileCommand.h | 10 ++ Source/cmStringCommand.cxx | 54 +++++++ Source/cmStringCommand.h | 30 +++- Source/cmTimestamp.cxx | 134 ++++++++++++++++++ Source/cmTimestamp.h | 40 ++++++ Tests/CMakeTests/File-TIMESTAMP-BadArg1.cmake | 1 + Tests/CMakeTests/File-TIMESTAMP-NoFile.cmake | 2 + .../CMakeTests/File-TIMESTAMP-NotBogus.cmake | 24 ++++ Tests/CMakeTests/File-TIMESTAMP-Works.cmake | 2 + Tests/CMakeTests/FileTest.cmake.in | 12 ++ .../String-TIMESTAMP-AllSpecifiers.cmake | 11 ++ .../CMakeTests/String-TIMESTAMP-BadArg1.cmake | 1 + .../CMakeTests/String-TIMESTAMP-BadArg2.cmake | 1 + .../CMakeTests/String-TIMESTAMP-BadArg3.cmake | 1 + .../String-TIMESTAMP-CustomFormatLocal.cmake | 2 + .../String-TIMESTAMP-CustomFormatUTC.cmake | 2 + .../String-TIMESTAMP-DefaulFormatUTC.cmake | 2 + .../String-TIMESTAMP-DefaultFormatLocal.cmake | 2 + .../String-TIMESTAMP-DefaultFormatUTC.cmake | 2 + ...String-TIMESTAMP-IncompleteSpecifier.cmake | 2 + .../String-TIMESTAMP-UnknownSpecifier.cmake | 2 + Tests/CMakeTests/StringTest.cmake.in | 30 ++++ 24 files changed, 424 insertions(+), 1 deletion(-) create mode 100644 Source/cmTimestamp.cxx create mode 100644 Source/cmTimestamp.h create mode 100644 Tests/CMakeTests/File-TIMESTAMP-BadArg1.cmake create mode 100644 Tests/CMakeTests/File-TIMESTAMP-NoFile.cmake create mode 100644 Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake create mode 100644 Tests/CMakeTests/File-TIMESTAMP-Works.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-AllSpecifiers.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-BadArg1.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-BadArg2.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-BadArg3.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-CustomFormatLocal.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-CustomFormatUTC.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-DefaulFormatUTC.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-DefaultFormatLocal.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-DefaultFormatUTC.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-IncompleteSpecifier.cmake create mode 100644 Tests/CMakeTests/String-TIMESTAMP-UnknownSpecifier.cmake diff --git a/Source/cmBootstrapCommands.cxx b/Source/cmBootstrapCommands.cxx index 9097a7482..e3a2ad4e5 100644 --- a/Source/cmBootstrapCommands.cxx +++ b/Source/cmBootstrapCommands.cxx @@ -89,6 +89,7 @@ #include "cmStringCommand.cxx" #include "cmSubdirCommand.cxx" #include "cmTargetLinkLibrariesCommand.cxx" +#include "cmTimestamp.cxx" #include "cmTryCompileCommand.cxx" #include "cmTryRunCommand.cxx" #include "cmUnsetCommand.cxx" diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index b877f3c3a..42df3a17f 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -17,6 +17,8 @@ #include "cmFileTimeComparison.h" #include "cmCryptoHash.h" +#include "cmTimestamp.h" + #if defined(CMAKE_BUILD_WITH_CMAKE) #include "cm_curl.h" #endif @@ -161,6 +163,10 @@ bool cmFileCommand { return this->HandleCMakePathCommand(args, true); } + else if ( subCommand == "TIMESTAMP" ) + { + return this->HandleTimestampCommand(args); + } std::string e = "does not recognize sub-command "+subCommand; this->SetError(e.c_str()); @@ -3241,3 +3247,54 @@ cmFileCommand::HandleUploadCommand(std::vector const& args) return false; #endif } + +//---------------------------------------------------------------------------- +bool cmFileCommand::HandleTimestampCommand( + std::vector const& args) +{ + if(args.size() < 3) + { + this->SetError("sub-command TIMESTAMP requires at least two arguments."); + return false; + } + else if(args.size() > 5) + { + this->SetError("sub-command TIMESTAMP takes at most four arguments."); + return false; + } + + int argsIndex = 1; + + const std::string& filename = args[argsIndex++]; + + const std::string& outputVariable = args[argsIndex++]; + + std::string formatString; + if(args.size() > argsIndex && args[argsIndex] != "UTC") + { + formatString = args[argsIndex++]; + } + + bool utcFlag = false; + if(args.size() > argsIndex) + { + if(args[argsIndex] == "UTC") + { + utcFlag = true; + } + else + { + std::string e = " TIMESTAMP sub-command does not recognize option " + + args[argsIndex] + "."; + this->SetError(e.c_str()); + return false; + } + } + + cmTimestamp timestamp; + std::string result = timestamp.FileModificationTime( + filename.c_str(), formatString, utcFlag); + this->Makefile->AddDefinition(outputVariable.c_str(), result.c_str()); + + return true; +} diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index a0862ec9b..5550dbe64 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -87,6 +87,8 @@ public: " [TLS_VERIFY on|off] [TLS_CAINFO file])\n" " file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n" " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n" + " file(TIMESTAMP " + " [] [UTC])\n" "WRITE will write a message into a file called 'filename'. It " "overwrites the file if it already exists, and creates the file " "if it does not exist. (If the file is a build input, use " @@ -200,6 +202,12 @@ public: "If SHOW_PROGRESS is specified, progress information will be printed " "as status messages until the operation is complete." "\n" + "TIMESTAMP will write a string representation of " + "the modification time of to .\n" + "Should the command be unable to obtain a timestamp " + " will be set to the empty string \"\".\n" + "See documentation of the string TIMESTAMP sub-command for more details." + "\n" "The file() command also provides COPY and INSTALL signatures:\n" " file( files... DESTINATION \n" " [FILE_PERMISSIONS permissions...]\n" @@ -260,6 +268,8 @@ protected: bool HandleInstallCommand(std::vector const& args); bool HandleDownloadCommand(std::vector const& args); bool HandleUploadCommand(std::vector const& args); + + bool HandleTimestampCommand(std::vector const& args); }; diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index 0193dc9e7..c402738fe 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -19,6 +19,8 @@ #include #include +#include + //---------------------------------------------------------------------------- bool cmStringCommand ::InitialPass(std::vector const& args, cmExecutionStatus &) @@ -87,6 +89,10 @@ bool cmStringCommand { return this->HandleFindCommand(args); } + else if(subCommand == "TIMESTAMP") + { + return this->HandleTimestampCommand(args); + } std::string e = "does not recognize sub-command "+subCommand; this->SetError(e.c_str()); @@ -879,3 +885,51 @@ bool cmStringCommand this->Makefile->AddDefinition(variableName.c_str(), &*result.begin()); return true; } + +//---------------------------------------------------------------------------- +bool cmStringCommand +::HandleTimestampCommand(std::vector const& args) +{ + if(args.size() < 2) + { + this->SetError("sub-command TIMESTAMP requires at least one argument."); + return false; + } + else if(args.size() > 4) + { + this->SetError("sub-command TIMESTAMP takes at most three arguments."); + return false; + } + + int argsIndex = 1; + + const std::string &outputVariable = args[argsIndex++]; + + std::string formatString; + if(args.size() > argsIndex && args[argsIndex] != "UTC") + { + formatString = args[argsIndex++]; + } + + bool utcFlag = false; + if(args.size() > argsIndex) + { + if(args[argsIndex] == "UTC") + { + utcFlag = true; + } + else + { + std::string e = " TIMESTAMP sub-command does not recognize option " + + args[argsIndex] + "."; + this->SetError(e.c_str()); + return false; + } + } + + cmTimestamp timestamp; + std::string result = timestamp.CurrentTime(formatString, utcFlag); + this->Makefile->AddDefinition(outputVariable.c_str(), result.c_str()); + + return true; +} diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index 728b1bc5f..7e0694ed6 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -93,6 +93,7 @@ public: " string(RANDOM [LENGTH ] [ALPHABET ]\n" " [RANDOM_SEED ] )\n" " string(FIND [REVERSE])\n" + " string(TIMESTAMP [] [UTC])\n" "REGEX MATCH will match the regular expression once and store the " "match in the output variable.\n" "REGEX MATCHALL will match the regular expression as many times as " @@ -142,7 +143,33 @@ public: " () Saves a matched subexpression, which can be referenced \n" " in the REGEX REPLACE operation. Additionally it is saved\n" " by all regular expression-related commands, including \n" - " e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9)."; + " e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).\n" + "TIMESTAMP will write a string representation of " + "the current date and/or time to .\n" + "Should the command be unable to obtain a timestamp " + " will be set to the empty string \"\".\n" + "The optional UTC flag requests the current date/time " + "representation to be in Coordinated Universal Time (UTC) " + "rather than local time.\n" + "The optional may contain the following " + "format specifiers: \n" + " %d The day of the current month (01-31).\n" + " %H The hour on a 24-hour clock (00-23).\n" + " %I The hour on a 12-hour clock (01-12).\n" + " %j The day of the current year (001-366).\n" + " %m The month of the current year (01-12).\n" + " %M The minute of the current hour (00-59).\n" + " %S The second of the current minute.\n" + " 60 represents a leap second. (00-60)\n" + " %U The week number of the current year (00-53).\n" + " %w The day of the current week. 0 is Sunday. (0-6)\n" + " %y The last two digits of the current year (00-99)\n" + " %Y The current year. \n" + "Unknown format specifiers will be ignored " + "and copied to the output as-is.\n" + "If no explicit is given it will default to:\n" + " %Y-%m-%dT%H:%M:%S for local time.\n" + " %Y-%m-%dT%H:%M:%SZ for UTC."; } cmTypeMacro(cmStringCommand, cmCommand); @@ -165,6 +192,7 @@ protected: bool HandleStripCommand(std::vector const& args); bool HandleRandomCommand(std::vector const& args); bool HandleFindCommand(std::vector const& args); + bool HandleTimestampCommand(std::vector const& args); class RegexReplacement { diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx new file mode 100644 index 000000000..f1115e672 --- /dev/null +++ b/Source/cmTimestamp.cxx @@ -0,0 +1,134 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmTimestamp.h" + +#include + +#include +#include + +//---------------------------------------------------------------------------- +std::string cmTimestamp::CurrentTime( + const std::string& formatString, bool utcFlag) +{ + time_t currentTimeT = time(0); + if(currentTimeT == time_t(-1)) return std::string(); + + return CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag); +} + +std::string cmTimestamp::FileModificationTime(const char* path, + const std::string& formatString, bool utcFlag) +{ +#ifdef _WIN32 + struct _stat info; + std::memset(&info, 0, sizeof(info)); + + if(_stat(path, &info) != 0) + return std::string(); + + time_t currentTimeT = info.st_mtime; +#else + struct stat info; + std::memset(&info, 0, sizeof(info)); + + if(stat(path, &info) != 0) + return std::string(); + + time_t currentTimeT = info.st_mtime; +#endif + + return CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag); +} + +std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT, + std::string formatString, bool utcFlag) +{ + if(formatString.empty()) + { + formatString = "%Y-%m-%dT%H:%M:%S"; + if(utcFlag) formatString += "Z"; + } + + struct tm timeStruct; + std::memset(&timeStruct, 0, sizeof(timeStruct)); + + if(utcFlag) + { + tm* ptr = gmtime(&timeT); + if(ptr == 0) return std::string(); + + timeStruct = *ptr; + } + else + { + struct tm* ptr = localtime(&timeT); + if(ptr == 0) return std::string(); + + timeStruct = *ptr; + } + + std::string result; + for(std::string::size_type i = 0; i < formatString.size(); ++i) + { + char c1 = formatString[i]; + char c2 = (i+1 < formatString.size()) ? + formatString[i+1] : 0; + + if(c1 == '%' && c2 != 0) + { + result += AddTimestampComponent(c2, timeStruct); + ++i; + } + else + { + result += c1; + } + } + + return result; +} + +//---------------------------------------------------------------------------- +std::string cmTimestamp::AddTimestampComponent( + char flag, struct tm& timeStruct) +{ + std::string formatString = "%"; + formatString += flag; + + switch(flag) + { + case 'd': + case 'H': + case 'I': + case 'j': + case 'm': + case 'M': + case 'S': + case 'U': + case 'w': + case 'y': + case 'Y': + break; + default: + { + return formatString; + } + } + + char buffer[16]; + + size_t size = strftime(buffer, sizeof(buffer), + formatString.c_str(), &timeStruct); + + return std::string(buffer, size); +} diff --git a/Source/cmTimestamp.h b/Source/cmTimestamp.h new file mode 100644 index 000000000..24c186983 --- /dev/null +++ b/Source/cmTimestamp.h @@ -0,0 +1,40 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#ifndef cmTimestamp_h +#define cmTimestamp_h + +#include +#include + +/** \class cmTimestamp + * \brief Utility class to generate sting representation of a timestamp + * + */ +class cmTimestamp +{ +public: + cmTimestamp() {} + + std::string CurrentTime(const std::string& formatString, bool utcFlag); + + std::string FileModificationTime(const char* path, + const std::string& formatString, bool utcFlag); + +private: + std::string CreateTimestampFromTimeT(time_t timeT, + std::string formatString, bool utcFlag); + + std::string AddTimestampComponent(char flag, struct tm& timeStruct); +}; + + +#endif diff --git a/Tests/CMakeTests/File-TIMESTAMP-BadArg1.cmake b/Tests/CMakeTests/File-TIMESTAMP-BadArg1.cmake new file mode 100644 index 000000000..cc15c77a8 --- /dev/null +++ b/Tests/CMakeTests/File-TIMESTAMP-BadArg1.cmake @@ -0,0 +1 @@ +file(TIMESTAMP "${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt") diff --git a/Tests/CMakeTests/File-TIMESTAMP-NoFile.cmake b/Tests/CMakeTests/File-TIMESTAMP-NoFile.cmake new file mode 100644 index 000000000..62390e792 --- /dev/null +++ b/Tests/CMakeTests/File-TIMESTAMP-NoFile.cmake @@ -0,0 +1,2 @@ +file(TIMESTAMP "${CMAKE_CURRENT_LIST_DIR}/DoesNotExist.cmake" output) +message("~${output}~") diff --git a/Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake b/Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake new file mode 100644 index 000000000..d0e5fe35f --- /dev/null +++ b/Tests/CMakeTests/File-TIMESTAMP-NotBogus.cmake @@ -0,0 +1,24 @@ +set(STAMP_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/FileTimestamp-Stamp") +set(STAMP_FORMAT "%Y-%m-%d") + +string(TIMESTAMP timestamp1 "${STAMP_FORMAT}") + +file(WRITE "${STAMP_FILENAME}" "foo") +file(TIMESTAMP "${STAMP_FILENAME}" timestamp2 "${STAMP_FORMAT}") + +string(TIMESTAMP timestamp3 "${STAMP_FORMAT}") + +message(STATUS "timestamp1 [${timestamp1}]") +message(STATUS "timestamp2 [${timestamp2}]") +message(STATUS "timestamp3 [${timestamp3}]") + +if(timestamp1 STREQUAL timestamp3) + if(NOT timestamp1 STREQUAL timestamp2) + message(FATAL_ERROR + "timestamp mismatch [${timestamp1}] != [${timestamp2}]") + else() + message("all timestamps match") + endif() +else() + message(WARNING "this test may race when run at midnight") +endif() diff --git a/Tests/CMakeTests/File-TIMESTAMP-Works.cmake b/Tests/CMakeTests/File-TIMESTAMP-Works.cmake new file mode 100644 index 000000000..4351b19dd --- /dev/null +++ b/Tests/CMakeTests/File-TIMESTAMP-Works.cmake @@ -0,0 +1,2 @@ +file(TIMESTAMP "${CMAKE_CURRENT_LIST_DIR}/CMakeLists.txt" output UTC) +message("~${output}~") diff --git a/Tests/CMakeTests/FileTest.cmake.in b/Tests/CMakeTests/FileTest.cmake.in index 960d3c172..61523e6f6 100644 --- a/Tests/CMakeTests/FileTest.cmake.in +++ b/Tests/CMakeTests/FileTest.cmake.in @@ -36,6 +36,14 @@ set(SHA384-Works-RESULT 0) set(SHA384-Works-STDERR "1de9560b4e030e02051ea408200ffc55d70c97ac64ebf822461a5c786f495c36df43259b14483bc8d364f0106f4971ee") set(SHA512-Works-RESULT 0) set(SHA512-Works-STDERR "3982a1b4e651768bec70ab1fb97045cb7a659f4ba7203d501c52ab2e803071f9d5fd272022df15f27727fc67f8cd022e710e29010b2a9c0b467c111e2f6abf51") +set(TIMESTAMP-NoFile-RESULT 0) +set(TIMESTAMP-NoFile-STDERR "~~") +set(TIMESTAMP-BadArg1-RESULT 1) +set(TIMESTAMP-BadArg1-STDERR "file sub-command TIMESTAMP requires at least two arguments") +set(TIMESTAMP-NotBogus-RESULT 0) +set(TIMESTAMP-NotBogus-STDERR "all timestamps match") +set(TIMESTAMP-Works-RESULT 0) +set(TIMESTAMP-Works-STDERR "~[0-9]*-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-6][0-9]Z~") include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") check_cmake_test(File @@ -58,6 +66,10 @@ check_cmake_test(File SHA256-Works SHA384-Works SHA512-Works + TIMESTAMP-NoFile + TIMESTAMP-BadArg1 + TIMESTAMP-NotBogus + TIMESTAMP-Works ) file(GLOB hum) diff --git a/Tests/CMakeTests/String-TIMESTAMP-AllSpecifiers.cmake b/Tests/CMakeTests/String-TIMESTAMP-AllSpecifiers.cmake new file mode 100644 index 000000000..2d0fcc89c --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-AllSpecifiers.cmake @@ -0,0 +1,11 @@ +string(TIMESTAMP output "%d;%H;%I;%j;%m;%M;%S;%U;%w;%y;%Y") +message("~${output}~") + +list(LENGTH output output_length) + +set(expected_output_length 11) + +if(NOT output_length EQUAL ${expected_output_length}) + message(FATAL_ERROR "expected ${expected_output_length} entries in output " + "with all specifiers; found ${output_length}") +endif() diff --git a/Tests/CMakeTests/String-TIMESTAMP-BadArg1.cmake b/Tests/CMakeTests/String-TIMESTAMP-BadArg1.cmake new file mode 100644 index 000000000..8f2d9f8b4 --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-BadArg1.cmake @@ -0,0 +1 @@ +string(TIMESTAMP) diff --git a/Tests/CMakeTests/String-TIMESTAMP-BadArg2.cmake b/Tests/CMakeTests/String-TIMESTAMP-BadArg2.cmake new file mode 100644 index 000000000..c1e512684 --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-BadArg2.cmake @@ -0,0 +1 @@ +string(TIMESTAMP output_variable "%Y" UTF) diff --git a/Tests/CMakeTests/String-TIMESTAMP-BadArg3.cmake b/Tests/CMakeTests/String-TIMESTAMP-BadArg3.cmake new file mode 100644 index 000000000..3d577df3f --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-BadArg3.cmake @@ -0,0 +1 @@ +string(TIMESTAMP output_variable "%Y" UTC UTC) diff --git a/Tests/CMakeTests/String-TIMESTAMP-CustomFormatLocal.cmake b/Tests/CMakeTests/String-TIMESTAMP-CustomFormatLocal.cmake new file mode 100644 index 000000000..eab2a45de --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-CustomFormatLocal.cmake @@ -0,0 +1,2 @@ +string(TIMESTAMP output "%S") +message("~${output}~") diff --git a/Tests/CMakeTests/String-TIMESTAMP-CustomFormatUTC.cmake b/Tests/CMakeTests/String-TIMESTAMP-CustomFormatUTC.cmake new file mode 100644 index 000000000..eab2a45de --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-CustomFormatUTC.cmake @@ -0,0 +1,2 @@ +string(TIMESTAMP output "%S") +message("~${output}~") diff --git a/Tests/CMakeTests/String-TIMESTAMP-DefaulFormatUTC.cmake b/Tests/CMakeTests/String-TIMESTAMP-DefaulFormatUTC.cmake new file mode 100644 index 000000000..dad6a8d97 --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-DefaulFormatUTC.cmake @@ -0,0 +1,2 @@ +string(TIMESTAMP output UTC) +message("~${output}~") diff --git a/Tests/CMakeTests/String-TIMESTAMP-DefaultFormatLocal.cmake b/Tests/CMakeTests/String-TIMESTAMP-DefaultFormatLocal.cmake new file mode 100644 index 000000000..d7c7dde1c --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-DefaultFormatLocal.cmake @@ -0,0 +1,2 @@ +string(TIMESTAMP output) +message("~${output}~") diff --git a/Tests/CMakeTests/String-TIMESTAMP-DefaultFormatUTC.cmake b/Tests/CMakeTests/String-TIMESTAMP-DefaultFormatUTC.cmake new file mode 100644 index 000000000..dad6a8d97 --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-DefaultFormatUTC.cmake @@ -0,0 +1,2 @@ +string(TIMESTAMP output UTC) +message("~${output}~") diff --git a/Tests/CMakeTests/String-TIMESTAMP-IncompleteSpecifier.cmake b/Tests/CMakeTests/String-TIMESTAMP-IncompleteSpecifier.cmake new file mode 100644 index 000000000..ffc5656fa --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-IncompleteSpecifier.cmake @@ -0,0 +1,2 @@ +string(TIMESTAMP output "foobar%") +message("~${output}~") diff --git a/Tests/CMakeTests/String-TIMESTAMP-UnknownSpecifier.cmake b/Tests/CMakeTests/String-TIMESTAMP-UnknownSpecifier.cmake new file mode 100644 index 000000000..0e145e5ec --- /dev/null +++ b/Tests/CMakeTests/String-TIMESTAMP-UnknownSpecifier.cmake @@ -0,0 +1,2 @@ +string(TIMESTAMP output "%g") +message("~${output}~") diff --git a/Tests/CMakeTests/StringTest.cmake.in b/Tests/CMakeTests/StringTest.cmake.in index 49e7dc90c..a9fe428e3 100644 --- a/Tests/CMakeTests/StringTest.cmake.in +++ b/Tests/CMakeTests/StringTest.cmake.in @@ -16,6 +16,26 @@ set(SHA384-Works-RESULT 0) set(SHA384-Works-STDERR "1de9560b4e030e02051ea408200ffc55d70c97ac64ebf822461a5c786f495c36df43259b14483bc8d364f0106f4971ee") set(SHA512-Works-RESULT 0) set(SHA512-Works-STDERR "3982a1b4e651768bec70ab1fb97045cb7a659f4ba7203d501c52ab2e803071f9d5fd272022df15f27727fc67f8cd022e710e29010b2a9c0b467c111e2f6abf51") +set(TIMESTAMP-BadArg1-RESULT 1) +set(TIMESTAMP-BadArg1-STDERR "string sub-command TIMESTAMP requires at least one argument") +set(TIMESTAMP-BadArg2-RESULT 1) +set(TIMESTAMP-BadArg2-STDERR "string TIMESTAMP sub-command does not recognize option UTF") +set(TIMESTAMP-BadArg3-RESULT 1) +set(TIMESTAMP-BadArg3-STDERR "string sub-command TIMESTAMP takes at most three arguments") +set(TIMESTAMP-DefaultFormatLocal-RESULT 0) +set(TIMESTAMP-DefaultFormatLocal-STDERR "~[0-9]*-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-6][0-9]~") +set(TIMESTAMP-DefaultFormatUTC-RESULT 0) +set(TIMESTAMP-DefaultFormatUTC-STDERR "~[0-9]*-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-6][0-9]Z~") +set(TIMESTAMP-CustomFormatLocal-RESULT 0) +set(TIMESTAMP-CustomFormatLocal-STDERR "~([0-5][0-9])|60~") +set(TIMESTAMP-CustomFormatUTC-RESULT 0) +set(TIMESTAMP-CustomFormatUTC-STDERR "~([0-5][0-9])|60~") +set(TIMESTAMP-UnknownSpecifier-RESULT 0) +set(TIMESTAMP-UnknownSpecifier-STDERR "~%g~") +set(TIMESTAMP-IncompleteSpecifier-RESULT 0) +set(TIMESTAMP-IncompleteSpecifier-STDERR "~foobar%~") +set(TIMESTAMP-AllSpecifiers-RESULT 0) +set(TIMESTAMP-AllSpecifiers-STDERR "~[0-9]+(;[0-9]+)*~") include("@CMAKE_CURRENT_SOURCE_DIR@/CheckCMakeTest.cmake") check_cmake_test(String @@ -28,6 +48,16 @@ check_cmake_test(String SHA256-Works SHA384-Works SHA512-Works + TIMESTAMP-BadArg1 + TIMESTAMP-BadArg2 + TIMESTAMP-BadArg3 + TIMESTAMP-DefaultFormatLocal + TIMESTAMP-DefaultFormatUTC + TIMESTAMP-CustomFormatLocal + TIMESTAMP-CustomFormatUTC + TIMESTAMP-UnknownSpecifier + TIMESTAMP-IncompleteSpecifier + TIMESTAMP-AllSpecifiers ) # Execute each test listed in StringTestScript.cmake: From d842d9062297435747117bd74b6e184cedd345cc Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 5 Dec 2012 09:55:27 -0500 Subject: [PATCH 068/170] CMake: Stylistic changes and documentation tweaks ...for the contributed file and string TIMESTAMP sub-commands. --- Source/cmFileCommand.h | 7 +-- Source/cmStringCommand.h | 4 +- Source/cmTimestamp.cxx | 56 ++++++++++--------- .../String-TIMESTAMP-DefaulFormatUTC.cmake | 2 - 4 files changed, 36 insertions(+), 33 deletions(-) delete mode 100644 Tests/CMakeTests/String-TIMESTAMP-DefaulFormatUTC.cmake diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h index 5550dbe64..5973fa732 100644 --- a/Source/cmFileCommand.h +++ b/Source/cmFileCommand.h @@ -87,8 +87,7 @@ public: " [TLS_VERIFY on|off] [TLS_CAINFO file])\n" " file(UPLOAD filename url [INACTIVITY_TIMEOUT timeout]\n" " [TIMEOUT timeout] [STATUS status] [LOG log] [SHOW_PROGRESS])\n" - " file(TIMESTAMP " - " [] [UTC])\n" + " file(TIMESTAMP filename variable [] [UTC])\n" "WRITE will write a message into a file called 'filename'. It " "overwrites the file if it already exists, and creates the file " "if it does not exist. (If the file is a build input, use " @@ -203,9 +202,9 @@ public: "as status messages until the operation is complete." "\n" "TIMESTAMP will write a string representation of " - "the modification time of to .\n" + "the modification time of filename to variable.\n" "Should the command be unable to obtain a timestamp " - " will be set to the empty string \"\".\n" + "variable will be set to the empty string \"\".\n" "See documentation of the string TIMESTAMP sub-command for more details." "\n" "The file() command also provides COPY and INSTALL signatures:\n" diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h index 7e0694ed6..4423a90e9 100644 --- a/Source/cmStringCommand.h +++ b/Source/cmStringCommand.h @@ -145,9 +145,9 @@ public: " by all regular expression-related commands, including \n" " e.g. if( MATCHES ), in the variables CMAKE_MATCH_(0..9).\n" "TIMESTAMP will write a string representation of " - "the current date and/or time to .\n" + "the current date and/or time to the output variable.\n" "Should the command be unable to obtain a timestamp " - " will be set to the empty string \"\".\n" + "the output variable will be set to the empty string \"\".\n" "The optional UTC flag requests the current date/time " "representation to be in Coordinated Universal Time (UTC) " "rather than local time.\n" diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index f1115e672..c3df495b7 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -21,62 +21,68 @@ std::string cmTimestamp::CurrentTime( const std::string& formatString, bool utcFlag) { time_t currentTimeT = time(0); - if(currentTimeT == time_t(-1)) return std::string(); + if(currentTimeT == time_t(-1)) + { + return std::string(); + } return CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag); } +//---------------------------------------------------------------------------- std::string cmTimestamp::FileModificationTime(const char* path, const std::string& formatString, bool utcFlag) { #ifdef _WIN32 - struct _stat info; - std::memset(&info, 0, sizeof(info)); - - if(_stat(path, &info) != 0) - return std::string(); - - time_t currentTimeT = info.st_mtime; + #define STAT _stat #else - struct stat info; - std::memset(&info, 0, sizeof(info)); - - if(stat(path, &info) != 0) - return std::string(); - - time_t currentTimeT = info.st_mtime; + #define STAT stat #endif - return CreateTimestampFromTimeT(currentTimeT, formatString, utcFlag); + struct STAT info; + std::memset(&info, 0, sizeof(info)); + + if(STAT(path, &info) != 0) + { + return std::string(); + } + + return CreateTimestampFromTimeT(info.st_mtime, formatString, utcFlag); } +//---------------------------------------------------------------------------- std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT, std::string formatString, bool utcFlag) { if(formatString.empty()) { formatString = "%Y-%m-%dT%H:%M:%S"; - if(utcFlag) formatString += "Z"; + if(utcFlag) + { + formatString += "Z"; + } } struct tm timeStruct; std::memset(&timeStruct, 0, sizeof(timeStruct)); + struct tm* ptr = (struct tm*) 0; if(utcFlag) { - tm* ptr = gmtime(&timeT); - if(ptr == 0) return std::string(); - - timeStruct = *ptr; + ptr = gmtime(&timeT); } else { - struct tm* ptr = localtime(&timeT); - if(ptr == 0) return std::string(); - - timeStruct = *ptr; + ptr = localtime(&timeT); } + if(ptr == 0) + { + return std::string(); + } + + timeStruct = *ptr; + std::string result; for(std::string::size_type i = 0; i < formatString.size(); ++i) { diff --git a/Tests/CMakeTests/String-TIMESTAMP-DefaulFormatUTC.cmake b/Tests/CMakeTests/String-TIMESTAMP-DefaulFormatUTC.cmake deleted file mode 100644 index dad6a8d97..000000000 --- a/Tests/CMakeTests/String-TIMESTAMP-DefaulFormatUTC.cmake +++ /dev/null @@ -1,2 +0,0 @@ -string(TIMESTAMP output UTC) -message("~${output}~") From f80ccac158c11b21319e6f4a82137bcc88f0dfaf Mon Sep 17 00:00:00 2001 From: Amit Kulkarni Date: Wed, 5 Dec 2012 11:36:14 -0600 Subject: [PATCH 069/170] OpenBSD: Add paths for Qt3/Qt4 Handle OpenBSD specific paths in Qt3/Qt4, allowing concurrent building and installation. Some common programs are renamed with suffixes of either 3 or 4. Also, allow qt3/qt4 installed under /usr/local to be searched and recognized appropriately. --- Modules/FindQt.cmake | 14 ++++++++++++++ Modules/FindQt3.cmake | 6 ++++-- Modules/FindQt4.cmake | 12 ++++++------ 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/Modules/FindQt.cmake b/Modules/FindQt.cmake index 541cc0565..54b7c6f97 100644 --- a/Modules/FindQt.cmake +++ b/Modules/FindQt.cmake @@ -43,6 +43,12 @@ if(GLOB_TEMP_VAR) endif() set(GLOB_TEMP_VAR) +file(GLOB GLOB_TEMP_VAR /usr/local/lib/qt3/bin/qmake) +if(GLOB_TEMP_VAR) + set(QT3_INSTALLED TRUE) +endif() +set(GLOB_TEMP_VAR) + # look for qt4 installations file(GLOB GLOB_TEMP_VAR /usr/local/qt-x11-commercial-4*/bin/qmake) if(GLOB_TEMP_VAR) @@ -56,6 +62,12 @@ if(GLOB_TEMP_VAR) endif() set(GLOB_TEMP_VAR) +file(GLOB GLOB_TEMP_VAR /usr/local/lib/qt4/bin/qmake) +if(GLOB_TEMP_VAR) + set(QT4_INSTALLED TRUE) +endif() +set(GLOB_TEMP_VAR) + if (Qt_FIND_VERSION) set(DESIRED_QT_VERSION "${Qt_FIND_VERSION}") endif () @@ -91,6 +103,7 @@ find_file( QT4_QGLOBAL_H_FILE qglobal.h /usr/lib/qt/include/Qt /usr/include/Qt /usr/share/qt4/include/Qt + /usr/local/include/X11/qt4/Qt C:/Progra~1/qt/include/Qt ) if(QT4_QGLOBAL_H_FILE) @@ -110,6 +123,7 @@ find_file( QT3_QGLOBAL_H_FILE qglobal.h /usr/lib/qt/include /usr/include /usr/share/qt3/include + /usr/local/include/X11/qt3 C:/Progra~1/qt/include /usr/include/qt3 ) diff --git a/Modules/FindQt3.cmake b/Modules/FindQt3.cmake index 07b6fef34..4fc8e406c 100644 --- a/Modules/FindQt3.cmake +++ b/Modules/FindQt3.cmake @@ -64,6 +64,7 @@ find_path(QT_INCLUDE_DIR qt.h /usr/share/qt3/include C:/Progra~1/qt/include /usr/include/qt3 + /usr/local/include/X11/qt3 ) # if qglobal.h is not in the qt_include_dir then set @@ -146,7 +147,7 @@ find_library(QT_QASSISTANTCLIENT_LIBRARY # Qt 3 should prefer QTDIR over the PATH find_program(QT_MOC_EXECUTABLE - NAMES moc-qt3 moc + NAMES moc-qt3 moc moc3 moc3-mt HINTS ENV QTDIR PATHS @@ -154,6 +155,7 @@ find_program(QT_MOC_EXECUTABLE "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.2.0;InstallDir]/include/Qt" "[HKEY_CURRENT_USER\\Software\\Trolltech\\Qt3Versions\\3.1.0;InstallDir]/include/Qt" ${GLOB_PATHS_BIN} + /usr/local/lib/qt3 /usr/local/qt /usr/lib/qt /usr/lib/qt3 @@ -170,7 +172,7 @@ endif() # Qt 3 should prefer QTDIR over the PATH find_program(QT_UIC_EXECUTABLE - NAMES uic-qt3 uic + NAMES uic-qt3 uic uic3 uic3-mt HINTS ENV QTDIR PATHS diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index b42247a1c..013461b85 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -982,13 +982,13 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) endif() find_program(QT_MOC_EXECUTABLE - NAMES moc-qt4 moc + NAMES moc-qt4 moc moc4 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) find_program(QT_UIC_EXECUTABLE - NAMES uic-qt4 uic + NAMES uic-qt4 uic uic4 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) @@ -1018,13 +1018,13 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) ) find_program(QT_LUPDATE_EXECUTABLE - NAMES lupdate-qt4 lupdate + NAMES lupdate-qt4 lupdate lupdate4 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) find_program(QT_LRELEASE_EXECUTABLE - NAMES lrelease-qt4 lrelease + NAMES lrelease-qt4 lrelease lrelease4 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) @@ -1036,13 +1036,13 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) ) find_program(QT_DESIGNER_EXECUTABLE - NAMES designer-qt4 designer + NAMES designer-qt4 designer designer4 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) find_program(QT_LINGUIST_EXECUTABLE - NAMES linguist-qt4 linguist + NAMES linguist-qt4 linguist linguist4 PATHS ${QT_BINARY_DIR} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) From 354ecc1e1f28b9f2412fa015064353c6e20cfe92 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 5 Dec 2012 13:14:56 -0500 Subject: [PATCH 070/170] CMake: Fix dashboard warnings ...in the new file and string TIMESTAMP sub-commands --- Source/cmFileCommand.cxx | 2 +- Source/cmStringCommand.cxx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx index 42df3a17f..0cdbb82d7 100644 --- a/Source/cmFileCommand.cxx +++ b/Source/cmFileCommand.cxx @@ -3263,7 +3263,7 @@ bool cmFileCommand::HandleTimestampCommand( return false; } - int argsIndex = 1; + unsigned int argsIndex = 1; const std::string& filename = args[argsIndex++]; diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx index c402738fe..e49edd878 100644 --- a/Source/cmStringCommand.cxx +++ b/Source/cmStringCommand.cxx @@ -901,7 +901,7 @@ bool cmStringCommand return false; } - int argsIndex = 1; + unsigned int argsIndex = 1; const std::string &outputVariable = args[argsIndex++]; From e28ce2483dbdc620aa92e2ba0d86e8923dcdb296 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 5 Dec 2012 15:16:22 -0500 Subject: [PATCH 071/170] CMake: Fix dashboard test failure Eliminate the platform difference in calling stat. We call stat normally in other places in the CMake code base just fine. Works everywhere we work. Will hopefully also fix the Borland Continuous dashboard failure that is occurring with respect to correctly measuring the modification time of a freshly generated file. --- Source/cmTimestamp.cxx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index c3df495b7..22bb4b789 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -33,16 +33,10 @@ std::string cmTimestamp::CurrentTime( std::string cmTimestamp::FileModificationTime(const char* path, const std::string& formatString, bool utcFlag) { -#ifdef _WIN32 - #define STAT _stat -#else - #define STAT stat -#endif - - struct STAT info; + struct stat info; std::memset(&info, 0, sizeof(info)); - if(STAT(path, &info) != 0) + if(stat(path, &info) != 0) { return std::string(); } From 8521a9e9cad06922dc316f2c3a82f0263bbd7e87 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Thu, 6 Dec 2012 00:01:05 -0500 Subject: [PATCH 072/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a97bf61ec..5c7799322 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 20121205) +set(CMake_VERSION_TWEAK 20121206) #set(CMake_VERSION_RC 1) From 12d87c04253bd203a9b8a510b1772291527d441c Mon Sep 17 00:00:00 2001 From: David Cole Date: Thu, 6 Dec 2012 07:20:12 -0500 Subject: [PATCH 073/170] CMake: Fix dashboard build errors and warnings memset is not in std:: for VS6, and though quite silly, 0 is not a char --- Source/cmTimestamp.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/cmTimestamp.cxx b/Source/cmTimestamp.cxx index 22bb4b789..ac26503c6 100644 --- a/Source/cmTimestamp.cxx +++ b/Source/cmTimestamp.cxx @@ -34,7 +34,7 @@ std::string cmTimestamp::FileModificationTime(const char* path, const std::string& formatString, bool utcFlag) { struct stat info; - std::memset(&info, 0, sizeof(info)); + memset(&info, 0, sizeof(info)); if(stat(path, &info) != 0) { @@ -58,7 +58,7 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT, } struct tm timeStruct; - std::memset(&timeStruct, 0, sizeof(timeStruct)); + memset(&timeStruct, 0, sizeof(timeStruct)); struct tm* ptr = (struct tm*) 0; if(utcFlag) @@ -82,7 +82,7 @@ std::string cmTimestamp::CreateTimestampFromTimeT(time_t timeT, { char c1 = formatString[i]; char c2 = (i+1 < formatString.size()) ? - formatString[i+1] : 0; + formatString[i+1] : static_cast(0); if(c1 == '%' && c2 != 0) { From 8039bd0864aae15fd0d95db728159a85d72bf0f4 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Thu, 6 Dec 2012 22:24:43 +0100 Subject: [PATCH 074/170] CONFIGURE_PACKAGE_CONFIG_FILE(): improve generated comments CONFIGURE_PACKAGE_CONFIG_FILE() now additionally generates "Any changes to this file will be overwritten by the next CMake run The input file was FooConfig.cmake.in" into the configured file. Alex --- Modules/CMakePackageConfigHelpers.cmake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/CMakePackageConfigHelpers.cmake b/Modules/CMakePackageConfigHelpers.cmake index 96ecb4270..a92ce7cc9 100644 --- a/Modules/CMakePackageConfigHelpers.cmake +++ b/Modules/CMakePackageConfigHelpers.cmake @@ -188,8 +188,13 @@ function(CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile) endif() endforeach() + get_filename_component(inputFileName "${_inputFile}" NAME) + set(PACKAGE_INIT " ####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### +####### Any changes to this file will be overwritten by the next CMake run #### +####### The input file was ${inputFileName} ######## + get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE) ") From 2be87f8ff832fc29daa3d4eca85de88130daa400 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Fri, 7 Dec 2012 00:01:10 -0500 Subject: [PATCH 075/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 5c7799322..fe2b1f310 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 20121206) +set(CMake_VERSION_TWEAK 20121207) #set(CMake_VERSION_RC 1) From 711b63f7e095992d6ab84063af076d23a916b1f3 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 6 Dec 2012 09:59:18 -0500 Subject: [PATCH 076/170] Add policy CMP0019 to skip include/link variable re-expansion Historically CMake has always expanded ${} variable references in the values given to include_directories(), link_directories(), and link_libraries(). This has been unnecessary since general ${} evaluation syntax was added to the language a LONG time ago, but has remained for compatibility with VERY early CMake versions. For a long time the re-expansion was a lightweight operation because it was only processed once at the directory level and the fast-path of cmMakefile::ExpandVariablesInString was usually taken because values did not have any '$' in them. Then commit d899eb71 (Call ExpandVariablesInString for each target's INCLUDE_DIRECTORIES, 2012-02-22) made the operation a bit heavier because the expansion is now needed on a per-target basis. In the future we will support generator expressions in INCLUDE_DIRECTORIES with $<> syntax, so the fast-path in cmMakefile::ExpandVariablesInString will no longer be taken and re-expansion will be very expensive. Add policy CMP0019 to skip the re-expansion altogether in NEW behavior. In OLD behavior perform the expansion but improve the fast-path heuristic to match ${} but not $<>. If the policy is not set then warn if expansion actually does anything. We expect this to be encountered very rarely in practice. --- Source/cmMakefile.cxx | 77 +++++++++++++++---- Source/cmMakefile.h | 2 +- Source/cmPolicies.cxx | 17 ++++ Source/cmPolicies.h | 1 + Tests/RunCMake/CMP0019/CMP0019-NEW.cmake | 2 + Tests/RunCMake/CMP0019/CMP0019-OLD.cmake | 2 + .../RunCMake/CMP0019/CMP0019-WARN-stderr.txt | 40 ++++++++++ Tests/RunCMake/CMP0019/CMP0019-WARN.cmake | 1 + Tests/RunCMake/CMP0019/CMP0019-code.cmake | 9 +++ Tests/RunCMake/CMP0019/CMakeLists.txt | 3 + Tests/RunCMake/CMP0019/RunCMakeTest.cmake | 5 ++ Tests/RunCMake/CMakeLists.txt | 1 + 12 files changed, 146 insertions(+), 14 deletions(-) create mode 100644 Tests/RunCMake/CMP0019/CMP0019-NEW.cmake create mode 100644 Tests/RunCMake/CMP0019/CMP0019-OLD.cmake create mode 100644 Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt create mode 100644 Tests/RunCMake/CMP0019/CMP0019-WARN.cmake create mode 100644 Tests/RunCMake/CMP0019/CMP0019-code.cmake create mode 100644 Tests/RunCMake/CMP0019/CMakeLists.txt create mode 100644 Tests/RunCMake/CMP0019/RunCMakeTest.cmake diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 8498d72fd..d943c450f 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -814,7 +814,7 @@ bool cmMakefile::NeedBackwardsCompatibility(unsigned int major, void cmMakefile::FinalPass() { // do all the variable expansions here - this->ExpandVariables(); + this->ExpandVariablesCMP0019(); // give all the commands a chance to do something // after the file has been parsed before generation @@ -2122,21 +2122,33 @@ void cmMakefile::AddExtraDirectory(const char* dir) this->AuxSourceDirectories.push_back(dir); } - -// expand CMAKE_BINARY_DIR and CMAKE_SOURCE_DIR in the -// include and library directories. - -void cmMakefile::ExpandVariables() +static bool mightExpandVariablesCMP0019(const char* s) { - // Now expand variables in the include and link strings + return s && *s && strstr(s,"${") && strchr(s,'}'); +} + +void cmMakefile::ExpandVariablesCMP0019() +{ + // Drop this ancient compatibility behavior with a policy. + cmPolicies::PolicyStatus pol = this->GetPolicyStatus(cmPolicies::CMP0019); + if(pol != cmPolicies::OLD && pol != cmPolicies::WARN) + { + return; + } + cmOStringStream w; - // May not be necessary anymore... But may need a policy for strict - // backwards compatibility const char *includeDirs = this->GetProperty("INCLUDE_DIRECTORIES"); - if (includeDirs) + if(mightExpandVariablesCMP0019(includeDirs)) { std::string dirs = includeDirs; this->ExpandVariablesInString(dirs, true, true); + if(pol == cmPolicies::WARN && dirs != includeDirs) + { + w << "Evaluated directory INCLUDE_DIRECTORIES\n" + << " " << includeDirs << "\n" + << "as\n" + << " " << dirs << "\n"; + } this->SetProperty("INCLUDE_DIRECTORIES", dirs.c_str()); } @@ -2146,10 +2158,17 @@ void cmMakefile::ExpandVariables() { cmTarget &t = l->second; includeDirs = t.GetProperty("INCLUDE_DIRECTORIES"); - if (includeDirs) + if(mightExpandVariablesCMP0019(includeDirs)) { std::string dirs = includeDirs; this->ExpandVariablesInString(dirs, true, true); + if(pol == cmPolicies::WARN && dirs != includeDirs) + { + w << "Evaluated target " << t.GetName() << " INCLUDE_DIRECTORIES\n" + << " " << includeDirs << "\n" + << "as\n" + << " " << dirs << "\n"; + } t.SetProperty("INCLUDE_DIRECTORIES", dirs.c_str()); } } @@ -2157,13 +2176,45 @@ void cmMakefile::ExpandVariables() for(std::vector::iterator d = this->LinkDirectories.begin(); d != this->LinkDirectories.end(); ++d) { - this->ExpandVariablesInString(*d, true, true); + if(mightExpandVariablesCMP0019(d->c_str())) + { + std::string orig = *d; + this->ExpandVariablesInString(*d, true, true); + if(pol == cmPolicies::WARN && *d != orig) + { + w << "Evaluated link directory\n" + << " " << orig << "\n" + << "as\n" + << " " << *d << "\n"; + } + } } for(cmTarget::LinkLibraryVectorType::iterator l = this->LinkLibraries.begin(); l != this->LinkLibraries.end(); ++l) { - this->ExpandVariablesInString(l->first, true, true); + if(mightExpandVariablesCMP0019(l->first.c_str())) + { + std::string orig = l->first; + this->ExpandVariablesInString(l->first, true, true); + if(pol == cmPolicies::WARN && l->first != orig) + { + w << "Evaluated link library\n" + << " " << orig << "\n" + << "as\n" + << " " << l->first << "\n"; + } + } + } + + if(!w.str().empty()) + { + cmOStringStream m; + m << this->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0019) + << "\n" + << "The following variable evaluations were encountered:\n" + << w.str(); + this->IssueMessage(cmake::AUTHOR_WARNING, m.str()); } } diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index 70cfe5421..eff05d091 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -693,7 +693,7 @@ public: /** * Expand variables in the makefiles ivars such as link directories etc */ - void ExpandVariables(); + void ExpandVariablesCMP0019(); /** * Replace variables and #cmakedefine lines in the given string. diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx index 6aef50243..eb7d6668e 100644 --- a/Source/cmPolicies.cxx +++ b/Source/cmPolicies.cxx @@ -491,6 +491,23 @@ cmPolicies::cmPolicies() "CMAKE_SHARED_LIBRARY__FLAGS whether it is modified or not and " "honor the POSITION_INDEPENDENT_CODE target property.", 2,8,9,0, cmPolicies::WARN); + + this->DefinePolicy( + CMP0019, "CMP0019", + "Do not re-expand variables in include and link information.", + "CMake 2.8.10 and lower re-evaluated values given to the " + "include_directories, link_directories, and link_libraries " + "commands to expand any leftover variable references at the " + "end of the configuration step. " + "This was for strict compatibility with VERY early CMake versions " + "because all variable references are now normally evaluated during " + "CMake language processing. " + "CMake 2.8.11 and higher prefer to skip the extra evaluation." + "\n" + "The OLD behavior for this policy is to re-evaluate the values " + "for strict compatibility. " + "The NEW behavior for this policy is to leave the values untouched.", + 2,8,11,0, cmPolicies::WARN); } cmPolicies::~cmPolicies() diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h index 6932565ab..d7d945c42 100644 --- a/Source/cmPolicies.h +++ b/Source/cmPolicies.h @@ -68,6 +68,7 @@ public: CMP0018, ///< Ignore language flags for shared libs, and adhere to /// POSITION_INDEPENDENT_CODE property and *_COMPILE_OPTIONS_PI{E,C} /// instead. + CMP0019, ///< No variable re-expansion in include and link info /** \brief Always the last entry. * diff --git a/Tests/RunCMake/CMP0019/CMP0019-NEW.cmake b/Tests/RunCMake/CMP0019/CMP0019-NEW.cmake new file mode 100644 index 000000000..3091e66ac --- /dev/null +++ b/Tests/RunCMake/CMP0019/CMP0019-NEW.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0019 NEW) +include(CMP0019-code.cmake) diff --git a/Tests/RunCMake/CMP0019/CMP0019-OLD.cmake b/Tests/RunCMake/CMP0019/CMP0019-OLD.cmake new file mode 100644 index 000000000..0f02f9ce5 --- /dev/null +++ b/Tests/RunCMake/CMP0019/CMP0019-OLD.cmake @@ -0,0 +1,2 @@ +cmake_policy(SET CMP0019 OLD) +include(CMP0019-code.cmake) diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt new file mode 100644 index 000000000..03faef90e --- /dev/null +++ b/Tests/RunCMake/CMP0019/CMP0019-WARN-stderr.txt @@ -0,0 +1,40 @@ +CMake Warning \(dev\) in CMakeLists.txt: + Policy CMP0019 is not set: Do not re-expand variables in include and link + information. Run "cmake --help-policy CMP0019" for policy details. Use + the cmake_policy command to set the policy and suppress this warning. + + The following variable evaluations were encountered: + + Evaluated directory INCLUDE_DIRECTORIES + + /usr/include/\${VAR_INCLUDE};/usr/include/normal + + as + + /usr/include/VAL_INCLUDE;/usr/include/normal + + Evaluated target some_target INCLUDE_DIRECTORIES + + /usr/include/\${VAR_INCLUDE};/usr/include/normal + + as + + /usr/include/VAL_INCLUDE;/usr/include/normal + + Evaluated link directory + + /usr/lib/\${VAR_LINK_DIRS} + + as + + /usr/lib/VAL_LINK_DIRS + + Evaluated link library + + \${VAR_LINK_LIBS} + + as + + VAL_LINK_LIBS + +This warning is for project developers. Use -Wno-dev to suppress it.$ diff --git a/Tests/RunCMake/CMP0019/CMP0019-WARN.cmake b/Tests/RunCMake/CMP0019/CMP0019-WARN.cmake new file mode 100644 index 000000000..a419f309e --- /dev/null +++ b/Tests/RunCMake/CMP0019/CMP0019-WARN.cmake @@ -0,0 +1 @@ +include(CMP0019-code.cmake) diff --git a/Tests/RunCMake/CMP0019/CMP0019-code.cmake b/Tests/RunCMake/CMP0019/CMP0019-code.cmake new file mode 100644 index 000000000..26c0e5b27 --- /dev/null +++ b/Tests/RunCMake/CMP0019/CMP0019-code.cmake @@ -0,0 +1,9 @@ +set(VAR_INCLUDE "VAL_INCLUDE") +set(VAR_LINK_DIRS "VAL_LINK_DIRS") +set(VAR_LINK_LIBS "VAL_LINK_LIBS") +add_custom_target(some_target) +include_directories("/usr/include/\${VAR_INCLUDE}" /usr/include/normal) +link_directories("/usr/lib/\${VAR_LINK_DIRS}" /usr/lib/normal) +link_libraries("\${VAR_LINK_LIBS}" normal) +add_custom_target(other_target) +set_property(TARGET other_target PROPERTY INCLUDE_DIRECTORIES "") diff --git a/Tests/RunCMake/CMP0019/CMakeLists.txt b/Tests/RunCMake/CMP0019/CMakeLists.txt new file mode 100644 index 000000000..e8db6b05b --- /dev/null +++ b/Tests/RunCMake/CMP0019/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/CMP0019/RunCMakeTest.cmake b/Tests/RunCMake/CMP0019/RunCMakeTest.cmake new file mode 100644 index 000000000..119fc2b30 --- /dev/null +++ b/Tests/RunCMake/CMP0019/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(CMP0019-WARN) +run_cmake(CMP0019-OLD) +run_cmake(CMP0019-NEW) diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 722d9c388..cc544a373 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -45,6 +45,7 @@ macro(add_RunCMake_test test) ) endmacro() +add_RunCMake_test(CMP0019) add_RunCMake_test(GeneratorExpression) add_RunCMake_test(TargetPropertyGeneratorExpressions) add_RunCMake_test(Languages) From 2bc22bdaacfc0f0f91c229685dc5dbadd0267601 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 7 Dec 2012 13:06:20 -0500 Subject: [PATCH 077/170] Xcode: Add frameworks search paths from link dependeny closure (#13397) The Xcode generator produces FRAMEWORK_SEARCH_PATHS from: (1) Include directories of the form /path/to/Foo.framework become -F/path/to so '#include ' can find H in the framework. (2) Linked frameworks of the form /path/to/Foo.framework become -F/path/to -framework Foo so the linker can find the framework. Originally commit 82bb6fae (add framework support to FIND_FILE, 2005-12-27) added these and used the (then current) old-style link dependency analysis results to get the frameworks. Later a second setting was added by commit 2ed6191f (add initial xcode framework stuff, 2007-05-08) to transform -F/path/to linker options produced by the old link line generation into entries appended to FRAMEWORK_SEARCH_PATHS. Then commit 96fd5909 (Implement linking with paths to library files, 2008-01-22) updated the second setting to directly use the results of full modern link dependency analysis, but forgot to remove the use of old-style link results from the original setting location. The two settings worked together for a while, with the second one appending to the first. Then commit f33a27ab (Generate native Xcode 3.0 and 3.1 projects, 2009-06-29) changed the internal representation format produced by the first setting but did not update the second setting to append to the new representation. As a result, if the first setting added any paths (usually via the old-style link analysis) then the second setting containing the modern link analysis results would not be applied at all. Fix this by removing use of the old-style link analysis results. Replace it using the modern link dependencies and remove the second setting altogether. Now all values for FRAMEWORK_SEARCH_PATHS are collected in one place so no special append logic is needed. --- Source/cmGlobalXCodeGenerator.cxx | 36 ++++++++++--------------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 9bbeeaf6f..b2d325c8a 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1997,15 +1997,20 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, dirs.Add(incpath.c_str()); } } - std::vector& frameworks = target.GetFrameworks(); - if(frameworks.size()) + if(target.GetType() != cmTarget::OBJECT_LIBRARY && + target.GetType() != cmTarget::STATIC_LIBRARY) { - for(std::vector::iterator fmIt = frameworks.begin(); - fmIt != frameworks.end(); ++fmIt) + // Add framework search paths needed for linking. + if(cmComputeLinkInformation* cli = target.GetLinkInformation(configName)) { - if(emitted.insert(*fmIt).second) + std::vector const& fwDirs = cli->GetFrameworkPaths(); + for(std::vector::const_iterator fdi = fwDirs.begin(); + fdi != fwDirs.end(); ++fdi) { - fdirs.Add(this->XCodeEscapePath(fmIt->c_str()).c_str()); + if(emitted.insert(*fdi).second) + { + fdirs.Add(this->XCodeEscapePath(fdi->c_str()).c_str()); + } } } } @@ -2691,25 +2696,6 @@ void cmGlobalXCodeGenerator linkDirs.c_str(), configName); } - // add the framework search paths - { - const char* sep = ""; - std::string fdirs; - std::vector const& fwDirs = cli.GetFrameworkPaths(); - for(std::vector::const_iterator fdi = fwDirs.begin(); - fdi != fwDirs.end(); ++fdi) - { - fdirs += sep; - sep = " "; - fdirs += this->XCodeEscapePath(fdi->c_str()); - } - if(!fdirs.empty()) - { - this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS", - fdirs.c_str(), configName); - } - } - // now add the link libraries { std::string linkLibs; From acc224005e99076da3561ada8c06985487b0ce11 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Fri, 7 Dec 2012 21:24:28 +0100 Subject: [PATCH 078/170] Automoc: get include dirs without stripping implicit include dirs off This should finally fix #13667 and #13762. Instead of adding special handling to guess whether implicit include dirs may have been removed, simply make it possible to query the include dirs without removing the implicit ones. Alex --- Source/cmLocalGenerator.cxx | 27 +++++++++------- Source/cmLocalGenerator.h | 3 +- Source/cmQtAutomoc.cxx | 62 ++----------------------------------- 3 files changed, 21 insertions(+), 71 deletions(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 6d396b340..b41f06010 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1329,7 +1329,9 @@ std::string cmLocalGenerator::GetIncludeFlags( void cmLocalGenerator::GetIncludeDirectories(std::vector& dirs, cmGeneratorTarget* target, const char* lang, - const char *config) + const char *config, + bool stripImplicitInclDirs + ) { // Need to decide whether to automatically include the source and // binary directories at the beginning of the include path. @@ -1404,18 +1406,21 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector& dirs, return; } - // Load implicit include directories for this language. - std::string impDirVar = "CMAKE_"; - impDirVar += lang; - impDirVar += "_IMPLICIT_INCLUDE_DIRECTORIES"; - if(const char* value = this->Makefile->GetDefinition(impDirVar.c_str())) + if (stripImplicitInclDirs) { - std::vector impDirVec; - cmSystemTools::ExpandListArgument(value, impDirVec); - for(std::vector::const_iterator i = impDirVec.begin(); - i != impDirVec.end(); ++i) + // Load implicit include directories for this language. + std::string impDirVar = "CMAKE_"; + impDirVar += lang; + impDirVar += "_IMPLICIT_INCLUDE_DIRECTORIES"; + if(const char* value = this->Makefile->GetDefinition(impDirVar.c_str())) { - emitted.insert(*i); + std::vector impDirVec; + cmSystemTools::ExpandListArgument(value, impDirVec); + for(std::vector::const_iterator i = impDirVec.begin(); + i != impDirVec.end(); ++i) + { + emitted.insert(*i); + } } } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index bd582181c..63559d750 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -212,7 +212,8 @@ public: /** Get the include flags for the current makefile and language. */ void GetIncludeDirectories(std::vector& dirs, cmGeneratorTarget* target, - const char* lang = "C", const char *config = 0); + const char* lang = "C", const char *config = 0, + bool stripImplicitInclDirs = true); /** Compute the language used to compile the given source file. */ const char* GetSourceFileLanguage(const cmSourceFile& source); diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 83688dd75..bf034cf44 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -212,36 +212,11 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) } - const char* qtIncDir = 0; - const char* qtCoreIncDir = 0; - - // check whether ${QT_INCLUDE_DIR} is part of the implicit include dirs, - // see http://public.kitware.com/Bug/view.php?id=13667 - bool qtIncludeDirMayHaveBeenRemoved = false; - if (makefile->IsSet("QT_INCLUDE_DIR")) - { - qtIncDir = makefile->GetDefinition("QT_INCLUDE_DIR"); - std::string s = - makefile->GetSafeDefinition("CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES"); - std::vector implIncDirs; - cmSystemTools::ExpandListArgument(s, implIncDirs); - if (std::find(implIncDirs.begin(), implIncDirs.end(),std::string(qtIncDir)) - != implIncDirs.end()) - { - qtIncludeDirMayHaveBeenRemoved = true; - if (makefile->IsSet("QT_QTCORE_INCLUDE_DIR")) - { - qtCoreIncDir = makefile->GetDefinition("QT_QTCORE_INCLUDE_DIR"); - } - } - } - - bool haveQtCoreIncDir = false; - bool haveQtIncDir = false; - std::vector includeDirs; cmGeneratorTarget gtgt(target); - localGen->GetIncludeDirectories(includeDirs, >gt, "CXX"); + // Get the include dirs for this target, without stripping the implicit + // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667 + localGen->GetIncludeDirectories(includeDirs, >gt, "CXX", 0, false); std::string _moc_incs = ""; const char* sep = ""; for(std::vector::const_iterator incDirIt = includeDirs.begin(); @@ -251,37 +226,6 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) _moc_incs += sep; sep = ";"; _moc_incs += *incDirIt; - - if (qtIncludeDirMayHaveBeenRemoved && qtCoreIncDir && qtIncDir) // #13667 - { - if (*incDirIt == qtIncDir) - { - haveQtIncDir = true; - qtIncludeDirMayHaveBeenRemoved = false; // it's here, i.e. not removed - } - if (*incDirIt == qtCoreIncDir) - { - haveQtCoreIncDir = true; - } - } - } - - // Some projects (kdelibs, phonon) query the compiler for its default - // include search dirs, and add those to - // CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES. - // These may include e.g./usr/lib/qt/include . This is typically also part - // of ${QT_INCLUDES}. If this directory is then contained in the implicit - // include dirs, it is removed from the include dirs returned from the - // target above. So we add ${QT_INCLUDE_DIR} manually for moc if we detected - // that ${QT_QTCORE_INCLUDE_DIR} is among the include dirs (there shouldn't - // be a way to use Qt4 without using ${QT_QTCORE_INCLUDE_DIR} I think. - // See #13646 and #13667. - if (qtIncludeDirMayHaveBeenRemoved && qtCoreIncDir && qtIncDir - && (haveQtCoreIncDir == true) && (haveQtIncDir == false)) - { - _moc_incs += sep; - sep = ";"; - _moc_incs += qtIncDir; } const char* tmp = target->GetProperty("COMPILE_DEFINITIONS"); From f0d938549eead63fb86bec28c299a1bceacbdd6b Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 7 Dec 2012 13:27:52 -0500 Subject: [PATCH 079/170] Makefile: Use modern link information for framework search paths Use cmComputeLinkInformation::GetFrameworkPaths to get the list of framework paths needed by the linker. Drop the now unused framework information from the old-style cmTarget link dependency analysis. --- Source/cmMakefileTargetGenerator.cxx | 26 +++++++++++++++----------- Source/cmTarget.cxx | 21 --------------------- Source/cmTarget.h | 5 ----- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 2b89c794b..9bf6b7d9e 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -1550,10 +1550,10 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags() this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget, "C", config); - std::vector::iterator i; // check all include directories for frameworks as this // will already have added a -F for the framework - for(i = includes.begin(); i != includes.end(); ++i) + for(std::vector::iterator i = includes.begin(); + i != includes.end(); ++i) { if(this->Target->NameResolvesToFramework(i->c_str())) { @@ -1565,17 +1565,21 @@ std::string cmMakefileTargetGenerator::GetFrameworkFlags() } std::string flags; - std::vector& frameworks = this->Target->GetFrameworks(); - for(i = frameworks.begin(); - i != frameworks.end(); ++i) + const char* cfg = this->LocalGenerator->ConfigurationName.c_str(); + if(cmComputeLinkInformation* cli = this->Target->GetLinkInformation(cfg)) { - if(emitted.insert(*i).second) + std::vector const& frameworks = cli->GetFrameworkPaths(); + for(std::vector::const_iterator i = frameworks.begin(); + i != frameworks.end(); ++i) { - flags += "-F"; - flags += this->Convert(i->c_str(), - cmLocalGenerator::START_OUTPUT, - cmLocalGenerator::SHELL, true); - flags += " "; + if(emitted.insert(*i).second) + { + flags += "-F"; + flags += this->Convert(i->c_str(), + cmLocalGenerator::START_OUTPUT, + cmLocalGenerator::SHELL, true); + flags += " "; + } } } return flags; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index be20464da..de3b23c78 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2092,26 +2092,6 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname) NameResolvesToFramework(libname); } -//---------------------------------------------------------------------------- -bool cmTarget::AddFramework(const std::string& libname, LinkLibraryType) -{ - if(this->NameResolvesToFramework(libname.c_str())) - { - std::string frameworkDir = libname; - frameworkDir += "/../"; - frameworkDir = cmSystemTools::CollapseFullPath(frameworkDir.c_str()); - std::vector::iterator i = - std::find(this->Frameworks.begin(), - this->Frameworks.end(), frameworkDir); - if(i == this->Frameworks.end()) - { - this->Frameworks.push_back(frameworkDir); - } - return true; - } - return false; -} - //---------------------------------------------------------------------------- void cmTarget::AddLinkLibrary(cmMakefile& mf, const char *target, const char* lib, @@ -2122,7 +2102,6 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, { return; } - this->AddFramework(lib, llt); cmTarget::LibraryID tmp; tmp.first = lib; tmp.second = llt; diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 9efd638f8..0dfbc68a1 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -109,9 +109,6 @@ public: std::vector &GetPostBuildCommands() {return this->PostBuildCommands;} - ///! Return the list of frameworks being linked to this target - std::vector &GetFrameworks() {return this->Frameworks;} - /** * Get the list of the source files used by this target */ @@ -179,7 +176,6 @@ public: // Check to see if a library is a framework and treat it different on Mac bool NameResolvesToFramework(const std::string& libname); - bool AddFramework(const std::string& lib, LinkLibraryType llt); void AddLinkLibrary(cmMakefile& mf, const char *target, const char* lib, LinkLibraryType llt); @@ -569,7 +565,6 @@ private: LinkLibraryVectorType LinkLibraries; LinkLibraryVectorType PrevLinkedLibraries; bool LinkLibrariesAnalyzed; - std::vector Frameworks; std::vector LinkDirectories; std::set LinkDirectoriesEmmitted; bool HaveInstallRule; From 0cbe7dd1e3fa4b2254c4d318e41f8167d8f2ad4e Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sat, 8 Dec 2012 00:01:06 -0500 Subject: [PATCH 080/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index fe2b1f310..34af95b45 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 20121207) +set(CMake_VERSION_TWEAK 20121208) #set(CMake_VERSION_RC 1) From 140ed91dd2598f4516b3290025a909e76b2871f6 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sun, 9 Dec 2012 00:01:06 -0500 Subject: [PATCH 081/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 34af95b45..1f1c7653c 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 20121208) +set(CMake_VERSION_TWEAK 20121209) #set(CMake_VERSION_RC 1) From 7ecaa4047bc1517f757f01e34747a0c4fdac4ee4 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Mon, 10 Dec 2012 00:01:04 -0500 Subject: [PATCH 082/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 1f1c7653c..18c483557 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 20121209) +set(CMake_VERSION_TWEAK 20121210) #set(CMake_VERSION_RC 1) From 61ace1df2616e472d056b302e4269cbf112fb020 Mon Sep 17 00:00:00 2001 From: David Cole Date: Mon, 10 Dec 2012 17:03:57 -0500 Subject: [PATCH 083/170] CTest: Coverage handler: expect certain output lines from gcov 4.7 (#13657) And do not report them as errors. --- Source/CTest/cmCTestCoverageHandler.cxx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Source/CTest/cmCTestCoverageHandler.cxx b/Source/CTest/cmCTestCoverageHandler.cxx index 4d1e249e6..20aded2b5 100644 --- a/Source/CTest/cmCTestCoverageHandler.cxx +++ b/Source/CTest/cmCTestCoverageHandler.cxx @@ -1097,10 +1097,17 @@ int cmCTestCoverageHandler::HandleGCovCoverage( } else { - cmCTestLog(this->CTest, ERROR_MESSAGE, - "Unknown gcov output line: [" << line->c_str() << "]" << std::endl); - cont->Error ++; - //abort(); + // gcov 4.7 can have output lines saying "No executable lines" and + // "Removing 'filename.gcov'"... Don't log those as "errors." + if(*line != "No executable lines" && + !cmSystemTools::StringStartsWith(line->c_str(), "Removing ")) + { + cmCTestLog(this->CTest, ERROR_MESSAGE, + "Unknown gcov output line: [" << line->c_str() << "]" + << std::endl); + cont->Error ++; + //abort(); + } } From ab2b1f44f88dd82129bcfe7f96007c30e1e07d08 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Tue, 11 Dec 2012 00:01:14 -0500 Subject: [PATCH 084/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 18c483557..20e68e91e 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 20121210) +set(CMake_VERSION_TWEAK 20121211) #set(CMake_VERSION_RC 1) From 017d90c50099540b2bc71b63d646271aa0968d36 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 11 Dec 2012 14:00:23 -0500 Subject: [PATCH 085/170] Documentation: Clarify handling of implicit link directories Extend documentation for CMAKE__IMPLICIT_LINK_DIRECTORIES to explain how it is used by CMake and how it can be influenced by environment variables. Inspired-by: Alex Neundorf --- Source/cmDocumentVariables.cxx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 55d70f862..32c543dce 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1621,7 +1621,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "These paths are implicit linker search directories for the compiler's " "language. " "CMake automatically detects these directories for each language and " - "reports the results in this variable.", false, + "reports the results in this variable." + "\n" + "When a library in one of these directories is given by full path to " + "target_link_libraries() CMake will generate the -l form on " + "link lines to ensure the linker searches its implicit directories " + "for the library. " + "Note that some toolchains read implicit directories from an " + "environment variable such as LIBRARY_PATH so keep its value " + "consistent when operating in a given build tree.",false, "Variables for Languages"); cm->DefineProperty From ba58d0c06fd8576844a5722930531a95d00c2003 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 11 Dec 2012 15:11:40 -0500 Subject: [PATCH 086/170] OS X: Link with all framework search paths, not just the last Refactoring in commit 8d674e78 (Ninja: move -LIBPATH behind -link option, 2012-09-26) accidentally added code that overwrites the framework search path flags on each iteration instead of appending. Change '=' to '+=' to fix it. This affects Makefile and Ninja generators. --- Source/cmLocalGenerator.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index b41f06010..b557ca19b 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1708,7 +1708,7 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries, for(std::vector::const_iterator fdi = fwDirs.begin(); fdi != fwDirs.end(); ++fdi) { - frameworkPath = " -F"; + frameworkPath += "-F"; frameworkPath += this->Convert(fdi->c_str(), NONE, SHELL, false); frameworkPath += " "; } From 2dd67c7ea095957d557d2934a67baacdf8a82d7b Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 5 Dec 2012 11:49:13 -0500 Subject: [PATCH 087/170] OS X: Detect implicit link directories on modern toolchains We detect the implicit link directories for the toolchain by adding a flag to get verbose output from the compiler front-end while linking the ABI detection binary. Newer OS X toolchains based on Clang do not add the implicit link directories with -L options to their internal invocation of "ld". Instead they use a linker that comes with the toolchain and is already configured with the proper directories. Add the "-Wl,-v" option to ask "ld" to print its implicit directories. It displays them in a block such as: Library search paths: /... Parse this block to extract the implicit link directories. While at it, remove the checks introduced by commit efaf335b (Skip implicit link information on Xcode, 2009-07-23) and commit 5195a664 (Skip implicit link info for multiple OS X archs, 2009-09-22). Discard the non-system link directories added by Xcode. Discard all detected implicit libraries in the multi-architecture case but keep the directories. The directories are still useful without the libraries just to suppress addition of explicit -L options for them. --- Modules/CMakeDetermineCompilerABI.cmake | 21 ++-- Modules/CMakeParseImplicitLinkInfo.cmake | 29 +++++- Modules/Platform/Darwin-Clang.cmake | 1 + Modules/Platform/Darwin-GNU.cmake | 1 + .../CMakeTests/ImplicitLinkInfoTest.cmake.in | 97 +++++++++++++++++++ 5 files changed, 134 insertions(+), 15 deletions(-) diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake index 75247d955..cb94aa655 100644 --- a/Modules/CMakeDetermineCompilerABI.cmake +++ b/Modules/CMakeDetermineCompilerABI.cmake @@ -72,18 +72,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) # Parse implicit linker information for this language, if available. set(implicit_dirs "") set(implicit_libs "") - set(MULTI_ARCH FALSE) - if(DEFINED CMAKE_OSX_ARCHITECTURES) - if( "${CMAKE_OSX_ARCHITECTURES}" MATCHES ";" ) - set(MULTI_ARCH TRUE) - endif() - endif() - if(CMAKE_${lang}_VERBOSE_FLAG - # Implicit link information cannot be used explicitly for - # multiple OS X architectures, so we skip it. - AND NOT MULTI_ARCH - # Skip this with Xcode for now. - AND NOT "${CMAKE_GENERATOR}" MATCHES Xcode) + if(CMAKE_${lang}_VERBOSE_FLAG) CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs log "${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}") file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log @@ -112,6 +101,14 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) message(STATUS "${_desc}") endif() + # Implicit link libraries cannot be used explicitly for multiple + # OS X architectures, so we skip it. + if(DEFINED CMAKE_OSX_ARCHITECTURES) + if("${CMAKE_OSX_ARCHITECTURES}" MATCHES ";") + set(implicit_libs "") + endif() + endif() + set(CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES "${implicit_libs}" PARENT_SCOPE) set(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE) diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index ecb20dc6b..54e812748 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake @@ -36,6 +36,16 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex) set(cmd) if("${line}" MATCHES "${linker_regex}" AND NOT "${line}" MATCHES "${linker_exclude_regex}") + if(XCODE) + # Xcode unconditionally adds a path under the project build tree and + # on older versions it is not reported with proper quotes. Remove it. + string(REGEX REPLACE "([][+.*()^])" "\\\\\\1" _dir_regex "${CMAKE_BINARY_DIR}") + string(REGEX REPLACE " -[FL]${_dir_regex}/([^ ]| [^-])+( |$)" " " xline "${line}") + if(NOT "x${xline}" STREQUAL "x${line}") + set(log "${log} reduced line: [${line}]\n to: [${xline}]\n") + set(line "${xline}") + endif() + endif() if(UNIX) separate_arguments(args UNIX_COMMAND "${line}") else() @@ -97,6 +107,13 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex) endif() endforeach() + # Look for library search paths reported by linker. + if("${output_lines}" MATCHES ";Library search paths:((;\t[^;]+)+)") + string(REPLACE ";\t" ";" implicit_dirs_match "${CMAKE_MATCH_1}") + set(log "${log} Library search paths: [${implicit_dirs_match}]\n") + list(APPEND implicit_dirs_tmp ${implicit_dirs_match}) + endif() + # Cleanup list of libraries and flags. # We remove items that are not language-specific. set(implicit_libs "") @@ -108,12 +125,18 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex) endif() endforeach() - # Cleanup list of directories. + # Cleanup list of library directories. set(implicit_dirs "") foreach(d IN LISTS implicit_dirs_tmp) get_filename_component(dir "${d}" ABSOLUTE) - list(APPEND implicit_dirs "${dir}") - set(log "${log} collapse dir [${d}] ==> [${dir}]\n") + string(FIND "${dir}" "${CMAKE_FILES_DIRECTORY}/" pos) + if(NOT pos LESS 0) + set(msg ", skipping non-system directory") + else() + set(msg "") + list(APPEND implicit_dirs "${dir}") + endif() + set(log "${log} collapse library dir [${d}] ==> [${dir}]${msg}\n") endforeach() list(REMOVE_DUPLICATES implicit_dirs) diff --git a/Modules/Platform/Darwin-Clang.cmake b/Modules/Platform/Darwin-Clang.cmake index de7a85636..528873cfd 100644 --- a/Modules/Platform/Darwin-Clang.cmake +++ b/Modules/Platform/Darwin-Clang.cmake @@ -19,6 +19,7 @@ endif() set(__DARWIN_COMPILER_CLANG 1) macro(__darwin_compiler_clang lang) + set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names") set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names") set(CMAKE_${lang}_SYSROOT_FLAG "-isysroot") diff --git a/Modules/Platform/Darwin-GNU.cmake b/Modules/Platform/Darwin-GNU.cmake index d9535039f..5fee7e3ae 100644 --- a/Modules/Platform/Darwin-GNU.cmake +++ b/Modules/Platform/Darwin-GNU.cmake @@ -19,6 +19,7 @@ endif() set(__DARWIN_COMPILER_GNU 1) macro(__darwin_compiler_gnu lang) + set(CMAKE_${lang}_VERBOSE_FLAG "-v -Wl,-v") # also tell linker to print verbose output # GNU does not have -shared on OS X set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names") set(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS "-bundle -Wl,-headerpad_max_install_names") diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in index dbe95005e..02963042c 100644 --- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in +++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in @@ -102,30 +102,127 @@ list(APPEND platforms linux64_test1) #----------------------------------------------------------------------------- # Mac +# gcc -arch i686 dummy.c -v -Wl,-v +set(mac_i686_gcc_Wlv_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccnhXAGL.o -lSystem -lgcc -lSystem +collect2 version 4.2.1 (Apple Inc. build 5646) (i686 Darwin) +/usr/libexec/gcc/i686-apple-darwin10/4.2.1/ld -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccSiuUhD.o -v -lSystem -lgcc -lSystem +@(#)PROGRAM:ld PROJECT:ld64-95.2.12 +Library search paths: + /usr/lib/i686-apple-darwin10/4.2.1 + /usr/lib/gcc/i686-apple-darwin10/4.2.1 + /usr/lib/gcc/i686-apple-darwin10/4.2.1 + /usr/lib/i686-apple-darwin10/4.2.1 + /usr/lib + /usr/lib + /usr/local/lib +Framework search paths: + /Library/Frameworks/ + /System/Library/Frameworks/") +set(mac_i686_gcc_Wlv_libs "") +set(mac_i686_gcc_Wlv_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib") +list(APPEND platforms mac_i686_gcc_Wlv) + # gcc -arch i686 dummy.c -v set(mac_i686_gcc_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccnhXAGL.o -lSystem -lgcc -lSystem") set(mac_i686_gcc_libs "") set(mac_i686_gcc_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib") list(APPEND platforms mac_i686_gcc) +# g++ -arch i686 dummy.cxx -v -Wl,-v +set(mac_i686_g++_Wlv_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccEXXICh.o -lstdc++ -lSystem -lgcc -lSystem +collect2 version 4.2.1 (Apple Inc. build 5646) (i686 Darwin) +/usr/libexec/gcc/i686-apple-darwin10/4.2.1/ld -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccWrBoVl.o -v -lstdc++ -lSystem -lgcc -lSystem +@(#)PROGRAM:ld PROJECT:ld64-95.2.12 +Library search paths: + /usr/lib/i686-apple-darwin10/4.2.1 + /usr/lib/gcc/i686-apple-darwin10/4.2.1 + /usr/lib/gcc/i686-apple-darwin10/4.2.1 + /usr/lib/i686-apple-darwin10/4.2.1 + /usr/lib + /usr/lib + /usr/local/lib +Framework search paths: + /Library/Frameworks/ + /System/Library/Frameworks/") +set(mac_i686_g++_Wlv_libs "stdc++") +set(mac_i686_g++_Wlv_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib") +list(APPEND platforms mac_i686_g++_Wlv) + # g++ -arch i686 dummy.cxx -v set(mac_i686_g++_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccEXXICh.o -lstdc++ -lSystem -lgcc -lSystem") set(mac_i686_g++_libs "stdc++") set(mac_i686_g++_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib") list(APPEND platforms mac_i686_g++) +# gfortran dummy.f -v -Wl,-v +set(mac_i686_gfortran_Wlv_text " /usr/local/libexec/gcc/i386-apple-darwin9.7.0/4.4.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1 -L/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1/../../.. /var/tmp//cc9zXNax.o -v -lgfortranbegin -lgfortran -lgcc_s.10.5 -lgcc -lSystem +collect2 version 4.4.1 20090623 (prerelease) (i686 Darwin) +/usr/bin/ld -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1 -L/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1/../../.. /var/tmp//cc9zXNax.o -v -lgfortranbegin -lgfortran -lgcc_s.10.5 -lgcc -lSystem +@(#)PROGRAM:ld PROJECT:ld64-95.2.12 +Library search paths: + /usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1 + /usr/local/lib + /usr/lib + /usr/local/lib +Framework search paths: + /Library/Frameworks/ + /System/Library/Frameworks/") +set(mac_i686_gfortran_Wlv_libs "gfortranbegin;gfortran") +set(mac_i686_gfortran_Wlv_dirs "/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1;/usr/local/lib;/usr/lib") +list(APPEND platforms mac_i686_gfortran_Wlv) + # gfortran dummy.f -v set(mac_i686_gfortran_text " /usr/libexec/gcc/i386-apple-darwin9.7.0/4.4.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1 -L/usr/lib/gcc -L/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1/../../.. /var/tmp//ccgqbX5P.o -lgfortranbegin -lgfortran -lgcc_s.10.5 -lgcc -lSystem") set(mac_i686_gfortran_libs "gfortranbegin;gfortran") set(mac_i686_gfortran_dirs "/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1;/usr/lib/gcc;/usr/lib") list(APPEND platforms mac_i686_gfortran) +# gcc -arch ppc dummy.c -v -Wl,-v +set(mac_ppc_gcc_Wlv_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//cclziQY4.o -v -lgcc -lSystemStubs -lSystem +collect2 version 4.2.1 (Apple Inc. build 5646) (Darwin/PowerPC) +/usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/ld -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//cclziQY4.o -v -lgcc -lSystemStubs -lSystem +@(#)PROGRAM:ld PROJECT:ld64-95.2.12 +Library search paths: + /usr/lib/powerpc-apple-darwin10/4.2.1 + /usr/lib/gcc/powerpc-apple-darwin10/4.2.1 + /usr/lib/gcc/powerpc-apple-darwin10/4.2.1 + /usr/lib/powerpc-apple-darwin10/4.2.1 + /usr/lib + /usr/lib + /usr/local/lib +Framework search paths: + /Library/Frameworks/ + /System/Library/Frameworks/") +set(mac_ppc_gcc_Wlv_libs "") +set(mac_ppc_gcc_Wlv_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib") +list(APPEND platforms mac_ppc_gcc_Wlv) + # gcc -arch ppc dummy.c -v set(mac_ppc_gcc_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccdcolsP.o -lgcc -lSystemStubs -lSystem") set(mac_ppc_gcc_libs "") set(mac_ppc_gcc_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib") list(APPEND platforms mac_ppc_gcc) +# g++ -arch ppc dummy.cxx -v -Wl,-v +set(mac_ppc_g++_Wlv_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccaFTkwq.o -v -lstdc++ -lgcc -lSystemStubs -lSystem +collect2 version 4.2.1 (Apple Inc. build 5646) (Darwin/PowerPC) +/usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/ld -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccaFTkwq.o -v -lstdc++ -lgcc -lSystemStubs -lSystem +@(#)PROGRAM:ld PROJECT:ld64-95.2.12 +Library search paths: + /usr/lib/powerpc-apple-darwin10/4.2.1 + /usr/lib/gcc/powerpc-apple-darwin10/4.2.1 + /usr/lib/gcc/powerpc-apple-darwin10/4.2.1 + /usr/lib/powerpc-apple-darwin10/4.2.1 + /usr/lib + /usr/lib + /usr/local/lib +Framework search paths: + /Library/Frameworks/ + /System/Library/Frameworks/") +set(mac_ppc_g++_Wlv_libs "stdc++") +set(mac_ppc_g++_Wlv_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib") +list(APPEND platforms mac_ppc_g++_Wlv) + # g++ -arch ppc dummy.cxx -v set(mac_ppc_g++_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccbjB6Lj.o -lstdc++ -lgcc -lSystemStubs -lSystem") set(mac_ppc_g++_libs "stdc++") From cc676c3a08019b17433931a9287d9cd8b0ccf2f2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 5 Dec 2012 13:46:04 -0500 Subject: [PATCH 088/170] OS X: Detect implicit linker framework search paths Previously we hard-coded a list of implicit framework directories but did not account for CMAKE_OSX_SYSROOT or for changes to the list across OS X versions. Instead we should automatically detect the framework directories for the active toolchain. The parent commit added the "-Wl,-v" option to ask "ld" to print its implicit directories. It displays a block such as: Framework search paths: /... Parse this block to extract the list of framework directories. Detection may fail on toolchains that do not list their framework directories, such as older OS X linkers. Always treat the paths /Library/Frameworks /System/Library/Frameworks /Network/Library/Frameworks # Older OS X only /System/Library/Frameworks as implicit. Note that /System/Library/Frameworks should always be considered implicit so that frameworks CMake finds there will not override the SDK copies. --- Modules/CMakeCCompiler.cmake.in | 1 + Modules/CMakeCXXCompiler.cmake.in | 1 + Modules/CMakeDetermineCompilerABI.cmake | 4 +- Modules/CMakeFortranCompiler.cmake.in | 1 + Modules/CMakeParseImplicitLinkInfo.cmake | 40 ++++++++++++------- Modules/Platform/Darwin.cmake | 18 +++++++++ Source/cmComputeLinkInformation.cxx | 29 ++++++++++++-- Source/cmDocumentVariables.cxx | 9 +++++ .../CMakeTests/ImplicitLinkInfoTest.cmake.in | 11 +++-- Tests/SystemInformation/SystemInformation.in | 2 + 10 files changed, 94 insertions(+), 22 deletions(-) diff --git a/Modules/CMakeCCompiler.cmake.in b/Modules/CMakeCCompiler.cmake.in index d74dcdcee..c41adc956 100644 --- a/Modules/CMakeCCompiler.cmake.in +++ b/Modules/CMakeCCompiler.cmake.in @@ -50,6 +50,7 @@ endif() set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "@CMAKE_C_IMPLICIT_LINK_LIBRARIES@") set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_DIRECTORIES@") +set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@") @SET_CMAKE_CMCLDEPS_EXECUTABLE@ @SET_CMAKE_CL_SHOWINCLUDE_PREFIX@ diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in index 8c5d84e6c..9287b8194 100644 --- a/Modules/CMakeCXXCompiler.cmake.in +++ b/Modules/CMakeCXXCompiler.cmake.in @@ -51,6 +51,7 @@ endif() set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "@CMAKE_CXX_IMPLICIT_LINK_LIBRARIES@") set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES@") +set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@") @SET_CMAKE_CMCLDEPS_EXECUTABLE@ @SET_CMAKE_CL_SHOWINCLUDE_PREFIX@ diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake index cb94aa655..25d6bbea7 100644 --- a/Modules/CMakeDetermineCompilerABI.cmake +++ b/Modules/CMakeDetermineCompilerABI.cmake @@ -72,8 +72,9 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) # Parse implicit linker information for this language, if available. set(implicit_dirs "") set(implicit_libs "") + set(implicit_fwks "") if(CMAKE_${lang}_VERBOSE_FLAG) - CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs log + CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs implicit_fwks log "${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}") file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Parsed ${lang} implicit link information from above output:\n${log}\n\n") @@ -111,6 +112,7 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src) set(CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES "${implicit_libs}" PARENT_SCOPE) set(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE) + set(CMAKE_${lang}_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "${implicit_fwks}" PARENT_SCOPE) # Detect library architecture directory name. if(CMAKE_LIBRARY_ARCHITECTURE_REGEX) diff --git a/Modules/CMakeFortranCompiler.cmake.in b/Modules/CMakeFortranCompiler.cmake.in index 55f827773..d193881d9 100644 --- a/Modules/CMakeFortranCompiler.cmake.in +++ b/Modules/CMakeFortranCompiler.cmake.in @@ -52,3 +52,4 @@ endif() set(CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES "@CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES@") set(CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES "@CMAKE_Fortran_IMPLICIT_LINK_DIRECTORIES@") +set(CMAKE_Fortran_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_Fortran_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@") diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake index 54e812748..234fb7fa1 100644 --- a/Modules/CMakeParseImplicitLinkInfo.cmake +++ b/Modules/CMakeParseImplicitLinkInfo.cmake @@ -16,9 +16,10 @@ # This is used internally by CMake and should not be included by user # code. -function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex) +function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj_regex) set(implicit_libs_tmp "") set(implicit_dirs_tmp) + set(implicit_fwks_tmp) set(log "") # Parse implicit linker arguments. @@ -113,6 +114,11 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex) set(log "${log} Library search paths: [${implicit_dirs_match}]\n") list(APPEND implicit_dirs_tmp ${implicit_dirs_match}) endif() + if("${output_lines}" MATCHES ";Framework search paths:((;\t[^;]+)+)") + string(REPLACE ";\t" ";" implicit_fwks_match "${CMAKE_MATCH_1}") + set(log "${log} Framework search paths: [${implicit_fwks_match}]\n") + list(APPEND implicit_fwks_tmp ${implicit_fwks_match}) + endif() # Cleanup list of libraries and flags. # We remove items that are not language-specific. @@ -125,27 +131,33 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var log_var obj_regex) endif() endforeach() - # Cleanup list of library directories. - set(implicit_dirs "") - foreach(d IN LISTS implicit_dirs_tmp) - get_filename_component(dir "${d}" ABSOLUTE) - string(FIND "${dir}" "${CMAKE_FILES_DIRECTORY}/" pos) - if(NOT pos LESS 0) - set(msg ", skipping non-system directory") - else() - set(msg "") - list(APPEND implicit_dirs "${dir}") - endif() - set(log "${log} collapse library dir [${d}] ==> [${dir}]${msg}\n") + # Cleanup list of library and framework directories. + set(desc_dirs "library") + set(desc_fwks "framework") + foreach(t dirs fwks) + set(implicit_${t} "") + foreach(d IN LISTS implicit_${t}_tmp) + get_filename_component(dir "${d}" ABSOLUTE) + string(FIND "${dir}" "${CMAKE_FILES_DIRECTORY}/" pos) + if(NOT pos LESS 0) + set(msg ", skipping non-system directory") + else() + set(msg "") + list(APPEND implicit_${t} "${dir}") + endif() + set(log "${log} collapse ${desc_${t}} dir [${d}] ==> [${dir}]${msg}\n") + endforeach() + list(REMOVE_DUPLICATES implicit_${t}) endforeach() - list(REMOVE_DUPLICATES implicit_dirs) # Log results. set(log "${log} implicit libs: [${implicit_libs}]\n") set(log "${log} implicit dirs: [${implicit_dirs}]\n") + set(log "${log} implicit fwks: [${implicit_fwks}]\n") # Return results. set(${lib_var} "${implicit_libs}" PARENT_SCOPE) set(${dir_var} "${implicit_dirs}" PARENT_SCOPE) + set(${fwk_var} "${implicit_fwks}" PARENT_SCOPE) set(${log_var} "${log}" PARENT_SCOPE) endfunction() diff --git a/Modules/Platform/Darwin.cmake b/Modules/Platform/Darwin.cmake index ed0b8af3f..2e6b71e36 100644 --- a/Modules/Platform/Darwin.cmake +++ b/Modules/Platform/Darwin.cmake @@ -256,6 +256,24 @@ set(CMAKE_CXX_CREATE_MACOSX_FRAMEWORK if(NOT DEFINED CMAKE_FIND_FRAMEWORK) set(CMAKE_FIND_FRAMEWORK FIRST) endif() + +# Older OS X linkers do not report their framework search path +# with -v but "man ld" documents the following locations. +set(CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES + ${_CMAKE_OSX_SYSROOT_PATH}/Library/Frameworks + ${_CMAKE_OSX_SYSROOT_PATH}/System/Library/Frameworks + ) +if(_CMAKE_OSX_SYSROOT_PATH) + # Treat some paths as implicit so we do not override the SDK versions. + list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES + /System/Library/Frameworks) +endif() +if("${_CURRENT_OSX_VERSION}" VERSION_LESS "10.5") + # Older OS X tools had more implicit paths. + list(APPEND CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES + ${_CMAKE_OSX_SYSROOT_PATH}/Network/Library/Frameworks) +endif() + # set up the default search directories for frameworks set(CMAKE_SYSTEM_FRAMEWORK_PATH ~/Library/Frameworks diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index d8ffb5e83..19de90347 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -1376,10 +1376,31 @@ void cmComputeLinkInformation::DropDirectoryItem(std::string const& item) //---------------------------------------------------------------------------- void cmComputeLinkInformation::ComputeFrameworkInfo() { - // Avoid adding system framework paths. See "man ld" on OS X. - this->FrameworkPathsEmmitted.insert("/Library/Frameworks"); - this->FrameworkPathsEmmitted.insert("/Network/Library/Frameworks"); - this->FrameworkPathsEmmitted.insert("/System/Library/Frameworks"); + // Avoid adding implicit framework paths. + std::vector implicitDirVec; + + // Get platform-wide implicit directories. + if(const char* implicitLinks = this->Makefile->GetDefinition + ("CMAKE_PLATFORM_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES")) + { + cmSystemTools::ExpandListArgument(implicitLinks, implicitDirVec); + } + + // Get language-specific implicit directories. + std::string implicitDirVar = "CMAKE_"; + implicitDirVar += this->LinkLanguage; + implicitDirVar += "_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES"; + if(const char* implicitDirs = + this->Makefile->GetDefinition(implicitDirVar.c_str())) + { + cmSystemTools::ExpandListArgument(implicitDirs, implicitDirVec); + } + + for(std::vector::const_iterator i = implicitDirVec.begin(); + i != implicitDirVec.end(); ++i) + { + this->FrameworkPathsEmmitted.insert(*i); + } // Regular expression to extract a framework path and name. this->SplitFramework.compile("(.*)/(.*)\\.framework$"); diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 55d70f862..0a4170b71 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1624,6 +1624,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "reports the results in this variable.", false, "Variables for Languages"); + cm->DefineProperty + ("CMAKE__IMPLICIT_LINK_FRAMEWORK_DIRECTORIES", cmProperty::VARIABLE, + "Implicit linker framework search path detected for language .", + "These paths are implicit linker framework search directories for " + "the compiler's language. " + "CMake automatically detects these directories for each language and " + "reports the results in this variable.", false, + "Variables for Languages"); + cm->DefineProperty ("CMAKE__IMPLICIT_LINK_LIBRARIES", cmProperty::VARIABLE, "Implicit link libraries and flags detected for language .", diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in index 02963042c..31488c0ff 100644 --- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in +++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in @@ -120,6 +120,7 @@ Framework search paths: /System/Library/Frameworks/") set(mac_i686_gcc_Wlv_libs "") set(mac_i686_gcc_Wlv_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib") +set(mac_i686_gcc_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks") list(APPEND platforms mac_i686_gcc_Wlv) # gcc -arch i686 dummy.c -v @@ -146,6 +147,7 @@ Framework search paths: /System/Library/Frameworks/") set(mac_i686_g++_Wlv_libs "stdc++") set(mac_i686_g++_Wlv_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib") +set(mac_i686_g++_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks") list(APPEND platforms mac_i686_g++_Wlv) # g++ -arch i686 dummy.cxx -v @@ -169,6 +171,7 @@ Framework search paths: /System/Library/Frameworks/") set(mac_i686_gfortran_Wlv_libs "gfortranbegin;gfortran") set(mac_i686_gfortran_Wlv_dirs "/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1;/usr/local/lib;/usr/lib") +set(mac_i686_gfortran_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks") list(APPEND platforms mac_i686_gfortran_Wlv) # gfortran dummy.f -v @@ -195,6 +198,7 @@ Framework search paths: /System/Library/Frameworks/") set(mac_ppc_gcc_Wlv_libs "") set(mac_ppc_gcc_Wlv_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib") +set(mac_ppc_gcc_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks") list(APPEND platforms mac_ppc_gcc_Wlv) # gcc -arch ppc dummy.c -v @@ -221,6 +225,7 @@ Framework search paths: /System/Library/Frameworks/") set(mac_ppc_g++_Wlv_libs "stdc++") set(mac_ppc_g++_Wlv_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib") +set(mac_ppc_g++_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks") list(APPEND platforms mac_ppc_g++_Wlv) # g++ -arch ppc dummy.cxx -v @@ -499,10 +504,10 @@ list(APPEND platforms msys_g77) # Test parsing for all above examples. foreach(p IN LISTS platforms) - cmake_parse_implicit_link_info("${${p}_text}" libs dirs log "${${p}_obj_regex}") + cmake_parse_implicit_link_info("${${p}_text}" libs dirs fwks log "${${p}_obj_regex}") - foreach(v libs dirs) - if(NOT "${${v}}" STREQUAL "${${p}_${v}}") + foreach(v libs dirs fwks) + if(DEFINED "${p}_${v}" AND NOT "${${v}}" STREQUAL "${${p}_${v}}") message(FATAL_ERROR "cmake_parse_implicit_link_info failed\n" "Expected '${p}' implicit ${v}\n" diff --git a/Tests/SystemInformation/SystemInformation.in b/Tests/SystemInformation/SystemInformation.in index ecbc05408..df3bf49d5 100644 --- a/Tests/SystemInformation/SystemInformation.in +++ b/Tests/SystemInformation/SystemInformation.in @@ -96,7 +96,9 @@ CMAKE_CXX_LINK_EXECUTABLE == "${CMAKE_CXX_LINK_EXECUTABLE}" // implicit link info CMAKE_C_IMPLICIT_LINK_LIBRARIES == "${CMAKE_C_IMPLICIT_LINK_LIBRARIES}" CMAKE_C_IMPLICIT_LINK_DIRECTORIES == "${CMAKE_C_IMPLICIT_LINK_DIRECTORIES}" +CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES == "${CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES}" CMAKE_CXX_IMPLICIT_LINK_LIBRARIES == "${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES}" CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES == "${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES}" +CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES == "${CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES}" XCODE_VERSION == "${XCODE_VERSION}" From daf17b13d5c8694c43c3c127dedbc93a1b2a894b Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Wed, 12 Dec 2012 00:01:06 -0500 Subject: [PATCH 089/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 20e68e91e..41fc6a20c 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 20121211) +set(CMake_VERSION_TWEAK 20121212) #set(CMake_VERSION_RC 1) From f6a9a64f16a6f79095dd3eb9563999253fa18f9f Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Thu, 13 Dec 2012 00:01:03 -0500 Subject: [PATCH 090/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 41fc6a20c..59bac2dbb 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 20121212) +set(CMake_VERSION_TWEAK 20121213) #set(CMake_VERSION_RC 1) From 34ecf7088b8d08bdc5cbf2462c8f9ad72425ecf9 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Fri, 14 Dec 2012 00:01:02 -0500 Subject: [PATCH 091/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 59bac2dbb..e4117d550 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 20121213) +set(CMake_VERSION_TWEAK 20121214) #set(CMake_VERSION_RC 1) From a076b256c4786a3d86c7d3655fa26cd72761e16b Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sat, 15 Dec 2012 00:01:04 -0500 Subject: [PATCH 092/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index e4117d550..6071fc27c 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 20121214) +set(CMake_VERSION_TWEAK 20121215) #set(CMake_VERSION_RC 1) From d8dcd639101de6eeccf21860c0048a6c8bb188dc Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sun, 16 Dec 2012 00:01:04 -0500 Subject: [PATCH 093/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 6071fc27c..4cf6b99e1 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 20121215) +set(CMake_VERSION_TWEAK 20121216) #set(CMake_VERSION_RC 1) From a3f63661e67c928c465562f988e4ab103b0ec865 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Mon, 17 Dec 2012 00:01:05 -0500 Subject: [PATCH 094/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 4cf6b99e1..aced2e752 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 20121216) +set(CMake_VERSION_TWEAK 20121217) #set(CMake_VERSION_RC 1) From 8931dd6e74bce78737baaf78c9867c992829c60b Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Tue, 18 Dec 2012 00:01:03 -0500 Subject: [PATCH 095/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index aced2e752..81d74c889 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 20121217) +set(CMake_VERSION_TWEAK 20121218) #set(CMake_VERSION_RC 1) From 324780697c5020a027efdc24bd9cc2fc926a3546 Mon Sep 17 00:00:00 2001 From: Casey Goodlett Date: Tue, 18 Dec 2012 13:09:53 -0500 Subject: [PATCH 096/170] CTest: Prevent creation of unbounded number of tests in ctest (#12904) Note it is still possible for CTest to start more than the number of processes specified by PARALLEL_LEVEL, but this prevents the number of tests to start from being unbounded because of overflow. --- Source/CTest/cmCTestMultiProcessHandler.cxx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index ebef1ed9c..76ddeea01 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -248,7 +248,12 @@ bool cmCTestMultiProcessHandler::StartTest(int test) //--------------------------------------------------------- void cmCTestMultiProcessHandler::StartNextTests() { - size_t numToStart = this->ParallelLevel - this->RunningCount; + size_t numToStart = 0; + if(this->RunningCount < this->ParallelLevel) + { + numToStart = this->ParallelLevel - this->RunningCount; + } + if(numToStart == 0) { return; From 5ac16ea6e4ddb086d48c97fa4f58543284ec3305 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Wed, 19 Dec 2012 00:01:09 -0500 Subject: [PATCH 097/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 81d74c889..84ed3680b 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 20121218) +set(CMake_VERSION_TWEAK 20121219) #set(CMake_VERSION_RC 1) From a0f91f1daa7765066a784e4479da7e231374a065 Mon Sep 17 00:00:00 2001 From: KWSys Robot Date: Wed, 19 Dec 2012 08:02:08 -0500 Subject: [PATCH 098/170] KWSys 2012-12-19 (933eb822) Extract upstream KWSys using the following shell commands. $ git archive --prefix=upstream-kwsys/ 933eb822 | tar x $ git shortlog --no-merges --abbrev=8 --format='%h %s' 3b17de34..933eb822 Brad King (2): fea37696 Process: Remove support for Windows 98 01e15c22 Remove KWSys Registry Rolf Eike Beer (7): f376ec32 SystemInformation: fix typos bfee5174 SystemInformation: sum up all caches found in /proc/cpuinfo 5690d711 SystemInformation: fix value extraction from /proc/cpuinfo 36295981 SystemInformation: PA-RISC chips are from HP 72e9d02e SystemInformation: try harder to find a useful processor name b39de34c SystemInformation: try harder to find the CPU family 933eb822 SystemInformation: extract CPU stepping information from /proc/cpuinfo, too Sean McBride (2): 5e17bfde Process: Dereference NULL++ instead of NULL to force crash 86a78cb7 SystemTools: Add check for empty strings to prevent integer underflow Change-Id: Id7194f434fe67be81e6ee9e96d705010a1171a06 --- CMakeLists.txt | 51 +-- EncodeExecutable.c | 114 ------ ProcessFwd9x.c | 211 ---------- ProcessWin32.c | 287 +------------ Registry.cxx | 818 -------------------------------------- Registry.hxx.in | 107 ----- SystemInformation.cxx | 99 ++++- SystemTools.cxx | 8 +- testProcess.c | 15 +- testRegistry.cxx | 109 ----- testSystemInformation.cxx | 1 + 11 files changed, 119 insertions(+), 1701 deletions(-) delete mode 100644 EncodeExecutable.c delete mode 100644 ProcessFwd9x.c delete mode 100644 Registry.cxx delete mode 100644 Registry.hxx.in delete mode 100644 testRegistry.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 777d76f4b..ccdff1255 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,6 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) SET(KWSYS_USE_MD5 1) SET(KWSYS_USE_Process 1) SET(KWSYS_USE_RegularExpression 1) - SET(KWSYS_USE_Registry 1) SET(KWSYS_USE_System 1) SET(KWSYS_USE_SystemTools 1) SET(KWSYS_USE_CommandLineArguments 1) @@ -762,7 +761,7 @@ SET(KWSYS_HXX_FILES Configure String # Add selected C++ classes. SET(cppclasses Directory DynamicLoader Glob RegularExpression SystemTools - CommandLineArguments Registry IOStream SystemInformation + CommandLineArguments IOStream SystemInformation ) FOREACH(cpp ${cppclasses}) IF(KWSYS_USE_${cpp}) @@ -800,12 +799,8 @@ SET(KWSYS_CXX_SRCS) # Add the proper sources for this platform's Process implementation. IF(KWSYS_USE_Process) IF(NOT UNIX) - # Use the Windows implementation. We need the encoded forwarding executable. - SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c - ${PROJECT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c) - SET_SOURCE_FILES_PROPERTIES( - ${PROJECT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c - PROPERTIES GENERATED 1) + # Use the Windows implementation. + SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessWin32.c) ELSE(NOT UNIX) # Use the UNIX implementation. SET(KWSYS_C_SRCS ${KWSYS_C_SRCS} ProcessUNIX.c) @@ -937,43 +932,6 @@ IF(KWSYS_USE_String) COMPILE_FLAGS "-DKWSYS_STRING_C") ENDIF(KWSYS_USE_String) -#----------------------------------------------------------------------------- -# Process execution on windows needs to build a forwarding executable -# that works around a Win9x bug. We encode the executable into a C -# file and build it into the library. Win9x platforms reproduce the -# executable into a temporary directory when it is needed. -IF(KWSYS_USE_Process) - IF(NOT UNIX) - # Build the forwarding executable itself and a program that will - # encode it into a C file. - ADD_EXECUTABLE(${KWSYS_NAMESPACE}ProcessFwd9x ProcessFwd9x.c) - ADD_EXECUTABLE(${KWSYS_NAMESPACE}EncodeExecutable EncodeExecutable.c) - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}ProcessFwd9x PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}EncodeExecutable PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}ProcessFwd9x PROPERTY LABELS ${KWSYS_LABELS_EXE}) - SET_PROPERTY(TARGET ${KWSYS_NAMESPACE}EncodeExecutable PROPERTY LABELS ${KWSYS_LABELS_EXE}) - - SET(CFG_INTDIR "/${CMAKE_CFG_INTDIR}") - IF(CMAKE_BUILD_TOOL MATCHES "make") - SET(CFG_INTDIR "") - ENDIF(CMAKE_BUILD_TOOL MATCHES "make") - - # Take advantage of a better custom command syntax if possible. - SET(CMD ${CMAKE_CURRENT_BINARY_DIR}${CFG_INTDIR}/${KWSYS_NAMESPACE}EncodeExecutable.exe) - SET(FWD ${CMAKE_CURRENT_BINARY_DIR}${CFG_INTDIR}/${KWSYS_NAMESPACE}ProcessFwd9x.exe) - ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c - COMMAND ${CMD} - ARGS ${FWD} ${CMAKE_CURRENT_BINARY_DIR}/${KWSYS_NAMESPACE}ProcessFwd9xEnc.c - ${KWSYS_NAMESPACE} ProcessFwd9x - DEPENDS ${CMD} ${FWD}) - - # Make sure build occurs in proper order. - ADD_DEPENDENCIES(${KWSYS_NAMESPACE} ${KWSYS_NAMESPACE}ProcessFwd9x - ${KWSYS_NAMESPACE}EncodeExecutable) - ENDIF(NOT UNIX) -ENDIF(KWSYS_USE_Process) - #----------------------------------------------------------------------------- # Setup testing if not being built as part of another project. IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) @@ -1012,7 +970,6 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) ) ENDIF(NOT WATCOM) SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} - testRegistry testIOS testSystemTools testCommandLineArguments @@ -1116,8 +1073,6 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR) # We expect test to fail SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES WILL_FAIL ON) GET_TEST_PROPERTY(kwsys.testFail WILL_FAIL wfv) - SET_TESTS_PROPERTIES(kwsys.testRegistry PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR_NOT_VALGRIND;FAIL;Test failed") - SET_TESTS_PROPERTIES(kwsys.testRegistry PROPERTIES PASS_REGULAR_EXPRESSION "Test passed") SET_TESTS_PROPERTIES(kwsys.testFail PROPERTIES MEASUREMENT "Some Key=Some Value") MESSAGE(STATUS "GET_TEST_PROPERTY returned: ${wfv}") ENDIF() diff --git a/EncodeExecutable.c b/EncodeExecutable.c deleted file mode 100644 index bc30568ff..000000000 --- a/EncodeExecutable.c +++ /dev/null @@ -1,114 +0,0 @@ -/*============================================================================ - KWSys - Kitware System Library - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#include -#ifdef __WATCOMC__ -#define _unlink unlink -#endif -int main(int argc, char* argv[]) -{ - FILE* ifp; - FILE* ofp; - int i; - int n; - int count = 0; - unsigned char buffer[1024]; - - /* Check arguments. */ - if(argc != 5) - { - fprintf(stderr, "Usage: %s \n", - argv[0]); - return 1; - } - - /* Open the input file. */ - ifp = fopen(argv[1], "rb"); - if(!ifp) - { - fprintf(stderr, "Cannot open input file: \"%s\"\n", argv[1]); - return 2; - } - ofp = fopen(argv[2], "w"); - if(!ofp) - { - fprintf(stderr, "Cannot open output file: \"%s\"\n", argv[2]); - fclose(ifp); - return 2; - } - - /* Prepend header comment. */ - fprintf(ofp, "/*\n * DO NOT EDIT\n * This file is generated by:\n"); - fprintf(ofp, " * %s\n */\n\n", argv[0]); - fprintf(ofp, "#include \"kwsysPrivate.h\"\n"); - fprintf(ofp, "#include KWSYS_HEADER(Configure.h)\n\n"); - fprintf(ofp, "#include \n\n"); - fprintf(ofp, "#if defined(_WIN32)\n"); - fprintf(ofp, "# include \n"); - fprintf(ofp, "#else\n"); - fprintf(ofp, "# include \n"); - fprintf(ofp, "#endif\n"); - fprintf(ofp, "\n"); - fprintf(ofp, "static void kwsys_unlink(const char* fname)\n"); - fprintf(ofp, "{\n"); - fprintf(ofp, "#if defined(__WATCOMC__)\n"); - fprintf(ofp, " unlink(fname);\n"); - fprintf(ofp, "#else\n"); - fprintf(ofp, " _unlink(fname);\n"); - fprintf(ofp, "#endif\n"); - fprintf(ofp, "}\n"); - fprintf(ofp, "\n"); - - /* Split file up in 1024-byte chunks. */ - while((n = (int)fread(buffer, 1, 1024, ifp)) > 0) - { - fprintf(ofp, "static unsigned char kwsysEncodedArray%s_%d[%d] = {\n", - argv[4], count++, n); - for(i=0; i < n-1; ++i) - { - fprintf(ofp, "0x%02X", buffer[i]); - if(i%10 == 9) - { - fprintf(ofp, ",\n"); - } - else - { - fprintf(ofp, ", "); - } - } - fprintf(ofp, "0x%02X};\n\n", buffer[n-1]); - } - fclose(ifp); - - /* Provide a function to write the data to a file. */ - fprintf(ofp, "extern %s_EXPORT int %sEncodedWriteArray%s(const char* fname)\n", - argv[3], argv[3], argv[4]); - fprintf(ofp, "{\n"); - fprintf(ofp, " FILE* ofp = fopen(fname, \"wb\");\n"); - fprintf(ofp, " if(!ofp) { return 0; }\n"); - for(i=0; i < count; ++i) - { - fprintf(ofp, " if(fwrite(kwsysEncodedArray%s_%d, 1,\n" - " sizeof(kwsysEncodedArray%s_%d), ofp) !=\n" - " sizeof(kwsysEncodedArray%s_%d))\n", - argv[4], i, argv[4], i, argv[4], i); - fprintf(ofp, " {\n"); - fprintf(ofp, " fclose(ofp);\n"); - fprintf(ofp, " kwsys_unlink(fname);\n"); - fprintf(ofp, " return 0;\n"); - fprintf(ofp, " }\n"); - } - fprintf(ofp, " fclose(ofp);\n"); - fprintf(ofp, " return 1;\n"); - fprintf(ofp, "}\n"); - fclose(ofp); - return 0; -} diff --git a/ProcessFwd9x.c b/ProcessFwd9x.c deleted file mode 100644 index 536c54b67..000000000 --- a/ProcessFwd9x.c +++ /dev/null @@ -1,211 +0,0 @@ -/*============================================================================ - KWSys - Kitware System Library - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ - -/* - On Windows9x platforms, this executable is spawned between a parent - process and the child it is invoking to work around a bug. See the - Win32 implementation file for details. - - Future Work: This executable must be linked statically against the C - runtime library before being encoded into the library. Building it - in this way may be hard because CMake has limited abilities to build - different targets with different configurations in the same - directory. We may just have to create and encode the executable - once instead of generating it during the build. This would be an - acceptable solution because the forwarding executable should not - change very often and is pretty simple. -*/ - -#ifdef _MSC_VER -#pragma warning (push, 1) -#endif -#include -#include - -void ReportLastError(HANDLE errorPipe); - -int main() -{ - /* Process startup information for the real child. */ - STARTUPINFO si; - PROCESS_INFORMATION pi; - - /* The result of waiting for the child to exit. */ - DWORD waitResult; - - /* The child's process return code. */ - DWORD retVal; - - /* The command line used to invoke this process. */ - LPSTR commandLine = GetCommandLine(); - - /* Pointer that will be advanced to the beginning of the command - line of the real child process. */ - LPSTR cmdLine = commandLine; - - /* Handle to the error reporting pipe provided by the parent. This - is parsed off the command line. */ - HANDLE errorPipe = 0; - HANDLE errorPipeOrig = 0; - - /* Handle to the event the parent uses to tell us to resume the child. - This is parsed off the command line. */ - HANDLE resumeEvent = 0; - - /* Handle to the event the parent uses to tell us to kill the child. - This is parsed off the command line. */ - HANDLE killEvent = 0; - - /* Flag for whether to hide window of child process. */ - int hideWindow = 0; - - /* An array of the handles on which we wait when the child is - running. */ - HANDLE waitHandles[2] = {0, 0}; - - /* Move the pointer past the name of this executable. */ - if(*cmdLine == '"') - { - ++cmdLine; - while(*cmdLine && *cmdLine != '"') { ++cmdLine; } - if(*cmdLine) { ++cmdLine; } - } - else - { - while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } - } - - /* Parse the error pipe handle. */ - while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } - sscanf(cmdLine, "%p", &errorPipeOrig); - - /* Parse the resume event handle. */ - while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } - while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } - sscanf(cmdLine, "%p", &resumeEvent); - - /* Parse the kill event handle. */ - while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } - while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } - sscanf(cmdLine, "%p", &killEvent); - - /* Parse the hide window flag. */ - while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } - while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } - sscanf(cmdLine, "%d", &hideWindow); - - /* Skip to the beginning of the command line of the real child. */ - while(*cmdLine && *cmdLine != ' ') { ++cmdLine; } - while(*cmdLine && *cmdLine == ' ') { ++cmdLine; } - - /* Create a non-inherited copy of the error pipe. We do not want - the child to get it. */ - if(DuplicateHandle(GetCurrentProcess(), errorPipeOrig, - GetCurrentProcess(), &errorPipe, - 0, FALSE, DUPLICATE_SAME_ACCESS)) - { - /* Have a non-inherited duplicate. Close the inherited one. */ - CloseHandle(errorPipeOrig); - } - else - { - /* Could not duplicate handle. Report the error. */ - ReportLastError(errorPipeOrig); - return 1; - } - - /* Create the subprocess. */ - ZeroMemory(&si, sizeof(si)); - ZeroMemory(&pi, sizeof(pi)); - si.cb = sizeof(si); - si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; - si.wShowWindow = hideWindow?SW_HIDE:SW_SHOWDEFAULT; - si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); - si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); - si.hStdError = GetStdHandle(STD_ERROR_HANDLE); - if(CreateProcess(0, cmdLine, 0, 0, TRUE, CREATE_SUSPENDED, 0, 0, &si, &pi)) - { - /* Process created successfully. Close the error reporting pipe - to notify the parent of success. */ - CloseHandle(errorPipe); - } - else - { - /* Error creating the process. Report the error to the parent - process through the special error reporting pipe. */ - ReportLastError(errorPipe); - return 1; - } - - /* Wait for resume or kill event from parent. */ - waitHandles[0] = killEvent; - waitHandles[1] = resumeEvent; - waitResult = WaitForMultipleObjects(2, waitHandles, 0, INFINITE); - - /* Check what happened. */ - if(waitResult == WAIT_OBJECT_0) - { - /* We were asked to kill the child. */ - TerminateProcess(pi.hProcess, 255); - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - return 1; - } - else - { - /* We were asked to resume the child. */ - ResumeThread(pi.hThread); - CloseHandle(pi.hThread); - } - - /* Wait for subprocess to exit or for kill event from parent. */ - waitHandles[0] = killEvent; - waitHandles[1] = pi.hProcess; - waitResult = WaitForMultipleObjects(2, waitHandles, 0, INFINITE); - - /* Check what happened. */ - if(waitResult == WAIT_OBJECT_0) - { - /* We were asked to kill the child. */ - TerminateProcess(pi.hProcess, 255); - WaitForSingleObject(pi.hProcess, INFINITE); - CloseHandle(pi.hProcess); - return 1; - } - else - { - /* The child exited. Get the return code. */ - GetExitCodeProcess(pi.hProcess, &retVal); - CloseHandle(pi.hProcess); - return retVal; - } -} - -void ReportLastError(HANDLE errorPipe) -{ - LPVOID lpMsgBuf; - DWORD n; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); - WriteFile(errorPipe, lpMsgBuf, strlen(lpMsgBuf)+1, &n, 0); - LocalFree( lpMsgBuf ); -} diff --git a/ProcessWin32.c b/ProcessWin32.c index 5aa4d8bf6..c836f9b08 100644 --- a/ProcessWin32.c +++ b/ProcessWin32.c @@ -28,14 +28,6 @@ On windows, a thread is created to wait for data on each pipe. The threads are synchronized with the main thread to simulate the use of a UNIX-style select system call. -On Windows9x platforms, a small WIN32 console application is spawned -in-between the calling process and the actual child to be executed. -This is to work-around a problem with connecting pipes from WIN16 -console applications to WIN32 applications. - -For more information, please check Microsoft Knowledge Base Articles -Q190351 and Q150956. - */ #ifdef _MSC_VER @@ -91,18 +83,12 @@ Q190351 and Q150956. # define KWSYSPE_DEBUG(x) (void)1 #endif -#define kwsysEncodedWriteArrayProcessFwd9x kwsys_ns(EncodedWriteArrayProcessFwd9x) - typedef LARGE_INTEGER kwsysProcessTime; typedef struct kwsysProcessCreateInformation_s { /* Windows child startup control data. */ STARTUPINFO StartupInfo; - - /* Special error reporting pipe for Win9x forwarding executable. */ - HANDLE ErrorPipeRead; - HANDLE ErrorPipeWrite; } kwsysProcessCreateInformation; /*--------------------------------------------------------------------------*/ @@ -146,7 +132,6 @@ static kwsysProcessTime kwsysProcessTimeSubtract(kwsysProcessTime in1, kwsysProc static void kwsysProcessSetExitException(kwsysProcess* cp, int code); static void kwsysProcessKillTree(int pid); static void kwsysProcessDisablePipeThreads(kwsysProcess* cp); -extern kwsysEXPORT int kwsysEncodedWriteArrayProcessFwd9x(const char* fname); /*--------------------------------------------------------------------------*/ /* A structure containing synchronization data for each thread. */ @@ -233,15 +218,6 @@ struct kwsysProcess_s /* Whether to treat command lines as verbatim. */ int Verbatim; - /* On Win9x platforms, the path to the forwarding executable. */ - char* Win9x; - - /* On Win9x platforms, the resume event for the forwarding executable. */ - HANDLE Win9xResumeEvent; - - /* On Win9x platforms, the kill event for the forwarding executable. */ - HANDLE Win9xKillEvent; - /* Mutex to protect the shared index used by threads to report data. */ HANDLE SharedIndexMutex; @@ -269,9 +245,6 @@ struct kwsysProcess_s HANDLE PipeNativeSTDOUT[2]; HANDLE PipeNativeSTDERR[2]; - /* Handle to automatically delete the Win9x forwarding executable. */ - HANDLE Win9xHandle; - /* ------------- Data managed per call to Execute ------------- */ /* The exceptional behavior that terminated the process, if any. */ @@ -311,7 +284,7 @@ struct kwsysProcess_s for pipes to close after process termination. */ int PipesLeft; - /* Buffer for error messages (possibly from Win9x child). */ + /* Buffer for error messages. */ char ErrorMessage[KWSYSPE_PIPE_BUFFER_SIZE+1]; /* Description for the ExitException. */ @@ -337,9 +310,6 @@ kwsysProcess* kwsysProcess_New(void) /* Process control structure. */ kwsysProcess* cp; - /* Path to Win9x forwarding executable. */ - char* win9x = 0; - /* Windows version number data. */ OSVERSIONINFO osv; @@ -365,73 +335,11 @@ kwsysProcess* kwsysProcess_New(void) GetVersionEx(&osv); if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) { - /* This is Win9x. We need the console forwarding executable to - work-around a Windows 9x bug. */ - char fwdName[_MAX_FNAME+1] = ""; - char tempDir[_MAX_PATH+1] = ""; - - /* We will try putting the executable in the system temp - directory. Note that the returned path already has a trailing - slash. */ - DWORD length = GetTempPath(_MAX_PATH+1, tempDir); - - /* Construct the executable name from the process id and kwsysProcess - instance. This should be unique. */ - sprintf(fwdName, KWSYS_NAMESPACE_STRING "pew9xfwd_%ld_%p.exe", - GetCurrentProcessId(), cp); - - /* If we have a temp directory, use it. */ - if(length > 0 && length <= _MAX_PATH) - { - /* Allocate a buffer to hold the forwarding executable path. */ - size_t tdlen = strlen(tempDir); - win9x = (char*)malloc(tdlen + strlen(fwdName) + 2); - if(!win9x) - { - kwsysProcess_Delete(cp); - return 0; - } - - /* Construct the full path to the forwarding executable. */ - sprintf(win9x, "%s%s", tempDir, fwdName); - } - - /* If we found a place to put the forwarding executable, try to - write it. */ - if(win9x) - { - if(!kwsysEncodedWriteArrayProcessFwd9x(win9x)) - { - /* Failed to create forwarding executable. Give up. */ - free(win9x); - kwsysProcess_Delete(cp); - return 0; - } - - /* Get a handle to the file that will delete it when closed. */ - cp->Win9xHandle = CreateFile(win9x, GENERIC_READ, FILE_SHARE_READ, 0, - OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0); - if(cp->Win9xHandle == INVALID_HANDLE_VALUE) - { - /* We were not able to get a read handle for the forwarding - executable. It will not be deleted properly. Give up. */ - _unlink(win9x); - free(win9x); - kwsysProcess_Delete(cp); - return 0; - } - } - else - { - /* Failed to find a place to put forwarding executable. */ - kwsysProcess_Delete(cp); - return 0; - } + /* Win9x no longer supported. */ + kwsysProcess_Delete(cp); + return 0; } - /* Save the path to the forwarding executable. */ - cp->Win9x = win9x; - /* Initially no thread owns the mutex. Initialize semaphore to 1. */ if(!(cp->SharedIndexMutex = CreateSemaphore(0, 1, 1, 0))) { @@ -446,30 +354,6 @@ kwsysProcess* kwsysProcess_New(void) return 0; } - if(cp->Win9x) - { - SECURITY_ATTRIBUTES sa; - ZeroMemory(&sa, sizeof(sa)); - sa.nLength = sizeof(sa); - sa.bInheritHandle = TRUE; - - /* Create an event to tell the forwarding executable to resume the - child. */ - if(!(cp->Win9xResumeEvent = CreateEvent(&sa, TRUE, 0, 0))) - { - kwsysProcess_Delete(cp); - return 0; - } - - /* Create an event to tell the forwarding executable to kill the - child. */ - if(!(cp->Win9xKillEvent = CreateEvent(&sa, TRUE, 0, 0))) - { - kwsysProcess_Delete(cp); - return 0; - } - } - /* Create the thread to read each pipe. */ for(i=0; i < KWSYSPE_PIPE_COUNT; ++i) { @@ -620,13 +504,6 @@ void kwsysProcess_Delete(kwsysProcess* cp) kwsysProcessCleanupHandle(&cp->SharedIndexMutex); kwsysProcessCleanupHandle(&cp->Full); - /* Close the Win9x resume and kill event handles. */ - if(cp->Win9x) - { - kwsysProcessCleanupHandle(&cp->Win9xResumeEvent); - kwsysProcessCleanupHandle(&cp->Win9xKillEvent); - } - /* Free memory. */ kwsysProcess_SetCommand(cp, 0); kwsysProcess_SetWorkingDirectory(cp, 0); @@ -637,12 +514,6 @@ void kwsysProcess_Delete(kwsysProcess* cp) { free(cp->CommandExitCodes); } - if(cp->Win9x) - { - /* Close our handle to the forwarding executable file. This will - cause it to be deleted. */ - kwsysProcessCleanupHandle(&cp->Win9xHandle); - } free(cp); } @@ -1017,21 +888,6 @@ void kwsysProcess_Execute(kwsysProcess* cp) SetCurrentDirectory(cp->WorkingDirectory); } - /* Reset the Win9x resume and kill events. */ - if(cp->Win9x) - { - if(!ResetEvent(cp->Win9xResumeEvent)) - { - kwsysProcessCleanup(cp, 1); - return; - } - if(!ResetEvent(cp->Win9xKillEvent)) - { - kwsysProcessCleanup(cp, 1); - return; - } - } - /* Initialize startup info data. */ ZeroMemory(&si, sizeof(si)); si.StartupInfo.cb = sizeof(si.StartupInfo); @@ -1130,8 +986,6 @@ void kwsysProcess_Execute(kwsysProcess* cp) STD_OUTPUT_HANDLE); kwsysProcessCleanupHandleSafe(&si.StartupInfo.hStdError, STD_ERROR_HANDLE); - kwsysProcessCleanupHandle(&si.ErrorPipeRead); - kwsysProcessCleanupHandle(&si.ErrorPipeWrite); return; } } @@ -1160,16 +1014,9 @@ void kwsysProcess_Execute(kwsysProcess* cp) /* All processes in the pipeline have been started in suspended mode. Resume them all now. */ - if(cp->Win9x) + for(i=0; i < cp->NumberOfCommands; ++i) { - SetEvent(cp->Win9xResumeEvent); - } - else - { - for(i=0; i < cp->NumberOfCommands; ++i) - { - ResumeThread(cp->ProcessInformation[i].hThread); - } + ResumeThread(cp->ProcessInformation[i].hThread); } /* ---- It is no longer safe to call kwsysProcessCleanup. ----- */ @@ -1480,21 +1327,12 @@ void kwsysProcess_Kill(kwsysProcess* cp) /* Kill the children. */ cp->Killed = 1; - if(cp->Win9x) + for(i=0; i < cp->NumberOfCommands; ++i) { - /* Windows 9x. Tell the forwarding executable to kill the child. */ - SetEvent(cp->Win9xKillEvent); - } - else - { - /* Not Windows 9x. Just terminate the children. */ - for(i=0; i < cp->NumberOfCommands; ++i) - { - kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId); - // close the handle if we kill it - kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread); - kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess); - } + kwsysProcessKillTree(cp->ProcessInformation[i].dwProcessId); + // close the handle if we kill it + kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hThread); + kwsysProcessCleanupHandle(&cp->ProcessInformation[i].hProcess); } /* We are killing the children and ignoring all data. Do not wait @@ -1815,97 +1653,13 @@ int kwsysProcessCreate(kwsysProcess* cp, int index, } } - /* Create the child process. */ - { - BOOL r; - char* realCommand; - if(cp->Win9x) - { - /* Create an error reporting pipe for the forwarding executable. - Neither end is directly inherited. */ - if(!CreatePipe(&si->ErrorPipeRead, &si->ErrorPipeWrite, 0, 0)) - { - return 0; - } - - /* Create an inherited duplicate of the write end. This also closes - the non-inherited version. */ - if(!DuplicateHandle(GetCurrentProcess(), si->ErrorPipeWrite, - GetCurrentProcess(), &si->ErrorPipeWrite, - 0, TRUE, (DUPLICATE_CLOSE_SOURCE | - DUPLICATE_SAME_ACCESS))) - { - return 0; - } - - /* The forwarding executable is given a handle to the error pipe - and resume and kill events. */ - realCommand = (char*)malloc(strlen(cp->Win9x)+strlen(cp->Commands[index])+100); - if(!realCommand) - { - return 0; - } - sprintf(realCommand, "%s %p %p %p %d %s", cp->Win9x, - si->ErrorPipeWrite, cp->Win9xResumeEvent, cp->Win9xKillEvent, - cp->HideWindow, cp->Commands[index]); - } - else - { - realCommand = cp->Commands[index]; - } - /* Create the child in a suspended state so we can wait until all children have been created before running any one. */ - r = CreateProcess(0, realCommand, 0, 0, TRUE, - cp->Win9x? 0 : CREATE_SUSPENDED, 0, 0, - &si->StartupInfo, &cp->ProcessInformation[index]); - if(cp->Win9x) - { - /* Free memory. */ - free(realCommand); - - /* Close the error pipe write end so we can detect when the - forwarding executable closes it. */ - kwsysProcessCleanupHandle(&si->ErrorPipeWrite); - if(r) - { - /* Wait for the forwarding executable to report an error or - close the error pipe to report success. */ - DWORD total = 0; - DWORD n = 1; - while(total < KWSYSPE_PIPE_BUFFER_SIZE && n > 0) - { - if(ReadFile(si->ErrorPipeRead, cp->ErrorMessage+total, - KWSYSPE_PIPE_BUFFER_SIZE-total, &n, 0)) - { - total += n; - } - else - { - n = 0; - } - } - if(total > 0 || GetLastError() != ERROR_BROKEN_PIPE) - { - /* The forwarding executable could not run the process, or - there was an error reading from its error pipe. Preserve - the last error while cleaning up the forwarding executable - so the cleanup our caller does reports the proper error. */ - DWORD error = GetLastError(); - kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hThread); - kwsysProcessCleanupHandle(&cp->ProcessInformation[index].hProcess); - SetLastError(error); - return 0; - } - } - kwsysProcessCleanupHandle(&si->ErrorPipeRead); - } - - if(!r) + if(!CreateProcess(0, cp->Commands[index], 0, 0, TRUE, CREATE_SUSPENDED, 0, + 0, &si->StartupInfo, &cp->ProcessInformation[index])) { return 0; } - } /* Successfully created this child process. Close the current process's copies of the inherited stdout and stdin handles. The @@ -2152,19 +1906,12 @@ void kwsysProcessCleanup(kwsysProcess* cp, int error) /* Cleanup any processes already started in a suspended state. */ if(cp->ProcessInformation) { - if(cp->Win9x) + for(i=0; i < cp->NumberOfCommands; ++i) { - SetEvent(cp->Win9xKillEvent); - } - else - { - for(i=0; i < cp->NumberOfCommands; ++i) + if(cp->ProcessInformation[i].hProcess) { - if(cp->ProcessInformation[i].hProcess) - { - TerminateProcess(cp->ProcessInformation[i].hProcess, 255); - WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE); - } + TerminateProcess(cp->ProcessInformation[i].hProcess, 255); + WaitForSingleObject(cp->ProcessInformation[i].hProcess, INFINITE); } } for(i=0; i < cp->NumberOfCommands; ++i) diff --git a/Registry.cxx b/Registry.cxx deleted file mode 100644 index cd521c966..000000000 --- a/Registry.cxx +++ /dev/null @@ -1,818 +0,0 @@ -/*============================================================================ - KWSys - Kitware System Library - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#include "kwsysPrivate.h" -#include KWSYS_HEADER(Registry.hxx) - -#include KWSYS_HEADER(Configure.hxx) -#include KWSYS_HEADER(ios/iostream) -#include KWSYS_HEADER(stl/string) -#include KWSYS_HEADER(stl/map) -#include KWSYS_HEADER(ios/iostream) -#include KWSYS_HEADER(ios/fstream) -#include KWSYS_HEADER(ios/sstream) -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Registry.hxx.in" -# include "Configure.hxx.in" -# include "kwsys_stl.hxx.in" -# include "kwsys_stl_string.hxx.in" -# include "kwsys_stl_map.hxx.in" -# include "kwsys_ios_iostream.h.in" -# include "kwsys_ios_fstream.h.in" -# include "kwsys_ios_sstream.h.in" -#endif - -#include // for isspace -#include -#include /* strlen, strncpy */ -#include /* getenv */ - -#ifdef _WIN32 -# include -#endif - - -namespace KWSYS_NAMESPACE -{ -class RegistryHelper { -public: - RegistryHelper(Registry::RegistryType registryType); - virtual ~RegistryHelper(); - - // Read a value from the registry. - virtual bool ReadValue(const char *key, const char **value); - - // Delete a key from the registry. - virtual bool DeleteKey(const char *key); - - // Delete a value from a given key. - virtual bool DeleteValue(const char *key); - - // Set value in a given key. - virtual bool SetValue(const char *key, const char *value); - - // Open the registry at toplevel/subkey. - virtual bool Open(const char *toplevel, const char *subkey, - int readonly); - - // Close the registry. - virtual bool Close(); - - // Set the value of changed - void SetChanged(bool b) { m_Changed = b; } - void SetTopLevel(const char* tl); - const char* GetTopLevel() { return m_TopLevel.c_str(); } - - //! Read from local or global scope. On Windows this mean from local machine - // or local user. On unix this will read from $HOME/.Projectrc or - // /etc/Project - void SetGlobalScope(bool b); - bool GetGlobalScope(); - - kwsys_stl::string EncodeKey(const char* str); - kwsys_stl::string EncodeValue(const char* str); - kwsys_stl::string DecodeValue(const char* str); - -protected: - bool m_Changed; - kwsys_stl::string m_TopLevel; - bool m_GlobalScope; - -#ifdef _WIN32 - HKEY HKey; -#endif - // Strip trailing and ending spaces. - char *Strip(char *str); - void SetSubKey(const char* sk); - kwsys_stl::string CreateKey(const char *key); - - typedef kwsys_stl::map StringToStringMap; - StringToStringMap EntriesMap; - kwsys_stl::string m_SubKey; - bool m_Empty; - bool m_SubKeySpecified; - kwsys_stl::string m_HomeDirectory; - - Registry::RegistryType m_RegistryType; -}; - -//---------------------------------------------------------------------------- -#define Registry_BUFFER_SIZE 8192 - -//---------------------------------------------------------------------------- -Registry::Registry(Registry::RegistryType registryType) -{ - m_Opened = false; - m_Locked = false; - this->Helper = 0; - this->Helper = new RegistryHelper(registryType); -} - -//---------------------------------------------------------------------------- -Registry::~Registry() -{ - if ( m_Opened ) - { - kwsys_ios::cerr << "Registry::Close should be " - "called here. The registry is not closed." - << kwsys_ios::endl; - } - delete this->Helper; -} - -//---------------------------------------------------------------------------- -void Registry::SetGlobalScope(bool b) -{ - this->Helper->SetGlobalScope(b); -} - -//---------------------------------------------------------------------------- -bool Registry::GetGlobalScope() -{ - return this->Helper->GetGlobalScope(); -} - -//---------------------------------------------------------------------------- -bool Registry::Open(const char *toplevel, - const char *subkey, int readonly) -{ - bool res = false; - if ( m_Locked ) - { - return res; - } - if ( m_Opened ) - { - if ( !this->Close() ) - { - return res; - } - } - if ( !toplevel || !*toplevel ) - { - kwsys_ios::cerr << "Registry::Opened() Toplevel not defined" - << kwsys_ios::endl; - return res; - } - - if ( isspace(toplevel[0]) || - isspace(toplevel[strlen(toplevel)-1]) ) - { - kwsys_ios::cerr << "Toplevel has to start with letter or number and end" - " with one" << kwsys_ios::endl; - return res; - } - - res = this->Helper->Open(toplevel, subkey, readonly); - if ( readonly != Registry::READONLY ) - { - m_Locked = true; - } - - if ( res ) - { - m_Opened = true; - this->Helper->SetTopLevel(toplevel); - } - return res; -} - -//---------------------------------------------------------------------------- -bool Registry::Close() -{ - bool res = false; - if ( m_Opened ) - { - res = this->Helper->Close(); - } - - if ( res ) - { - m_Opened = false; - m_Locked = false; - this->Helper->SetChanged(false); - } - return res; -} - -//---------------------------------------------------------------------------- -bool Registry::ReadValue(const char *subkey, - const char *key, - const char **value) -{ - bool res = false; - bool open = false; - if ( ! value ) - { - return res; - } - *value = 0; - if ( !m_Opened ) - { - if ( !this->Open(this->GetTopLevel(), subkey, - Registry::READONLY) ) - { - return res; - } - open = true; - } - res = this->Helper->ReadValue(key, value); - - if ( open ) - { - if ( !this->Close() ) - { - res = false; - } - } - return res; -} - -//---------------------------------------------------------------------------- -bool Registry::DeleteKey(const char *subkey, const char *key) -{ - bool res = false; - bool open = false; - if ( !m_Opened ) - { - if ( !this->Open(this->GetTopLevel(), subkey, - Registry::READWRITE) ) - { - return res; - } - open = true; - } - - res = this->Helper->DeleteKey(key); - if ( res ) - { - this->Helper->SetChanged(true); - } - - if ( open ) - { - if ( !this->Close() ) - { - res = false; - } - } - return res; -} - -//---------------------------------------------------------------------------- -bool Registry::DeleteValue(const char *subkey, const char *key) -{ - bool res = false; - bool open = false; - if ( !m_Opened ) - { - if ( !this->Open(this->GetTopLevel(), subkey, - Registry::READWRITE) ) - { - return res; - } - open = true; - } - - res = this->Helper->DeleteValue(key); - if ( res ) - { - this->Helper->SetChanged(true); - } - - if ( open ) - { - if ( !this->Close() ) - { - res = false; - } - } - return res; -} - -//---------------------------------------------------------------------------- -bool Registry::SetValue(const char *subkey, const char *key, - const char *value) -{ - bool res = false; - bool open = false; - if ( !m_Opened ) - { - if ( !this->Open(this->GetTopLevel(), subkey, - Registry::READWRITE) ) - { - return res; - } - open = true; - } - - res = this->Helper->SetValue( key, value ); - if ( res ) - { - this->Helper->SetChanged(true); - } - - if ( open ) - { - if ( !this->Close() ) - { - res = false; - } - } - return res; -} - -//---------------------------------------------------------------------------- -const char* Registry::GetTopLevel() -{ - return this->Helper->GetTopLevel(); -} - -//---------------------------------------------------------------------------- -void Registry::SetTopLevel(const char* tl) -{ - this->Helper->SetTopLevel(tl); -} - -//---------------------------------------------------------------------------- -void RegistryHelper::SetTopLevel(const char* tl) -{ - if ( tl ) - { - m_TopLevel = tl; - } - else - { - m_TopLevel = ""; - } -} - -//---------------------------------------------------------------------------- -RegistryHelper::RegistryHelper(Registry::RegistryType registryType) -{ - m_Changed = false; - m_TopLevel = ""; - m_SubKey = ""; - m_SubKeySpecified = false; - m_Empty = true; - m_GlobalScope = false; - m_RegistryType = registryType; -} - -//---------------------------------------------------------------------------- -RegistryHelper::~RegistryHelper() -{ -} - - -//---------------------------------------------------------------------------- -bool RegistryHelper::Open(const char *toplevel, const char *subkey, - int readonly) -{ - this->EntriesMap.clear(); - m_Empty = 1; - -#ifdef _WIN32 - if ( m_RegistryType == Registry::WIN32_REGISTRY) - { - HKEY scope = HKEY_CURRENT_USER; - if ( this->GetGlobalScope() ) - { - scope = HKEY_LOCAL_MACHINE; - } - int res = 0; - kwsys_ios::ostringstream str; - DWORD dwDummy; - str << "Software\\Kitware\\" << toplevel << "\\" << subkey; - if ( readonly == Registry::READONLY ) - { - res = ( RegOpenKeyEx(scope, str.str().c_str(), - 0, KEY_READ, &this->HKey) == ERROR_SUCCESS ); - } - else - { - char lpClass[] = ""; - res = ( RegCreateKeyEx(scope, str.str().c_str(), - 0, lpClass, REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE, - NULL, &this->HKey, &dwDummy) == ERROR_SUCCESS ); - } - if ( res != 0 ) - { - this->SetSubKey( subkey ); - } - return (res != 0); - } -#endif - if ( m_RegistryType == Registry::FILE_REGISTRY ) - { - bool res = false; - int cc; - kwsys_ios::ostringstream str; - const char* homeDirectory; - if ( (homeDirectory = getenv("HOME")) == 0 ) - { - if ( (homeDirectory = getenv("USERPROFILE")) == 0 ) - { - return false; - } - } - m_HomeDirectory = homeDirectory; - str << m_HomeDirectory.c_str() << "/." << toplevel << "rc"; - if ( readonly == Registry::READWRITE ) - { - kwsys_ios::ofstream ofs( str.str().c_str(), kwsys_ios::ios::out|kwsys_ios::ios::app ); - if ( ofs.fail() ) - { - return false; - } - ofs.close(); - } - - kwsys_ios::ifstream *ifs = new kwsys_ios::ifstream(str.str().c_str(), kwsys_ios::ios::in -#ifndef KWSYS_IOS_USE_ANSI - | kwsys_ios::ios::nocreate -#endif - ); - if ( !ifs ) - { - return false; - } - if ( ifs->fail()) - { - delete ifs; - return false; - } - - res = true; - char buffer[Registry_BUFFER_SIZE]; - while( !ifs->fail() ) - { - ifs->getline(buffer, Registry_BUFFER_SIZE); - if ( ifs->fail() || ifs->eof() ) - { - break; - } - char *line = this->Strip(buffer); - if ( *line == '#' || *line == 0 ) - { - // Comment - continue; - } - int linelen = static_cast(strlen(line)); - for ( cc = 0; cc < linelen; cc++ ) - { - if ( line[cc] == '=' ) - { - char *key = new char[ cc+1 ]; - strncpy( key, line, cc ); - key[cc] = 0; - char *value = line + cc + 1; - char *nkey = this->Strip(key); - char *nvalue = this->Strip(value); - this->EntriesMap[nkey] = this->DecodeValue(nvalue); - m_Empty = 0; - delete [] key; - break; - } - } - } - ifs->close(); - this->SetSubKey( subkey ); - delete ifs; - return res; - } - return false; -} - -//---------------------------------------------------------------------------- -bool RegistryHelper::Close() -{ -#ifdef _WIN32 - if ( m_RegistryType == Registry::WIN32_REGISTRY) - { - int res; - res = ( RegCloseKey(this->HKey) == ERROR_SUCCESS ); - return (res != 0); - } -#endif - if ( m_RegistryType == Registry::FILE_REGISTRY ) - { - if ( !m_Changed ) - { - this->SetSubKey(0); - return true; - } - - kwsys_ios::ostringstream str; - str << m_HomeDirectory.c_str() << "/." << this->GetTopLevel() << "rc"; - kwsys_ios::ofstream *ofs = new kwsys_ios::ofstream(str.str().c_str(), kwsys_ios::ios::out); - if ( !ofs ) - { - return false; - } - if ( ofs->fail()) - { - delete ofs; - return false; - } - *ofs << "# This file is automatically generated by the application" << kwsys_ios::endl - << "# If you change any lines or add new lines, note that all" << kwsys_ios::endl - << "# comments and empty lines will be deleted. Every line has" << kwsys_ios::endl - << "# to be in format: " << kwsys_ios::endl - << "# key = value" << kwsys_ios::endl - << "#" << kwsys_ios::endl; - - if ( !this->EntriesMap.empty() ) - { - RegistryHelper::StringToStringMap::iterator it; - for ( it = this->EntriesMap.begin(); - it != this->EntriesMap.end(); - ++ it ) - { - *ofs << it->first.c_str() << " = " << this->EncodeValue(it->second.c_str()).c_str() << kwsys_ios::endl; - } - } - this->EntriesMap.clear(); - ofs->close(); - delete ofs; - this->SetSubKey(0); - m_Empty = 1; - return true; - } - return false; -} - -//---------------------------------------------------------------------------- -bool RegistryHelper::ReadValue(const char *skey, const char **value) - -{ -#ifdef _WIN32 - if ( m_RegistryType == Registry::WIN32_REGISTRY) - { - kwsys_stl::string key = this->CreateKey( skey ); - if ( key.empty() ) - { - return false; - } - DWORD dwType, dwSize; - dwType = REG_SZ; - char buffer[1024]; // Replace with RegQueryInfoKey - dwSize = sizeof(buffer); - int res = ( RegQueryValueEx(this->HKey, skey, NULL, &dwType, - (BYTE *)buffer, &dwSize) == ERROR_SUCCESS ); - if ( !res ) - { - return false; - } - this->EntriesMap[key] = buffer; - RegistryHelper::StringToStringMap::iterator it - = this->EntriesMap.find(key); - *value = it->second.c_str(); - return true; - } -#endif - if ( m_RegistryType == Registry::FILE_REGISTRY ) - { - bool res = false; - kwsys_stl::string key = this->CreateKey( skey ); - if ( key.empty() ) - { - return false; - } - - RegistryHelper::StringToStringMap::iterator it - = this->EntriesMap.find(key); - if ( it != this->EntriesMap.end() ) - { - *value = it->second.c_str(); - res = true; - } - return res; - } - return false; -} - -//---------------------------------------------------------------------------- -bool RegistryHelper::DeleteKey(const char* skey) -{ -#ifdef _WIN32 - if ( m_RegistryType == Registry::WIN32_REGISTRY) - { - int res = ( RegDeleteKey( this->HKey, skey ) == ERROR_SUCCESS ); - return (res != 0); - } -#endif - if ( m_RegistryType == Registry::FILE_REGISTRY ) - { - kwsys_stl::string key = this->CreateKey( skey ); - if ( key.empty() ) - { - return false; - } - this->EntriesMap.erase(key); - return true; - } - return false; -} - -//---------------------------------------------------------------------------- -bool RegistryHelper::DeleteValue(const char *skey) -{ -#ifdef _WIN32 - if ( m_RegistryType == Registry::WIN32_REGISTRY) - { - int res = ( RegDeleteValue( this->HKey, skey ) == ERROR_SUCCESS ); - return (res != 0); - } -#endif - if ( m_RegistryType == Registry::FILE_REGISTRY ) - { - kwsys_stl::string key = this->CreateKey( skey ); - if ( key.empty() ) - { - return false; - } - this->EntriesMap.erase(key); - return true; - } - return false; -} - -//---------------------------------------------------------------------------- -bool RegistryHelper::SetValue(const char *skey, const char *value) -{ -#ifdef _WIN32 - if ( m_RegistryType == Registry::WIN32_REGISTRY) - { - DWORD len = (DWORD)(value ? strlen(value) : 0); - int res = ( RegSetValueEx(this->HKey, skey, 0, REG_SZ, - (CONST BYTE *)(const char *)value, - len+1) == ERROR_SUCCESS ); - return (res != 0); - } -#endif - if ( m_RegistryType == Registry::FILE_REGISTRY ) - { - kwsys_stl::string key = this->CreateKey( skey ); - if ( key.empty() ) - { - return 0; - } - this->EntriesMap[key] = value; - return 1; - } - return false; -} - -//---------------------------------------------------------------------------- -kwsys_stl::string RegistryHelper::CreateKey( const char *key ) -{ - if ( !m_SubKeySpecified || m_SubKey.empty() || !key ) - { - return ""; - } - kwsys_ios::ostringstream ostr; - ostr << this->EncodeKey(this->m_SubKey.c_str()).c_str() - << "\\" << this->EncodeKey(key).c_str(); - return ostr.str(); -} - -//---------------------------------------------------------------------------- -void RegistryHelper::SetSubKey(const char* sk) -{ - if ( !sk ) - { - m_SubKey = ""; - m_SubKeySpecified = false; - } - else - { - m_SubKey = sk; - m_SubKeySpecified = true; - } -} - -//---------------------------------------------------------------------------- -char *RegistryHelper::Strip(char *str) -{ - int cc; - size_t len; - char *nstr; - if ( !str ) - { - return NULL; - } - len = strlen(str); - nstr = str; - for( cc=0; cc < static_cast(len); cc++ ) - { - if ( !isspace( *nstr ) ) - { - break; - } - nstr ++; - } - for( cc= static_cast(strlen(nstr))-1; cc>=0; cc-- ) - { - if ( !isspace( nstr[cc] ) ) - { - nstr[cc+1] = 0; - break; - } - } - return nstr; -} - -//---------------------------------------------------------------------------- -void RegistryHelper::SetGlobalScope(bool b) -{ - m_GlobalScope = b; -} - -//---------------------------------------------------------------------------- -bool RegistryHelper::GetGlobalScope() -{ - return m_GlobalScope; -} - -//---------------------------------------------------------------------------- -kwsys_stl::string RegistryHelper::EncodeKey(const char* str) -{ - kwsys_ios::ostringstream ostr; - while ( *str ) - { - switch ( *str ) - { - case '%': case '=': case '\n': case '\r': case '\t': - char buffer[4]; - sprintf(buffer, "%%%02X", *str); - ostr << buffer; - break; - default: - ostr << *str; - } - str ++; - } - return ostr.str(); -} - -//---------------------------------------------------------------------------- -kwsys_stl::string RegistryHelper::EncodeValue(const char* str) -{ - kwsys_ios::ostringstream ostr; - while ( *str ) - { - switch ( *str ) - { - case '%': case '=': case '\n': case '\r': case '\t': - char buffer[4]; - sprintf(buffer, "%%%02X", *str); - ostr << buffer; - break; - default: - ostr << *str; - } - str ++; - } - return ostr.str(); -} - -//---------------------------------------------------------------------------- -kwsys_stl::string RegistryHelper::DecodeValue(const char* str) -{ - kwsys_ios::ostringstream ostr; - while ( *str ) - { - unsigned int val; - switch ( *str ) - { - case '%': - if ( *(str+1) && *(str+2) && sscanf(str+1, "%x", &val) == 1 ) - { - ostr << static_cast(val); - str += 2; - } - else - { - ostr << *str; - } - break; - default: - ostr << *str; - } - str ++; - } - return ostr.str(); -} - -} // namespace KWSYS_NAMESPACE diff --git a/Registry.hxx.in b/Registry.hxx.in deleted file mode 100644 index ed9b01072..000000000 --- a/Registry.hxx.in +++ /dev/null @@ -1,107 +0,0 @@ -/*============================================================================ - KWSys - Kitware System Library - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#ifndef @KWSYS_NAMESPACE@_Registry_hxx -#define @KWSYS_NAMESPACE@_Registry_hxx - -#include <@KWSYS_NAMESPACE@/Configure.h> - -#include <@KWSYS_NAMESPACE@/stl/string> - -namespace @KWSYS_NAMESPACE@ -{ - -class RegistryHelper; - -/** \class Registry - * \brief Portable registry class - * - * This class abstracts the storing of data that can be restored - * when the program executes again. On Win32 platform it is - * implemented using the registry and on unix as a file in - * the user's home directory. - */ -class @KWSYS_NAMESPACE@_EXPORT Registry -{ -public: - enum RegistryType - { -#ifdef _WIN32 - WIN32_REGISTRY, -#endif - FILE_REGISTRY - }; - -#ifdef _WIN32 - Registry(RegistryType registryType = WIN32_REGISTRY); -#else - Registry(RegistryType registryType = FILE_REGISTRY); -#endif - - virtual ~Registry(); - - //! Read a value from the registry. - bool ReadValue(const char *subkey, const char *key, const char **value); - - //! Delete a key from the registry. - bool DeleteKey(const char *subkey, const char *key); - - //! Delete a value from a given key. - bool DeleteValue(const char *subkey, const char *key); - - //! Set value in a given key. - bool SetValue(const char *subkey, const char *key, - const char *value); - - //! Open the registry at toplevel/subkey. - bool Open(const char *toplevel, const char *subkey, - int readonly); - - //! Close the registry. - bool Close(); - - //! Read from local or global scope. On Windows this mean from local machine - // or local user. On unix this will read from $HOME/.Projectrc or - // /etc/Project - void GlobalScopeOn() { this->SetGlobalScope(1); } - void GlobalScopeOff() { this->SetGlobalScope(0); } - void SetGlobalScope(bool b); - bool GetGlobalScope(); - - // Set or get the toplevel registry key. - void SetTopLevel(const char* tl); - const char* GetTopLevel(); - - // Return true if registry opened - bool GetOpened() { return m_Opened; } - - // Should the registry be locked? - bool GetLocked() { return m_Locked; } - - enum { - READONLY, - READWRITE - }; - - // Return true if the character is space. - int IsSpace(char c); - -private: - RegistryHelper* Helper; - - bool m_Opened; - - bool m_Locked; -}; // End Class: Registry - -} // namespace @KWSYS_NAMESPACE@ - -#endif diff --git a/SystemInformation.cxx b/SystemInformation.cxx index 6d990a99d..bfdb0edd6 100644 --- a/SystemInformation.cxx +++ b/SystemInformation.cxx @@ -307,7 +307,7 @@ public: enum Manufacturer { AMD, Intel, NSC, UMC, Cyrix, NexGen, IDT, Rise, Transmeta, Sun, IBM, - Motorola, UnknownManufacturer + Motorola, HP, UnknownManufacturer }; protected: @@ -346,7 +346,7 @@ protected: static void Delay (unsigned int); static void DelayOverhead (unsigned int); - void FindManufacturer(); + void FindManufacturer(const kwsys_stl::string &family = ""); // For Mac bool ParseSysCtl(); @@ -1144,6 +1144,7 @@ void SystemInformationImplementation::RunCPUCheck() { // Retrieve the CPU details. RetrieveCPUIdentity(); + this->FindManufacturer(); RetrieveCPUFeatures(); } @@ -1415,6 +1416,8 @@ const char * SystemInformationImplementation::GetVendorID() return "IBM"; case Motorola: return "Motorola"; + case HP: + return "Hewlett-Packard"; default: return "Unknown Manufacturer"; } @@ -1670,7 +1673,7 @@ bool SystemInformationImplementation::RetrieveCPUFeatures() #endif ; <> ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision - ; ebx: 31..24 - default APIC ID, 23..16 - logical processsor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID + ; ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID ; edx: CPU feature flags mov eax,1 CPUID_INSTRUCTION @@ -1755,7 +1758,7 @@ bool SystemInformationImplementation::RetrieveCPUFeatures() /** Find the manufacturer given the vendor id */ -void SystemInformationImplementation::FindManufacturer() +void SystemInformationImplementation::FindManufacturer(const kwsys_stl::string& family) { if (this->ChipID.Vendor == "GenuineIntel") this->ChipManufacturer = Intel; // Intel Corp. else if (this->ChipID.Vendor == "UMC UMC UMC ") this->ChipManufacturer = UMC; // United Microelectronics Corp. @@ -1771,6 +1774,7 @@ void SystemInformationImplementation::FindManufacturer() else if (this->ChipID.Vendor == "Sun") this->ChipManufacturer = Sun; // Sun Microelectronics else if (this->ChipID.Vendor == "IBM") this->ChipManufacturer = IBM; // IBM Microelectronics else if (this->ChipID.Vendor == "Motorola") this->ChipManufacturer = Motorola; // Motorola Microelectronics + else if (family.substr(0, 7) == "PA-RISC") this->ChipManufacturer = HP; // Hewlett-Packard else this->ChipManufacturer = UnknownManufacturer; // Unknown manufacturer } @@ -1809,7 +1813,7 @@ bool SystemInformationImplementation::RetrieveCPUIdentity() ; <> ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision - ; ebx: 31..24 - default APIC ID, 23..16 - logical processsor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID + ; ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID ; edx: CPU feature flags mov eax,1 CPUID_INSTRUCTION @@ -1836,8 +1840,6 @@ bool SystemInformationImplementation::RetrieveCPUIdentity() vbuf[12] = '\0'; this->ChipID.Vendor = vbuf; - this->FindManufacturer(); - // Retrieve the family of CPU present. this->ChipID.ExtendedFamily = ((localCPUSignature & 0x0FF00000) >> 20); // Bits 27..20 Used this->ChipID.ExtendedModel = ((localCPUSignature & 0x000F0000) >> 16); // Bits 19..16 Used @@ -2436,7 +2438,7 @@ bool SystemInformationImplementation::RetrieveExtendedCPUFeatures() #endif ; <> ; eax = 0x80000001 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision - ; ebx: 31..24 - default APIC ID, 23..16 - logical processsor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID + ; ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID ; edx: CPU feature flags mov eax,0x80000001 CPUID_INSTRUCTION @@ -3002,6 +3004,16 @@ kwsys_stl::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(k size_t pos2 = buffer.find("\n",pos); if(pos!=buffer.npos && pos2!=buffer.npos) { + // It may happen that the beginning matches, but this is still not the requested key. + // An example is looking for "cpu" when "cpu family" comes first. So we check that + // we have only spaces from here to pos, otherwise we search again. + for(size_t i=this->CurrentPositionInFile+strlen(word); i < pos; ++i) + { + if(buffer[i] != ' ' && buffer[i] != '\t') + { + return this->ExtractValueFromCpuInfoFile(buffer, word, pos2); + } + } return buffer.substr(pos+2,pos2-pos-2); } } @@ -3073,7 +3085,7 @@ int SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() this->NumberOfLogicalCPU = atoi(cpucount.c_str()); #endif // gotta have one, and if this is 0 then we get a / by 0n - // beter to have a bad answer than a crash + // better to have a bad answer than a crash if(this->NumberOfPhysicalCPU <= 0) { this->NumberOfPhysicalCPU = 1; @@ -3082,32 +3094,83 @@ int SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical= this->NumberOfLogicalCPU/this->NumberOfPhysicalCPU; - // CPU speed (checking only the first proc + // CPU speed (checking only the first processor) kwsys_stl::string CPUSpeed = this->ExtractValueFromCpuInfoFile(buffer,"cpu MHz"); this->CPUSpeedInMHz = static_cast(atof(CPUSpeed.c_str())); // Chip family - this->ChipID.Family = atoi(this->ExtractValueFromCpuInfoFile(buffer,"cpu family").c_str()); + kwsys_stl::string familyStr = + this->ExtractValueFromCpuInfoFile(buffer,"cpu family"); + if(familyStr.empty()) + { + familyStr = this->ExtractValueFromCpuInfoFile(buffer,"CPU architecture"); + } + this->ChipID.Family = atoi(familyStr.c_str()); // Chip Vendor this->ChipID.Vendor = this->ExtractValueFromCpuInfoFile(buffer,"vendor_id"); - this->FindManufacturer(); + this->FindManufacturer(familyStr); + + // second try for setting family + if (this->ChipID.Family == 0 && this->ChipManufacturer == HP) + { + if (familyStr == "PA-RISC 1.1a") + this->ChipID.Family = 0x11a; + else if (familyStr == "PA-RISC 2.0") + this->ChipID.Family = 0x200; + // If you really get CMake to work on a machine not belonging to + // any of those families I owe you a dinner if you get it to + // contribute nightly builds regularly. + } // Chip Model this->ChipID.Model = atoi(this->ExtractValueFromCpuInfoFile(buffer,"model").c_str()); - this->RetrieveClassicalCPUIdentity(); + if(!this->RetrieveClassicalCPUIdentity()) + { + // Some platforms (e.g. PA-RISC) tell us their CPU name here. + // Note: x86 does not. + kwsys_stl::string cpuname = this->ExtractValueFromCpuInfoFile(buffer,"cpu"); + if(!cpuname.empty()) + { + this->ChipID.ProcessorName = cpuname; + } + } + + // Chip revision + kwsys_stl::string cpurev = this->ExtractValueFromCpuInfoFile(buffer,"stepping"); + if(cpurev.empty()) + { + cpurev = this->ExtractValueFromCpuInfoFile(buffer,"CPU revision"); + } + this->ChipID.Revision = atoi(cpurev.c_str()); // Chip Model Name this->ChipID.ModelName = this->ExtractValueFromCpuInfoFile(buffer,"model name").c_str(); // L1 Cache size - kwsys_stl::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer,"cache size"); - pos = cacheSize.find(" KB"); - if(pos!=cacheSize.npos) + // Different architectures may show different names for the caches. + // Sum up everything we find. + kwsys_stl::vector cachename; + cachename.clear(); + + cachename.push_back("cache size"); // e.g. x86 + cachename.push_back("I-cache"); // e.g. PA-RISC + cachename.push_back("D-cache"); // e.g. PA-RISC + + this->Features.L1CacheSize = 0; + for (size_t index = 0; index < cachename.size(); index ++) { - cacheSize = cacheSize.substr(0,pos); + kwsys_stl::string cacheSize = this->ExtractValueFromCpuInfoFile(buffer,cachename[index]); + if (!cacheSize.empty()) + { + pos = cacheSize.find(" KB"); + if(pos!=cacheSize.npos) + { + cacheSize = cacheSize.substr(0,pos); + } + this->Features.L1CacheSize += atoi(cacheSize.c_str()); + } } - this->Features.L1CacheSize = atoi(cacheSize.c_str()); return 1; } diff --git a/SystemTools.cxx b/SystemTools.cxx index 085d98836..1054d6526 100644 --- a/SystemTools.cxx +++ b/SystemTools.cxx @@ -2754,9 +2754,15 @@ kwsys_stl::string SystemTools::GetRealPath(const char* path) bool SystemTools::FileIsDirectory(const char* name) { + size_t length = strlen(name); + if (length == 0) + { + return false; + } + // Remove any trailing slash from the name. char buffer[KWSYS_SYSTEMTOOLS_MAXPATH]; - size_t last = strlen(name)-1; + size_t last = length-1; if(last > 0 && (name[last] == '/' || name[last] == '\\') && strcmp(name, "/") !=0) { diff --git a/testProcess.c b/testProcess.c index 877002a14..ec561ead7 100644 --- a/testProcess.c +++ b/testProcess.c @@ -82,6 +82,14 @@ int test3(int argc, const char* argv[]) int test4(int argc, const char* argv[]) { + /* Prepare a pointer to an invalid address. Don't use null, because + dereferencing null is undefined behaviour and compilers are free to + do whatever they want. ex: Clang will warn at compile time, or even + optimize away the write. We hope to 'outsmart' them by using + 'volatile' and a slightly larger address, based on a runtime value. */ + volatile int* invalidAddress = 0; + invalidAddress += argc?1:2; + #if defined(_WIN32) /* Avoid error diagnostic popups since we are crashing on purpose. */ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX); @@ -94,11 +102,8 @@ int test4(int argc, const char* argv[]) fprintf(stderr, "Output before crash on stderr from crash test.\n"); fflush(stdout); fflush(stderr); -#if defined(__clang__) - *(int*)1 = 0; /* Clang warns about 0-ptr; undefined behavior. */ -#else - *(int*)0 = 0; -#endif + /* Provoke deliberate crash by writing to the invalid address. */ + *invalidAddress = 0; fprintf(stdout, "Output after crash on stdout from crash test.\n"); fprintf(stderr, "Output after crash on stderr from crash test.\n"); return 0; diff --git a/testRegistry.cxx b/testRegistry.cxx deleted file mode 100644 index 7e9b0d49b..000000000 --- a/testRegistry.cxx +++ /dev/null @@ -1,109 +0,0 @@ -/*============================================================================ - KWSys - Kitware System Library - Copyright 2000-2009 Kitware, Inc., Insight Software Consortium - - Distributed under the OSI-approved BSD License (the "License"); - see accompanying file Copyright.txt for details. - - This software is distributed WITHOUT ANY WARRANTY; without even the - implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the License for more information. -============================================================================*/ -#include "kwsysPrivate.h" - -#include KWSYS_HEADER(Registry.hxx) -#include KWSYS_HEADER(ios/iostream) -#include - -// Work-around CMake dependency scanning limitation. This must -// duplicate the above list of headers. -#if 0 -# include "Registry.hxx.in" -# include "kwsys_ios_iostream.h.in" -#endif - -#define IFT(x,res) if ( !x ) \ - { \ - res = 1; \ - kwsys_ios::cout << "Error in: " << #x << kwsys_ios::endl; \ - } -#define IFNT(x,res) if ( x ) \ - { \ - res = 1; \ - kwsys_ios::cout << "Error in: " << #x << kwsys_ios::endl; \ - } - -#define CHE(x,y,res) if ( x && strcmp(x,y) ) \ - { \ - res = 1; \ - kwsys_ios::cout << "Error, " << x << " != " << y << kwsys_ios::endl; \ - } - -int testRegistry(int, char*[]) -{ - int res = 0; - - kwsys::Registry reg; - reg.SetTopLevel("TestRegistry"); - - IFT(reg.SetValue("TestSubkey", "TestKey1", "Test Value 1"), res); - IFT(reg.SetValue("TestSubkey1", "TestKey2", "Test Value 2"), res); - IFT(reg.SetValue("TestSubkey", "TestKey3", "Test Value 3"), res); - IFT(reg.SetValue("TestSubkey2", "TestKey4", "Test Value 4"), res); - - const char *buffer; - IFT(reg.ReadValue("TestSubkey", "TestKey1", &buffer), res); - CHE(buffer, "Test Value 1", res); - IFT(reg.ReadValue("TestSubkey1", "TestKey2", &buffer), res); - CHE(buffer, "Test Value 2", res); - IFT(reg.ReadValue("TestSubkey", "TestKey3", &buffer), res); - CHE(buffer, "Test Value 3", res); - IFT(reg.ReadValue("TestSubkey2", "TestKey4", &buffer), res); - CHE(buffer, "Test Value 4", res); - - IFT(reg.SetValue("TestSubkey", "TestKey1", "New Test Value 1"), res); - IFT(reg.SetValue("TestSubkey1", "TestKey2", "New Test Value 2"), res); - IFT(reg.SetValue("TestSubkey", "TestKey3", "New Test Value 3"), res); - IFT(reg.SetValue("TestSubkey2", "TestKey4", "New Test Value 4"), res); - - IFT(reg.ReadValue("TestSubkey", "TestKey1", &buffer), res); - CHE(buffer, "New Test Value 1", res); - IFT(reg.ReadValue("TestSubkey1", "TestKey2", &buffer), res); - CHE(buffer, "New Test Value 2", res); - IFT(reg.ReadValue("TestSubkey", "TestKey3", &buffer), res); - CHE(buffer, "New Test Value 3", res); - IFT(reg.ReadValue("TestSubkey2", "TestKey4", &buffer), res); - CHE(buffer, "New Test Value 4", res); - - IFT( reg.DeleteValue("TestSubkey", "TestKey1"), res); - IFNT(reg.ReadValue( "TestSubkey", "TestKey1", &buffer), res); - IFT( reg.DeleteValue("TestSubkey1", "TestKey2"), res); - IFNT(reg.ReadValue( "TestSubkey1", "TestKey2", &buffer), res); - IFT( reg.DeleteValue("TestSubkey", "TestKey3"), res); - IFNT(reg.ReadValue( "TestSubkey", "TestKey3", &buffer), res); - IFT( reg.DeleteValue("TestSubkey2", "TestKey4"), res); - IFNT(reg.ReadValue( "TestSubkey2", "TestKey5", &buffer), res); - - const char* longStringWithNewLines = "Value with embedded CR and LF characters CR='\015' LF='\012' CRLF='\015\012'"; - IFT(reg.SetValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1", longStringWithNewLines), res); - IFT(reg.ReadValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1", &buffer), res); - CHE(buffer, longStringWithNewLines, res); - IFT(reg.DeleteValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1"), res); - IFNT(reg.ReadValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1", &buffer), res); - - IFT(reg.SetValue("TestSubkeyWith = EqualSignChar", "TestKey = 1", "Some value"), res); - IFT(reg.ReadValue("TestSubkeyWith = EqualSignChar", "TestKey = 1", &buffer), res); - CHE(buffer, "Some value", res); - IFT(reg.DeleteValue("TestSubkeyWith = EqualSignChar", "TestKey = 1"), res); - IFNT(reg.ReadValue("TestSubkeyWith = EqualSignChar", "TestKey = 1", &buffer), res); - - if ( res ) - { - kwsys_ios::cout << "Test failed" << kwsys_ios::endl; - } - else - { - kwsys_ios::cout << "Test passed" << kwsys_ios::endl; - } - return res; -} diff --git a/testSystemInformation.cxx b/testSystemInformation.cxx index 41fcf384b..cfd7ce210 100644 --- a/testSystemInformation.cxx +++ b/testSystemInformation.cxx @@ -66,6 +66,7 @@ int testSystemInformation(int, char*[]) printMethod(info, GetFamilyID); printMethod(info, GetModelID); printMethod(info, GetExtendedProcessorName); + printMethod(info, GetSteppingCode); printMethod(info, GetProcessorSerialNumber); printMethod2(info, GetProcessorCacheSize, "KB"); printMethod(info, GetLogicalProcessorsPerPhysical); From 2c24ca92193f0a03fbf8c0bb13f6a1cca83dd08e Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 19 Dec 2012 09:00:55 -0500 Subject: [PATCH 099/170] Remove references to KWSys Process Win9x support The KWSys "EncodeExecutable" and "ProcessFwd9x" executables were dropped from KWSys along with Win9x Process support. Drop references from the rest of the CMake build rules. --- CMakeLists.txt | 2 -- bootstrap | 27 +++------------------------ 2 files changed, 3 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a67fb6e62..9ad9587e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -234,8 +234,6 @@ macro (CMAKE_BUILD_UTILITIES) set(kwsys_folder "Utilities/KWSys") CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE} "${kwsys_folder}") CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}_c "${kwsys_folder}") - CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}EncodeExecutable "${kwsys_folder}") - CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}ProcessFwd9x "${kwsys_folder}") if(BUILD_TESTING) CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestDynload "${kwsys_folder}") CMAKE_SET_TARGET_FOLDER(${KWSYS_NAMESPACE}TestProcess "${kwsys_folder}") diff --git a/bootstrap b/bootstrap index 0e6d16ca9..643720c86 100755 --- a/bootstrap +++ b/bootstrap @@ -284,18 +284,11 @@ if ${cmake_system_mingw}; then ProcessWin32 \ String \ System" - KWSYS_C_MINGW_SOURCES="\ - ProcessFwd9x \ - EncodeExecutable" - KWSYS_C_GENERATED_SOURCES="\ - cmsysProcessFwd9xEnc" else KWSYS_C_SOURCES="\ ProcessUNIX \ String \ System" - KWSYS_C_MINGW_SOURCES="" - KWSYS_C_GENERATED_SOURCES="" fi KWSYS_CXX_SOURCES="\ @@ -1351,7 +1344,7 @@ cmake_compiler_settings_comment="/* * Sources: * ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} * kwSys Sources: - * ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES} ${KWSYS_C_MINGW_SOURCES} + * ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES} */ " @@ -1447,7 +1440,7 @@ done # Generate Makefile dep="cmConfigure.h cmsys/*.hxx cmsys/*.h `cmake_escape \"${cmake_source_dir}\"`/Source/*.h" objs="" -for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES} ${KWSYS_C_GENERATED_SOURCES}; do +for a in ${CMAKE_CXX_SOURCES} ${CMAKE_C_SOURCES} ${KWSYS_CXX_SOURCES} ${KWSYS_C_SOURCES}; do objs="${objs} ${a}.o" done @@ -1488,7 +1481,7 @@ for a in ${CMAKE_C_SOURCES}; do echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile" echo " ${cmake_c_compiler} ${cmake_c_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile" done -for a in ${KWSYS_C_SOURCES} ${KWSYS_C_MINGW_SOURCES}; do +for a in ${KWSYS_C_SOURCES}; do src=`cmake_escape "${cmake_source_dir}/Source/kwsys/${a}.c"` src_flags=`eval echo \\${cmake_c_flags_\${a}}` echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile" @@ -1500,20 +1493,6 @@ for a in ${KWSYS_CXX_SOURCES}; do echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile" echo " ${cmake_cxx_compiler} ${cmake_cxx_flags} -DKWSYS_NAMESPACE=cmsys ${src_flags} -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile" done -if ${cmake_system_mingw}; then - src=`cmake_escape "${cmake_bootstrap_dir}/cmsysProcessFwd9xEnc.c"` - in=`cmake_escape "${cmake_bootstrap_dir}/cmsysProcessFwd9x.exe"` - cmd=`cmake_escape "${cmake_bootstrap_dir}/cmsysEncodeExecutable.exe"` - a="cmsysProcessFwd9xEnc" - echo "${cmd} : EncodeExecutable.o" >> "${cmake_bootstrap_dir}/Makefile" - echo " ${cmake_c_compiler} ${cmake_ld_flags} ${cmake_c_flags} EncodeExecutable.o -o ${cmd}" >> "${cmake_bootstrap_dir}/Makefile" - echo "${in} : ProcessFwd9x.o" >> "${cmake_bootstrap_dir}/Makefile" - echo " ${cmake_c_compiler} ${cmake_ld_flags} ${cmake_c_flags} ProcessFwd9x.o -o ${in}" >> "${cmake_bootstrap_dir}/Makefile" - echo "${src} : ${cmd} ${in}" >> "${cmake_bootstrap_dir}/Makefile" - echo " ${cmd} ${in} ${src} cmsys ProcessFwd9x" >> "${cmake_bootstrap_dir}/Makefile" - echo "${a}.o : ${src} ${dep}" >> "${cmake_bootstrap_dir}/Makefile" - echo " ${cmake_c_compiler} ${cmake_c_flags} -I`cmake_escape \"${cmake_source_dir}/Source/kwsys\"` -DKWSYS_NAMESPACE=cmsys -c ${src} -o ${a}.o" >> "${cmake_bootstrap_dir}/Makefile" -fi echo ' rebuild_cache: cd "${cmake_binary_dir}" && "${cmake_source_dir}/bootstrap" From e1d211abba91b37907e71b4de1fffb59ebe3c05d Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Thu, 20 Dec 2012 00:01:02 -0500 Subject: [PATCH 100/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 84ed3680b..66ae4c689 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 20121219) +set(CMake_VERSION_TWEAK 20121220) #set(CMake_VERSION_RC 1) From 76ea420fb9a8ceada0e806f1201230e5a7c1202c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 19 Nov 2012 19:30:56 +0100 Subject: [PATCH 101/170] Use cmsys::auto_ptr to manage cmCompiledGeneratorExpressions The compiled generator expressions need to outlive the creating type. For the same reason, store the input string in a std::string. --- Source/cmCustomCommandGenerator.cxx | 4 +-- Source/cmGeneratorExpression.cxx | 46 ++++++++++++----------------- Source/cmGeneratorExpression.h | 24 +++++++++------ Source/cmGeneratorTarget.cxx | 4 +-- Source/cmTarget.cxx | 7 +++-- Source/cmTestGenerator.cxx | 4 +-- 6 files changed, 44 insertions(+), 45 deletions(-) diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index 07df7d5e0..f2f77eea0 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -47,7 +47,7 @@ std::string cmCustomCommandGenerator::GetCommand(unsigned int c) const { return target->GetLocation(this->Config); } - return this->GE->Parse(argv0).Evaluate(this->Makefile, this->Config); + return this->GE->Parse(argv0)->Evaluate(this->Makefile, this->Config); } //---------------------------------------------------------------------------- @@ -58,7 +58,7 @@ cmCustomCommandGenerator cmCustomCommandLine const& commandLine = this->CC.GetCommandLines()[c]; for(unsigned int j=1;j < commandLine.size(); ++j) { - std::string arg = this->GE->Parse(commandLine[j]).Evaluate(this->Makefile, + std::string arg = this->GE->Parse(commandLine[j])->Evaluate(this->Makefile, this->Config); cmd += " "; if(this->OldStyle) diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 32bf941eb..3fd4a5f8e 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -25,44 +25,29 @@ //---------------------------------------------------------------------------- cmGeneratorExpression::cmGeneratorExpression( cmListFileBacktrace const& backtrace): - Backtrace(backtrace), CompiledExpression(0) + Backtrace(backtrace) { } //---------------------------------------------------------------------------- -const cmCompiledGeneratorExpression & +cmsys::auto_ptr cmGeneratorExpression::Parse(std::string const& input) { return this->Parse(input.c_str()); } //---------------------------------------------------------------------------- -const cmCompiledGeneratorExpression & +cmsys::auto_ptr cmGeneratorExpression::Parse(const char* input) { - cmGeneratorExpressionLexer l; - std::vector tokens = l.Tokenize(input); - bool needsParsing = l.GetSawGeneratorExpression(); - std::vector evaluators; - - if (needsParsing) - { - cmGeneratorExpressionParser p(tokens); - p.Parse(evaluators); - } - - delete this->CompiledExpression; - this->CompiledExpression = new cmCompiledGeneratorExpression( - this->Backtrace, - evaluators, - input, - needsParsing); - return *this->CompiledExpression; + return cmsys::auto_ptr( + new cmCompiledGeneratorExpression( + this->Backtrace, + input)); } cmGeneratorExpression::~cmGeneratorExpression() { - delete this->CompiledExpression; } //---------------------------------------------------------------------------- @@ -73,7 +58,7 @@ const char *cmCompiledGeneratorExpression::Evaluate( { if (!this->NeedsParsing) { - return this->Input; + return this->Input.c_str(); } this->Output = ""; @@ -108,12 +93,19 @@ const char *cmCompiledGeneratorExpression::Evaluate( cmCompiledGeneratorExpression::cmCompiledGeneratorExpression( cmListFileBacktrace const& backtrace, - const std::vector &evaluators, - const char *input, bool needsParsing) - : Backtrace(backtrace), Evaluators(evaluators), Input(input), - NeedsParsing(needsParsing) + const char *input) + : Backtrace(backtrace), Input(input ? input : "") { + cmGeneratorExpressionLexer l; + std::vector tokens = + l.Tokenize(this->Input.c_str()); + this->NeedsParsing = l.GetSawGeneratorExpression(); + if (this->NeedsParsing) + { + cmGeneratorExpressionParser p(tokens); + p.Parse(this->Evaluators); + } } diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index ea3e7d03b..961e53d75 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -14,10 +14,12 @@ #define cmGeneratorExpression_h #include "cmStandardIncludes.h" +#include "cmListFileCache.h" #include #include +#include class cmTarget; class cmMakefile; @@ -44,8 +46,9 @@ public: cmGeneratorExpression(cmListFileBacktrace const& backtrace); ~cmGeneratorExpression(); - const cmCompiledGeneratorExpression& Parse(std::string const& input); - const cmCompiledGeneratorExpression& Parse(const char* input); + cmsys::auto_ptr Parse( + std::string const& input); + cmsys::auto_ptr Parse(const char* input); enum PreprocessContext { StripAllGeneratorExpressions @@ -59,7 +62,6 @@ private: void operator=(const cmGeneratorExpression &); cmListFileBacktrace const& Backtrace; - cmCompiledGeneratorExpression *CompiledExpression; }; class cmCompiledGeneratorExpression @@ -76,20 +78,24 @@ public: ~cmCompiledGeneratorExpression(); + std::string GetInput() const + { + return this->Input; + } + private: cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace, - const std::vector &evaluators, - const char *input, bool needsParsing); + const char *input); friend class cmGeneratorExpression; cmCompiledGeneratorExpression(const cmCompiledGeneratorExpression &); void operator=(const cmCompiledGeneratorExpression &); - cmListFileBacktrace const& Backtrace; - const std::vector Evaluators; - const char* const Input; - const bool NeedsParsing; + cmListFileBacktrace Backtrace; + std::vector Evaluators; + const std::string Input; + bool NeedsParsing; mutable std::set Targets; mutable std::string Output; diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index de8b5e369..55507ddf3 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -267,7 +267,7 @@ std::vector cmGeneratorTarget::GetIncludeDirectories( "INCLUDE_DIRECTORIES", 0, 0); cmSystemTools::ExpandListArgument(ge.Parse(prop) - .Evaluate(this->Makefile, + ->Evaluate(this->Makefile, config, false, this->Target, @@ -315,7 +315,7 @@ std::string cmGeneratorTarget::GetCompileDefinitions(const char *config) cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(), defPropName, 0, 0); - return ge.Parse(prop).Evaluate(this->Makefile, + return ge.Parse(prop)->Evaluate(this->Makefile, config, false, this->Target, diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index de3b23c78..e7b34ee42 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -1728,9 +1728,10 @@ cmTargetTraceDependencies for(cmCustomCommandLine::const_iterator cli = cit->begin(); cli != cit->end(); ++cli) { - const cmCompiledGeneratorExpression &cge = ge.Parse(*cli); - cge.Evaluate(this->Makefile, 0, true); - std::set geTargets = cge.GetTargets(); + const cmsys::auto_ptr cge + = ge.Parse(*cli); + cge->Evaluate(this->Makefile, 0, true); + std::set geTargets = cge->GetTargets(); for(std::set::const_iterator it = geTargets.begin(); it != geTargets.end(); ++it) { diff --git a/Source/cmTestGenerator.cxx b/Source/cmTestGenerator.cxx index 2f650e72e..42f511ea3 100644 --- a/Source/cmTestGenerator.cxx +++ b/Source/cmTestGenerator.cxx @@ -112,7 +112,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, else { // Use the command name given. - exe = ge.Parse(exe.c_str()).Evaluate(mf, config); + exe = ge.Parse(exe.c_str())->Evaluate(mf, config); cmSystemTools::ConvertToUnixSlashes(exe); } @@ -122,7 +122,7 @@ void cmTestGenerator::GenerateScriptForConfig(std::ostream& os, for(std::vector::const_iterator ci = command.begin()+1; ci != command.end(); ++ci) { - os << " " << lg->EscapeForCMake(ge.Parse(*ci).Evaluate(mf, config)); + os << " " << lg->EscapeForCMake(ge.Parse(*ci)->Evaluate(mf, config)); } // Finish the test command. From 0d3b89ed7634598ef446da6b279f79b8bce20dd2 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Fri, 21 Dec 2012 00:01:16 -0500 Subject: [PATCH 102/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 66ae4c689..7eec30209 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 20121220) +set(CMake_VERSION_TWEAK 20121221) #set(CMake_VERSION_RC 1) From 349165223d26f0ffc5ad004b4a05a8a92121ac20 Mon Sep 17 00:00:00 2001 From: Riku Voipio Date: Fri, 21 Dec 2012 13:20:02 +0200 Subject: [PATCH 103/170] KWIML: Teach ABI.h about Aarch64 The __aarch64__ defines Aarch64, while __AARCH64EB__ defines bigendian and __AARCH64EL__ little endian. Only little endian tested, no big endian toolchain exists yet. Signed-off-by: Riku Voipio --- ABI.h.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ABI.h.in b/ABI.h.in index f93ddbaae..7f4772ae5 100644 --- a/ABI.h.in +++ b/ABI.h.in @@ -418,6 +418,14 @@ suppression macro @KWIML@_ABI_NO_VERIFY was defined. #elif defined(__vax__) # define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG +/* Aarch64 */ +#elif defined(__aarch64__) +# if !defined(__AARCH64EB__) +# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_LITTLE +# else +# define @KWIML@_ABI_ENDIAN_ID @KWIML@_ABI_ENDIAN_ID_BIG +# endif + /* Unknown CPU */ #elif !defined(@KWIML@_ABI_NO_ERROR_ENDIAN) # error "Byte order of target CPU unknown." From c95a13ecb9db33d4c74b0ab67b67baba1f9599ac Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sat, 22 Dec 2012 00:01:12 -0500 Subject: [PATCH 104/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 7eec30209..2d4011dc3 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 20121221) +set(CMake_VERSION_TWEAK 20121222) #set(CMake_VERSION_RC 1) From 310455cc188c52373637f984b99017884e802e8a Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sat, 22 Dec 2012 12:46:04 +0100 Subject: [PATCH 105/170] Fix some warnings from -Wundef Other warnings come from kwsys, so the flag can't be enabled. --- Source/cmCommandArgumentParser.cxx | 4 ++-- Source/cmake.cxx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/cmCommandArgumentParser.cxx b/Source/cmCommandArgumentParser.cxx index 696a6a8c3..c5146c5d7 100644 --- a/Source/cmCommandArgumentParser.cxx +++ b/Source/cmCommandArgumentParser.cxx @@ -279,7 +279,7 @@ typedef short int yytype_int16; #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ -# if YYENABLE_NLS +# if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) @@ -701,7 +701,7 @@ while (YYID (0)) we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ diff --git a/Source/cmake.cxx b/Source/cmake.cxx index fba4860fd..a44c825f7 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -953,7 +953,7 @@ int cmake::AddCMakePaths() cMakeSelf = cmSystemTools::GetRealPath(cMakeSelf.c_str()); cMakeSelf += "/cmake"; cMakeSelf += cmSystemTools::GetExecutableExtension(); -#if __APPLE__ +#ifdef __APPLE__ // on the apple this might be the gui bundle if(!cmSystemTools::FileExists(cMakeSelf.c_str())) { From 567e7d946788e46f9709fe08985520b55e98293b Mon Sep 17 00:00:00 2001 From: KWSys Robot Date: Fri, 21 Dec 2012 08:29:37 -0500 Subject: [PATCH 106/170] KWSys 2012-12-21 (8ce09af5) Extract upstream KWSys using the following shell commands. $ git archive --prefix=upstream-kwsys/ 8ce09af5 | tar x $ git shortlog --no-merges --abbrev=8 --format='%h %s' 933eb822..8ce09af5 Riku Voipio (1): 8ce09af5 CPU: Add Aarch64 support Change-Id: I4bd0a97abaa0f958e2679afe2d4ad4bcc37434a0 --- CPU.h.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CPU.h.in b/CPU.h.in index ecd29d133..2e1a584b1 100644 --- a/CPU.h.in +++ b/CPU.h.in @@ -98,6 +98,14 @@ #elif defined(__SYSC_ZARCH__) # define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG +/* Aarch64 */ +#elif defined(__aarch64__) +# if !defined(__AARCH64EB__) +# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_LITTLE +# else +# define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID @KWSYS_NAMESPACE@_CPU_ENDIAN_ID_BIG +# endif + /* Unknown CPU */ #else # define @KWSYS_NAMESPACE@_CPU_ENDIAN_ID 0 From 00deb127be64cf8934d92c1593c8ea4a5f0f2061 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sun, 23 Dec 2012 00:01:21 -0500 Subject: [PATCH 107/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 2d4011dc3..a13524d0a 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 20121222) +set(CMake_VERSION_TWEAK 20121223) #set(CMake_VERSION_RC 1) From 7d736af60e554e32115fdc188140fd63232d09c9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 10 Dec 2012 11:32:42 +0100 Subject: [PATCH 108/170] Replace some 'if' with 'else if' For consistency with the rest of the method. --- Source/cmGeneratorExpressionEvaluator.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 102927edb..3b7cfc03a 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -553,13 +553,13 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) { if (identifier == "0") return &zeroNode; - if (identifier == "1") + else if (identifier == "1") return &oneNode; - if (identifier == "AND") + else if (identifier == "AND") return &andNode; - if (identifier == "OR") + else if (identifier == "OR") return &orNode; - if (identifier == "NOT") + else if (identifier == "NOT") return ¬Node; else if (identifier == "CONFIGURATION") return &configurationNode; From 4d580517a963138d5d22823b0827396d2864d3b0 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Mon, 24 Dec 2012 00:01:20 -0500 Subject: [PATCH 109/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a13524d0a..493960bbe 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 20121223) +set(CMake_VERSION_TWEAK 20121224) #set(CMake_VERSION_RC 1) From a73294b9080bb1fbef889b29c0216f8bf47913bf Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Tue, 25 Dec 2012 00:01:07 -0500 Subject: [PATCH 110/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 493960bbe..6fef1aaa1 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 20121224) +set(CMake_VERSION_TWEAK 20121225) #set(CMake_VERSION_RC 1) From 94933a5ec9a28909c4cb6fc883a4bb8da8c31ef0 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Wed, 26 Dec 2012 00:01:05 -0500 Subject: [PATCH 111/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 6fef1aaa1..0685525f5 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 20121225) +set(CMake_VERSION_TWEAK 20121226) #set(CMake_VERSION_RC 1) From 539c222de029a8063f84ba528dd58b021f091e35 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Thu, 27 Dec 2012 00:01:14 -0500 Subject: [PATCH 112/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 0685525f5..07d0371f8 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 20121226) +set(CMake_VERSION_TWEAK 20121227) #set(CMake_VERSION_RC 1) From fb2db0e470002c372decf2aae2447de2cf27384c Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Fri, 28 Dec 2012 00:01:02 -0500 Subject: [PATCH 113/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 07d0371f8..f8fc90a78 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 20121227) +set(CMake_VERSION_TWEAK 20121228) #set(CMake_VERSION_RC 1) From 3793dca08a41fd9199e65ff834b839b4f65397c7 Mon Sep 17 00:00:00 2001 From: Eric LaFranchi Date: Fri, 14 Dec 2012 12:50:18 -0800 Subject: [PATCH 114/170] CPack: WIX Product Icon, UI Banner, UI Dialog support (#13789) --- Modules/CPackWIX.cmake | 26 ++++++++++++++++++++++++ Modules/WIX.template.in | 13 ++++++++++++ Source/CPack/WiX/cmCPackWIXGenerator.cxx | 3 +++ 3 files changed, 42 insertions(+) diff --git a/Modules/CPackWIX.cmake b/Modules/CPackWIX.cmake index f278953dd..0c0a8f19f 100644 --- a/Modules/CPackWIX.cmake +++ b/Modules/CPackWIX.cmake @@ -49,6 +49,32 @@ # by the WiX Generator in case CPACK_RESOURCE_FILE_LICENSE # is in an unsupported format or the .txt -> .rtf # conversion does not work as expected. +# +##end +# +##variable +# CPACK_WIX_PRODUCT_ICON - The Icon shown next to the program name in Add/Remove programs. +# +# If set, this icon is used in place of the default icon. +# +##end +# +##variable +# CPACK_WIX_UI_BANNER - The bitmap will appear at the top of all installer pages other than the welcome and completion dialogs. +# +# If set, this image will replace the default banner image. +# +# This image must be 493 by 58 pixels. +# +##end +# +##variable +# CPACK_WIX_UI_DIALOG - Background bitmap used on the welcome and completion dialogs. +# +# If this variable is set, the installer will replace the default dialog image. +# +# This image must be 493 by 312 pixels. +# ##end #============================================================================= diff --git a/Modules/WIX.template.in b/Modules/WIX.template.in index 63fad7cb7..0bc7e10ce 100644 --- a/Modules/WIX.template.in +++ b/Modules/WIX.template.in @@ -24,6 +24,19 @@ + + ProductIcon.ico + + + + + + + + + + + diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx index 8b5862559..e8b0ea971 100644 --- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx +++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx @@ -221,6 +221,9 @@ bool cmCPackWIXGenerator::CreateWiXVariablesIncludeFile() CopyDefinition(includeFile, "CPACK_PACKAGE_NAME"); CopyDefinition(includeFile, "CPACK_PACKAGE_VERSION"); CopyDefinition(includeFile, "CPACK_WIX_LICENSE_RTF"); + CopyDefinition(includeFile, "CPACK_WIX_PRODUCT_ICON"); + CopyDefinition(includeFile, "CPACK_WIX_UI_BANNER"); + CopyDefinition(includeFile, "CPACK_WIX_UI_DIALOG"); return true; } From 6bd93ea2402704e598519444d2d53252ed40153f Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sat, 29 Dec 2012 00:01:11 -0500 Subject: [PATCH 115/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index f8fc90a78..cbe5b8760 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 20121228) +set(CMake_VERSION_TWEAK 20121229) #set(CMake_VERSION_RC 1) From 2716d8976fbbf728b2336b3793b5c2f7a470c0af Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sun, 30 Dec 2012 00:01:07 -0500 Subject: [PATCH 116/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index cbe5b8760..d3e31c216 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 20121229) +set(CMake_VERSION_TWEAK 20121230) #set(CMake_VERSION_RC 1) From fb864d6e03efdb82f8f2744972ad14c012d86cc7 Mon Sep 17 00:00:00 2001 From: Benjamin Eikel Date: Sun, 30 Dec 2012 16:12:34 +0100 Subject: [PATCH 117/170] FindSDL_...: Restore dropped search paths (#13819) Restore the search paths that were accidentally dropped by me in commit 9ed24c53. This was already fixed for FindSDL.cmake in commit 7cb51739. --- Modules/FindSDL_image.cmake | 3 ++- Modules/FindSDL_mixer.cmake | 3 ++- Modules/FindSDL_net.cmake | 3 ++- Modules/FindSDL_sound.cmake | 3 ++- Modules/FindSDL_ttf.cmake | 3 ++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Modules/FindSDL_image.cmake b/Modules/FindSDL_image.cmake index 4cae03274..30d74acfb 100644 --- a/Modules/FindSDL_image.cmake +++ b/Modules/FindSDL_image.cmake @@ -40,7 +40,7 @@ find_path(SDL_IMAGE_INCLUDE_DIR SDL_image.h HINTS ENV SDLIMAGEDIR ENV SDLDIR - PATH_SUFFIXES SDL SDL12 SDL11 + PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include ) if(NOT SDL_IMAGE_LIBRARY AND SDLIMAGE_LIBRARY) @@ -52,6 +52,7 @@ find_library(SDL_IMAGE_LIBRARY HINTS ENV SDLIMAGEDIR ENV SDLDIR + PATH_SUFFIXES lib ) if(SDL_IMAGE_INCLUDE_DIR AND EXISTS "${SDL_IMAGE_INCLUDE_DIR}/SDL_image.h") diff --git a/Modules/FindSDL_mixer.cmake b/Modules/FindSDL_mixer.cmake index 666fc6e0f..8ca7cc33c 100644 --- a/Modules/FindSDL_mixer.cmake +++ b/Modules/FindSDL_mixer.cmake @@ -40,7 +40,7 @@ find_path(SDL_MIXER_INCLUDE_DIR SDL_mixer.h HINTS ENV SDLMIXERDIR ENV SDLDIR - PATH_SUFFIXES SDL SDL12 SDL11 + PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include ) if(NOT SDL_MIXER_LIBRARY AND SDLMIXER_LIBRARY) @@ -52,6 +52,7 @@ find_library(SDL_MIXER_LIBRARY HINTS ENV SDLMIXERDIR ENV SDLDIR + PATH_SUFFIXES lib ) if(SDL_MIXER_INCLUDE_DIR AND EXISTS "${SDL_MIXER_INCLUDE_DIR}/SDL_mixer.h") diff --git a/Modules/FindSDL_net.cmake b/Modules/FindSDL_net.cmake index d8f479f5b..ca707af8d 100644 --- a/Modules/FindSDL_net.cmake +++ b/Modules/FindSDL_net.cmake @@ -40,7 +40,7 @@ find_path(SDL_NET_INCLUDE_DIR SDL_net.h HINTS ENV SDLNETDIR ENV SDLDIR - PATH_SUFFIXES SDL SDL12 SDL11 + PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include ) if(NOT SDL_NET_LIBRARY AND SDLNET_LIBRARY) @@ -52,6 +52,7 @@ find_library(SDL_NET_LIBRARY HINTS ENV SDLNETDIR ENV SDLDIR + PATH_SUFFIXES lib ) if(SDL_NET_INCLUDE_DIR AND EXISTS "${SDL_NET_INCLUDE_DIR}/SDL_net.h") diff --git a/Modules/FindSDL_sound.cmake b/Modules/FindSDL_sound.cmake index 5ff50be64..efd26580b 100644 --- a/Modules/FindSDL_sound.cmake +++ b/Modules/FindSDL_sound.cmake @@ -77,7 +77,7 @@ find_path(SDL_SOUND_INCLUDE_DIR SDL_sound.h HINTS ENV SDLSOUNDDIR ENV SDLDIR - PATH_SUFFIXES SDL SDL12 SDL11 + PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include ) find_library(SDL_SOUND_LIBRARY @@ -85,6 +85,7 @@ find_library(SDL_SOUND_LIBRARY HINTS ENV SDLSOUNDDIR ENV SDLDIR + PATH_SUFFIXES lib ) if(SDL_FOUND AND SDL_SOUND_INCLUDE_DIR AND SDL_SOUND_LIBRARY) diff --git a/Modules/FindSDL_ttf.cmake b/Modules/FindSDL_ttf.cmake index 2cc5ee232..bb0ca9147 100644 --- a/Modules/FindSDL_ttf.cmake +++ b/Modules/FindSDL_ttf.cmake @@ -40,7 +40,7 @@ find_path(SDL_TTF_INCLUDE_DIR SDL_ttf.h HINTS ENV SDLTTFDIR ENV SDLDIR - PATH_SUFFIXES SDL SDL12 SDL11 + PATH_SUFFIXES include/SDL include/SDL12 include/SDL11 include ) if(NOT SDL_TTF_LIBRARY AND SDLTTF_LIBRARY) @@ -52,6 +52,7 @@ find_library(SDL_TTF_LIBRARY HINTS ENV SDLTTFDIR ENV SDLDIR + PATH_SUFFIXES lib ) if(SDL_TTF_INCLUDE_DIR AND EXISTS "${SDL_TTF_INCLUDE_DIR}/SDL_ttf.h") From 34a8c823788c34e62f0c879c986a7b7940872976 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Mon, 31 Dec 2012 00:01:17 -0500 Subject: [PATCH 118/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index d3e31c216..106a6f0fc 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 20121230) +set(CMake_VERSION_TWEAK 20121231) #set(CMake_VERSION_RC 1) From 74be149bb3c28b45f20f330ff8d91f76ded28178 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Tue, 1 Jan 2013 00:01:05 -0500 Subject: [PATCH 119/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 106a6f0fc..bd2775847 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 20121231) +set(CMake_VERSION_TWEAK 20130101) #set(CMake_VERSION_RC 1) From 953043e679286ed77907e4c9b5cad362e3155301 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Wed, 2 Jan 2013 00:01:16 -0500 Subject: [PATCH 120/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index bd2775847..25a95d896 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 20130101) +set(CMake_VERSION_TWEAK 20130102) #set(CMake_VERSION_RC 1) From 510c9cfe030f400944bbcc1cfe8128e1636f1802 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Thu, 3 Jan 2013 00:01:17 -0500 Subject: [PATCH 121/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 25a95d896..3badbd7c5 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 20130102) +set(CMake_VERSION_TWEAK 20130103) #set(CMake_VERSION_RC 1) From 30962029325b2126b0b986db0c5ce8e0660428a0 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 26 Dec 2012 10:58:21 +0100 Subject: [PATCH 122/170] Make targets depend on the link interface of their dependees. --- Source/cmComputeTargetDepends.cxx | 59 +++++++++++++++++++ Source/cmComputeTargetDepends.h | 6 +- .../target_link_libraries/CMakeLists.txt | 7 +++ .../target_link_libraries/depIfaceOnly.cpp | 7 +++ .../target_link_libraries/depIfaceOnly.h | 7 +++ .../target_link_libraries/targetA.cpp | 5 +- 6 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 Tests/CMakeCommands/target_link_libraries/depIfaceOnly.cpp create mode 100644 Tests/CMakeCommands/target_link_libraries/depIfaceOnly.h diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index ab77c6bc9..3b15ec11a 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -214,6 +214,8 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) if(emitted.insert(lib->first).second) { this->AddTargetDepend(depender_index, lib->first.c_str(), true); + this->AddInterfaceDepends(depender_index, lib->first.c_str(), + true, emitted); } } } @@ -236,6 +238,63 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) } } +//---------------------------------------------------------------------------- +void cmComputeTargetDepends::AddInterfaceDepends(int depender_index, + cmTarget* dependee, + const char *config, + std::set &emitted) +{ + if(cmTarget::LinkInterface const* iface = + dependee->GetLinkInterface(config)) + { + for(std::vector::const_iterator + lib = iface->Libraries.begin(); + lib != iface->Libraries.end(); ++lib) + { + // Don't emit the same library twice for this target. + if(emitted.insert(*lib).second) + { + this->AddTargetDepend(depender_index, lib->c_str(), true); + } + } + } +} + +//---------------------------------------------------------------------------- +void cmComputeTargetDepends::AddInterfaceDepends(int depender_index, + const char* dependee_name, + bool linking, + std::set &emitted) +{ + cmTarget* depender = this->Targets[depender_index]; + cmTarget* dependee = + depender->GetMakefile()->FindTargetToUse(dependee_name); + // Skip targets that will not really be linked. This is probably a + // name conflict between an external library and an executable + // within the project. + if(linking && dependee && + dependee->GetType() == cmTarget::EXECUTABLE && + !dependee->IsExecutableWithExports()) + { + dependee = 0; + } + + if(dependee) + { + this->AddInterfaceDepends(depender_index, dependee, 0, emitted); + std::vector configs; + depender->GetMakefile()->GetConfigurations(configs); + for (std::vector::const_iterator it = configs.begin(); + it != configs.end(); ++it) + { + // A target should not depend on itself. + emitted.insert(depender->GetName()); + this->AddInterfaceDepends(depender_index, dependee, + it->c_str(), emitted); + } + } +} + //---------------------------------------------------------------------------- void cmComputeTargetDepends::AddTargetDepend(int depender_index, const char* dependee_name, diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h index 67bce72d9..d6131cf1c 100644 --- a/Source/cmComputeTargetDepends.h +++ b/Source/cmComputeTargetDepends.h @@ -48,7 +48,11 @@ private: bool linking); void AddTargetDepend(int depender_index, cmTarget* dependee, bool linking); bool ComputeFinalDepends(cmComputeComponentGraph const& ccg); - + void AddInterfaceDepends(int depender_index, const char* dependee_name, + bool linking, std::set &emitted); + void AddInterfaceDepends(int depender_index, cmTarget* dependee, + const char *config, + std::set &emitted); cmGlobalGenerator* GlobalGenerator; bool DebugMode; bool NoCycles; diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt index 1faa88848..60b36fc27 100644 --- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt @@ -56,3 +56,10 @@ assert_property(targetA LINK_INTERFACE_LIBRARIES "") target_link_libraries(targetA depB depC) assert_property(targetA LINK_INTERFACE_LIBRARIES "") + +# Exclude depIfaceOnly from ALL so that it will only be built if something +# depends on it. As it is in the link interface of depB, targetA +# will depend on it. That dependency is what is being tested here. +add_library(depIfaceOnly SHARED EXCLUDE_FROM_ALL depIfaceOnly.cpp) +generate_export_header(depIfaceOnly) +set_property(TARGET depB APPEND PROPERTY LINK_INTERFACE_LIBRARIES depIfaceOnly) diff --git a/Tests/CMakeCommands/target_link_libraries/depIfaceOnly.cpp b/Tests/CMakeCommands/target_link_libraries/depIfaceOnly.cpp new file mode 100644 index 000000000..3b90af008 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/depIfaceOnly.cpp @@ -0,0 +1,7 @@ + +#include "depIfaceOnly.h" + +int DepIfaceOnly::foo() +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_link_libraries/depIfaceOnly.h b/Tests/CMakeCommands/target_link_libraries/depIfaceOnly.h new file mode 100644 index 000000000..dddf6a5e4 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/depIfaceOnly.h @@ -0,0 +1,7 @@ + +#include "depifaceonly_export.h" + +struct DEPIFACEONLY_EXPORT DepIfaceOnly +{ + int foo(); +}; diff --git a/Tests/CMakeCommands/target_link_libraries/targetA.cpp b/Tests/CMakeCommands/target_link_libraries/targetA.cpp index 3c6472e9a..6ff65b106 100644 --- a/Tests/CMakeCommands/target_link_libraries/targetA.cpp +++ b/Tests/CMakeCommands/target_link_libraries/targetA.cpp @@ -1,6 +1,7 @@ #include "depB.h" #include "depC.h" +#include "depIfaceOnly.h" int main(int argc, char **argv) { @@ -8,5 +9,7 @@ int main(int argc, char **argv) DepB b; DepC c; - return a.foo() + b.foo() + c.foo(); + DepIfaceOnly iface_only; + + return a.foo() + b.foo() + c.foo() + iface_only.foo(); } From e378ba5f39a9d8ebe0335390870a82774ecdd171 Mon Sep 17 00:00:00 2001 From: David Cole Date: Wed, 26 Dec 2012 15:22:59 -0500 Subject: [PATCH 123/170] Add CTestLimitDashJ test (#12904) Add a test that verifies that when ctest -j 4 is called, at most, 4 tests are executed at any one time. The test works by running the same script as each of 100 tests. And then setting up test properties for DEPENDS, RUN_SERIAL, PROCESSORS and COST in order to get the tests to run in a semi-deterministic ordering, even in parallel. The script writes a file, sleeps for a bit, and then deletes the file. In the meantime, it counts files that currently exist, and emits output that triggers a test failure if the count of files is ever greater than 4. Prior to the commit that fixed bug #12904, this would result in a failed test because the output of some of the tests would indicate that more than 4 tests were running simultaneously. Now that this issue is resolved, this test will help guarantee that it stays resolved moving forward. --- Tests/CMakeLists.txt | 3 ++ Tests/CTestLimitDashJ/CMakeLists.txt | 50 +++++++++++++++++++ Tests/CTestLimitDashJ/CreateSleepDelete.cmake | 48 ++++++++++++++++++ 3 files changed, 101 insertions(+) create mode 100644 Tests/CTestLimitDashJ/CMakeLists.txt create mode 100644 Tests/CTestLimitDashJ/CreateSleepDelete.cmake diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index f443b5b36..b3302f91f 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1959,6 +1959,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --output-log "${CMake_BINARY_DIR}/Tests/CTestTestParallel/testOutput.log" ) + add_test_macro(CTestLimitDashJ ${CMAKE_CTEST_COMMAND} -j 4 + --output-on-failure -C "\${CTestTest_CONFIG}") + add_test(CTestTestPrintLabels ${CMAKE_CTEST_COMMAND} --print-labels) set_tests_properties(CTestTestPrintLabels PROPERTIES LABELS "Label1;Label2") set_tests_properties(CTestTestPrintLabels PROPERTIES PASS_REGULAR_EXPRESSION diff --git a/Tests/CTestLimitDashJ/CMakeLists.txt b/Tests/CTestLimitDashJ/CMakeLists.txt new file mode 100644 index 000000000..0c5950c9d --- /dev/null +++ b/Tests/CTestLimitDashJ/CMakeLists.txt @@ -0,0 +1,50 @@ +cmake_minimum_required(VERSION 2.8) +project(CTestLimitDashJ NONE) + +# This file demonstrates http://public.kitware.com/Bug/view.php?id=12904 +# when configured with CMake 2.8.10.2 and earlier, and when running +# "ctest -j 4" in the resulting build tree. This example is hard-coded +# to assume -j 4 just to reproduce the issue easily. Adjust the +# FAIL_REGULAR_EXPRESSION and PROCESSORS values to reproduce this problem +# with a different ctest -j value... + +if(EXISTS "${CMAKE_BINARY_DIR}/Testing/Temporary/CTestCostData.txt") + message(STATUS "Removing CTestCostData.txt to force ordering by COST PROPERTY value rather than prior run data") + file(REMOVE "${CMAKE_BINARY_DIR}/Testing/Temporary/CTestCostData.txt") +endif() + +include(CTest) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/CreateSleepDelete.cmake + ${CMAKE_CURRENT_BINARY_DIR}/CreateSleepDelete.cmake + @ONLY + ) + +foreach(n RANGE 1 100) + add_test(NAME t${n} + COMMAND ${CMAKE_CTEST_COMMAND} + -D basefilename=f${n} + -S ${CMAKE_CURRENT_BINARY_DIR}/CreateSleepDelete.cmake + ) + set_property(TEST t${n} PROPERTY FAIL_REGULAR_EXPRESSION "(c='[5-9]'|c='[1-9][0-9]+')") +endforeach() + +set_property(TEST t1 PROPERTY RUN_SERIAL 1) +set_property(TEST t1 PROPERTY PROCESSORS 4) + +set_property(TEST t51 PROPERTY RUN_SERIAL 1) +set_property(TEST t51 PROPERTY PROCESSORS 4) + +foreach(n RANGE 2 50) + set_property(TEST t${n} PROPERTY DEPENDS t1) +endforeach() +set_property(TEST t1 PROPERTY DEPENDS t51) +set_property(TEST t51 PROPERTY DEPENDS t100) + +foreach(n 50) + set_property(TEST t${n} PROPERTY COST 6) +endforeach() +foreach(n RANGE 52 99) + set_property(TEST t${n} PROPERTY COST 3) +endforeach() diff --git a/Tests/CTestLimitDashJ/CreateSleepDelete.cmake b/Tests/CTestLimitDashJ/CreateSleepDelete.cmake new file mode 100644 index 000000000..b09307feb --- /dev/null +++ b/Tests/CTestLimitDashJ/CreateSleepDelete.cmake @@ -0,0 +1,48 @@ +set(CTEST_RUN_CURRENT_SCRIPT 0) + +if(NOT DEFINED basefilename) + message(FATAL_ERROR "pass -Dbasefilename=f1") +endif() + +if(NOT DEFINED ext) + set(ext "jkqvxz") +endif() + +if(NOT DEFINED sleep_interval) + set(sleep_interval 1) +endif() + +get_filename_component(self_dir "${CMAKE_CURRENT_LIST_FILE}" PATH) +set(filename "${self_dir}/${basefilename}.${ext}") + +# count files +file(GLOB f1 *.${ext}) +list(LENGTH f1 c1) +message("c='${c1}'") + +# write a new file +message("Writing file: filename='${filename}'") +file(WRITE "${filename}" "${filename}") + +# count files again +file(GLOB f2 *.${ext}) +list(LENGTH f2 c2) +message("c='${c2}'") + +# snooze +message("Sleeping: sleep_interval='${sleep_interval}'") +ctest_sleep(${sleep_interval}) + +# count files again +file(GLOB f3 *.${ext}) +list(LENGTH f3 c3) +message("c='${c3}'") + +# delete the file we wrote earlier +message("Removing file: filename='${filename}'") +file(REMOVE "${filename}") + +# count files again +file(GLOB f4 *.${ext}) +list(LENGTH f4 c4) +message("c='${c4}'") From 18a3195ad57cafd06851ecf4cb7265cab95cfa38 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 19 Nov 2012 22:47:30 +0100 Subject: [PATCH 124/170] Keep track of INCLUDE_DIRECTORIES as a vector of structs. The struct can keep track of where the include came from, which gives us proper backtraces. --- Source/cmGeneratorTarget.cxx | 40 +----- Source/cmMakefile.cxx | 90 +++++++------ Source/cmMakefile.h | 10 ++ Source/cmMakefileIncludeDirectoriesEntry.h | 28 ++++ Source/cmTarget.cxx | 125 +++++++++++++++++- Source/cmTarget.h | 4 + .../BadInvalidName1-stderr.txt | 4 +- .../BadInvalidName2-stderr.txt | 6 +- .../BadInvalidName3-stderr.txt | 6 +- .../BadInvalidName4-stderr.txt | 6 +- .../BadInvalidName5-stderr.txt | 4 +- .../BadInvalidName6-stderr.txt | 4 +- .../BadInvalidName7-stderr.txt | 4 +- .../BadInvalidName8-stderr.txt | 4 +- .../BadNonTarget-stderr.txt | 6 +- 15 files changed, 243 insertions(+), 98 deletions(-) create mode 100644 Source/cmMakefileIncludeDirectoriesEntry.h diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 55507ddf3..62ee26a22 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -252,45 +252,7 @@ const char* cmGeneratorTarget::GetCreateRuleVariable() std::vector cmGeneratorTarget::GetIncludeDirectories( const char *config) { - std::vector includes; - const char *prop = this->Target->GetProperty("INCLUDE_DIRECTORIES"); - if(!prop) - { - return includes; - } - - cmListFileBacktrace lfbt; - cmGeneratorExpression ge(lfbt); - - cmGeneratorExpressionDAGChecker dagChecker(lfbt, - this->GetName(), - "INCLUDE_DIRECTORIES", 0, 0); - - cmSystemTools::ExpandListArgument(ge.Parse(prop) - ->Evaluate(this->Makefile, - config, - false, - this->Target, - &dagChecker), - includes); - - std::set uniqueIncludes; - std::vector orderedAndUniqueIncludes; - for(std::vector::const_iterator - li = includes.begin(); li != includes.end(); ++li) - { - std::string inc = *li; - if (!cmSystemTools::IsOff(inc.c_str())) - { - cmSystemTools::ConvertToUnixSlashes(inc); - } - if(uniqueIncludes.insert(inc).second) - { - orderedAndUniqueIncludes.push_back(inc); - } - } - - return orderedAndUniqueIncludes; + return this->Target->GetIncludeDirectories(config); } //---------------------------------------------------------------------------- diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index d943c450f..b432986a8 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1485,9 +1485,12 @@ void cmMakefile::InitializeFromParent() // Initialize definitions with the closure of the parent scope. this->Internal->VarStack.top() = parent->Internal->VarStack.top().Closure(); - // copy include paths - this->SetProperty("INCLUDE_DIRECTORIES", - parent->GetProperty("INCLUDE_DIRECTORIES")); + const std::vector parentIncludes = + parent->GetIncludeDirectoriesEntries(); + this->IncludeDirectoriesEntries.insert(this->IncludeDirectoriesEntries.end(), + parentIncludes.begin(), + parentIncludes.end()); + this->SystemIncludeDirectories = parent->SystemIncludeDirectories; // define flags @@ -1612,41 +1615,6 @@ void cmMakefile::AddSubDirectory(const char* srcPath, const char *binPath, } } -//---------------------------------------------------------------------------- -void AddStringToProperty(cmProperty *prop, const char* name, const char* s, - bool before) -{ - if (!prop) - { - return; - } - - // Don't worry about duplicates at this point. We eliminate them when - // we convert the property to a vector in GetIncludeDirectories. - - if (before) - { - const char *val = prop->GetValue(); - cmOStringStream oss; - - if(val && *val) - { - oss << s << ";" << val; - } - else - { - oss << s; - } - - std::string newVal = oss.str(); - prop->Set(name, newVal.c_str()); - } - else - { - prop->Append(name, s); - } -} - //---------------------------------------------------------------------------- void cmMakefile::AddIncludeDirectory(const char* inc, bool before) { @@ -1655,18 +1623,21 @@ void cmMakefile::AddIncludeDirectory(const char* inc, bool before) return; } - // Directory property: - cmProperty *prop = - this->GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES"); - AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before); + std::vector::iterator position = + before ? this->IncludeDirectoriesEntries.begin() + : this->IncludeDirectoriesEntries.end(); + + cmListFileBacktrace lfbt; + this->GetBacktrace(lfbt); + IncludeDirectoriesEntry entry(inc, lfbt); + this->IncludeDirectoriesEntries.insert(position, entry); // Property on each target: for (cmTargets::iterator l = this->Targets.begin(); l != this->Targets.end(); ++l) { cmTarget &t = l->second; - prop = t.GetProperties().GetOrCreateProperty("INCLUDE_DIRECTORIES"); - AddStringToProperty(prop, "INCLUDE_DIRECTORIES", inc, before); + t.InsertInclude(entry, before); } } @@ -3451,6 +3422,15 @@ void cmMakefile::SetProperty(const char* prop, const char* value) this->SetLinkDirectories(varArgsExpanded); return; } + if (propname == "INCLUDE_DIRECTORIES") + { + this->IncludeDirectoriesEntries.clear(); + cmListFileBacktrace lfbt; + this->GetBacktrace(lfbt); + this->IncludeDirectoriesEntries.push_back( + IncludeDirectoriesEntry(value, lfbt)); + return; + } if ( propname == "INCLUDE_REGULAR_EXPRESSION" ) { @@ -3482,6 +3462,14 @@ void cmMakefile::AppendProperty(const char* prop, const char* value, // handle special props std::string propname = prop; + if (propname == "INCLUDE_DIRECTORIES") + { + cmListFileBacktrace lfbt; + this->GetBacktrace(lfbt); + this->IncludeDirectoriesEntries.push_back( + IncludeDirectoriesEntry(value, lfbt)); + return; + } if ( propname == "LINK_DIRECTORIES" ) { std::vector varArgsExpanded; @@ -3593,6 +3581,20 @@ const char *cmMakefile::GetProperty(const char* prop, output = str.str(); return output.c_str(); } + else if (!strcmp("INCLUDE_DIRECTORIES",prop)) + { + std::string sep; + for (std::vector::const_iterator + it = this->IncludeDirectoriesEntries.begin(), + end = this->IncludeDirectoriesEntries.end(); + it != end; ++it) + { + output += sep; + output += it->Value; + sep = ";"; + } + return output.c_str(); + } bool chain = false; const char *retVal = diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index eff05d091..a85015fe6 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -22,6 +22,7 @@ #include "cmNewLineStyle.h" #include "cmGeneratorTarget.h" #include "cmake.h" +#include "cmMakefileIncludeDirectoriesEntry.h" #if defined(CMAKE_BUILD_WITH_CMAKE) #include "cmSourceGroup.h" @@ -861,6 +862,13 @@ public: /** Set whether or not to report a CMP0000 violation. */ void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; } + typedef cmMakefileIncludeDirectoriesEntry IncludeDirectoriesEntry; + + std::vector GetIncludeDirectoriesEntries() const + { + return this->IncludeDirectoriesEntries; + } + protected: // add link libraries and directories to the target void AddGlobalLinkInformation(const char* name, cmTarget& target); @@ -909,6 +917,8 @@ protected: std::vector HeaderFileExtensions; std::string DefineFlags; + std::vector IncludeDirectoriesEntries; + // Track the value of the computed DEFINITIONS property. void AddDefineFlag(const char*, std::string&); void RemoveDefineFlag(const char*, std::string::size_type, std::string&); diff --git a/Source/cmMakefileIncludeDirectoriesEntry.h b/Source/cmMakefileIncludeDirectoriesEntry.h new file mode 100644 index 000000000..f35642dfb --- /dev/null +++ b/Source/cmMakefileIncludeDirectoriesEntry.h @@ -0,0 +1,28 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2012 Stephen Kelly + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmMakefileIncludeDirectoriesEntry_h +#define cmMakefileIncludeDirectoriesEntry_h + +#include +#include "cmListFileCache.h" + +struct cmMakefileIncludeDirectoriesEntry { + cmMakefileIncludeDirectoriesEntry(const std::string &value, + const cmListFileBacktrace &bt) + : Value(value), Backtrace(bt) + {} + std::string Value; + cmListFileBacktrace Backtrace; +}; + +#endif diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index e7b34ee42..0c6bb1c5f 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -21,6 +21,7 @@ #include "cmDocumentLocationUndefined.h" #include "cmListFileCache.h" #include "cmGeneratorExpression.h" +#include "cmGeneratorExpressionDAGChecker.h" #include #include #include @@ -118,6 +119,14 @@ public: struct SourceEntry { std::vector Depends; }; typedef std::map SourceEntriesType; SourceEntriesType SourceEntries; + + struct IncludeDirectoriesEntry { + IncludeDirectoriesEntry(cmsys::auto_ptr cge) + : ge(cge) + {} + const cmsys::auto_ptr ge; + }; + std::vector IncludeDirectoriesEntries; }; //---------------------------------------------------------------------------- @@ -1392,8 +1401,14 @@ void cmTarget::SetMakefile(cmMakefile* mf) // Initialize the INCLUDE_DIRECTORIES property based on the current value // of the same directory property: - this->SetProperty("INCLUDE_DIRECTORIES", - this->Makefile->GetProperty("INCLUDE_DIRECTORIES")); + const std::vector parentIncludes = + this->Makefile->GetIncludeDirectoriesEntries(); + + for (std::vector::const_iterator it + = parentIncludes.begin(); it != parentIncludes.end(); ++it) + { + this->InsertInclude(*it); + } if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY || this->TargetTypeValue == cmTarget::MODULE_LIBRARY) @@ -2445,6 +2460,20 @@ void cmTarget::GatherDependencies( const cmMakefile& mf, } } +//---------------------------------------------------------------------------- +void deleteAndClear( + std::vector &entries) +{ + for (std::vector::const_iterator + it = entries.begin(), + end = entries.end(); + it != end; ++it) + { + delete *it; + } + entries.clear(); +} + //---------------------------------------------------------------------------- void cmTarget::SetProperty(const char* prop, const char* value) { @@ -2453,6 +2482,16 @@ void cmTarget::SetProperty(const char* prop, const char* value) return; } + if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0) + { + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + deleteAndClear(this->Internal->IncludeDirectoriesEntries); + cmsys::auto_ptr cge = ge.Parse(value); + this->Internal->IncludeDirectoriesEntries.push_back( + new cmTargetInternals::IncludeDirectoriesEntry(cge)); + return; + } this->Properties.SetProperty(prop, value, cmProperty::TARGET); this->MaybeInvalidatePropertyCache(prop); } @@ -2465,10 +2504,73 @@ void cmTarget::AppendProperty(const char* prop, const char* value, { return; } + if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0) + { + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + this->Internal->IncludeDirectoriesEntries.push_back( + new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(value))); + return; + } this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); this->MaybeInvalidatePropertyCache(prop); } +//---------------------------------------------------------------------------- +void cmTarget::InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry, + bool before) +{ + cmGeneratorExpression ge(entry.Backtrace); + + std::vector::iterator position + = before ? this->Internal->IncludeDirectoriesEntries.begin() + : this->Internal->IncludeDirectoriesEntries.end(); + + this->Internal->IncludeDirectoriesEntries.insert(position, + new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(entry.Value))); +} + +//---------------------------------------------------------------------------- +std::vector cmTarget::GetIncludeDirectories(const char *config) +{ + std::vector includes; + std::set uniqueIncludes; + cmListFileBacktrace lfbt; + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "INCLUDE_DIRECTORIES", 0, 0); + + for (std::vector::const_iterator + it = this->Internal->IncludeDirectoriesEntries.begin(), + end = this->Internal->IncludeDirectoriesEntries.end(); + it != end; ++it) + { + std::vector entryIncludes; + cmSystemTools::ExpandListArgument((*it)->ge->Evaluate(this->Makefile, + config, + false, + this, + &dagChecker), + entryIncludes); + for(std::vector::const_iterator + li = entryIncludes.begin(); li != entryIncludes.end(); ++li) + { + std::string inc = *li; + if (!cmSystemTools::IsOff(inc.c_str())) + { + cmSystemTools::ConvertToUnixSlashes(inc); + } + + if(uniqueIncludes.insert(inc).second) + { + includes.push_back(*li); + } + } + } + return includes; +} + //---------------------------------------------------------------------------- void cmTarget::MaybeInvalidatePropertyCache(const char* prop) { @@ -2796,6 +2898,24 @@ const char *cmTarget::GetProperty(const char* prop, } } } + if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0) + { + static std::string output; + output = ""; + std::string sep; + typedef cmTargetInternals::IncludeDirectoriesEntry + IncludeDirectoriesEntry; + for (std::vector::const_iterator + it = this->Internal->IncludeDirectoriesEntries.begin(), + end = this->Internal->IncludeDirectoriesEntries.end(); + it != end; ++it) + { + output += sep; + output += (*it)->ge->GetInput(); + sep = ";"; + } + return output.c_str(); + } if (strcmp(prop,"IMPORTED") == 0) { @@ -4919,6 +5039,7 @@ cmTargetInternalPointer //---------------------------------------------------------------------------- cmTargetInternalPointer::~cmTargetInternalPointer() { + deleteAndClear(this->Pointer->IncludeDirectoriesEntries); delete this->Pointer; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 0dfbc68a1..3f3605043 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -15,6 +15,7 @@ #include "cmCustomCommand.h" #include "cmPropertyMap.h" #include "cmPolicies.h" +#include "cmMakefileIncludeDirectoriesEntry.h" #include @@ -470,6 +471,9 @@ public: /** @return the Mac framework directory without the base. */ std::string GetFrameworkDirectory(const char* config = 0); + std::vector GetIncludeDirectories(const char *config); + void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry, + bool before = false); private: /** * A list of direct dependencies. Use in conjunction with DependencyMap. diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName1-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName1-stderr.txt index 3287d19ac..9c146e057 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName1-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName1-stderr.txt @@ -1,6 +1,8 @@ -CMake Error: +CMake Error at BadInvalidName1.cmake:7 \(include_directories\): Error evaluating generator expression: \$ Target name not supported. +Call Stack \(most recent call first\): + CMakeLists.txt:8 \(include\) diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName2-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName2-stderr.txt index e527e2275..451888cc6 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName2-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName2-stderr.txt @@ -1,6 +1,8 @@ -CMake Error: +CMake Error at BadInvalidName2.cmake:7 \(include_directories\): Error evaluating generator expression: \$ - Target name and property name not supported.$ + Target name and property name not supported. +Call Stack \(most recent call first\): + CMakeLists.txt:8 \(include\)$ diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName3-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName3-stderr.txt index 517debbca..39692c4ef 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName3-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName3-stderr.txt @@ -1,6 +1,8 @@ -CMake Error: +CMake Error at BadInvalidName3.cmake:7 \(include_directories\): Error evaluating generator expression: \$ - Property name not supported.$ + Property name not supported. +Call Stack \(most recent call first\): + CMakeLists.txt:8 \(include\)$ diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName4-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName4-stderr.txt index eab6fb690..c3aa1b1a9 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName4-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName4-stderr.txt @@ -1,6 +1,8 @@ -CMake Error: +CMake Error at BadInvalidName4.cmake:9 \(include_directories\): Error evaluating generator expression: \$ - Property name not supported.$ + Property name not supported. +Call Stack \(most recent call first\): + CMakeLists.txt:8 \(include\)$ diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName5-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName5-stderr.txt index e2b4fc6fa..1c6fad4b0 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName5-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName5-stderr.txt @@ -1,7 +1,9 @@ -CMake Error: +CMake Error at BadInvalidName5.cmake:7 \(include_directories\): Error evaluating generator expression: \$ \$ expression requires a non-empty target name and property name. +Call Stack \(most recent call first\): + CMakeLists.txt:8 \(include\)$ diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName6-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName6-stderr.txt index e94f52fa2..8b147dca6 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName6-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName6-stderr.txt @@ -1,6 +1,8 @@ -CMake Error: +CMake Error at BadInvalidName6.cmake:7 \(include_directories\): Error evaluating generator expression: \$ \$ expression requires a non-empty target name. +Call Stack \(most recent call first\): + CMakeLists.txt:8 \(include\)$ diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName7-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName7-stderr.txt index 2548215f4..dad6bf86a 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName7-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName7-stderr.txt @@ -1,6 +1,8 @@ -CMake Error: +CMake Error at BadInvalidName7.cmake:9 \(include_directories\): Error evaluating generator expression: \$ \$ expression requires a non-empty property name. +Call Stack \(most recent call first\): + CMakeLists.txt:8 \(include\)$ diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName8-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName8-stderr.txt index 2a98f6f06..4e8c14c99 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName8-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadInvalidName8-stderr.txt @@ -1,6 +1,8 @@ -CMake Error: +CMake Error at BadInvalidName8.cmake:7 \(include_directories\): Error evaluating generator expression: \$ \$ expression requires a non-empty property name. +Call Stack \(most recent call first\): + CMakeLists.txt:8 \(include\)$ diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt index d2ac7a963..3b3bab07d 100644 --- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt +++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/BadNonTarget-stderr.txt @@ -1,6 +1,8 @@ -CMake Error: +CMake Error at BadNonTarget.cmake:7 \(include_directories\): Error evaluating generator expression: \$ - Target "NonExistant" not found.$ + Target "NonExistant" not found. +Call Stack \(most recent call first\): + CMakeLists.txt:8 \(include\)$ From 0941d6232a979a129a651915972ab7332c15550d Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 18 Dec 2012 16:16:14 +0100 Subject: [PATCH 125/170] Add a way to print the origins of used include directories. --- Source/cmDocumentVariables.cxx | 9 ++++ Source/cmGeneratorExpression.h | 5 +++ Source/cmTarget.cxx | 27 ++++++++++++ .../DebugIncludes-result.txt | 1 + .../DebugIncludes-stderr.txt | 42 +++++++++++++++++++ .../include_directories/DebugIncludes.cmake | 38 +++++++++++++++++ .../include_directories/RunCMakeTest.cmake | 1 + 7 files changed, 123 insertions(+) create mode 100644 Tests/RunCMake/include_directories/DebugIncludes-result.txt create mode 100644 Tests/RunCMake/include_directories/DebugIncludes-stderr.txt create mode 100644 Tests/RunCMake/include_directories/DebugIncludes.cmake diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index 32c543dce..d4a876d0a 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -896,6 +896,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) " script, it may get fatal error messages from the script.",false, "Variables That Change Behavior"); + cm->DefineProperty + ("CMAKE_DEBUG_TARGET_PROPERTIES", cmProperty::VARIABLE, + "Enables tracing output for target properties.", + "This variable can be populated with a list of properties to generate " + "debug output for when evaluating target properties. Currently it can " + "only be used when evaluating the INCLUDE_DIRECTORIES target property. " + "In that case, it outputs a backtrace for each include directory in " + "the build. Default is unset.",false,"Variables That Change Behavior"); + // Variables defined by CMake that describe the system cm->DefineProperty diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 961e53d75..15e637cb7 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -83,6 +83,11 @@ public: return this->Input; } + cmListFileBacktrace GetBacktrace() const + { + return this->Backtrace; + } + private: cmCompiledGeneratorExpression(cmListFileBacktrace const& backtrace, const char *input); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 0c6bb1c5f..58fab80cc 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2485,6 +2485,7 @@ void cmTarget::SetProperty(const char* prop, const char* value) if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0) { cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); cmGeneratorExpression ge(lfbt); deleteAndClear(this->Internal->IncludeDirectoriesEntries); cmsys::auto_ptr cge = ge.Parse(value); @@ -2507,6 +2508,7 @@ void cmTarget::AppendProperty(const char* prop, const char* value, if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0) { cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); cmGeneratorExpression ge(lfbt); this->Internal->IncludeDirectoriesEntries.push_back( new cmTargetInternals::IncludeDirectoriesEntry(ge.Parse(value))); @@ -2541,6 +2543,20 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) this->GetName(), "INCLUDE_DIRECTORIES", 0, 0); + + std::vector debugProperties; + const char *debugProp = + this->Makefile->GetDefinition("CMAKE_DEBUG_TARGET_PROPERTIES"); + if (debugProp) + { + cmSystemTools::ExpandListArgument(debugProp, debugProperties); + } + + bool debugIncludes = std::find(debugProperties.begin(), + debugProperties.end(), + "INCLUDE_DIRECTORIES") + != debugProperties.end(); + for (std::vector::const_iterator it = this->Internal->IncludeDirectoriesEntries.begin(), end = this->Internal->IncludeDirectoriesEntries.end(); @@ -2553,6 +2569,7 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) this, &dagChecker), entryIncludes); + std::string usedIncludes; for(std::vector::const_iterator li = entryIncludes.begin(); li != entryIncludes.end(); ++li) { @@ -2565,8 +2582,18 @@ std::vector cmTarget::GetIncludeDirectories(const char *config) if(uniqueIncludes.insert(inc).second) { includes.push_back(*li); + if (debugIncludes) + { + usedIncludes += " * " + *li + "\n"; + } } } + if (!usedIncludes.empty()) + { + this->Makefile->GetCMakeInstance()->IssueMessage(cmake::LOG, + "Used includes:\n" + usedIncludes, + (*it)->ge->GetBacktrace()); + } } return includes; } diff --git a/Tests/RunCMake/include_directories/DebugIncludes-result.txt b/Tests/RunCMake/include_directories/DebugIncludes-result.txt new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/Tests/RunCMake/include_directories/DebugIncludes-result.txt @@ -0,0 +1 @@ +0 diff --git a/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt b/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt new file mode 100644 index 000000000..948def117 --- /dev/null +++ b/Tests/RunCMake/include_directories/DebugIncludes-stderr.txt @@ -0,0 +1,42 @@ +CMake Warning at DebugIncludes.cmake:8 \(include_directories\): + Used includes: + + \* .*/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: + + \* .*/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: + + \* .*/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: + + \* .*/Tests/RunCMake/include_directories/five + \* .*/Tests/RunCMake/include_directories/six + +Call Stack \(most recent call first\): + DebugIncludes.cmake:35 \(some_macro\) + DebugIncludes.cmake:38 \(some_function\) + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/include_directories/DebugIncludes.cmake b/Tests/RunCMake/include_directories/DebugIncludes.cmake new file mode 100644 index 000000000..51daf7480 --- /dev/null +++ b/Tests/RunCMake/include_directories/DebugIncludes.cmake @@ -0,0 +1,38 @@ + +project(DebugIncludes) + +set(CMAKE_DEBUG_TARGET_PROPERTIES INCLUDE_DIRECTORIES) + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/DebugIncludes.cpp" "enum { dummy };\n") + +include_directories( + "${CMAKE_CURRENT_SOURCE_DIR}/one" + "${CMAKE_CURRENT_SOURCE_DIR}/two" +) + +set_property(DIRECTORY APPEND PROPERTY INCLUDE_DIRECTORIES + "${CMAKE_CURRENT_SOURCE_DIR}/three") + +add_library(lll "${CMAKE_CURRENT_BINARY_DIR}/DebugIncludes.cpp") + +include_directories( + "${CMAKE_CURRENT_SOURCE_DIR}/two" + "${CMAKE_CURRENT_SOURCE_DIR}/three" + "${CMAKE_CURRENT_SOURCE_DIR}/four" +) + +macro(some_macro) + set_property(TARGET lll APPEND PROPERTY + INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/one" + "${CMAKE_CURRENT_SOURCE_DIR}/three" + "${CMAKE_CURRENT_SOURCE_DIR}/four" + "${CMAKE_CURRENT_SOURCE_DIR}/five" + "${CMAKE_CURRENT_SOURCE_DIR}/six" + ) +endmacro() + +function(some_function) + some_macro() +endfunction() + +some_function() diff --git a/Tests/RunCMake/include_directories/RunCMakeTest.cmake b/Tests/RunCMake/include_directories/RunCMakeTest.cmake index aee3f799b..de3725226 100644 --- a/Tests/RunCMake/include_directories/RunCMakeTest.cmake +++ b/Tests/RunCMake/include_directories/RunCMakeTest.cmake @@ -1,3 +1,4 @@ include(RunCMake) run_cmake(NotFoundContent) +run_cmake(DebugIncludes) From b6346f25565f06bde208b8303d70bbe0fabc8210 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 1 Jan 2013 18:35:28 +0100 Subject: [PATCH 126/170] Tests: Fix warning about unused variable Resolve this warning: ".../Tests/CMakeCommands/target_link_libraries/depB.cpp", line 8: warning: variable "a" was declared but never referenced DepA a; ^ --- Tests/CMakeCommands/target_link_libraries/depB.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/CMakeCommands/target_link_libraries/depB.cpp b/Tests/CMakeCommands/target_link_libraries/depB.cpp index 97e5be274..1bbe38bc2 100644 --- a/Tests/CMakeCommands/target_link_libraries/depB.cpp +++ b/Tests/CMakeCommands/target_link_libraries/depB.cpp @@ -7,5 +7,5 @@ int DepB::foo() { DepA a; - return 0; + return a.foo(); } From e767ffcda58ab73cf2c4394202eec7ae1f6035b5 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 3 Jan 2013 20:56:32 +0100 Subject: [PATCH 127/170] Don't crash when a target is expected but is not available. --- Source/cmGeneratorExpressionEvaluator.cxx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 3b7cfc03a..d86ae5497 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -18,6 +18,8 @@ #include +#include + //---------------------------------------------------------------------------- #if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x510 static @@ -291,6 +293,17 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode cmTarget* target = context->Target; std::string propertyName = *parameters.begin(); + + if (!target && parameters.size() == 1) + { + reportError(context, content->GetOriginalExpression(), + "$ may only be used with targets. It may not " + "be used with add_custom_command. Specify the target to read a " + "property from using the $ signature " + "instead."); + return std::string(); + } + if (parameters.size() == 2) { if (parameters.begin()->empty() && parameters[1].empty()) @@ -351,6 +364,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode return std::string(); } + assert(target); + cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, target->GetName(), propertyName, From 95b74cafed4ba7ce572dc03b11e72d902f4df7ca Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Fri, 4 Jan 2013 00:01:13 -0500 Subject: [PATCH 128/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 3badbd7c5..370c76bc8 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 20130103) +set(CMake_VERSION_TWEAK 20130104) #set(CMake_VERSION_RC 1) From 51988a4f91c6c6a4b91eedfb5010fdbc57b71891 Mon Sep 17 00:00:00 2001 From: Brad King Date: Fri, 4 Jan 2013 09:38:22 -0500 Subject: [PATCH 129/170] add_library: Document object library portability suggestion Xcode and VS <= 7.1 will not build targets that have no source files besides $. Suggest in the documentation that projects always add at least one real source file. --- Source/cmAddLibraryCommand.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h index c14456535..e5f27cb51 100644 --- a/Source/cmAddLibraryCommand.h +++ b/Source/cmAddLibraryCommand.h @@ -134,6 +134,10 @@ public: "They may contain custom commands generating such sources, but not " "PRE_BUILD, PRE_LINK, or POST_BUILD commands. " "Object libraries cannot be imported, exported, installed, or linked." + " " + "Some native build systems may not like targets that have only " + "object files, so consider adding at least one real source file " + "to any target that references $." ; } From b2f1700bc7caf12c3f28890ebe183ae09c90d7dc Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 23 Sep 2012 13:16:44 +0200 Subject: [PATCH 130/170] GenEx: Add expressions to specify build- or install-only values This is for specifying INCLUDE_DIRECTORIES relevant to the build-location or the install location for example: set_property(TARGET foo PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$" "$" ) A 'bar' target can then use: set_property(TARGET bar PROPERTY INCLUDE_DIRECTORIES "$" ) and it will work whether foo is in the same project, or an imported target from an installation location, or an imported target from a build location generated by the export() command. Because the generator expressions are only evaluated at build-time, these new expressions are equivalent to the ZeroNode and OneNode. The GeneratorExpression test is split into parts. Some shells can't run the custom command as it is getting too long. --- Source/cmDocumentGeneratorExpressions.h | 6 ++ Source/cmGeneratorExpression.cxx | 88 +++++++++++++++++-- Source/cmGeneratorExpression.h | 4 +- Source/cmGeneratorExpressionEvaluator.cxx | 10 +++ Tests/GeneratorExpression/CMakeLists.txt | 15 +++- Tests/GeneratorExpression/check-common.cmake | 5 ++ .../{check.cmake => check-part1.cmake} | 28 +----- Tests/GeneratorExpression/check-part2.cmake | 26 ++++++ 8 files changed, 144 insertions(+), 38 deletions(-) create mode 100644 Tests/GeneratorExpression/check-common.cmake rename Tests/GeneratorExpression/{check.cmake => check-part1.cmake} (60%) create mode 100644 Tests/GeneratorExpression/check-part2.cmake diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index 445fd0e12..19270120f 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -26,6 +26,12 @@ "strings which contain a '>' for example.\n" \ " $ = A literal ','. Used to compare " \ "strings which contain a ',' for example.\n" \ + " $ = content of \"...\" when the property " \ + "is exported using install(EXPORT), and empty otherwise.\n" \ + " $ = content of \"...\" when the property " \ + "is exported using export(), or when the target is used by another " \ + "target in the same buildsystem. Expands to the empty string " \ + "otherwise.\n" \ " $ = main file (.exe, .so.1.2, .a)\n" \ " $ = file used to link (.a, .lib, .so)\n" \ " $ = file with soname (.so.3)\n" \ diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 3fd4a5f8e..841fbb780 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -123,15 +123,9 @@ cmCompiledGeneratorExpression::~cmCompiledGeneratorExpression() } } -std::string cmGeneratorExpression::Preprocess(const std::string &input, - PreprocessContext context) +//---------------------------------------------------------------------------- +static std::string stripAllGeneratorExpressions(const std::string &input) { - if (context != StripAllGeneratorExpressions) - { - assert(!"cmGeneratorExpression::Preprocess called with invalid args"); - return std::string(); - } - std::string result; std::string::size_type pos = 0; std::string::size_type lastPos = pos; @@ -170,3 +164,81 @@ std::string cmGeneratorExpression::Preprocess(const std::string &input, result += input.substr(lastPos); return result; } + +//---------------------------------------------------------------------------- +static std::string stripExportInterface(const std::string &input, + cmGeneratorExpression::PreprocessContext context) +{ + std::string result; + + std::string::size_type pos = 0; + std::string::size_type lastPos = pos; + while((pos = input.find("$') + { + --nestingLevel; + if (nestingLevel != 0) + { + continue; + } + if(context == cmGeneratorExpression::BuildInterface + && !gotInstallInterface) + { + result += input.substr(pos, c - cStart); + } + else if(context == cmGeneratorExpression::InstallInterface + && gotInstallInterface) + { + result += input.substr(pos, c - cStart); + } + break; + } + } + const std::string::size_type traversed = (c - cStart) + 1; + if (!*c) + { + result += std::string(gotInstallInterface ? "$ Parse(const char* input); enum PreprocessContext { - StripAllGeneratorExpressions + StripAllGeneratorExpressions, + BuildInterface, + InstallInterface }; static std::string Preprocess(const std::string &input, diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 3b7cfc03a..e20e203e6 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -95,6 +95,12 @@ static const struct OneNode : public cmGeneratorExpressionNode } } oneNode; +//---------------------------------------------------------------------------- +static const struct OneNode buildInterfaceNode; + +//---------------------------------------------------------------------------- +static const struct ZeroNode installInterfaceNode; + //---------------------------------------------------------------------------- #define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE) \ static const struct OP ## Node : public cmGeneratorExpressionNode \ @@ -593,6 +599,10 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &commaNode; else if (identifier == "TARGET_PROPERTY") return &targetPropertyNode; + else if (identifier == "BUILD_INTERFACE") + return &buildInterfaceNode; + else if (identifier == "INSTALL_INTERFACE") + return &installInterfaceNode; return 0; } diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 3a92d81b1..db6fb7479 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required (VERSION 2.8.8) project(GeneratorExpression NONE) -add_custom_target(check ALL +add_custom_target(check-part1 ALL COMMAND ${CMAKE_COMMAND} -Dtest_0=$<0:nothing> -Dtest_0_with_comma=$<0:-Wl,--no-undefined> @@ -57,6 +57,13 @@ add_custom_target(check ALL -Dtest_colons_3=$<1:Qt5::Core> -Dtest_colons_4=$<1:C:\\CMake> -Dtest_colons_5=$<1:C:/CMake> + -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part1.cmake + COMMAND ${CMAKE_COMMAND} -E echo "check done (part 1 of 2)" + VERBATIM + ) + +add_custom_target(check-part2 ALL + COMMAND ${CMAKE_COMMAND} -Dtest_incomplete_1=$< -Dtest_incomplete_2=$ -Dtest_incomplete_20=$ -Dtest_incomplete_21=$ - -P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake - COMMAND ${CMAKE_COMMAND} -E echo "check done" + -Dtest_build_interface=$ + -Dtest_install_interface=$ + -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake + COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 2)" VERBATIM ) diff --git a/Tests/GeneratorExpression/check-common.cmake b/Tests/GeneratorExpression/check-common.cmake new file mode 100644 index 000000000..8ffebd740 --- /dev/null +++ b/Tests/GeneratorExpression/check-common.cmake @@ -0,0 +1,5 @@ +macro(check var val) + if(NOT "${${var}}" STREQUAL "${val}") + message(SEND_ERROR "${var} is \"${${var}}\", not \"${val}\"") + endif() +endmacro() diff --git a/Tests/GeneratorExpression/check.cmake b/Tests/GeneratorExpression/check-part1.cmake similarity index 60% rename from Tests/GeneratorExpression/check.cmake rename to Tests/GeneratorExpression/check-part1.cmake index af436de9e..7abfa823f 100644 --- a/Tests/GeneratorExpression/check.cmake +++ b/Tests/GeneratorExpression/check-part1.cmake @@ -1,8 +1,5 @@ -macro(check var val) - if(NOT "${${var}}" STREQUAL "${val}") - message(SEND_ERROR "${var} is \"${${var}}\", not \"${val}\"") - endif() -endmacro() + +include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake) message(STATUS "config=[${config}]") check(test_0 "") @@ -57,24 +54,3 @@ check(test_colons_2 "::") check(test_colons_3 "Qt5::Core") check(test_colons_4 "C:\\\\CMake") check(test_colons_5 "C:/CMake") -check(test_incomplete_1 "$<") -check(test_incomplete_2 "$") -check(test_incomplete_6 "") -check(test_incomplete_7 "$") -check(test_incomplete_15 "$") -check(test_incomplete_20 "$") -check(test_incomplete_21 "$") diff --git a/Tests/GeneratorExpression/check-part2.cmake b/Tests/GeneratorExpression/check-part2.cmake new file mode 100644 index 000000000..149a658e3 --- /dev/null +++ b/Tests/GeneratorExpression/check-part2.cmake @@ -0,0 +1,26 @@ + +include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake) + +check(test_incomplete_1 "$<") +check(test_incomplete_2 "$") +check(test_incomplete_6 "") +check(test_incomplete_7 "$") +check(test_incomplete_15 "$") +check(test_incomplete_20 "$") +check(test_incomplete_21 "$") +check(test_build_interface "build") +check(test_install_interface "") From 77475fe61d0a1bbd562228bf66d5043bd001cb48 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 10 Dec 2012 11:31:59 +0100 Subject: [PATCH 131/170] Allow generator expressions to require literals. --- Source/cmGeneratorExpressionEvaluator.cxx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index e20e203e6..a67cad5b0 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -47,6 +47,8 @@ struct cmGeneratorExpressionNode virtual bool GeneratesContent() const { return true; } + virtual bool RequiresLiteralInput() const { return false; } + virtual bool AcceptsSingleArbitraryContentParameter() const { return false; } @@ -692,6 +694,15 @@ std::string GeneratorExpressionContent::Evaluate( = pit->end(); for ( ; it != end; ++it) { + if (node->RequiresLiteralInput()) + { + if ((*it)->GetType() != cmGeneratorExpressionEvaluator::Text) + { + reportError(context, this->GetOriginalExpression(), + "$<" + identifier + "> expression requires literal input."); + return std::string(); + } + } result += (*it)->Evaluate(context, dagChecker); if (context->HadError) { @@ -699,6 +710,12 @@ std::string GeneratorExpressionContent::Evaluate( } } } + if (node->RequiresLiteralInput()) + { + std::vector parameters; + parameters.push_back(result); + return node->Evaluate(parameters, context, this, dagChecker); + } return result; } From b0c8f73eb62c5651b4a039f95676cae310bcada9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 10 Dec 2012 11:33:23 +0100 Subject: [PATCH 132/170] Add the TARGET_NAME generator expression. It will be used as a preprocessing marker. --- Source/cmDocumentGeneratorExpressions.h | 4 ++++ Source/cmGeneratorExpressionEvaluator.cxx | 24 +++++++++++++++++++ Tests/GeneratorExpression/CMakeLists.txt | 2 ++ Tests/GeneratorExpression/check-part2.cmake | 2 ++ .../BadTargetName-result.txt | 1 + .../BadTargetName-stderr.txt | 8 +++++++ .../GeneratorExpression/BadTargetName.cmake | 3 +++ .../GeneratorExpression/RunCMakeTest.cmake | 1 + 8 files changed, 45 insertions(+) create mode 100644 Tests/RunCMake/GeneratorExpression/BadTargetName-result.txt create mode 100644 Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt create mode 100644 Tests/RunCMake/GeneratorExpression/BadTargetName.cmake diff --git a/Source/cmDocumentGeneratorExpressions.h b/Source/cmDocumentGeneratorExpressions.h index 19270120f..b8889ac20 100644 --- a/Source/cmDocumentGeneratorExpressions.h +++ b/Source/cmDocumentGeneratorExpressions.h @@ -26,6 +26,10 @@ "strings which contain a '>' for example.\n" \ " $ = A literal ','. Used to compare " \ "strings which contain a ',' for example.\n" \ + " $ = Marks ... as being the name of a " \ + "target. This is required if exporting targets to multiple " \ + "dependent export sets. The '...' must be a literal name of a " \ + "target- it may not contain generator expressions.\n" \ " $ = content of \"...\" when the property " \ "is exported using install(EXPORT), and empty otherwise.\n" \ " $ = content of \"...\" when the property " \ diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index a67cad5b0..c8f5b82d1 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -376,6 +376,28 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } } targetPropertyNode; +//---------------------------------------------------------------------------- +static const struct TargetNameNode : public cmGeneratorExpressionNode +{ + TargetNameNode() {} + + virtual bool GeneratesContent() const { return true; } + + virtual bool AcceptsSingleArbitraryContentParameter() const { return true; } + virtual bool RequiresLiteralInput() const { return true; } + + std::string Evaluate(const std::vector ¶meters, + cmGeneratorExpressionContext *, + const GeneratorExpressionContent *, + cmGeneratorExpressionDAGChecker *) const + { + return parameters.front(); + } + + virtual int NumExpectedParameters() const { return 1; } + +} targetNameNode; + //---------------------------------------------------------------------------- template struct TargetFilesystemArtifactResultCreator @@ -601,6 +623,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &commaNode; else if (identifier == "TARGET_PROPERTY") return &targetPropertyNode; + else if (identifier == "TARGET_NAME") + return &targetNameNode; else if (identifier == "BUILD_INTERFACE") return &buildInterfaceNode; else if (identifier == "INSTALL_INTERFACE") diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index db6fb7479..ecbbedf44 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -87,6 +87,8 @@ add_custom_target(check-part2 ALL -Dtest_incomplete_21=$ -Dtest_build_interface=$ -Dtest_install_interface=$ + -Dtest_target_name_1=$ + -Dtest_target_name_2=$ -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 2)" VERBATIM diff --git a/Tests/GeneratorExpression/check-part2.cmake b/Tests/GeneratorExpression/check-part2.cmake index 149a658e3..8855a977c 100644 --- a/Tests/GeneratorExpression/check-part2.cmake +++ b/Tests/GeneratorExpression/check-part2.cmake @@ -24,3 +24,5 @@ check(test_incomplete_20 "$") check(test_incomplete_21 "$") check(test_build_interface "build") check(test_install_interface "") +check(test_target_name_1 "tgt,ok") +check(test_target_name_2 "tgt:ok") diff --git a/Tests/RunCMake/GeneratorExpression/BadTargetName-result.txt b/Tests/RunCMake/GeneratorExpression/BadTargetName-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadTargetName-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt b/Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt new file mode 100644 index 000000000..969393acc --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadTargetName-stderr.txt @@ -0,0 +1,8 @@ +CMake Error at BadTargetName.cmake:1 \(add_custom_target\): + Error evaluating generator expression: + + \$> + + \$ expression requires literal input. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\)$ diff --git a/Tests/RunCMake/GeneratorExpression/BadTargetName.cmake b/Tests/RunCMake/GeneratorExpression/BadTargetName.cmake new file mode 100644 index 000000000..e125cab42 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/BadTargetName.cmake @@ -0,0 +1,3 @@ +add_custom_target(check ALL COMMAND check + $> + VERBATIM) diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake index 992ba792f..8a6967594 100644 --- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake @@ -6,3 +6,4 @@ run_cmake(BadAND) run_cmake(BadNOT) run_cmake(BadStrEqual) run_cmake(BadZero) +run_cmake(BadTargetName) From e04f737c7a3e66c49e2d50813af1fa40a415eff8 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 10 Dec 2012 23:07:09 +0100 Subject: [PATCH 133/170] Add API to extract target names from a genex string. The TARGET_NAME expression, which requires a literal, provides target names. $ also provides target names in the cases where tgt is a literal, so that TARGET_NAME is not needed then in addition. --- Source/cmExportFileGenerator.cxx | 136 +++++++++++++++++++++++++++++++ Source/cmExportFileGenerator.h | 4 + 2 files changed, 140 insertions(+) diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 3f738ccde..2507b72ab 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -124,6 +124,142 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os, this->GenerateImportTargetsConfig(os, config, suffix); } +//---------------------------------------------------------------------------- +void +cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( + std::string &input, + cmTarget* target, + std::vector &missingTargets) +{ + std::string::size_type pos = 0; + std::string::size_type lastPos = pos; + + cmMakefile *mf = target->GetMakefile(); + std::string errorString; + + while((pos = input.find("$", nameStartPos); + std::string::size_type commaPos = input.find(",", nameStartPos); + std::string::size_type nextOpenPos = input.find("$<", nameStartPos); + if (commaPos == input.npos // Implied 'this' target + || closePos == input.npos // Imcomplete expression. + || closePos < commaPos // Implied 'this' target + || nextOpenPos < commaPos) // Non-literal + { + lastPos = nameStartPos; + continue; + } + + const std::string targetName = input.substr(nameStartPos, + commaPos - nameStartPos); + + pos = nameStartPos; // We're not going to replace the entire expression, + // but only the target parameter. + if (cmTarget *tgt = mf->FindTargetToUse(targetName.c_str())) + { + if(tgt->IsImported()) + { + pos += targetName.size(); + } + else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end()) + { + input.replace(pos, targetName.size(), + this->Namespace + targetName); + pos += this->Namespace.size() + targetName.size(); + } + else + { + std::string namespacedTarget; + this->HandleMissingTarget(namespacedTarget, missingTargets, + mf, target, tgt); + if (!namespacedTarget.empty()) + { + input.replace(pos, targetName.size(), namespacedTarget); + pos += namespacedTarget.size(); + } + } + } + else + { + errorString = "$ requires " + "its first parameter to be a reachable target."; + } + lastPos = pos; + if (!errorString.empty()) + { + break; + } + } + if (!errorString.empty()) + { + mf->IssueMessage(cmake::FATAL_ERROR, errorString); + return; + } + + pos = 0; + lastPos = pos; + while((pos = input.find("$", nameStartPos); + if (endPos == input.npos) + { + errorString = "$ expression incomplete"; + } + const std::string targetName = input.substr(nameStartPos, + endPos - nameStartPos); + if(targetName.find("$<", lastPos) != input.npos) + { + errorString = "$ requires its parameter to be a " + "literal."; + } + if (cmTarget *tgt = mf->FindTargetToUse(targetName.c_str())) + { + if(tgt->IsImported()) + { + input.replace(pos, sizeof("$ExportedTargets.find(tgt) != this->ExportedTargets.end()) + { + input.replace(pos, sizeof("$Namespace + targetName); + pos += sizeof("$HandleMissingTarget(namespacedTarget, missingTargets, + mf, target, tgt); + if (!namespacedTarget.empty()) + { + input.replace(pos, sizeof("$IssueMessage(cmake::FATAL_ERROR, errorString); + } +} + //---------------------------------------------------------------------------- void cmExportFileGenerator diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 4a75c52d5..0b89a642d 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -94,6 +94,10 @@ protected: cmTarget* depender, cmTarget* dependee) = 0; + void ResolveTargetsInGeneratorExpressions(std::string &input, + cmTarget* target, + std::vector &missingTargets); + // The namespace in which the exports are placed in the generated file. std::string Namespace; From 0c657dc637ca4da6861102c7306069ad157ec08d Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 10 Dec 2012 23:05:11 +0100 Subject: [PATCH 134/170] Add API to populate INTERFACE properties in exported targets. The INTERFACE properties need to be preprocessed for context (build location or install location) and to extract target names etc. --- Source/cmExportFileGenerator.cxx | 59 ++++++++++++++++++++++++++++++++ Source/cmExportFileGenerator.h | 15 ++++++++ 2 files changed, 74 insertions(+) diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 2507b72ab..2b133be09 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -124,6 +124,65 @@ void cmExportFileGenerator::GenerateImportConfig(std::ostream& os, this->GenerateImportTargetsConfig(os, config, suffix); } +//---------------------------------------------------------------------------- +void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, + const char *outputName, + cmTarget *target, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap &properties, + std::vector &missingTargets) +{ + const char *input = target->GetProperty(propName); + if (input) + { + if (!*input) + { + // Set to empty + properties[outputName] = ""; + return; + } + + std::string prepro = cmGeneratorExpression::Preprocess(input, + preprocessRule); + if (!prepro.empty()) + { + this->ResolveTargetsInGeneratorExpressions(prepro, target, + missingTargets); + properties[outputName] = prepro; + } + } +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::PopulateInterfaceProperty(const char *propName, + cmTarget *target, + cmGeneratorExpression::PreprocessContext preprocessRule, + ImportPropertyMap &properties, + std::vector &missingTargets) +{ + this->PopulateInterfaceProperty(propName, propName, target, preprocessRule, + properties, missingTargets); +} + +//---------------------------------------------------------------------------- +void cmExportFileGenerator::GenerateInterfaceProperties(cmTarget *target, + std::ostream& os, + const ImportPropertyMap &properties) +{ + if (!properties.empty()) + { + std::string targetName = this->Namespace; + targetName += target->GetName(); + os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n"; + for(ImportPropertyMap::const_iterator pi = properties.begin(); + pi != properties.end(); ++pi) + { + os << " " << pi->first << " \"" << pi->second << "\"\n"; + } + os << ")\n\n"; + } +} + //---------------------------------------------------------------------------- void cmExportFileGenerator::ResolveTargetsInGeneratorExpressions( diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 0b89a642d..7c58ad8b4 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -13,6 +13,7 @@ #define cmExportFileGenerator_h #include "cmCommand.h" +#include "cmGeneratorExpression.h" /** \class cmExportFileGenerator * \brief Generate a file exporting targets from a build or install tree. @@ -93,6 +94,13 @@ protected: cmMakefile* mf, cmTarget* depender, cmTarget* dependee) = 0; + void PopulateInterfaceProperty(const char *, + cmTarget *target, + cmGeneratorExpression::PreprocessContext, + ImportPropertyMap &properties, + std::vector &missingTargets); + void GenerateInterfaceProperties(cmTarget *target, std::ostream& os, + const ImportPropertyMap &properties); void ResolveTargetsInGeneratorExpressions(std::string &input, cmTarget* target, @@ -113,6 +121,13 @@ protected: // The set of targets included in the export. std::set ExportedTargets; + +private: + void PopulateInterfaceProperty(const char *, const char *, + cmTarget *target, + cmGeneratorExpression::PreprocessContext, + ImportPropertyMap &properties, + std::vector &missingTargets); }; #endif From 26def1771dfbf502129212c9e728e34860477fac Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 6 Nov 2012 16:06:31 +0100 Subject: [PATCH 135/170] Make all relevant targets available in the genex context. The current node being evaluated transitively in the generator expression must be available to resolve mapped configs. --- Source/cmGeneratorExpression.cxx | 20 ++++++++++++++++++-- Source/cmGeneratorExpression.h | 7 ++++++- Source/cmGeneratorExpressionDAGChecker.cxx | 2 +- Source/cmGeneratorExpressionEvaluator.cxx | 2 +- Source/cmGeneratorExpressionEvaluator.h | 4 +++- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 841fbb780..6d003e10f 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -53,7 +53,22 @@ cmGeneratorExpression::~cmGeneratorExpression() //---------------------------------------------------------------------------- const char *cmCompiledGeneratorExpression::Evaluate( cmMakefile* mf, const char* config, bool quiet, - cmTarget *target, + cmTarget *headTarget, + cmGeneratorExpressionDAGChecker *dagChecker) const +{ + return this->Evaluate(mf, + config, + quiet, + headTarget, + headTarget, + dagChecker); +} + +//---------------------------------------------------------------------------- +const char *cmCompiledGeneratorExpression::Evaluate( + cmMakefile* mf, const char* config, bool quiet, + cmTarget *headTarget, + cmTarget *currentTarget, cmGeneratorExpressionDAGChecker *dagChecker) const { if (!this->NeedsParsing) @@ -73,7 +88,8 @@ const char *cmCompiledGeneratorExpression::Evaluate( context.Config = config; context.Quiet = quiet; context.HadError = false; - context.Target = target; + context.HeadTarget = headTarget; + context.CurrentTarget = currentTarget ? currentTarget : headTarget; context.Backtrace = this->Backtrace; for ( ; it != end; ++it) diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index 99056a53a..dcdfefbad 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -71,8 +71,13 @@ class cmCompiledGeneratorExpression public: const char* Evaluate(cmMakefile* mf, const char* config, bool quiet = false, - cmTarget *target = 0, + cmTarget *headTarget = 0, + cmTarget *currentTarget = 0, cmGeneratorExpressionDAGChecker *dagChecker = 0) const; + const char* Evaluate(cmMakefile* mf, const char* config, + bool quiet, + cmTarget *headTarget, + cmGeneratorExpressionDAGChecker *dagChecker) const; /** Get set of targets found during evaluations. */ std::set const& GetTargets() const diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index bfb0ddf92..4a9fc28dc 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -57,7 +57,7 @@ void cmGeneratorExpressionDAGChecker::reportError( e << "Error evaluating generator expression:\n" << " " << expr << "\n" << "Self reference on target \"" - << context->Target->GetName() << "\".\n"; + << context->HeadTarget->GetName() << "\".\n"; context->Makefile->GetCMakeInstance() ->IssueMessage(cmake::FATAL_ERROR, e.str().c_str(), parent->Backtrace); diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index c8f5b82d1..4a7a034c0 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -297,7 +297,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode cmsys::RegularExpression propertyNameValidator; propertyNameValidator.compile("^[A-Za-z0-9_]+$"); - cmTarget* target = context->Target; + cmTarget* target = context->HeadTarget; std::string propertyName = *parameters.begin(); if (parameters.size() == 2) { diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index d904b027f..59804ff95 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -26,7 +26,9 @@ struct cmGeneratorExpressionContext std::set Targets; cmMakefile *Makefile; const char *Config; - cmTarget *Target; + cmTarget *HeadTarget; // The target whose property is being evaluated. + cmTarget *CurrentTarget; // The dependent of HeadTarget which appears + // directly or indirectly in the property. bool Quiet; bool HadError; }; From d0f950fdba88ac08d0e25e340fe558eba008810e Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 23 Dec 2012 11:20:37 +0100 Subject: [PATCH 136/170] Use mapped config properties to evaluate $ --- Source/cmGeneratorExpressionEvaluator.cxx | 20 +- Source/cmTarget.cxx | 236 ++++++++++++---------- Source/cmTarget.h | 5 + 3 files changed, 147 insertions(+), 114 deletions(-) diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 4a7a034c0..8b8b86084 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -265,8 +265,24 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode return parameters.front().empty() ? "1" : "0"; } - return cmsysString_strcasecmp(parameters.begin()->c_str(), - context->Config) == 0 ? "1" : "0"; + if (cmsysString_strcasecmp(parameters.begin()->c_str(), + context->Config) == 0) + { + return "1"; + } + + if (context->CurrentTarget + && context->CurrentTarget->IsImported()) + { + const char* loc = 0; + const char* imp = 0; + std::string suffix; + return context->CurrentTarget->GetMappedConfig(context->Config, + &loc, + &imp, + suffix) ? "1" : "0"; + } + return "0"; } } configurationTestNode; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 58fab80cc..d60979c0a 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -4365,6 +4365,128 @@ cmTarget::GetImportInfo(const char* config) return &i->second; } +bool cmTarget::GetMappedConfig(std::string const& desired_config, + const char** loc, + const char** imp, + std::string& suffix) +{ + // Track the configuration-specific property suffix. + suffix = "_"; + suffix += desired_config; + + std::vector mappedConfigs; + { + std::string mapProp = "MAP_IMPORTED_CONFIG_"; + mapProp += desired_config; + if(const char* mapValue = this->GetProperty(mapProp.c_str())) + { + cmSystemTools::ExpandListArgument(mapValue, mappedConfigs); + } + } + + // If we needed to find one of the mapped configurations but did not + // On a DLL platform there may be only IMPORTED_IMPLIB for a shared + // library or an executable with exports. + bool allowImp = this->HasImportLibrary(); + + // If a mapping was found, check its configurations. + for(std::vector::const_iterator mci = mappedConfigs.begin(); + !*loc && !*imp && mci != mappedConfigs.end(); ++mci) + { + // Look for this configuration. + std::string mcUpper = cmSystemTools::UpperCase(mci->c_str()); + std::string locProp = "IMPORTED_LOCATION_"; + locProp += mcUpper; + *loc = this->GetProperty(locProp.c_str()); + if(allowImp) + { + std::string impProp = "IMPORTED_IMPLIB_"; + impProp += mcUpper; + *imp = this->GetProperty(impProp.c_str()); + } + + // If it was found, use it for all properties below. + if(*loc || *imp) + { + suffix = "_"; + suffix += mcUpper; + } + } + + // If we needed to find one of the mapped configurations but did not + // then the target is not found. The project does not want any + // other configuration. + if(!mappedConfigs.empty() && !*loc && !*imp) + { + return false; + } + + // If we have not yet found it then there are no mapped + // configurations. Look for an exact-match. + if(!*loc && !*imp) + { + std::string locProp = "IMPORTED_LOCATION"; + locProp += suffix; + *loc = this->GetProperty(locProp.c_str()); + if(allowImp) + { + std::string impProp = "IMPORTED_IMPLIB"; + impProp += suffix; + *imp = this->GetProperty(impProp.c_str()); + } + } + + // If we have not yet found it then there are no mapped + // configurations and no exact match. + if(!*loc && !*imp) + { + // The suffix computed above is not useful. + suffix = ""; + + // Look for a configuration-less location. This may be set by + // manually-written code. + *loc = this->GetProperty("IMPORTED_LOCATION"); + if(allowImp) + { + *imp = this->GetProperty("IMPORTED_IMPLIB"); + } + } + + // If we have not yet found it then the project is willing to try + // any available configuration. + if(!*loc && !*imp) + { + std::vector availableConfigs; + if(const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) + { + cmSystemTools::ExpandListArgument(iconfigs, availableConfigs); + } + for(std::vector::const_iterator + aci = availableConfigs.begin(); + !*loc && !*imp && aci != availableConfigs.end(); ++aci) + { + suffix = "_"; + suffix += cmSystemTools::UpperCase(*aci); + std::string locProp = "IMPORTED_LOCATION"; + locProp += suffix; + *loc = this->GetProperty(locProp.c_str()); + if(allowImp) + { + std::string impProp = "IMPORTED_IMPLIB"; + impProp += suffix; + *imp = this->GetProperty(impProp.c_str()); + } + } + } + // If we have not yet found it then the target is not available. + if(!*loc && !*imp) + { + return false; + } + + return true; +} + //---------------------------------------------------------------------------- void cmTarget::ComputeImportInfo(std::string const& desired_config, ImportInfo& info) @@ -4376,120 +4498,10 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config, // Initialize members. info.NoSOName = false; - // Track the configuration-specific property suffix. - std::string suffix = "_"; - suffix += desired_config; - - // On a DLL platform there may be only IMPORTED_IMPLIB for a shared - // library or an executable with exports. - bool allowImp = this->HasImportLibrary(); - - // Look for a mapping from the current project's configuration to - // the imported project's configuration. - std::vector mappedConfigs; - { - std::string mapProp = "MAP_IMPORTED_CONFIG_"; - mapProp += desired_config; - if(const char* mapValue = this->GetProperty(mapProp.c_str())) - { - cmSystemTools::ExpandListArgument(mapValue, mappedConfigs); - } - } - - // If a mapping was found, check its configurations. const char* loc = 0; const char* imp = 0; - for(std::vector::const_iterator mci = mappedConfigs.begin(); - !loc && !imp && mci != mappedConfigs.end(); ++mci) - { - // Look for this configuration. - std::string mcUpper = cmSystemTools::UpperCase(mci->c_str()); - std::string locProp = "IMPORTED_LOCATION_"; - locProp += mcUpper; - loc = this->GetProperty(locProp.c_str()); - if(allowImp) - { - std::string impProp = "IMPORTED_IMPLIB_"; - impProp += mcUpper; - imp = this->GetProperty(impProp.c_str()); - } - - // If it was found, use it for all properties below. - if(loc || imp) - { - suffix = "_"; - suffix += mcUpper; - } - } - - // If we needed to find one of the mapped configurations but did not - // then the target is not found. The project does not want any - // other configuration. - if(!mappedConfigs.empty() && !loc && !imp) - { - return; - } - - // If we have not yet found it then there are no mapped - // configurations. Look for an exact-match. - if(!loc && !imp) - { - std::string locProp = "IMPORTED_LOCATION"; - locProp += suffix; - loc = this->GetProperty(locProp.c_str()); - if(allowImp) - { - std::string impProp = "IMPORTED_IMPLIB"; - impProp += suffix; - imp = this->GetProperty(impProp.c_str()); - } - } - - // If we have not yet found it then there are no mapped - // configurations and no exact match. - if(!loc && !imp) - { - // The suffix computed above is not useful. - suffix = ""; - - // Look for a configuration-less location. This may be set by - // manually-written code. - loc = this->GetProperty("IMPORTED_LOCATION"); - if(allowImp) - { - imp = this->GetProperty("IMPORTED_IMPLIB"); - } - } - - // If we have not yet found it then the project is willing to try - // any available configuration. - if(!loc && !imp) - { - std::vector availableConfigs; - if(const char* iconfigs = this->GetProperty("IMPORTED_CONFIGURATIONS")) - { - cmSystemTools::ExpandListArgument(iconfigs, availableConfigs); - } - for(std::vector::const_iterator - aci = availableConfigs.begin(); - !loc && !imp && aci != availableConfigs.end(); ++aci) - { - suffix = "_"; - suffix += cmSystemTools::UpperCase(*aci); - std::string locProp = "IMPORTED_LOCATION"; - locProp += suffix; - loc = this->GetProperty(locProp.c_str()); - if(allowImp) - { - std::string impProp = "IMPORTED_IMPLIB"; - impProp += suffix; - imp = this->GetProperty(impProp.c_str()); - } - } - } - - // If we have not yet found it then the target is not available. - if(!loc && !imp) + std::string suffix; + if (!this->GetMappedConfig(desired_config, &loc, &imp, suffix)) { return; } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 3f3605043..52d5ca611 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -404,6 +404,11 @@ public: // Get the properties cmPropertyMap &GetProperties() { return this->Properties; }; + bool GetMappedConfig(std::string const& desired_config, + const char** loc, + const char** imp, + std::string& suffix); + // Define the properties static void DefineProperties(cmake *cm); From c67b8124f735e7f96567a276e16969607b300e43 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 21 Dec 2012 15:49:19 +0100 Subject: [PATCH 137/170] Make cycles in target properties ignored, not an error. Constructs such as these are an error as they are direct self-references: set_property(TARGET foo APPEND PROPERTY INCLUDE_DIRECTORIES $) set_property(TARGET foo APPEND PROPERTY INCLUDE_DIRECTORIES $) However, this is an indirect self-reference in a cycle, and not an error: set_property(TARGET foo APPEND PROPERTY INCLUDE_DIRECTORIES $) set_property(TARGET bar APPEND PROPERTY INCLUDE_DIRECTORIES $) --- Source/cmGeneratorExpressionDAGChecker.cxx | 16 +++++++++------- Source/cmGeneratorExpressionDAGChecker.h | 12 +++++++++--- Source/cmGeneratorExpressionEvaluator.cxx | 8 +++++++- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 4a9fc28dc..2e5b5ae11 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -24,13 +24,14 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( : Parent(parent), Target(target), Property(property), Content(content), Backtrace(backtrace) { - this->IsDAG = this->isDAG(); + this->CheckResult = this->checkGraph(); } //---------------------------------------------------------------------------- -bool cmGeneratorExpressionDAGChecker::check() const +cmGeneratorExpressionDAGChecker::Result +cmGeneratorExpressionDAGChecker::check() const { - return this->IsDAG; + return this->CheckResult; } //---------------------------------------------------------------------------- @@ -38,7 +39,7 @@ void cmGeneratorExpressionDAGChecker::reportError( cmGeneratorExpressionContext *context, const std::string &expr) { - if (this->IsDAG) + if (this->CheckResult == DAG) { return; } @@ -91,16 +92,17 @@ void cmGeneratorExpressionDAGChecker::reportError( } //---------------------------------------------------------------------------- -bool cmGeneratorExpressionDAGChecker::isDAG() const +cmGeneratorExpressionDAGChecker::Result +cmGeneratorExpressionDAGChecker::checkGraph() const { const cmGeneratorExpressionDAGChecker *parent = this->Parent; while (parent) { if (this->Target == parent->Target && this->Property == parent->Property) { - return false; + return parent->Parent ? CYCLIC_REFERENCE : SELF_REFERENCE; } parent = parent->Parent; } - return true; + return DAG; } diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index ffc84f8fd..48f26ed38 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -25,12 +25,18 @@ struct cmGeneratorExpressionDAGChecker const GeneratorExpressionContent *content, cmGeneratorExpressionDAGChecker *parent); - bool check() const; + enum Result { + DAG, + SELF_REFERENCE, + CYCLIC_REFERENCE + }; + + Result check() const; void reportError(cmGeneratorExpressionContext *context, const std::string &expr); private: - bool isDAG() const; + Result checkGraph() const; private: const cmGeneratorExpressionDAGChecker * const Parent; @@ -38,7 +44,7 @@ private: const std::string Property; const GeneratorExpressionContent * const Content; const cmListFileBacktrace Backtrace; - bool IsDAG; + Result CheckResult; }; #endif diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 8b8b86084..4b44ebee3 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -381,10 +381,16 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode content, dagCheckerParent); - if (!dagChecker.check()) + switch (dagChecker.check()) { + case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: dagChecker.reportError(context, content->GetOriginalExpression()); return std::string(); + case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: + // No error. We just skip cyclic references. + return std::string(); + case cmGeneratorExpressionDAGChecker::DAG: + break; } const char *prop = target->GetProperty(propertyName.c_str()); From f5b1980fb27fa902d37856ec3e22daddfeb9d52f Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 30 Dec 2012 22:06:12 +0100 Subject: [PATCH 138/170] Populate the ExportedTargets member early in GenerateMainFile The member variable is checked to determine whether to call HandleMissingTarget(). As that could be called during the loop in the comming commits, ensure that it contains all targets being exported. --- Source/cmExportBuildFileGenerator.cxx | 25 ++++++++++++++----------- Source/cmExportInstallFileGenerator.cxx | 25 ++++++++++++++----------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index cd6a7ab9e..3e9a9fd7f 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -22,6 +22,7 @@ cmExportBuildFileGenerator::cmExportBuildFileGenerator() //---------------------------------------------------------------------------- bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) { + std::vector allTargets; { std::string expectedTargets; std::string sep; @@ -31,20 +32,10 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) { expectedTargets += sep + this->Namespace + (*tei)->GetName(); sep = " "; - } - - this->GenerateExpectedTargetsCode(os, expectedTargets); - } - - // Create all the imported targets. - for(std::vector::const_iterator - tei = this->Exports->begin(); - tei != this->Exports->end(); ++tei) - { cmTarget* te = *tei; if(this->ExportedTargets.insert(te).second) { - this->GenerateImportTargetCode(os, te); + allTargets.push_back(te); } else { @@ -58,6 +49,18 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) } } + this->GenerateExpectedTargetsCode(os, expectedTargets); + } + + // Create all the imported targets. + for(std::vector::const_iterator + tei = allTargets.begin(); + tei != allTargets.end(); ++tei) + { + cmTarget* te = *tei; + this->GenerateImportTargetCode(os, te); + } + // Generate import file content for each configuration. for(std::vector::const_iterator ci = this->Configurations.begin(); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 6ba7d9fc2..2b7937e53 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -39,6 +39,7 @@ std::string cmExportInstallFileGenerator::GetConfigImportFileGlob() //---------------------------------------------------------------------------- bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { + std::vector allTargets; { std::string expectedTargets; std::string sep; @@ -48,20 +49,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { expectedTargets += sep + this->Namespace + (*tei)->Target->GetName(); sep = " "; - } - - this->GenerateExpectedTargetsCode(os, expectedTargets); - } - - // Create all the imported targets. - for(std::vector::const_iterator - tei = this->IEGen->GetExportSet()->GetTargetExports()->begin(); - tei != this->IEGen->GetExportSet()->GetTargetExports()->end(); ++tei) - { cmTargetExport const* te = *tei; if(this->ExportedTargets.insert(te->Target).second) { - this->GenerateImportTargetCode(os, te->Target); + allTargets.push_back(te->Target); } else { @@ -75,6 +66,18 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) } } + this->GenerateExpectedTargetsCode(os, expectedTargets); + } + + // Create all the imported targets. + for(std::vector::const_iterator + tei = allTargets.begin(); + tei != allTargets.end(); ++tei) + { + cmTarget* te = *tei; + this->GenerateImportTargetCode(os, te); + } + // 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" From 894f52f32d96ae92df0ba3dac2a70fe9c87e818d Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 23 Sep 2012 13:45:17 +0200 Subject: [PATCH 139/170] Handle INTERFACE properties transitively for includes and defines. Contextually, the behavior is as if the properties content from another target is included in the string and then the result is evaluated. --- Source/cmExportBuildFileGenerator.cxx | 15 ++++ Source/cmExportInstallFileGenerator.cxx | 17 +++++ Source/cmGeneratorExpressionEvaluator.cxx | 30 +++++++- Source/cmTarget.cxx | 22 ++++++ Tests/ExportImport/Export/CMakeLists.txt | 75 ++++++++++++++++++- Tests/ExportImport/Export/testLibDepends.c | 16 ++++ Tests/ExportImport/Import/A/CMakeLists.txt | 15 ++++ Tests/ExportImport/Import/A/deps_iface.cpp | 24 ++++++ .../TargetIncludeDirectories/CMakeLists.txt | 31 ++++++++ 9 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 Tests/ExportImport/Import/A/deps_iface.cpp diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx index 3e9a9fd7f..9533319e9 100644 --- a/Source/cmExportBuildFileGenerator.cxx +++ b/Source/cmExportBuildFileGenerator.cxx @@ -52,6 +52,8 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) this->GenerateExpectedTargetsCode(os, expectedTargets); } + std::vector missingTargets; + // Create all the imported targets. for(std::vector::const_iterator tei = allTargets.begin(); @@ -59,8 +61,21 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os) { cmTarget* te = *tei; this->GenerateImportTargetCode(os, te); + + ImportPropertyMap properties; + + this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", te, + cmGeneratorExpression::BuildInterface, + properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", te, + cmGeneratorExpression::BuildInterface, + properties, missingTargets); + + this->GenerateInterfaceProperties(te, os, properties); } + this->GenerateMissingTargetsCheckCode(os, missingTargets); + // Generate import file content for each configuration. for(std::vector::const_iterator ci = this->Configurations.begin(); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 2b7937e53..bc953c9c1 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -69,6 +69,8 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) this->GenerateExpectedTargetsCode(os, expectedTargets); } + std::vector missingTargets; + // Create all the imported targets. for(std::vector::const_iterator tei = allTargets.begin(); @@ -76,8 +78,23 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) { cmTarget* te = *tei; this->GenerateImportTargetCode(os, te); + + ImportPropertyMap properties; + + this->PopulateInterfaceProperty("INTERFACE_INCLUDE_DIRECTORIES", + te, + cmGeneratorExpression::InstallInterface, + properties, missingTargets); + this->PopulateInterfaceProperty("INTERFACE_COMPILE_DEFINITIONS", + te, + cmGeneratorExpression::InstallInterface, + properties, missingTargets); + + this->GenerateInterfaceProperties(te, os, properties); } + this->GenerateMissingTargetsCheckCode(os, missingTargets); + // Now load per-configuration properties for them. os << "# Load information for each installed configuration.\n" << "GET_FILENAME_COMPONENT(_DIR \"${CMAKE_CURRENT_LIST_FILE}\" PATH)\n" diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 4b44ebee3..b7ce15578 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -286,6 +286,13 @@ static const struct ConfigurationTestNode : public cmGeneratorExpressionNode } } configurationTestNode; + +//---------------------------------------------------------------------------- +static const char* targetPropertyTransitiveWhitelist[] = { + "INTERFACE_INCLUDE_DIRECTORIES" + , "INTERFACE_COMPILE_DEFINITIONS" +}; + //---------------------------------------------------------------------------- static const struct TargetPropertyNode : public cmGeneratorExpressionNode { @@ -394,7 +401,28 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } const char *prop = target->GetProperty(propertyName.c_str()); - return prop ? prop : ""; + if (!prop) + { + return std::string(); + } + + for (size_t i = 0; + i < (sizeof(targetPropertyTransitiveWhitelist) / + sizeof(*targetPropertyTransitiveWhitelist)); + ++i) + { + if (targetPropertyTransitiveWhitelist[i] == propertyName) + { + cmGeneratorExpression ge(context->Backtrace); + return ge.Parse(prop)->Evaluate(context->Makefile, + context->Config, + context->Quiet, + context->HeadTarget, + target, + &dagChecker); + } + } + return prop; } } targetPropertyNode; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d60979c0a..ca53a39d2 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -719,6 +719,28 @@ void cmTarget::DefineProperties(cmake *cm) "If set, this property completely overrides the generic property " "for the named configuration."); + cm->DefineProperty + ("INTERFACE_INCLUDE_DIRECTORIES", cmProperty::TARGET, + "List of public include directories for a library.", + "Targets may populate this property to publish the include directories " + "required to compile against the headers for the target. Consuming " + "targets can add entries to their own INCLUDE_DIRECTORIES property such " + "as $ to use the " + "include directories specified in the interface of 'foo'." + "\n" + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS); + + cm->DefineProperty + ("INTERFACE_COMPILE_DEFINITIONS", cmProperty::TARGET, + "List of public compile definitions for a library.", + "Targets may populate this property to publish the compile definitions " + "required to compile against the headers for the target. Consuming " + "targets can add entries to their own COMPILE_DEFINITIONS property such " + "as $ to use the " + "compile definitions specified in the interface of 'foo'." + "\n" + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS); + cm->DefineProperty ("LINK_INTERFACE_MULTIPLICITY", cmProperty::TARGET, "Repetition count for STATIC libraries with cyclic dependencies.", diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt index e19ab88de..569845a71 100644 --- a/Tests/ExportImport/Export/CMakeLists.txt +++ b/Tests/ExportImport/Export/CMakeLists.txt @@ -90,9 +90,82 @@ set_property(TARGET testLibCycleA PROPERTY LINK_INTERFACE_MULTIPLICITY 3) # Test exporting dependent libraries into different exports add_library(testLibRequired testLibRequired.c) add_library(testLibDepends testLibDepends.c) +set_property(TARGET testLibDepends APPEND PROPERTY + INCLUDE_DIRECTORIES + $ +) +set_property(TARGET testLibDepends APPEND PROPERTY + COMPILE_DEFINITIONS + $ +) +set_property(TARGET testLibDepends APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES + $ +) +set_property(TARGET testLibDepends APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS + $ +) target_link_libraries(testLibDepends testLibRequired) -install(TARGETS testLibRequired EXPORT RequiredExp DESTINATION lib ) +macro(add_include_lib _libName) + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c" "// no content\n") + add_library(${_libName} "${CMAKE_CURRENT_BINARY_DIR}/${_libName}.c") + file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_libName}") + set_property(TARGET ${_libName} APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/${_libName}") + if (NOT "${ARGV1}" STREQUAL "NO_HEADER") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_libName}/${_libName}.h" "// no content\n") + endif() +endmacro() + +add_include_lib(testLibIncludeRequired1) +add_include_lib(testLibIncludeRequired2) +add_include_lib(testLibIncludeRequired3 NO_HEADER) +# Generate testLibIncludeRequired4 in the testLibIncludeRequired3 directory +# with an error. If the includes from testLibIncludeRequired3 appear first, +# the error will be hit. +# Below, the '3' library appears before the '4' library +# but we are testing that the INSTALL_INTERFACE causes it not to be used +# at build time. +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired3/testLibIncludeRequired4.h" "#error Should not be included\n") +add_include_lib(testLibIncludeRequired4) +add_include_lib(testLibIncludeRequired5 NO_HEADER) +# Generate testLibIncludeRequired6 in the testLibIncludeRequired5 directory +# with an error. If the includes from testLibIncludeRequired5 appear first, +# the error will be hit. +# Below, the '5' library appears before the '6' library +# but we are testing that when the installed IMPORTED target is used, from +# the Import side of this unit test, the '6' include from the '5' directory +# will not be used because it is in the BUILD_INTERFACE only. +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/testLibIncludeRequired5/testLibIncludeRequired6.h" "#error Should not be included\n") +add_include_lib(testLibIncludeRequired6) + +set_property(TARGET testLibRequired APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES + $ + $>,INTERFACE_INCLUDE_DIRECTORIES> + $> + $> + $> + $> +) + +set_property(TARGET testLibRequired APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS + testLibRequired_IFACE_DEFINE + $ + $ +) + +install(TARGETS testLibRequired + testLibIncludeRequired1 + testLibIncludeRequired2 + testLibIncludeRequired3 + testLibIncludeRequired4 + testLibIncludeRequired5 + testLibIncludeRequired6 + EXPORT RequiredExp DESTINATION lib ) install(EXPORT RequiredExp NAMESPACE Req:: FILE testLibRequiredConfig.cmake DESTINATION lib/cmake/testLibRequired) install(TARGETS testLibDepends EXPORT DependsExp DESTINATION lib ) diff --git a/Tests/ExportImport/Export/testLibDepends.c b/Tests/ExportImport/Export/testLibDepends.c index 2849b336d..fb5a002e0 100644 --- a/Tests/ExportImport/Export/testLibDepends.c +++ b/Tests/ExportImport/Export/testLibDepends.c @@ -1,4 +1,20 @@ +#include "testLibIncludeRequired1.h" +#include "testLibIncludeRequired2.h" +#include "testLibIncludeRequired4.h" + +#ifndef testLibRequired_IFACE_DEFINE +#error Expected testLibRequired_IFACE_DEFINE +#endif + +#ifndef BuildOnly_DEFINE +#error Expected BuildOnly_DEFINE +#endif + +#ifdef InstallOnly_DEFINE +#error Unexpected InstallOnly_DEFINE +#endif + extern int testLibRequired(void); int testLibDepends(void) { return testLibRequired(); } diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt index 884179225..b77562ee6 100644 --- a/Tests/ExportImport/Import/A/CMakeLists.txt +++ b/Tests/ExportImport/Import/A/CMakeLists.txt @@ -152,3 +152,18 @@ check_function_exists(testLib1 HAVE_TESTLIB1_FUNCTION) if (NOT HAVE_TESTLIB1_FUNCTION) message(SEND_ERROR "Using imported target testLib2 in check_function_exists() failed !") endif() + +#----------------------------------------------------------------------------- +# Test that dependent imported targets have usable +# INTERFACE_COMPILE_DEFINITIONS and INTERFACE_INCLUDE_DIRECTORIES + +add_library(deps_iface deps_iface.cpp) +target_link_libraries(deps_iface testLibsDepends) +set_property(TARGET deps_iface APPEND PROPERTY + COMPILE_DEFINITIONS + $ +) +set_property(TARGET deps_iface APPEND PROPERTY + INCLUDE_DIRECTORIES + $ +) diff --git a/Tests/ExportImport/Import/A/deps_iface.cpp b/Tests/ExportImport/Import/A/deps_iface.cpp new file mode 100644 index 000000000..7190b9242 --- /dev/null +++ b/Tests/ExportImport/Import/A/deps_iface.cpp @@ -0,0 +1,24 @@ + +#include "testLibIncludeRequired1.h" +#include "testLibIncludeRequired2.h" +#include "testLibIncludeRequired6.h" + +#ifndef testLibRequired_IFACE_DEFINE +#error Expected testLibRequired_IFACE_DEFINE +#endif + +#ifdef BuildOnly_DEFINE +#error Unexpected BuildOnly_DEFINE +#endif + +#ifndef InstallOnly_DEFINE +#error Expected InstallOnly_DEFINE +#endif + +extern int testLibDepends(void); + + +int main(int,char **) +{ + return testLibDepends(); +} diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt index 7cb1b42e0..63a54925a 100644 --- a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt @@ -37,6 +37,37 @@ include_directories("sing$<1:/ting>") include_directories("$<1:${CMAKE_CURRENT_BINARY_DIR}/arguments;${CMAKE_CURRENT_BINARY_DIR}/list>") +create_header(fee) +create_header(fiy) +create_header(foh) +create_header(fum) + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib1.cpp" "#include \"fee.h\"\n") +add_library(lib1 "${CMAKE_CURRENT_BINARY_DIR}/lib1.cpp") +set_property(TARGET lib1 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fee") +set_property(TARGET lib1 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fiy") +set_property(TARGET lib1 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<$,EXECUTABLE>:${CMAKE_CURRENT_BINARY_DIR}/foh>") + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib2.cpp" "#include \"fiy.h\"\n") +add_library(lib2 "${CMAKE_CURRENT_BINARY_DIR}/lib2.cpp") +set_property(TARGET lib2 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fum;$") +set_property(TARGET lib2 APPEND PROPERTY INCLUDE_DIRECTORIES "$") + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/main3.cpp" "#include \"fiy.h\"\n#include \"foh.h\"\n#include \"fum.h\"\nint main(int,char**) { return 0; }\n") +add_executable(exe3 "${CMAKE_CURRENT_BINARY_DIR}/main3.cpp") +set_property(TARGET exe3 APPEND PROPERTY INCLUDE_DIRECTORIES "$") + +# Test cycles +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib3.cpp" "#include \"fiy.h\"\n#include \"foh.h\"\n") +add_library(lib3 "${CMAKE_CURRENT_BINARY_DIR}/lib3.cpp") +set_property(TARGET lib3 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fiy;$") +set_property(TARGET lib3 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/fiy;$") + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/lib4.cpp" "#include \"fiy.h\"\n#include \"foh.h\"\n") +add_library(lib4 "${CMAKE_CURRENT_BINARY_DIR}/lib4.cpp") +set_property(TARGET lib4 APPEND PROPERTY INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foh;$") +set_property(TARGET lib4 APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/foh;$") + add_library(somelib::withcolons UNKNOWN IMPORTED) set_property(TARGET somelib::withcolons PROPERTY IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/target") set_property(TARGET somelib::withcolons PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/target") From 0c1f291a27e3916a62c66d48b37b21e0e5d3ce6e Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sat, 5 Jan 2013 00:01:14 -0500 Subject: [PATCH 140/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 370c76bc8..17b2b25eb 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 20130104) +set(CMake_VERSION_TWEAK 20130105) #set(CMake_VERSION_RC 1) From 76c44309717adf25ebe5892adc3b4181766868a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20K=C3=BCmmel?= Date: Sat, 5 Jan 2013 08:29:58 +0100 Subject: [PATCH 141/170] Ninja: fix building from Codeblocks GUI Many thx to Chuck Frayman BUG: 13652 --- Source/cmExtraCodeBlocksGenerator.cxx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/cmExtraCodeBlocksGenerator.cxx b/Source/cmExtraCodeBlocksGenerator.cxx index 25b13e52e..0cf9cbbf2 100644 --- a/Source/cmExtraCodeBlocksGenerator.cxx +++ b/Source/cmExtraCodeBlocksGenerator.cxx @@ -811,6 +811,11 @@ std::string cmExtraCodeBlocksGenerator::BuildMakeCommand( command += " VERBOSE=1 "; command += target; } + else if (strcmp(this->GlobalGenerator->GetName(), "Ninja")==0) + { + command += " -v "; + command += target; + } else { std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile); From 427ef824988a926fc7c7e948345929fcd359d6fb Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Sun, 6 Jan 2013 00:01:29 -0500 Subject: [PATCH 142/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 17b2b25eb..69de3dd43 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 20130105) +set(CMake_VERSION_TWEAK 20130106) #set(CMake_VERSION_RC 1) From c7550d5ef12d8185fad93d581ebd52474ae3d1b0 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Mon, 7 Jan 2013 00:01:16 -0500 Subject: [PATCH 143/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 69de3dd43..a18fcf042 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 20130106) +set(CMake_VERSION_TWEAK 20130107) #set(CMake_VERSION_RC 1) From 09a0da77891bae3820b48c44c48bef3837b0a6e2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 7 Jan 2013 10:31:07 -0500 Subject: [PATCH 144/170] Revert "load_command: Deprecate and document pending removal" This reverts commit d2d43986e7f5013465473a71c393fc3897cecbac. We will add a policy to remove the command more gracefully. --- Source/cmLoadCommandCommand.cxx | 4 ---- Source/cmLoadCommandCommand.h | 15 +-------------- Tests/RunCMake/CMakeLists.txt | 1 - Tests/RunCMake/load_command/CMakeLists.txt | 3 --- .../load_command/LoadCommandDeprecated-stderr.txt | 6 ------ .../load_command/LoadCommandDeprecated.cmake | 1 - Tests/RunCMake/load_command/RunCMakeTest.cmake | 3 --- 7 files changed, 1 insertion(+), 32 deletions(-) delete mode 100644 Tests/RunCMake/load_command/CMakeLists.txt delete mode 100644 Tests/RunCMake/load_command/LoadCommandDeprecated-stderr.txt delete mode 100644 Tests/RunCMake/load_command/LoadCommandDeprecated.cmake delete mode 100644 Tests/RunCMake/load_command/RunCMakeTest.cmake diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx index 181b922b1..b2acf06ad 100644 --- a/Source/cmLoadCommandCommand.cxx +++ b/Source/cmLoadCommandCommand.cxx @@ -224,10 +224,6 @@ cmLoadedCommand::~cmLoadedCommand() bool cmLoadCommandCommand ::InitialPass(std::vector const& args, cmExecutionStatus &) { - this->Makefile->IssueMessage( - cmake::AUTHOR_WARNING, - "The \"load_command\" command will be removed in CMake 3.0. " - "See command documentation for details."); if(args.size() < 1 ) { return true; diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h index bcd1831e4..f0b34ee59 100644 --- a/Source/cmLoadCommandCommand.h +++ b/Source/cmLoadCommandCommand.h @@ -47,7 +47,7 @@ public: */ virtual const char* GetTerseDocumentation() const { - return "Deprecated. Use macro() or function() instead."; + return "Load a command into a running CMake."; } /** @@ -56,13 +56,6 @@ public: virtual const char* GetFullDocumentation() const { return - "This command will be removed in CMake 3.0. " - "It works only when the target architecture matches the " - "running CMake binary. " - "Use macro() or function() to add commands. " - "Use execute_process() to run advanced computations " - "in external processes." - "\n" " load_command(COMMAND_NAME [loc2 ...])\n" "The given locations are searched for a library whose name is " "cmCOMMAND_NAME. If found, it is loaded as a module and the command " @@ -74,12 +67,6 @@ public: "Otherwise the variable will not be set."; } - /** This command is kept for compatibility with older CMake versions. */ - virtual bool IsDiscouraged() const - { - return true; - } - cmTypeMacro(cmLoadCommandCommand, cmCommand); }; diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index a484983cd..3ea54f169 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -53,7 +53,6 @@ add_RunCMake_test(build_command) add_RunCMake_test(find_package) add_RunCMake_test(include) add_RunCMake_test(list) -add_RunCMake_test(load_command) if("${CMAKE_TEST_GENERATOR}" MATCHES "Visual Studio [^6]") add_RunCMake_test(include_external_msproject) diff --git a/Tests/RunCMake/load_command/CMakeLists.txt b/Tests/RunCMake/load_command/CMakeLists.txt deleted file mode 100644 index e8db6b05b..000000000 --- a/Tests/RunCMake/load_command/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -cmake_minimum_required(VERSION 2.8) -project(${RunCMake_TEST} NONE) -include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/load_command/LoadCommandDeprecated-stderr.txt b/Tests/RunCMake/load_command/LoadCommandDeprecated-stderr.txt deleted file mode 100644 index 7d374b2d5..000000000 --- a/Tests/RunCMake/load_command/LoadCommandDeprecated-stderr.txt +++ /dev/null @@ -1,6 +0,0 @@ -CMake Warning \(dev\) at LoadCommandDeprecated.cmake:1 \(load_command\): - The "load_command" command will be removed in CMake 3.0. See command - documentation for details. -Call Stack \(most recent call first\): - CMakeLists.txt:3 \(include\) -This warning is for project developers. Use -Wno-dev to suppress it. diff --git a/Tests/RunCMake/load_command/LoadCommandDeprecated.cmake b/Tests/RunCMake/load_command/LoadCommandDeprecated.cmake deleted file mode 100644 index 9e9b1f464..000000000 --- a/Tests/RunCMake/load_command/LoadCommandDeprecated.cmake +++ /dev/null @@ -1 +0,0 @@ -load_command() diff --git a/Tests/RunCMake/load_command/RunCMakeTest.cmake b/Tests/RunCMake/load_command/RunCMakeTest.cmake deleted file mode 100644 index 9a0f98d52..000000000 --- a/Tests/RunCMake/load_command/RunCMakeTest.cmake +++ /dev/null @@ -1,3 +0,0 @@ -include(RunCMake) - -run_cmake(LoadCommandDeprecated) From b684b395812872184cbf10e0e0513e2a18546047 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 7 Jan 2013 11:31:52 -0500 Subject: [PATCH 145/170] VS11: Simplify external object file handling (#13831) Since commit 9a6ff950 (Fix for bug where VS2010 did not use .obj files as part of the build, 2011-04-01) and commit b291d9e7 (VS10: Fix external objects generated outside target, 2012-03-19) we try to detect whether an external object file is also a custom command output in the same target. This is because VS10 includes .obj custom command outputs on the link line by default. VS 11 supports a "false" setting in custom command rules to tell VS not to link the outputs. From the VS help: Specify whether the Inputs and output files with specific extensions (.obj, .lib, .res, .rsc) are passed to the linker. Treat all external object files the same and add "" settings for them. --- Source/cmVisualStudio10TargetGenerator.cxx | 25 +++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index ec9c125a9..2596d7340 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -572,6 +572,12 @@ cmVisualStudio10TargetGenerator::WriteCustomRule(cmSourceFile* source, sep = ";"; } (*this->BuildFileStream ) << "\n"; + if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10) + { + // VS >= 11 let us turn off linking of custom command outputs. + this->WritePlatformConfigTag("LinkObjects", i->c_str(), 3); + (*this->BuildFileStream ) << "false\n"; + } } this->WriteString("\n", 2); } @@ -879,14 +885,23 @@ void cmVisualStudio10TargetGenerator::WriteAllSources() } } - for(std::vector::const_iterator - si = this->GeneratorTarget->ExternalObjects.begin(); - si != this->GeneratorTarget->ExternalObjects.end(); ++si) + if(this->LocalGenerator->GetVersion() > cmLocalVisualStudioGenerator::VS10) + { + // For VS >= 11 we use LinkObjects to avoid linking custom command + // outputs. Use Object for all external objects, generated or not. + this->WriteSources("Object", this->GeneratorTarget->ExternalObjects); + } + else { // If an object file is generated in this target, then vs10 will use // it in the build, and we have to list it as None instead of Object. - std::vector const* d = this->Target->GetSourceDepends(*si); - this->WriteSource((d && !d->empty())? "None":"Object", *si); + for(std::vector::const_iterator + si = this->GeneratorTarget->ExternalObjects.begin(); + si != this->GeneratorTarget->ExternalObjects.end(); ++si) + { + std::vector const* d=this->Target->GetSourceDepends(*si); + this->WriteSource((d && !d->empty())? "None":"Object", *si); + } } this->WriteSources("None", this->GeneratorTarget->ExtraSources); From 4b9ec00d0e175ec4cc7e1fbe6ed7d1dcbcfb25ba Mon Sep 17 00:00:00 2001 From: Clinton Stimpson Date: Mon, 7 Jan 2013 11:06:35 -0700 Subject: [PATCH 146/170] FindQt4: set QT_VERSION_* variables sooner. Set QT_VERSION_* variables sooner so they can be set before Qt4ConfigDependentSettings.cmake uses them. --- Modules/FindQt4.cmake | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index ea4d8f473..84196cce6 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -538,6 +538,11 @@ endif () if (QT_QMAKE_EXECUTABLE AND QTVERSION) + # set version variables + string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${QTVERSION}") + string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${QTVERSION}") + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${QTVERSION}") + # ask qmake for the mkspecs directory # we do this first because QT_LIBINFIX might be set if (NOT QT_MKSPECS_DIR OR QT_QMAKE_CHANGED) @@ -1174,11 +1179,6 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) include("${_qt4_current_dir}/Qt4Macros.cmake") - # set version variables - string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" QT_VERSION_MAJOR "${QTVERSION}") - string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" QT_VERSION_MINOR "${QTVERSION}") - string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" QT_VERSION_PATCH "${QTVERSION}") - endif() #support old QT_MIN_VERSION if set, but not if version is supplied by find_package() From 57a67bf27efc286fffa883baad86c7d5d51834cc Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 31 Dec 2012 09:41:09 +0100 Subject: [PATCH 147/170] Qt4: Add module dependencies to the IMPORTED targets This means for example, that consumers can use: target_link_libraries(foo ${QT_QTGUI_LIBRARIES}) instead of also needing to specify all 'public' dependencies: target_link_libraries(foo ${QT_QTGUI_LIBRARIES} ${QT_QTCORE_LIBRARIES} ) when using the IMPORTED targets. Also populate the IMPORTED_LINK_DEPENDENT_LIBRARIES property so CMake can help the linker find shared library dependencies. --- Modules/FindQt4.cmake | 55 +++++++++++++++++++++++++++++++++ Tests/CMakeLists.txt | 15 +++++++++ Tests/Qt4Targets/CMakeLists.txt | 14 +++++++++ Tests/Qt4Targets/main.cpp | 16 ++++++++++ 4 files changed, 100 insertions(+) create mode 100644 Tests/Qt4Targets/CMakeLists.txt create mode 100644 Tests/Qt4Targets/main.cpp diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index ea4d8f473..381141c5f 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -942,12 +942,36 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) ############################################ + macro(_qt4_add_target_depends_internal _QT_MODULE _PROPERTY) + if (TARGET Qt4::${_QT_MODULE}) + foreach(_DEPEND ${ARGN}) + if (NOT TARGET Qt4::Qt${_DEPEND}) + message(FATAL_ERROR "_qt4_add_target_depends invoked with invalid arguments") + endif() + set_property(TARGET Qt4::${_QT_MODULE} APPEND PROPERTY + ${_PROPERTY} + "Qt4::Qt${_DEPEND}" + ) + endforeach() + endif() + endmacro() + + macro(_qt4_add_target_depends _QT_MODULE) + _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_INTERFACE_LIBRARIES ${ARGN}) + endmacro() + + macro(_qt4_add_target_private_depends _QT_MODULE) + _qt4_add_target_depends_internal(${_QT_MODULE} IMPORTED_LINK_DEPENDENT_LIBRARIES ${ARGN}) + endmacro() + + # Set QT_xyz_LIBRARY variable and add # library include path to QT_INCLUDES _QT4_ADJUST_LIB_VARS(QtCore) foreach(QT_MODULE ${QT_MODULES}) _QT4_ADJUST_LIB_VARS(${QT_MODULE}) + _qt4_add_target_depends(${QT_MODULE} Core) endforeach() _QT4_ADJUST_LIB_VARS(QtAssistant) @@ -962,6 +986,37 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) _QT4_ADJUST_LIB_VARS(QAxContainer) endif() + # Only public dependencies are listed here. + # Eg, QtDBus links to QtXml, but users of QtDBus do not need to + # link to QtXml because QtDBus only uses it internally, not in public + # headers. + # Everything depends on QtCore, but that is covered above already + _qt4_add_target_depends(Qt3Support Sql Gui Network) + _qt4_add_target_depends(QtDeclarative Script Gui) + _qt4_add_target_depends(QtDesigner Gui) + _qt4_add_target_depends(QtHelp Gui) + _qt4_add_target_depends(QtMultimedia Gui) + _qt4_add_target_depends(QtOpenGL Gui) + _qt4_add_target_depends(QtSvg Gui) + _qt4_add_target_depends(QtWebKit Gui Network) + + _qt4_add_target_private_depends(Qt3Support Xml) + _qt4_add_target_private_depends(QtSvg Xml) + _qt4_add_target_private_depends(QtDBus Xml) + _qt4_add_target_private_depends(QtUiTools Xml Gui) + _qt4_add_target_private_depends(QtHelp Sql Xml Network) + _qt4_add_target_private_depends(QtXmlPatterns Network) + _qt4_add_target_private_depends(QtScriptTools Gui) + _qt4_add_target_private_depends(QtWebKit XmlPatterns) + _qt4_add_target_private_depends(QtDeclarative XmlPatterns Svg Sql Gui) + _qt4_add_target_private_depends(QtMultimedia Gui) + _qt4_add_target_private_depends(QtOpenGL Gui) + _qt4_add_target_private_depends(QAxServer Gui) + _qt4_add_target_private_depends(QAxContainer Gui) + _qt4_add_target_private_depends(phonon Gui) + if(QT_QTDBUS_FOUND) + _qt4_add_target_private_depends(phonon DBus) + endif() ####################################### # diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index f443b5b36..924ff38c1 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -989,6 +989,21 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ) list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc") endif() + if(QT4_WORKS AND QT_QTGUI_FOUND) + add_test(Qt4Targets ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/Qt4Targets" + "${CMake_BINARY_DIR}/Tests/Qt4Targets" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project Qt4Targets + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Targets" + --force-new-ctest-process + --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Targets") + endif() add_test(ExternalProject ${CMAKE_CTEST_COMMAND} --build-and-test diff --git a/Tests/Qt4Targets/CMakeLists.txt b/Tests/Qt4Targets/CMakeLists.txt new file mode 100644 index 000000000..3adff48fd --- /dev/null +++ b/Tests/Qt4Targets/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 2.8) + +project(Qt4Targets) + +find_package(Qt4 REQUIRED) + +include_directories(${QT_INCLUDES}) + +add_executable(Qt4Targets WIN32 main.cpp) +target_link_libraries(Qt4Targets Qt4::QtGui) + +if (WIN32) + target_link_libraries(Qt4Targets Qt4::qtmain) +endif() diff --git a/Tests/Qt4Targets/main.cpp b/Tests/Qt4Targets/main.cpp new file mode 100644 index 000000000..f4890fa9e --- /dev/null +++ b/Tests/Qt4Targets/main.cpp @@ -0,0 +1,16 @@ + +#include +#include + +#include + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + QWidget w; + w.setWindowTitle(QString::fromLatin1("SomeTitle")); + w.show(); + + return 0; +} From 119bf4bf7f1db2aea6afb64fff471d6994cadf44 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 3 Jan 2013 19:56:54 +0100 Subject: [PATCH 148/170] Add test for custom command with a genex referring to a target. This test failed before d8a59ea4 (Port cmGeneratorExpression to cmTarget from cmGeneratorTarget, 2012-10-27), and passes after. --- .../TargetIncludeDirectories/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt index 7cb1b42e0..3044abd5e 100644 --- a/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/TargetIncludeDirectories/CMakeLists.txt @@ -45,3 +45,9 @@ set_property(TARGET TargetIncludeDirectories APPEND PROPERTY INCLUDE_DIRECTORIES "$" ) + +add_custom_target(test_custom_target + "some_bogus_custom_tool" + $ + WORKING_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}") From ed96d9a605471694465dd7142dd25748dfdf3a90 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Mon, 7 Jan 2013 21:09:18 +0100 Subject: [PATCH 149/170] bootstrap: use better defaults for Haiku These values are patched into that file by Haiku since 2.8.1. --- bootstrap | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bootstrap b/bootstrap index 643720c86..9a4f796fe 100755 --- a/bootstrap +++ b/bootstrap @@ -159,7 +159,9 @@ if ${cmake_system_mingw}; then cmake_default_prefix="c:/Program Files/CMake" fi elif ${cmake_system_haiku}; then - cmake_default_prefix=`/bin/finddir B_COMMON_DIRECTORY` + cmake_default_prefix=`finddir B_COMMON_DIRECTORY` + cmake_man_dir="/documentation/man" + cmake_doc_dir="/documentation/doc/cmake-${cmake_version}" else cmake_default_prefix="/usr/local" fi From 7a1b961de8b79416d168355e71f5af80fa4dbd02 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Mon, 7 Jan 2013 21:20:11 +0100 Subject: [PATCH 150/170] Haiku no longer defines __BEOS__ --- Modules/CheckForPthreads.c | 2 +- Source/CPack/cmCPackGeneratorFactory.cxx | 4 ++-- Source/cmCTest.cxx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/CheckForPthreads.c b/Modules/CheckForPthreads.c index 882dc21b7..7250fbff6 100644 --- a/Modules/CheckForPthreads.c +++ b/Modules/CheckForPthreads.c @@ -16,7 +16,7 @@ int main(int ac, char*av[]){ pthread_create(&tid[0], 0, runner, (void*)1); pthread_create(&tid[1], 0, runner, (void*)2); -#if defined(__BEOS__) && !defined(__ZETA__) && !defined(__HAIKU__) // (no usleep on BeOS 5.) +#if defined(__BEOS__) && !defined(__ZETA__) // (no usleep on BeOS 5.) usleep(1); // for strange behavior on single-processor sun #endif diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index 557767391..b36c2a2f8 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -33,7 +33,7 @@ #endif #if !defined(_WIN32) \ - && !defined(__QNXNTO__) && !defined(__BEOS__) + && !defined(__QNXNTO__) && !defined(__BEOS__) && !defined(__HAIKU__) # include "cmCPackDebGenerator.h" # include "cmCPackRPMGenerator.h" #endif @@ -126,7 +126,7 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() } #endif #if !defined(_WIN32) \ - && !defined(__QNXNTO__) && !defined(__BEOS__) + && !defined(__QNXNTO__) && !defined(__BEOS__) && !defined(__HAIKU__) if (cmCPackDebGenerator::CanGenerate()) { this->RegisterGenerator("DEB", "Debian packages", diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index bb6f3f29d..322a6a26f 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -53,7 +53,7 @@ #include #include -#if defined(__BEOS__) && !defined(__HAIKU__) +#if defined(__BEOS__) #include /* disable_debugger() API. */ #endif From 3d2e6a06874603ebe6152045c34de9147a0c11dc Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Mon, 7 Jan 2013 21:52:45 +0100 Subject: [PATCH 151/170] check for Haiku only with __HAIKU__ --- Modules/CMakeFortranCompilerId.F.in | 6 +----- Modules/CMakePlatformId.h.in | 5 +---- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 4d25de0ba..f84852aeb 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -74,12 +74,8 @@ PRINT *, 'INFO:platform[IRIX]' #elif defined(__hpux) || defined(__hpux__) PRINT *, 'INFO:platform[HP-UX]' -#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU) +#elif defined(__HAIKU__) PRINT *, 'INFO:platform[Haiku]' -# if 0 -! Haiku also defines __BEOS__ so we must -! put it prior to the check for __BEOS__ -# endif #elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) PRINT *, 'INFO:platform[BeOS]' #elif defined(__QNX__) || defined(__QNXNTO__) diff --git a/Modules/CMakePlatformId.h.in b/Modules/CMakePlatformId.h.in index c37341411..69171c2a3 100644 --- a/Modules/CMakePlatformId.h.in +++ b/Modules/CMakePlatformId.h.in @@ -35,11 +35,8 @@ #elif defined(__hpux) || defined(__hpux__) # define PLATFORM_ID "HP-UX" -#elif defined(__HAIKU) || defined(__HAIKU__) || defined(_HAIKU) +#elif defined(__HAIKU__) # define PLATFORM_ID "Haiku" -/* Haiku also defines __BEOS__ so we must - put it prior to the check for __BEOS__ -*/ #elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS) # define PLATFORM_ID "BeOS" From 50bfedf391a078e628bf1259f819da42dea1cde0 Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Mon, 7 Jan 2013 23:26:18 +0100 Subject: [PATCH 152/170] FindLua51: do not try to link libm on BeOS This includes Haiku, which currently is treated as BeOS. The ComplexOneConfig test already knew about this. --- Modules/FindLua51.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/FindLua51.cmake b/Modules/FindLua51.cmake index 2d7ed3d6c..a2bf0c0ef 100644 --- a/Modules/FindLua51.cmake +++ b/Modules/FindLua51.cmake @@ -54,7 +54,7 @@ find_library(LUA_LIBRARY if(LUA_LIBRARY) # include the math library for Unix - if(UNIX AND NOT APPLE) + if(UNIX AND NOT APPLE AND NOT BEOS) find_library(LUA_MATH_LIBRARY m) set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") # For Windows and Mac, don't need to explicitly include the math library From 8e9630c719f59f69f813e3eb4a4f91ba2396b4ef Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Mon, 7 Jan 2013 23:57:07 +0100 Subject: [PATCH 153/170] FindGLUT: BeOS does not have libXi and libXmu --- Modules/FindGLUT.cmake | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/Modules/FindGLUT.cmake b/Modules/FindGLUT.cmake index 55790ae7c..843d1389f 100644 --- a/Modules/FindGLUT.cmake +++ b/Modules/FindGLUT.cmake @@ -40,25 +40,39 @@ else () set(GLUT_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX") else () + if (BEOS) + + set(_GLUT_INC_DIR /boot/develop/headers/os/opengl) + set(_GLUT_glut_LIB_DIR /boot/develop/lib/x86) + + else() + + find_library( GLUT_Xi_LIBRARY Xi + /usr/openwin/lib + ) + + find_library( GLUT_Xmu_LIBRARY Xmu + /usr/openwin/lib + ) + + endif () + find_path( GLUT_INCLUDE_DIR GL/glut.h /usr/include/GL /usr/openwin/share/include /usr/openwin/include /opt/graphics/OpenGL/include /opt/graphics/OpenGL/contrib/libglut + ${_GLUT_INC_DIR} ) find_library( GLUT_glut_LIBRARY glut /usr/openwin/lib + ${_GLUT_glut_LIB_DIR} ) - find_library( GLUT_Xi_LIBRARY Xi - /usr/openwin/lib - ) - - find_library( GLUT_Xmu_LIBRARY Xmu - /usr/openwin/lib - ) + unset(_GLUT_INC_DIR) + unset(_GLUT_glut_LIB_DIR) endif () From 0380f36cd8dbdf7a89f8fac91d99235e75075bde Mon Sep 17 00:00:00 2001 From: Rolf Eike Beer Date: Tue, 8 Jan 2013 00:38:08 +0100 Subject: [PATCH 154/170] FindOpenGL: add Haiku paths Also check the HP-UX specific paths only when on HP-UX. --- Modules/FindOpenGL.cmake | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake index 4a393f225..96c4d8db5 100644 --- a/Modules/FindOpenGL.cmake +++ b/Modules/FindOpenGL.cmake @@ -58,14 +58,22 @@ else () find_path(OPENGL_INCLUDE_DIR OpenGL/gl.h DOC "Include for OpenGL on OSX") else() - # Handle HP-UX cases where we only want to find OpenGL in either hpux64 - # or hpux32 depending on if we're doing a 64 bit build. - if(CMAKE_SIZEOF_VOID_P EQUAL 4) - set(HPUX_IA_OPENGL_LIB_PATH /opt/graphics/OpenGL/lib/hpux32/) - else() - set(HPUX_IA_OPENGL_LIB_PATH - /opt/graphics/OpenGL/lib/hpux64/ - /opt/graphics/OpenGL/lib/pa20_64) + if (CMAKE_SYSTEM_NAME MATCHES "HP-UX") + # Handle HP-UX cases where we only want to find OpenGL in either hpux64 + # or hpux32 depending on if we're doing a 64 bit build. + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(_OPENGL_LIB_PATH + /opt/graphics/OpenGL/lib/hpux32/) + else() + set(_OPENGL_LIB_PATH + /opt/graphics/OpenGL/lib/hpux64/ + /opt/graphics/OpenGL/lib/pa20_64) + endif() + elseif(CMAKE_SYSTEM_NAME STREQUAL Haiku) + set(_OPENGL_LIB_PATH + /boot/develop/lib/x86) + set(_OPENGL_INCLUDE_PATH + /boot/develop/headers/os/opengl) endif() # The first line below is to make sure that the proper headers @@ -80,6 +88,7 @@ else () /usr/share/doc/NVIDIA_GLX-1.0/include /usr/openwin/share/include /opt/graphics/OpenGL/include /usr/X11R6/include + ${_OPENGL_INCLUDE_PATH} ) find_path(OPENGL_xmesa_INCLUDE_DIR GL/xmesa.h @@ -93,9 +102,12 @@ else () PATHS /opt/graphics/OpenGL/lib /usr/openwin/lib /usr/shlib /usr/X11R6/lib - ${HPUX_IA_OPENGL_LIB_PATH} + ${_OPENGL_LIB_PATH} ) + unset(_OPENGL_INCLUDE_PATH) + unset(_OPENGL_LIB_PATH) + # On Unix OpenGL most certainly always requires X11. # Feel free to tighten up these conditions if you don't # think this is always true. From 97758f29206a172524edd144e588558bb4a83700 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Tue, 8 Jan 2013 00:01:19 -0500 Subject: [PATCH 155/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index a18fcf042..528fa13e6 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 20130107) +set(CMake_VERSION_TWEAK 20130108) #set(CMake_VERSION_RC 1) From 495fa24d70ce4c5b594e15cae464af243a127fb8 Mon Sep 17 00:00:00 2001 From: KWSys Robot Date: Mon, 7 Jan 2013 10:20:26 -0500 Subject: [PATCH 156/170] KWSys 2013-01-07 (fc60c8b8) Extract upstream KWSys using the following shell commands. $ git archive --prefix=upstream-kwsys/ fc60c8b8 | tar x $ git shortlog --no-merges --abbrev=8 --format='%h %s' 8ce09af5..fc60c8b8 Brad King (3): cb5f835f SystemTools: Fix MakeDirectory with colon in path 1643507a IOStream: Fix check for compiler 'long long' support 34177aec SystemTools: Fix MakeDirectory after recent cleanup Rolf Eike Beer (24): 4da9894d SystemInformation: Clean up QuerySolarisInfo() 01392358 SystemInformation: don't attribute i386 Solaris systems to Sun 3db65ac1 SystemInformation: wrap the call to CPUID in a function 61bd9b42 SystemInformation: use the __cpuid compiler intrinsic if present 5932e7c0 SystemInformation: query memory size on Cygwin using sysconf() ea5612ed SystemInformation: count memory with _SC_PAGESIZE and _SC_PHYS_PAGES 3aca6642 SystemInformation: query memory size, CPU count, and CPU speed on BSD 3572c54d SystemInformation: count CPUs on HP-UX e6771b34 SystemInformation: determine CPU type on HP-UX 640210e5 SystemInformation: use /proc/cpuinfo only when present 5bdcfd10 SystemInformation: query total memory on AIX de69d547 SystemInformation: use intrinsic for RDTSC if supported 9808d4e7 SystemInformation: get CPU speed on Windows when RDTSC fails f4c625b5 tests: avoid truncation of testSystemInformation output in CDash 03d6fbe5 SystemInformation: get x86 CPU features from /proc/cpuinfo f8e917c1 SystemInformation: remove the #define CPUID_INSTRUCTION 59c4b5c5 SystemInformation: split Windows code out of QueryMemory() 200ee91f SystemInformation: split HP-UX code out of QueryMemory() 88217703 SystemInformation: split Linux code out of QueryMemory() 9e317872 SystemInformation: split AIX code out of QueryMemory() 349cee5b SystemInformation: remove useless zeroing from QueryMemory() 7271926e SystemInformation: split Cygwin code out of QueryMemory() 6da78ad1 SystemInformation: make QueryMemory() return bool 182179e9 Haiku no longer defines __BEOS__ Stephen Kelly (1): 247b8a3c SystemTools: Rename MakeCnidentifier() to MakeCidentifier() Change-Id: Ib95b5bddab7ecc0a4025ab29792426acf57e5623 --- CMakeLists.txt | 7 + IOStream.hxx.in | 6 +- ProcessUNIX.c | 4 - SystemInformation.cxx | 1185 +++++++++++++++++++------------------ SystemTools.cxx | 19 +- SystemTools.hxx.in | 9 +- testDynamicLoader.cxx | 2 +- testProcess.c | 2 +- testSystemInformation.cxx | 9 + 9 files changed, 641 insertions(+), 602 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ccdff1255..6bfcab040 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -596,6 +596,13 @@ IF(KWSYS_USE_SystemInformation) ENDIF() ENDIF() ENDIF() + IF(CMAKE_SYSTEM MATCHES "HP-UX") + CHECK_INCLUDE_FILES("sys/mpctl.h" KWSYS_SYS_HAS_MPCTL_H) + IF(KWSYS_SYS_HAS_MPCTL_H) + SET_PROPERTY(SOURCE SystemInformation.cxx APPEND PROPERTY + COMPILE_DEFINITIONS KWSYS_SYS_HAS_MPCTL_H=1) + ENDIF() + ENDIF() IF(KWSYS_LFS_AVAILABLE AND NOT KWSYS_LFS_DISABLE) SET(KWSYS_PLATFORM_CXX_TEST_DEFINES -DKWSYS_HAS_LFS=1) ENDIF() diff --git a/IOStream.hxx.in b/IOStream.hxx.in index 9eb99e058..2eeedf2ff 100644 --- a/IOStream.hxx.in +++ b/IOStream.hxx.in @@ -26,12 +26,9 @@ /* Whether ostream supports long long. */ #define @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG @KWSYS_IOS_HAS_OSTREAM_LONG_LONG@ -/* Size of type long long and 0 if not available. */ -#define @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG @KWSYS_SIZEOF_LONG_LONG@ - /* Determine whether we need to define the streaming operators for long long or __int64. */ -#if @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG +#if @KWSYS_USE_LONG_LONG@ # if !@KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG || \ !@KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG # define @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL 1 @@ -136,7 +133,6 @@ operator<<(kwsys_ios::ostream& os, @KWSYS_NAMESPACE@::IOStreamULL value) /* If building a C++ file in kwsys itself, give the source file access to the macros without a configured namespace. */ #if defined(KWSYS_NAMESPACE) -# define KWSYS_IOS_SIZEOF_LONG_LONG @KWSYS_NAMESPACE@_IOS_SIZEOF_LONG_LONG # define KWSYS_IOS_HAS_ISTREAM_LONG_LONG @KWSYS_NAMESPACE@_IOS_HAS_ISTREAM_LONG_LONG # define KWSYS_IOS_HAS_OSTREAM_LONG_LONG @KWSYS_NAMESPACE@_IOS_HAS_OSTREAM_LONG_LONG # define KWSYS_IOS_NEED_OPERATORS_LL @KWSYS_NAMESPACE@_IOS_NEED_OPERATORS_LL diff --git a/ProcessUNIX.c b/ProcessUNIX.c index 19922111a..83838affc 100644 --- a/ProcessUNIX.c +++ b/ProcessUNIX.c @@ -63,10 +63,6 @@ do. #include /* DIR, dirent */ #include /* isspace */ -#ifdef __HAIKU__ -#undef __BEOS__ -#endif - #if defined(__VMS) # define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK #else diff --git a/SystemInformation.cxx b/SystemInformation.cxx index bfdb0edd6..0460b2906 100644 --- a/SystemInformation.cxx +++ b/SystemInformation.cxx @@ -86,6 +86,15 @@ typedef int siginfo_t; # endif #endif +#if defined(__OpenBSD__) || defined(__NetBSD__) +# include +# include +#endif + +#if defined(__DragonFly__) +# include +#endif + #ifdef __APPLE__ # include # include @@ -133,6 +142,9 @@ typedef struct rlimit ResourceLimitType; #elif defined( __hpux ) # include # include +# if defined(KWSYS_SYS_HAS_MPCTL_H) +# include +# endif #endif #ifdef __HAIKU__ @@ -173,6 +185,87 @@ typedef struct rlimit ResourceLimitType; # endif #endif +#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_WIN64) +#define USE_ASM_INSTRUCTIONS 1 +#else +#define USE_ASM_INSTRUCTIONS 0 +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#include +#define USE_CPUID_INTRINSICS 1 +#else +#define USE_CPUID_INTRINSICS 0 +#endif + +#if USE_ASM_INSTRUCTIONS || USE_CPUID_INTRINSICS +# define USE_CPUID 1 +#else +# define USE_CPUID 0 +#endif + +#if USE_CPUID + +#define CPUID_AWARE_COMPILER + +/** + * call CPUID instruction + * + * Will return false if the instruction failed. + */ +static bool call_cpuid(int select, int result[4]) +{ +#if USE_CPUID_INTRINSICS + __cpuid(result, select); + return true; +#else + int tmp[4]; + // Use SEH to determine CPUID presence + __try { + _asm { +#ifdef CPUID_AWARE_COMPILER + ; we must push/pop the registers <> writes to, as the + ; optimiser doesn't know about <>, and so doesn't expect + ; these registers to change. + push eax + push ebx + push ecx + push edx +#endif + ; <> + mov eax, select +#ifdef CPUID_AWARE_COMPILER + cpuid +#else + _asm _emit 0x0f + _asm _emit 0xa2 +#endif + mov tmp[0 * TYPE int], eax + mov tmp[1 * TYPE int], ebx + mov tmp[2 * TYPE int], ecx + mov tmp[3 * TYPE int], edx + +#ifdef CPUID_AWARE_COMPILER + pop edx + pop ecx + pop ebx + pop eax +#endif + } + } + __except(1) + { + return false; + } + + memcpy(result, tmp, sizeof(tmp)); + // The cpuid instruction succeeded. + return true; +#endif +} +#endif + + namespace KWSYS_NAMESPACE { template @@ -336,13 +429,16 @@ protected: unsigned char LogicalCPUPerPhysicalCPU(); unsigned char GetAPICId(); unsigned int IsHyperThreadingSupported(); - LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); + static LongLong GetCyclesDifference(DELAY_FUNC, unsigned int); // For Linux and Cygwin, /proc/cpuinfo formats are slightly different - int RetreiveInformationFromCpuInfoFile(); + bool RetreiveInformationFromCpuInfoFile(); kwsys_stl::string ExtractValueFromCpuInfoFile(kwsys_stl::string buffer, const char* word, size_t init=0); + bool QueryLinuxMemory(); + bool QueryCygwinMemory(); + static void Delay (unsigned int); static void DelayOverhead (unsigned int); @@ -367,8 +463,24 @@ protected: bool QueryQNXMemory(); bool QueryQNXProcessor(); + //For OpenBSD, FreeBSD, NetBSD, DragonFly + bool QueryBSDMemory(); + bool QueryBSDProcessor(); + + //For HP-UX + bool QueryHPUXMemory(); + bool QueryHPUXProcessor(); + + //For Microsoft Windows + bool QueryWindowsMemory(); + + //For AIX + bool QueryAIXMemory(); + + bool QueryProcessor(); + // Evaluate the memory information. - int QueryMemory(); + bool QueryMemory(); size_t TotalVirtualMemory; size_t AvailableVirtualMemory; size_t TotalPhysicalMemory; @@ -695,24 +807,11 @@ void SystemInformation::RunMemoryCheck() // -------------------------------------------------------------- // SystemInformationImplementation starts here -#if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(_WIN64) -#define USE_ASM_INSTRUCTIONS 1 -#else -#define USE_ASM_INSTRUCTIONS 0 -#endif - #define STORE_TLBCACHE_INFO(x,y) x = (x < y) ? y : x #define TLBCACHE_INFO_UNITS (15) #define CLASSICAL_CPU_FREQ_LOOP 10000000 #define RDTSC_INSTRUCTION _asm _emit 0x0f _asm _emit 0x31 -#define CPUID_AWARE_COMPILER -#ifdef CPUID_AWARE_COMPILER - #define CPUID_INSTRUCTION cpuid -#else - #define CPUID_INSTRUCTION _asm _emit 0x0f _asm _emit 0xa2 -#endif - #define MMX_FEATURE 0x00000001 #define MMX_PLUS_FEATURE 0x00000002 #define SSE_FEATURE 0x00000004 @@ -1189,8 +1288,14 @@ void SystemInformationImplementation::RunCPUCheck() this->QueryHaikuInfo(); #elif defined(__QNX__) this->QueryQNXProcessor(); -#else +#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) + this->QueryBSDProcessor(); +#elif defined(__hpux) + this->QueryHPUXProcessor(); +#elif defined(__linux) || defined(__CYGWIN__) this->RetreiveInformationFromCpuInfoFile(); +#else + this->QueryProcessor(); #endif } @@ -1209,6 +1314,18 @@ void SystemInformationImplementation::RunMemoryCheck() this->QueryHaikuInfo(); #elif defined(__QNX__) this->QueryQNXMemory(); +#elif defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) + this->QueryBSDMemory(); +#elif defined(__CYGWIN__) + this->QueryCygwinMemory(); +#elif defined(_WIN32) + this->QueryWindowsMemory(); +#elif defined(__hpux) + this->QueryHPUXMemory(); +#elif defined(__linux) + this->QueryLinuxMemory(); +#elif defined(_AIX) + this->QueryAIXMemory(); #else this->QueryMemory(); #endif @@ -1612,40 +1729,15 @@ void SystemInformationImplementation::Delay(unsigned int uiMS) bool SystemInformationImplementation::DoesCPUSupportCPUID() { +#if USE_CPUID + int dummy[4] = { 0, 0, 0, 0 }; + #if USE_ASM_INSTRUCTIONS - // Use SEH to determine CPUID presence - __try { - _asm { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx + return call_cpuid(0, dummy); +#else + call_cpuid(0, dummy); + return dummy[0] || dummy[1] || dummy[2] || dummy[3]; #endif - ; <> - mov eax, 0 - CPUID_INSTRUCTION - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif - } - } - __except(1) - { - // Stop the class from trying to use CPUID again! - return false; - } - - // The cpuid instruction succeeded. - return true; - #else // Assume no cpuid instruction. return false; @@ -1655,58 +1747,29 @@ bool SystemInformationImplementation::DoesCPUSupportCPUID() bool SystemInformationImplementation::RetrieveCPUFeatures() { -#if USE_ASM_INSTRUCTIONS - int localCPUFeatures = 0; - int localCPUAdvanced = 0; +#if USE_CPUID + int cpuinfo[4] = { 0, 0, 0, 0 }; - // Use assembly to detect CPUID information... - __try { - _asm { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -#endif - ; <> - ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision - ; ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID - ; edx: CPU feature flags - mov eax,1 - CPUID_INSTRUCTION - mov localCPUFeatures, edx - mov localCPUAdvanced, ebx - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif - } - } - __except(1) + if (!call_cpuid(1, cpuinfo)) { return false; } // Retrieve the features of CPU present. - this->Features.HasFPU = ((localCPUFeatures & 0x00000001) != 0); // FPU Present --> Bit 0 - this->Features.HasTSC = ((localCPUFeatures & 0x00000010) != 0); // TSC Present --> Bit 4 - this->Features.HasAPIC = ((localCPUFeatures & 0x00000200) != 0); // APIC Present --> Bit 9 - this->Features.HasMTRR = ((localCPUFeatures & 0x00001000) != 0); // MTRR Present --> Bit 12 - this->Features.HasCMOV = ((localCPUFeatures & 0x00008000) != 0); // CMOV Present --> Bit 15 - this->Features.HasSerial = ((localCPUFeatures & 0x00040000) != 0); // Serial Present --> Bit 18 - this->Features.HasACPI = ((localCPUFeatures & 0x00400000) != 0); // ACPI Capable --> Bit 22 - this->Features.HasMMX = ((localCPUFeatures & 0x00800000) != 0); // MMX Present --> Bit 23 - this->Features.HasSSE = ((localCPUFeatures & 0x02000000) != 0); // SSE Present --> Bit 25 - this->Features.HasSSE2 = ((localCPUFeatures & 0x04000000) != 0); // SSE2 Present --> Bit 26 - this->Features.HasThermal = ((localCPUFeatures & 0x20000000) != 0); // Thermal Monitor Present --> Bit 29 - this->Features.HasIA64 = ((localCPUFeatures & 0x40000000) != 0); // IA64 Present --> Bit 30 + this->Features.HasFPU = ((cpuinfo[3] & 0x00000001) != 0); // FPU Present --> Bit 0 + this->Features.HasTSC = ((cpuinfo[3] & 0x00000010) != 0); // TSC Present --> Bit 4 + this->Features.HasAPIC = ((cpuinfo[3] & 0x00000200) != 0); // APIC Present --> Bit 9 + this->Features.HasMTRR = ((cpuinfo[3] & 0x00001000) != 0); // MTRR Present --> Bit 12 + this->Features.HasCMOV = ((cpuinfo[3] & 0x00008000) != 0); // CMOV Present --> Bit 15 + this->Features.HasSerial = ((cpuinfo[3] & 0x00040000) != 0); // Serial Present --> Bit 18 + this->Features.HasACPI = ((cpuinfo[3] & 0x00400000) != 0); // ACPI Capable --> Bit 22 + this->Features.HasMMX = ((cpuinfo[3] & 0x00800000) != 0); // MMX Present --> Bit 23 + this->Features.HasSSE = ((cpuinfo[3] & 0x02000000) != 0); // SSE Present --> Bit 25 + this->Features.HasSSE2 = ((cpuinfo[3] & 0x04000000) != 0); // SSE2 Present --> Bit 26 + this->Features.HasThermal = ((cpuinfo[3] & 0x20000000) != 0); // Thermal Monitor Present --> Bit 29 + this->Features.HasIA64 = ((cpuinfo[3] & 0x40000000) != 0); // IA64 Present --> Bit 30 +#if USE_ASM_INSTRUCTIONS // Retrieve extended SSE capabilities if SSE is available. if (this->Features.HasSSE) { @@ -1735,17 +1798,20 @@ bool SystemInformationImplementation::RetrieveCPUFeatures() // Set the advanced SSE capabilities to not available. this->Features.HasSSEFP = false; } +#else + this->Features.HasSSEFP = false; +#endif // Retrieve Intel specific extended features. if (this->ChipManufacturer == Intel) { - this->Features.ExtendedFeatures.SupportsHyperthreading = ((localCPUFeatures & 0x10000000) != 0); // Intel specific: Hyperthreading --> Bit 28 - this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = (this->Features.ExtendedFeatures.SupportsHyperthreading) ? ((localCPUAdvanced & 0x00FF0000) >> 16) : 1; + this->Features.ExtendedFeatures.SupportsHyperthreading = ((cpuinfo[3] & 0x10000000) != 0); // Intel specific: Hyperthreading --> Bit 28 + this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = (this->Features.ExtendedFeatures.SupportsHyperthreading) ? ((cpuinfo[1] & 0x00FF0000) >> 16) : 1; if ((this->Features.ExtendedFeatures.SupportsHyperthreading) && (this->Features.HasAPIC)) { // Retrieve APIC information if there is one present. - this->Features.ExtendedFeatures.APIC_ID = ((localCPUAdvanced & 0xFF000000) >> 24); + this->Features.ExtendedFeatures.APIC_ID = ((cpuinfo[1] & 0xFF000000) >> 24); } } @@ -1773,6 +1839,7 @@ void SystemInformationImplementation::FindManufacturer(const kwsys_stl::string& else if (this->ChipID.Vendor == "Geode By NSC") this->ChipManufacturer = NSC; // National Semiconductor else if (this->ChipID.Vendor == "Sun") this->ChipManufacturer = Sun; // Sun Microelectronics else if (this->ChipID.Vendor == "IBM") this->ChipManufacturer = IBM; // IBM Microelectronics + else if (this->ChipID.Vendor == "Hewlett-Packard") this->ChipManufacturer = HP; // Hewlett-Packard else if (this->ChipID.Vendor == "Motorola") this->ChipManufacturer = Motorola; // Motorola Microelectronics else if (family.substr(0, 7) == "PA-RISC") this->ChipManufacturer = HP; // Hewlett-Packard else this->ChipManufacturer = UnknownManufacturer; // Unknown manufacturer @@ -1782,71 +1849,41 @@ void SystemInformationImplementation::FindManufacturer(const kwsys_stl::string& /** */ bool SystemInformationImplementation::RetrieveCPUIdentity() { -#if USE_ASM_INSTRUCTIONS - int localCPUVendor[3]; - int localCPUSignature; +#if USE_CPUID + int localCPUVendor[4]; + int localCPUSignature[4]; - // Use assembly to detect CPUID information... - __try + if (!call_cpuid(0, localCPUVendor)) { - _asm - { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -#endif - ; <> - ; eax = 0 --> eax: maximum value of CPUID instruction. - ; ebx: part 1 of 3; CPU signature. - ; edx: part 2 of 3; CPU signature. - ; ecx: part 3 of 3; CPU signature. - mov eax, 0 - CPUID_INSTRUCTION - mov localCPUVendor[0 * TYPE int], ebx - mov localCPUVendor[1 * TYPE int], edx - mov localCPUVendor[2 * TYPE int], ecx - - ; <> - ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision - ; ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID - ; edx: CPU feature flags - mov eax,1 - CPUID_INSTRUCTION - mov localCPUSignature, eax - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif + return false; } - } - __except(1) + if (!call_cpuid(1, localCPUSignature)) { return false; } // Process the returned information. + // ; eax = 0 --> eax: maximum value of CPUID instruction. + // ; ebx: part 1 of 3; CPU signature. + // ; edx: part 2 of 3; CPU signature. + // ; ecx: part 3 of 3; CPU signature. char vbuf[13]; - memcpy (&(vbuf[0]), &(localCPUVendor[0]), sizeof (int)); - memcpy (&(vbuf[4]), &(localCPUVendor[1]), sizeof (int)); + memcpy (&(vbuf[0]), &(localCPUVendor[1]), sizeof (int)); + memcpy (&(vbuf[4]), &(localCPUVendor[3]), sizeof (int)); memcpy (&(vbuf[8]), &(localCPUVendor[2]), sizeof (int)); vbuf[12] = '\0'; this->ChipID.Vendor = vbuf; // Retrieve the family of CPU present. - this->ChipID.ExtendedFamily = ((localCPUSignature & 0x0FF00000) >> 20); // Bits 27..20 Used - this->ChipID.ExtendedModel = ((localCPUSignature & 0x000F0000) >> 16); // Bits 19..16 Used - this->ChipID.Type = ((localCPUSignature & 0x0000F000) >> 12); // Bits 15..12 Used - this->ChipID.Family = ((localCPUSignature & 0x00000F00) >> 8); // Bits 11..8 Used - this->ChipID.Model = ((localCPUSignature & 0x000000F0) >> 4); // Bits 7..4 Used - this->ChipID.Revision = ((localCPUSignature & 0x0000000F) >> 0); // Bits 3..0 Used + // ; eax = 1 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision + // ; ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID + // ; edx: CPU feature flags + this->ChipID.ExtendedFamily = ((localCPUSignature[0] & 0x0FF00000) >> 20); // Bits 27..20 Used + this->ChipID.ExtendedModel = ((localCPUSignature[0] & 0x000F0000) >> 16); // Bits 19..16 Used + this->ChipID.Type = ((localCPUSignature[0] & 0x0000F000) >> 12); // Bits 15..12 Used + this->ChipID.Family = ((localCPUSignature[0] & 0x00000F00) >> 8); // Bits 11..8 Used + this->ChipID.Model = ((localCPUSignature[0] & 0x000000F0) >> 4); // Bits 7..4 Used + this->ChipID.Revision = ((localCPUSignature[0] & 0x0000000F) >> 0); // Bits 3..0 Used return true; @@ -1859,48 +1896,14 @@ bool SystemInformationImplementation::RetrieveCPUIdentity() /** */ bool SystemInformationImplementation::RetrieveCPUCacheDetails() { -#if USE_ASM_INSTRUCTIONS +#if USE_CPUID int L1Cache[4] = { 0, 0, 0, 0 }; int L2Cache[4] = { 0, 0, 0, 0 }; // Check to see if what we are about to do is supported... if (RetrieveCPUExtendedLevelSupport (0x80000005)) { - // Use assembly to retrieve the L1 cache information ... - __try - { - _asm - { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -#endif - ; <> - ; eax = 0x80000005 --> eax: L1 cache information - Part 1 of 4. - ; ebx: L1 cache information - Part 2 of 4. - ; edx: L1 cache information - Part 3 of 4. - ; ecx: L1 cache information - Part 4 of 4. - mov eax, 0x80000005 - CPUID_INSTRUCTION - mov L1Cache[0 * TYPE int], eax - mov L1Cache[1 * TYPE int], ebx - mov L1Cache[2 * TYPE int], ecx - mov L1Cache[3 * TYPE int], edx - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif - } - } - __except(1) + if (!call_cpuid(0x80000005, L1Cache)) { return false; } @@ -1917,41 +1920,7 @@ bool SystemInformationImplementation::RetrieveCPUCacheDetails() // Check to see if what we are about to do is supported... if (RetrieveCPUExtendedLevelSupport (0x80000006)) { - // Use assembly to retrieve the L2 cache information ... - __try - { - _asm - { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -#endif - ; <> - ; eax = 0x80000006 --> eax: L2 cache information - Part 1 of 4. - ; ebx: L2 cache information - Part 2 of 4. - ; edx: L2 cache information - Part 3 of 4. - ; ecx: L2 cache information - Part 4 of 4. - mov eax, 0x80000006 - CPUID_INSTRUCTION - mov L2Cache[0 * TYPE int], eax - mov L2Cache[1 * TYPE int], ebx - mov L2Cache[2 * TYPE int], ecx - mov L2Cache[3 * TYPE int], edx - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif - } - } - __except(1) + if (!call_cpuid(0x80000006, L2Cache)) { return false; } @@ -1977,7 +1946,7 @@ bool SystemInformationImplementation::RetrieveCPUCacheDetails() /** */ bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails() { -#if USE_ASM_INSTRUCTIONS +#if USE_CPUID int TLBCode = -1, TLBData = -1, L1Code = -1, L1Data = -1, L1Trace = -1, L2Unified = -1, L3Unified = -1; int TLBCacheData[4] = { 0, 0, 0, 0 }; int TLBPassCounter = 0; @@ -1985,39 +1954,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUCacheDetails() do { - // Use assembly to retrieve the L2 cache information ... - __try { - _asm { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -#endif - ; <> - ; eax = 2 --> eax: TLB and cache information - Part 1 of 4. - ; ebx: TLB and cache information - Part 2 of 4. - ; ecx: TLB and cache information - Part 3 of 4. - ; edx: TLB and cache information - Part 4 of 4. - mov eax, 2 - CPUID_INSTRUCTION - mov TLBCacheData[0 * TYPE int], eax - mov TLBCacheData[1 * TYPE int], ebx - mov TLBCacheData[2 * TYPE int], ecx - mov TLBCacheData[3 * TYPE int], edx - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif - } - } - __except(1) + if (!call_cpuid(2, TLBCacheData)) { return false; } @@ -2184,11 +2121,40 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed() bool retrieved = false; #if defined(_WIN32) - // First of all we check to see if the RDTSC (0x0F, 0x31) instruction is - // supported. If not, we fallback to trying to read this value from the - // registry: - // - if (!this->Features.HasTSC) + unsigned int uiRepetitions = 1; + unsigned int uiMSecPerRepetition = 50; + __int64 i64Total = 0; + __int64 i64Overhead = 0; + + // Check if the TSC implementation works at all + if (this->Features.HasTSC && + GetCyclesDifference(SystemInformationImplementation::Delay, + uiMSecPerRepetition) > 0) + { + for (unsigned int nCounter = 0; nCounter < uiRepetitions; nCounter ++) + { + i64Total += GetCyclesDifference (SystemInformationImplementation::Delay, + uiMSecPerRepetition); + i64Overhead += + GetCyclesDifference (SystemInformationImplementation::DelayOverhead, + uiMSecPerRepetition); + } + + // Calculate the MHz speed. + i64Total -= i64Overhead; + i64Total /= uiRepetitions; + i64Total /= uiMSecPerRepetition; + i64Total /= 1000; + + // Save the CPU speed. + this->CPUSpeedInMHz = (float) i64Total; + + retrieved = true; + } + + // If RDTSC is not supported, we fallback to trying to read this value + // from the registry: + if (!retrieved) { HKEY hKey = NULL; LONG err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, @@ -2213,34 +2179,7 @@ bool SystemInformationImplementation::RetrieveCPUClockSpeed() RegCloseKey(hKey); hKey = NULL; } - - return retrieved; } - - unsigned int uiRepetitions = 1; - unsigned int uiMSecPerRepetition = 50; - __int64 i64Total = 0; - __int64 i64Overhead = 0; - - for (unsigned int nCounter = 0; nCounter < uiRepetitions; nCounter ++) - { - i64Total += GetCyclesDifference (SystemInformationImplementation::Delay, - uiMSecPerRepetition); - i64Overhead += - GetCyclesDifference (SystemInformationImplementation::DelayOverhead, - uiMSecPerRepetition); - } - - // Calculate the MHz speed. - i64Total -= i64Overhead; - i64Total /= uiRepetitions; - i64Total /= uiMSecPerRepetition; - i64Total /= 1000; - - // Save the CPU speed. - this->CPUSpeedInMHz = (float) i64Total; - - retrieved = true; #endif return retrieved; @@ -2312,7 +2251,7 @@ bool SystemInformationImplementation::RetrieveClassicalCPUClockSpeed() /** */ bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULevelToCheck) { - int MaxCPUExtendedLevel = 0; + int cpuinfo[4] = { 0, 0, 0, 0 }; // The extended CPUID is supported by various vendors starting with the following CPU models: // @@ -2355,35 +2294,8 @@ bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULev } } -#if USE_ASM_INSTRUCTIONS - - // Use assembly to detect CPUID information... - __try { - _asm { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -#endif - ; <> - ; eax = 0x80000000 --> eax: maximum supported extended level - mov eax,0x80000000 - CPUID_INSTRUCTION - mov MaxCPUExtendedLevel, eax - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif - } - } - __except(1) +#if USE_CPUID + if (!call_cpuid(0x80000000, cpuinfo)) { return false; } @@ -2391,7 +2303,7 @@ bool SystemInformationImplementation::RetrieveCPUExtendedLevelSupport(int CPULev // Now we have to check the level wanted vs level returned... int nLevelWanted = (CPULevelToCheck & 0x7FFFFFFF); - int nLevelReturn = (MaxCPUExtendedLevel & 0x7FFFFFFF); + int nLevelReturn = (cpuinfo[0] & 0x7FFFFFFF); // Check to see if the level provided is supported... if (nLevelWanted > nLevelReturn) @@ -2419,60 +2331,30 @@ bool SystemInformationImplementation::RetrieveExtendedCPUFeatures() return false; } -#if USE_ASM_INSTRUCTIONS - int localCPUExtendedFeatures = 0; +#if USE_CPUID + int localCPUExtendedFeatures[4] = { 0, 0, 0, 0 }; - // Use assembly to detect CPUID information... - __try - { - _asm - { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -#endif - ; <> - ; eax = 0x80000001 --> eax: CPU ID - bits 31..16 - unused, bits 15..12 - type, bits 11..8 - family, bits 7..4 - model, bits 3..0 - mask revision - ; ebx: 31..24 - default APIC ID, 23..16 - logical processor ID, 15..8 - CFLUSH chunk size , 7..0 - brand ID - ; edx: CPU feature flags - mov eax,0x80000001 - CPUID_INSTRUCTION - mov localCPUExtendedFeatures, edx - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif - } - } - __except(1) + if (!call_cpuid(0x80000001, localCPUExtendedFeatures)) { return false; } // Retrieve the extended features of CPU present. - this->Features.ExtendedFeatures.Has3DNow = ((localCPUExtendedFeatures & 0x80000000) != 0); // 3DNow Present --> Bit 31. - this->Features.ExtendedFeatures.Has3DNowPlus = ((localCPUExtendedFeatures & 0x40000000) != 0); // 3DNow+ Present -- > Bit 30. - this->Features.ExtendedFeatures.HasSSEMMX = ((localCPUExtendedFeatures & 0x00400000) != 0); // SSE MMX Present --> Bit 22. - this->Features.ExtendedFeatures.SupportsMP = ((localCPUExtendedFeatures & 0x00080000) != 0); // MP Capable -- > Bit 19. + this->Features.ExtendedFeatures.Has3DNow = ((localCPUExtendedFeatures[3] & 0x80000000) != 0); // 3DNow Present --> Bit 31. + this->Features.ExtendedFeatures.Has3DNowPlus = ((localCPUExtendedFeatures[3] & 0x40000000) != 0); // 3DNow+ Present -- > Bit 30. + this->Features.ExtendedFeatures.HasSSEMMX = ((localCPUExtendedFeatures[3] & 0x00400000) != 0); // SSE MMX Present --> Bit 22. + this->Features.ExtendedFeatures.SupportsMP = ((localCPUExtendedFeatures[3] & 0x00080000) != 0); // MP Capable -- > Bit 19. // Retrieve AMD specific extended features. if (this->ChipManufacturer == AMD) { - this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures & 0x00400000) != 0); // AMD specific: MMX-SSE --> Bit 22 + this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures[3] & 0x00400000) != 0); // AMD specific: MMX-SSE --> Bit 22 } // Retrieve Cyrix specific extended features. if (this->ChipManufacturer == Cyrix) { - this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures & 0x01000000) != 0); // Cyrix specific: Extended MMX --> Bit 24 + this->Features.ExtendedFeatures.HasMMXPlus = ((localCPUExtendedFeatures[3] & 0x01000000) != 0); // Cyrix specific: Extended MMX --> Bit 24 } return true; @@ -2492,51 +2374,20 @@ bool SystemInformationImplementation::RetrieveProcessorSerialNumber() return false; } -#if USE_ASM_INSTRUCTIONS - int SerialNumber[3]; +#if USE_CPUID + int SerialNumber[4]; - // Use assembly to detect CPUID information... - __try { - _asm { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -#endif - ; <> - ; eax = 3 --> ebx: top 32 bits are the processor signature bits --> NB: Transmeta only ?!? - ; ecx: middle 32 bits are the processor signature bits - ; edx: bottom 32 bits are the processor signature bits - mov eax, 3 - CPUID_INSTRUCTION - mov SerialNumber[0 * TYPE int], ebx - mov SerialNumber[1 * TYPE int], ecx - mov SerialNumber[2 * TYPE int], edx - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif - } - } - __except(1) + if (!call_cpuid(3, SerialNumber)) { return false; } // Process the returned information. + // ; eax = 3 --> ebx: top 32 bits are the processor signature bits --> NB: Transmeta only ?!? + // ; ecx: middle 32 bits are the processor signature bits + // ; edx: bottom 32 bits are the processor signature bits char sn[128]; sprintf (sn, "%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x-%.2x%.2x", - ((SerialNumber[0] & 0xff000000) >> 24), - ((SerialNumber[0] & 0x00ff0000) >> 16), - ((SerialNumber[0] & 0x0000ff00) >> 8), - ((SerialNumber[0] & 0x000000ff) >> 0), ((SerialNumber[1] & 0xff000000) >> 24), ((SerialNumber[1] & 0x00ff0000) >> 16), ((SerialNumber[1] & 0x0000ff00) >> 8), @@ -2544,7 +2395,11 @@ bool SystemInformationImplementation::RetrieveProcessorSerialNumber() ((SerialNumber[2] & 0xff000000) >> 24), ((SerialNumber[2] & 0x00ff0000) >> 16), ((SerialNumber[2] & 0x0000ff00) >> 8), - ((SerialNumber[2] & 0x000000ff) >> 0)); + ((SerialNumber[2] & 0x000000ff) >> 0), + ((SerialNumber[3] & 0xff000000) >> 24), + ((SerialNumber[3] & 0x00ff0000) >> 16), + ((SerialNumber[3] & 0x0000ff00) >> 8), + ((SerialNumber[3] & 0x000000ff) >> 0)); this->ChipID.SerialNumber = sn; return true; @@ -2566,45 +2421,18 @@ bool SystemInformationImplementation::RetrieveCPUPowerManagement() return false; } -#if USE_ASM_INSTRUCTIONS - int localCPUPowerManagement = 0; +#if USE_CPUID + int localCPUPowerManagement[4] = { 0, 0, 0, 0 }; - - // Use assembly to detect CPUID information... - __try { - _asm { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -#endif - ; <> - ; eax = 0x80000007 --> edx: get processor power management - mov eax,0x80000007 - CPUID_INSTRUCTION - mov localCPUPowerManagement, edx - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif - } - } - __except(1) + if (!call_cpuid(0x80000007, localCPUPowerManagement)) { return false; } // Check for the power management capabilities of the CPU. - this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode = ((localCPUPowerManagement & 0x00000001) != 0); - this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID = ((localCPUPowerManagement & 0x00000002) != 0); - this->Features.ExtendedFeatures.PowerManagement.HasVoltageID = ((localCPUPowerManagement & 0x00000004) != 0); + this->Features.ExtendedFeatures.PowerManagement.HasTempSenseDiode = ((localCPUPowerManagement[3] & 0x00000001) != 0); + this->Features.ExtendedFeatures.PowerManagement.HasFrequencyID = ((localCPUPowerManagement[3] & 0x00000002) != 0); + this->Features.ExtendedFeatures.PowerManagement.HasVoltageID = ((localCPUPowerManagement[3] & 0x00000004) != 0); return true; @@ -2634,57 +2462,18 @@ bool SystemInformationImplementation::RetrieveExtendedCPUIdentity() if (!RetrieveCPUExtendedLevelSupport(static_cast(0x80000004))) return false; -#if USE_ASM_INSTRUCTIONS +#if USE_CPUID int CPUExtendedIdentity[12]; - // Use assembly to detect CPUID information... - __try { - _asm { -#ifdef CPUID_AWARE_COMPILER - ; we must push/pop the registers <> writes to, as the - ; optimiser doesn't know about <>, and so doesn't expect - ; these registers to change. - push eax - push ebx - push ecx - push edx -#endif - ; <> - ; eax = 0x80000002 --> eax, ebx, ecx, edx: get processor name string (part 1) - mov eax,0x80000002 - CPUID_INSTRUCTION - mov CPUExtendedIdentity[0 * TYPE int], eax - mov CPUExtendedIdentity[1 * TYPE int], ebx - mov CPUExtendedIdentity[2 * TYPE int], ecx - mov CPUExtendedIdentity[3 * TYPE int], edx - - ; <> - ; eax = 0x80000003 --> eax, ebx, ecx, edx: get processor name string (part 2) - mov eax,0x80000003 - CPUID_INSTRUCTION - mov CPUExtendedIdentity[4 * TYPE int], eax - mov CPUExtendedIdentity[5 * TYPE int], ebx - mov CPUExtendedIdentity[6 * TYPE int], ecx - mov CPUExtendedIdentity[7 * TYPE int], edx - - ; <> - ; eax = 0x80000004 --> eax, ebx, ecx, edx: get processor name string (part 3) - mov eax,0x80000004 - CPUID_INSTRUCTION - mov CPUExtendedIdentity[8 * TYPE int], eax - mov CPUExtendedIdentity[9 * TYPE int], ebx - mov CPUExtendedIdentity[10 * TYPE int], ecx - mov CPUExtendedIdentity[11 * TYPE int], edx - -#ifdef CPUID_AWARE_COMPILER - pop edx - pop ecx - pop ebx - pop eax -#endif + if (!call_cpuid(0x80000002, CPUExtendedIdentity)) + { + return false; } - } - __except(1) + if (!call_cpuid(0x80000003, CPUExtendedIdentity + 4)) + { + return false; + } + if (!call_cpuid(0x80000004, CPUExtendedIdentity + 8)) { return false; } @@ -3022,7 +2811,7 @@ kwsys_stl::string SystemInformationImplementation::ExtractValueFromCpuInfoFile(k } /** Query for the cpu status */ -int SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() +bool SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() { this->NumberOfLogicalCPU = 0; this->NumberOfPhysicalCPU = 0; @@ -3032,7 +2821,7 @@ int SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() if ( !fd ) { kwsys_ios::cout << "Problem opening /proc/cpuinfo" << kwsys_ios::endl; - return 0; + return false; } size_t fileSize = 0; @@ -3171,7 +2960,79 @@ int SystemInformationImplementation::RetreiveInformationFromCpuInfoFile() this->Features.L1CacheSize += atoi(cacheSize.c_str()); } } - return 1; + + // processor feature flags (probably x86 specific) + kwsys_stl::string cpuflags = this->ExtractValueFromCpuInfoFile(buffer,"flags"); + if(!cpurev.empty()) + { + // now we can match every flags as space + flag + space + cpuflags = " " + cpuflags + " "; + if ((cpuflags.find(" fpu ")!=kwsys_stl::string::npos)) + { + this->Features.HasFPU = true; + } + if ((cpuflags.find(" tsc ")!=kwsys_stl::string::npos)) + { + this->Features.HasTSC = true; + } + if ((cpuflags.find(" mmx ")!=kwsys_stl::string::npos)) + { + this->Features.HasMMX = true; + } + if ((cpuflags.find(" sse ")!=kwsys_stl::string::npos)) + { + this->Features.HasSSE = true; + } + if ((cpuflags.find(" sse2 ")!=kwsys_stl::string::npos)) + { + this->Features.HasSSE2 = true; + } + if ((cpuflags.find(" apic ")!=kwsys_stl::string::npos)) + { + this->Features.HasAPIC = true; + } + if ((cpuflags.find(" cmov ")!=kwsys_stl::string::npos)) + { + this->Features.HasCMOV = true; + } + if ((cpuflags.find(" mtrr ")!=kwsys_stl::string::npos)) + { + this->Features.HasMTRR = true; + } + if ((cpuflags.find(" acpi ")!=kwsys_stl::string::npos)) + { + this->Features.HasACPI = true; + } + if ((cpuflags.find(" 3dnow ")!=kwsys_stl::string::npos)) + { + this->Features.ExtendedFeatures.Has3DNow = true; + } + } + + return true; +} + +bool SystemInformationImplementation::QueryProcessor() +{ +#if defined(_SC_NPROC_ONLN) && !defined(_SC_NPROCESSORS_ONLN) +// IRIX names this slightly different +# define _SC_NPROCESSORS_ONLN _SC_NPROC_ONLN +#endif + +#ifdef _SC_NPROCESSORS_ONLN + long c = sysconf(_SC_NPROCESSORS_ONLN); + if (c <= 0) + { + return false; + } + + this->NumberOfPhysicalCPU = c; + this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU; + + return true; +#else + return false; +#endif } /** @@ -3501,16 +3362,9 @@ void SystemInformationImplementation::SetStackTraceOnError(int enable) #endif } -/** Query for the memory status */ -int SystemInformationImplementation::QueryMemory() +bool SystemInformationImplementation::QueryWindowsMemory() { - this->TotalVirtualMemory = 0; - this->TotalPhysicalMemory = 0; - this->AvailableVirtualMemory = 0; - this->AvailablePhysicalMemory = 0; -#ifdef __CYGWIN__ - return 0; -#elif defined(_WIN32) +#if defined(_WIN32) # if defined(_MSC_VER) && _MSC_VER < 1300 MEMORYSTATUS ms; unsigned long tv, tp, av, ap; @@ -3535,8 +3389,15 @@ int SystemInformationImplementation::QueryMemory() this->TotalPhysicalMemory = tp>>10>>10; this->AvailableVirtualMemory = av>>10>>10; this->AvailablePhysicalMemory = ap>>10>>10; - return 1; -#elif defined(__linux) + return true; +#else + return false; +#endif +} + +bool SystemInformationImplementation::QueryLinuxMemory() +{ +#if defined(__linux) unsigned long tv=0; unsigned long tp=0; unsigned long av=0; @@ -3553,7 +3414,7 @@ int SystemInformationImplementation::QueryMemory() if( errorFlag!=0 ) { kwsys_ios::cout << "Problem calling uname(): " << strerror(errno) << kwsys_ios::endl; - return 0; + return false; } if( unameInfo.release!=0 && strlen(unameInfo.release)>=3 ) @@ -3577,7 +3438,7 @@ int SystemInformationImplementation::QueryMemory() if ( !fd ) { kwsys_ios::cout << "Problem opening /proc/meminfo" << kwsys_ios::endl; - return 0; + return false; } if( linuxMajor>=3 || ( (linuxMajor>=2) && (linuxMinor>=6) ) ) @@ -3616,7 +3477,7 @@ int SystemInformationImplementation::QueryMemory() { kwsys_ios::cout << "Problem parsing /proc/meminfo" << kwsys_ios::endl; fclose(fd); - return 0; + return false; } } else @@ -3648,39 +3509,87 @@ int SystemInformationImplementation::QueryMemory() { kwsys_ios::cout << "Problem parsing /proc/meminfo" << kwsys_ios::endl; fclose(fd); - return 0; + return false; } } fclose( fd ); - return 1; -#elif defined(__hpux) - unsigned long tv=0; - unsigned long tp=0; - unsigned long av=0; - unsigned long ap=0; - struct pst_static pst; - struct pst_dynamic pdy; - unsigned long ps = 0; - if (pstat_getstatic(&pst, sizeof(pst), (size_t) 1, 0) != -1) - { - ps = pst.page_size; - tp = pst.physical_memory *ps; - tv = (pst.physical_memory + pst.pst_maxmem) * ps; - if (pstat_getdynamic(&pdy, sizeof(pdy), (size_t) 1, 0) != -1) - { - ap = tp - pdy.psd_rm * ps; - av = tv - pdy.psd_vm; - this->TotalVirtualMemory = tv>>10>>10; - this->TotalPhysicalMemory = tp>>10>>10; - this->AvailableVirtualMemory = av>>10>>10; - this->AvailablePhysicalMemory = ap>>10>>10; - return 1; - } - } - return 0; + return true; #else - return 0; + return false; +#endif +} + +bool SystemInformationImplementation::QueryCygwinMemory() +{ +#ifdef __CYGWIN__ + // _SC_PAGE_SIZE does return the mmap() granularity on Cygwin, + // see http://cygwin.com/ml/cygwin/2006-06/msg00350.html + // Therefore just use 4096 as the page size of Windows. + long m = sysconf(_SC_PHYS_PAGES); + if (m < 0) + { + return false; + } + this->TotalPhysicalMemory = m >> 8; + return true; +#else + return false; +#endif +} + +bool SystemInformationImplementation::QueryAIXMemory() +{ +#if defined(_AIX) + long c = sysconf(_SC_AIX_REALMEM); + if (c <= 0) + { + return false; + } + + this->TotalPhysicalMemory = c / 1024; + + return true; +#else + return false; +#endif +} + +/** Query for the memory status */ +bool SystemInformationImplementation::QueryMemory() +{ +#if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) + // Assume the mmap() granularity as returned by _SC_PAGESIZE is also + // the system page size. The only known system where this isn't true + // is Cygwin. + long p = sysconf(_SC_PHYS_PAGES); + long m = sysconf(_SC_PAGESIZE); + + if (p < 0 || m < 0) + { + return false; + } + + // assume pagesize is a power of 2 and smaller 1 MiB + size_t pagediv = (1024 * 1024 / m); + + this->TotalPhysicalMemory = p; + this->TotalPhysicalMemory /= pagediv; + +#if defined(_SC_AVPHYS_PAGES) + p = sysconf(_SC_AVPHYS_PAGES); + if (p < 0) + { + return false; + } + + this->AvailablePhysicalMemory = p; + this->AvailablePhysicalMemory /= pagediv; +#endif + + return true; +#else + return false; #endif } @@ -3712,7 +3621,15 @@ SystemInformation::LongLong SystemInformationImplementation::GetCyclesDifference (DELAY_FUNC DelayFunction, unsigned int uiParameter) { -#if USE_ASM_INSTRUCTIONS +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + unsigned __int64 stamp1, stamp2; + + stamp1 = __rdtsc(); + DelayFunction(uiParameter); + stamp2 = __rdtsc(); + + return stamp2 - stamp1; +#elif USE_ASM_INSTRUCTIONS unsigned int edx1, eax1; unsigned int edx2, eax2; @@ -3794,20 +3711,15 @@ unsigned char SystemInformationImplementation::LogicalCPUPerPhysicalCPU(void) } return static_cast(cores_per_package); #else - unsigned int Regebx = 0; -#if USE_ASM_INSTRUCTIONS + int Regs[4] = { 0, 0, 0, 0 }; +#if USE_CPUID if (!this->IsHyperThreadingSupported()) { return static_cast(1); // HT not supported } - __asm - { - mov eax, 1 - cpuid - mov Regebx, ebx - } + call_cpuid(1, Regs); #endif - return static_cast ((Regebx & NUM_LOGICAL_BITS) >> 16); + return static_cast ((Regs[1] & NUM_LOGICAL_BITS) >> 16); #endif } @@ -3815,40 +3727,30 @@ unsigned char SystemInformationImplementation::LogicalCPUPerPhysicalCPU(void) /** Works only for windows */ unsigned int SystemInformationImplementation::IsHyperThreadingSupported() { -#if USE_ASM_INSTRUCTIONS - unsigned int Regedx = 0, - Regeax = 0, - VendorId[3] = {0, 0, 0}; - __try // Verify cpuid instruction is supported +#if USE_CPUID + int Regs[4] = { 0, 0, 0, 0 }, + VendorId[4] = { 0, 0, 0, 0 }; + // Get vendor id string + if (!call_cpuid(0, VendorId)) { - __asm - { - xor eax, eax // call cpuid with eax = 0 - cpuid // Get vendor id string - mov VendorId, ebx - mov VendorId + 4, edx - mov VendorId + 8, ecx - - mov eax, 1 // call cpuid with eax = 1 - cpuid - mov Regeax, eax // eax contains family processor type - mov Regedx, edx // edx has info about the availability of hyper-Threading - } + return false; } - __except (EXCEPTION_EXECUTE_HANDLER) + // eax contains family processor type + // edx has info about the availability of hyper-Threading + if (!call_cpuid(1, Regs)) { - return(0); // cpuid is unavailable + return false; } - if (((Regeax & FAMILY_ID) == PENTIUM4_ID) || (Regeax & EXT_FAMILY_ID)) + if (((Regs[0] & FAMILY_ID) == PENTIUM4_ID) || (Regs[0] & EXT_FAMILY_ID)) { - if (VendorId[0] == 'uneG') + if (VendorId[1] == 'uneG') { - if (VendorId[1] == 'Ieni') + if (VendorId[3] == 'Ieni') { if (VendorId[2] == 'letn') { - return(Regedx & HT_BIT); // Genuine Intel with hyper-Threading technology + return(Regs[3] & HT_BIT); // Genuine Intel with hyper-Threading technology } } } @@ -3862,22 +3764,17 @@ unsigned int SystemInformationImplementation::IsHyperThreadingSupported() /** Return the APIC Id. Works only for windows. */ unsigned char SystemInformationImplementation::GetAPICId() { - unsigned int Regebx = 0; + int Regs[4] = { 0, 0, 0, 0 }; -#if USE_ASM_INSTRUCTIONS +#if USE_CPUID if (!this->IsHyperThreadingSupported()) { return static_cast(-1); // HT not supported } // Logical processor = 1 - __asm - { - mov eax, 1 - cpuid - mov Regebx, ebx - } + call_cpuid(1, Regs); #endif - return static_cast((Regebx & INITIAL_APIC_ID_BITS) >> 24); + return static_cast((Regs[1] & INITIAL_APIC_ID_BITS) >> 24); } @@ -4284,25 +4181,24 @@ bool SystemInformationImplementation::QuerySolarisInfo() this->NumberOfPhysicalCPU = static_cast( atoi(this->ParseValueFromKStat("-n syste_misc -s ncpus").c_str())); this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU; - - if(this->NumberOfPhysicalCPU!=0) - { - this->NumberOfLogicalCPU /= this->NumberOfPhysicalCPU; - } + this->Features.ExtendedFeatures.LogicalProcessorsPerPhysical = 1; this->CPUSpeedInMHz = static_cast(atoi(this->ParseValueFromKStat("-s clock_MHz").c_str())); // Chip family this->ChipID.Family = 0; - // Chip Vendor - this->ChipID.Vendor = "Sun"; - this->FindManufacturer(); - // Chip Model this->ChipID.ProcessorName = this->ParseValueFromKStat("-s cpu_type"); this->ChipID.Model = 0; + // Chip Vendor + if (this->ChipID.ProcessorName != "i386") + { + this->ChipID.Vendor = "Sun"; + this->FindManufacturer(); + } + // Cache size this->Features.L1CacheSize = 0; this->Features.L2CacheSize = 0; @@ -4310,9 +4206,7 @@ bool SystemInformationImplementation::QuerySolarisInfo() char* tail; unsigned long totalMemory = strtoul(this->ParseValueFromKStat("-s physmem").c_str(),&tail,0); - this->TotalPhysicalMemory = totalMemory/1024; - this->TotalPhysicalMemory *= 8192; - this->TotalPhysicalMemory /= 1024; + this->TotalPhysicalMemory = totalMemory/128; // Undefined values (for now at least) this->TotalVirtualMemory = 0; @@ -4426,6 +4320,31 @@ bool SystemInformationImplementation::QueryQNXMemory() return false; } +bool SystemInformationImplementation::QueryBSDMemory() +{ +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) + int ctrl[2] = { CTL_HW, HW_PHYSMEM }; +#if defined(HW_PHYSMEM64) + int64_t k; + ctrl[1] = HW_PHYSMEM64; +#else + int k; +#endif + size_t sz = sizeof(k); + + if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) + { + return false; + } + + this->TotalPhysicalMemory = k>>10>>10; + + return true; +#else + return false; +#endif +} + bool SystemInformationImplementation::QueryQNXProcessor() { #if defined(__QNX__) @@ -4479,6 +4398,124 @@ bool SystemInformationImplementation::QueryQNXProcessor() #endif } +bool SystemInformationImplementation::QueryBSDProcessor() +{ +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) + int k; + size_t sz = sizeof(k); + int ctrl[2] = { CTL_HW, HW_NCPU }; + + if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) + { + return false; + } + + this->NumberOfPhysicalCPU = k; + this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU; + +#if defined(HW_CPUSPEED) + ctrl[1] = HW_CPUSPEED; + + if (sysctl(ctrl, 2, &k, &sz, NULL, 0) != 0) + { + return false; + } + + this->CPUSpeedInMHz = (float) k; +#endif + + return true; +#else + return false; +#endif +} + +bool SystemInformationImplementation::QueryHPUXMemory() +{ +#if defined(__hpux) + unsigned long tv=0; + unsigned long tp=0; + unsigned long av=0; + unsigned long ap=0; + struct pst_static pst; + struct pst_dynamic pdy; + + unsigned long ps = 0; + if (pstat_getstatic(&pst, sizeof(pst), (size_t) 1, 0) == -1) + { + return false; + } + + ps = pst.page_size; + tp = pst.physical_memory *ps; + tv = (pst.physical_memory + pst.pst_maxmem) * ps; + if (pstat_getdynamic(&pdy, sizeof(pdy), (size_t) 1, 0) == -1) + { + return false; + } + + ap = tp - pdy.psd_rm * ps; + av = tv - pdy.psd_vm; + this->TotalVirtualMemory = tv>>10>>10; + this->TotalPhysicalMemory = tp>>10>>10; + this->AvailableVirtualMemory = av>>10>>10; + this->AvailablePhysicalMemory = ap>>10>>10; + return true; +#else + return false; +#endif +} + +bool SystemInformationImplementation::QueryHPUXProcessor() +{ +#if defined(__hpux) +# if defined(KWSYS_SYS_HAS_MPCTL_H) + int c = mpctl(MPC_GETNUMSPUS_SYS, 0, 0); + if (c <= 0) + { + return false; + } + + this->NumberOfPhysicalCPU = c; + this->NumberOfLogicalCPU = this->NumberOfPhysicalCPU; + + long t = sysconf(_SC_CPU_VERSION); + + if (t == -1) + { + return false; + } + + switch (t) + { + case CPU_PA_RISC1_0: + this->ChipID.Vendor = "Hewlett-Packard"; + this->ChipID.Family = 0x100; + case CPU_PA_RISC1_1: + this->ChipID.Vendor = "Hewlett-Packard"; + this->ChipID.Family = 0x110; + case CPU_PA_RISC2_0: + this->ChipID.Vendor = "Hewlett-Packard"; + this->ChipID.Family = 0x200; + case CPU_IA64_ARCHREV_0: + this->ChipID.Vendor = "GenuineIntel"; + this->Features.HasIA64 = true; + break; + default: + return false; + } + + this->FindManufacturer(); + + return true; +# else + return false; +# endif +#else + return false; +#endif +} + /** Query the operating system information */ bool SystemInformationImplementation::QueryOSInformation() { diff --git a/SystemTools.cxx b/SystemTools.cxx index 1054d6526..b75993ea6 100644 --- a/SystemTools.cxx +++ b/SystemTools.cxx @@ -157,7 +157,7 @@ public: #include #endif -#if defined(__BEOS__) && !defined(__ZETA__) && !defined(__HAIKU__) +#if defined(__BEOS__) && !defined(__ZETA__) #include #include @@ -622,11 +622,7 @@ bool SystemTools::MakeDirectory(const char* path) } SystemTools::ConvertToUnixSlashes(dir); - kwsys_stl::string::size_type pos = dir.find(':'); - if(pos == kwsys_stl::string::npos) - { - pos = 0; - } + kwsys_stl::string::size_type pos = 0; kwsys_stl::string topdir; while((pos = dir.find('/', pos)) != kwsys_stl::string::npos) { @@ -634,14 +630,7 @@ bool SystemTools::MakeDirectory(const char* path) Mkdir(topdir.c_str()); pos++; } - if(dir[dir.size()-1] == '/') - { - topdir = dir.substr(0, dir.size()); - } - else - { - topdir = dir; - } + topdir = dir; if(Mkdir(topdir.c_str()) != 0) { // There is a bug in the Borland Run time library which makes MKDIR @@ -4054,7 +4043,7 @@ kwsys_stl::string SystemTools::GetCurrentDateTime(const char* format) return kwsys_stl::string(buf); } -kwsys_stl::string SystemTools::MakeCindentifier(const char* s) +kwsys_stl::string SystemTools::MakeCidentifier(const char* s) { kwsys_stl::string str(s); if (str.find_first_of("0123456789") == 0) diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in index 5171125ce..9c56e96b0 100644 --- a/SystemTools.hxx.in +++ b/SystemTools.hxx.in @@ -91,8 +91,13 @@ public: * then an underscore is prepended. Note that this can produce * identifiers that the standard reserves (_[A-Z].* and __.*). */ - static kwsys_stl::string MakeCindentifier(const char* s); - + static kwsys_stl::string MakeCidentifier(const char* s); + + static kwsys_stl::string MakeCindentifier(const char* s) + { + return MakeCidentifier(s); + } + /** * Replace replace all occurences of the string in the source string. */ diff --git a/testDynamicLoader.cxx b/testDynamicLoader.cxx index a7adbcad9..cbfb65b1c 100644 --- a/testDynamicLoader.cxx +++ b/testDynamicLoader.cxx @@ -15,7 +15,7 @@ #include KWSYS_HEADER(ios/iostream) #include KWSYS_HEADER(stl/string) -#if defined(__BEOS__) && !defined(__HAIKU__) +#if defined(__BEOS__) #include /* disable_debugger() API. */ #endif diff --git a/testProcess.c b/testProcess.c index ec561ead7..269b84ba8 100644 --- a/testProcess.c +++ b/testProcess.c @@ -32,7 +32,7 @@ # pragma warn -8060 /* possibly incorrect assignment */ #endif -#if defined(__BEOS__) && !defined(__ZETA__) && !defined(__HAIKU__) +#if defined(__BEOS__) && !defined(__ZETA__) /* BeOS 5 doesn't have usleep(), but it has snooze(), which is identical. */ # include static inline void testProcess_usleep(unsigned int msec) diff --git a/testSystemInformation.cxx b/testSystemInformation.cxx index cfd7ce210..49a686c17 100644 --- a/testSystemInformation.cxx +++ b/testSystemInformation.cxx @@ -47,6 +47,8 @@ int testSystemInformation(int, char*[]) { + kwsys_ios::cout << "CTEST_FULL_OUTPUT\n"; // avoid truncation + kwsys::SystemInformation info; info.RunCPUCheck(); info.RunOSCheck(); @@ -86,6 +88,13 @@ int testSystemInformation(int, char*[]) printMethod3(info, GetHostMemoryUsed(), "KiB"); printMethod3(info, GetProcMemoryUsed(), "KiB"); + for (int i = 0; i <= 31; i++) + { + if (info.DoesCPUSupportFeature(1 << i)) + { + kwsys_ios::cout << "CPU feature " << i << "\n"; + } + } //int GetProcessorCacheXSize(long int); // bool DoesCPUSupportFeature(long int); return 0; From 40cf3fb95bc391519c0db4be1dc03c49e040579f Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 4 Jan 2013 13:31:01 +0100 Subject: [PATCH 157/170] Make linking APIs aware of 'head' target The 'head' is the dependent target to be linked with the current target. It will be used to evaluate generator expressions with proper handling of mapped configurations and is used as the source target of properties. This requires that memoization is done with a key of a pair of target and config, instead of just config, because now the result also depends on the target. Removing the memoization entirely is not an option because it slows cmake down considerably. --- Source/cmComputeLinkDepends.cxx | 11 +-- Source/cmComputeLinkDepends.h | 3 +- Source/cmComputeLinkInformation.cxx | 11 ++- Source/cmComputeLinkInformation.h | 4 +- Source/cmComputeTargetDepends.cxx | 3 +- Source/cmExportFileGenerator.cxx | 3 +- Source/cmGlobalXCodeGenerator.cxx | 2 +- Source/cmTarget.cxx | 120 ++++++++++++++++++---------- Source/cmTarget.h | 32 +++++--- 9 files changed, 119 insertions(+), 70 deletions(-) diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 055aab032..dec2b54d1 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -172,10 +172,11 @@ satisfy dependencies. //---------------------------------------------------------------------------- cmComputeLinkDepends -::cmComputeLinkDepends(cmTarget* target, const char* config) +::cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget* head) { // Store context information. this->Target = target; + this->HeadTarget = head; this->Makefile = this->Target->GetMakefile(); this->LocalGenerator = this->Makefile->GetLocalGenerator(); this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator(); @@ -352,7 +353,7 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe) { // Follow the target dependencies. if(cmTarget::LinkInterface const* iface = - entry.Target->GetLinkInterface(this->Config)) + entry.Target->GetLinkInterface(this->Config, this->HeadTarget)) { // This target provides its own link interface information. this->AddLinkEntries(depender_index, iface->Libraries); @@ -444,7 +445,7 @@ void cmComputeLinkDepends::HandleSharedDependency(SharedDepEntry const& dep) if(entry.Target) { if(cmTarget::LinkInterface const* iface = - entry.Target->GetLinkInterface(this->Config)) + entry.Target->GetLinkInterface(this->Config, this->HeadTarget)) { // Follow public and private dependencies transitively. this->FollowSharedDeps(index, iface, true); @@ -533,7 +534,7 @@ void cmComputeLinkDepends::AddDirectLinkEntries() { // Add direct link dependencies in this configuration. cmTarget::LinkImplementation const* impl = - this->Target->GetLinkImplementation(this->Config); + this->Target->GetLinkImplementation(this->Config, this->HeadTarget); this->AddLinkEntries(-1, impl->Libraries); for(std::vector::const_iterator wi = impl->WrongConfigLibraries.begin(); @@ -944,7 +945,7 @@ int cmComputeLinkDepends::ComputeComponentCount(NodeList const& nl) if(cmTarget* target = this->EntryList[*ni].Target) { if(cmTarget::LinkInterface const* iface = - target->GetLinkInterface(this->Config)) + target->GetLinkInterface(this->Config, this->HeadTarget)) { if(iface->Multiplicity > count) { diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index 80a04541f..1d5d1b920 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -32,7 +32,7 @@ class cmake; class cmComputeLinkDepends { public: - cmComputeLinkDepends(cmTarget* target, const char* config); + cmComputeLinkDepends(cmTarget* target, const char* config, cmTarget *head); ~cmComputeLinkDepends(); // Basic information about each link item. @@ -59,6 +59,7 @@ private: // Context information. cmTarget* Target; + cmTarget* HeadTarget; cmMakefile* Makefile; cmLocalGenerator* LocalGenerator; cmGlobalGenerator* GlobalGenerator; diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx index d8ffb5e83..504c6e76f 100644 --- a/Source/cmComputeLinkInformation.cxx +++ b/Source/cmComputeLinkInformation.cxx @@ -239,10 +239,12 @@ because this need be done only for shared libraries without soname-s. //---------------------------------------------------------------------------- cmComputeLinkInformation -::cmComputeLinkInformation(cmTarget* target, const char* config) +::cmComputeLinkInformation(cmTarget* target, const char* config, + cmTarget *headTarget) { // Store context information. this->Target = target; + this->HeadTarget = headTarget; this->Makefile = this->Target->GetMakefile(); this->LocalGenerator = this->Makefile->GetLocalGenerator(); this->GlobalGenerator = this->LocalGenerator->GetGlobalGenerator(); @@ -265,7 +267,7 @@ cmComputeLinkInformation this->OrderDependentRPath = 0; // Get the language used for linking this target. - this->LinkLanguage = this->Target->GetLinkerLanguage(config); + this->LinkLanguage = this->Target->GetLinkerLanguage(config, headTarget); if(!this->LinkLanguage) { // The Compute method will do nothing, so skip the rest of the @@ -503,7 +505,7 @@ bool cmComputeLinkInformation::Compute() } // Compute the ordered link line items. - cmComputeLinkDepends cld(this->Target, this->Config); + cmComputeLinkDepends cld(this->Target, this->Config, this->HeadTarget); cld.SetOldLinkDirMode(this->OldLinkDirMode); cmComputeLinkDepends::EntryVector const& linkEntries = cld.Compute(); @@ -569,7 +571,8 @@ bool cmComputeLinkInformation::Compute() void cmComputeLinkInformation::AddImplicitLinkInfo() { // The link closure lists all languages whose implicit info is needed. - cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config); + cmTarget::LinkClosure const* lc=this->Target->GetLinkClosure(this->Config, + this->HeadTarget); for(std::vector::const_iterator li = lc->Languages.begin(); li != lc->Languages.end(); ++li) { diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h index e0078af2a..1a76922a5 100644 --- a/Source/cmComputeLinkInformation.h +++ b/Source/cmComputeLinkInformation.h @@ -29,7 +29,8 @@ class cmOrderDirectories; class cmComputeLinkInformation { public: - cmComputeLinkInformation(cmTarget* target, const char* config); + cmComputeLinkInformation(cmTarget* target, const char* config, + cmTarget* headTarget); ~cmComputeLinkInformation(); bool Compute(); @@ -74,6 +75,7 @@ private: // Context information. cmTarget* Target; + cmTarget* HeadTarget; cmMakefile* Makefile; cmLocalGenerator* LocalGenerator; cmGlobalGenerator* GlobalGenerator; diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 3b15ec11a..c3a75e4b6 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -244,8 +244,9 @@ void cmComputeTargetDepends::AddInterfaceDepends(int depender_index, const char *config, std::set &emitted) { + cmTarget* depender = this->Targets[depender_index]; if(cmTarget::LinkInterface const* iface = - dependee->GetLinkInterface(config)) + dependee->GetLinkInterface(config, depender)) { for(std::vector::const_iterator lib = iface->Libraries.begin(); diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index 2b133be09..90c0c4111 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -357,7 +357,8 @@ cmExportFileGenerator } // Add the transitive link dependencies for this configuration. - if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config)) + if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config, + target)) { this->SetImportLinkProperty(suffix, target, "IMPORTED_LINK_INTERFACE_LANGUAGES", diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index b2d325c8a..4c26b829b 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1206,7 +1206,7 @@ void cmGlobalXCodeGenerator::ForceLinkerLanguage(cmTarget& cmtarget) // If the language is compiled as a source trust Xcode to link with it. cmTarget::LinkImplementation const* impl = - cmtarget.GetLinkImplementation("NOCONFIG"); + cmtarget.GetLinkImplementation("NOCONFIG", &cmtarget); for(std::vector::const_iterator li = impl->Languages.begin(); li != impl->Languages.end(); ++li) { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index ca53a39d2..1338ec491 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -72,6 +72,11 @@ struct cmTarget::ImportInfo cmTarget::LinkInterface LinkInterface; }; +struct TargetConfigPair : public std::pair { + TargetConfigPair(cmTarget* tgt, const std::string &config) + : std::pair(tgt, config) {} +}; + //---------------------------------------------------------------------------- class cmTargetInternals { @@ -100,20 +105,24 @@ public: OptionalLinkInterface(): Exists(false) {} bool Exists; }; - typedef std::map LinkInterfaceMapType; + typedef std::map + LinkInterfaceMapType; LinkInterfaceMapType LinkInterfaceMap; typedef std::map OutputInfoMapType; OutputInfoMapType OutputInfoMap; - typedef std::map ImportInfoMapType; + typedef std::map + ImportInfoMapType; ImportInfoMapType ImportInfoMap; // Cache link implementation computation from each configuration. - typedef std::map LinkImplMapType; + typedef std::map LinkImplMapType; LinkImplMapType LinkImplMap; - typedef std::map LinkClosureMapType; + typedef std::map + LinkClosureMapType; LinkClosureMapType LinkClosureMap; struct SourceEntry { std::vector Depends; }; @@ -3024,8 +3033,11 @@ class cmTargetCollectLinkLanguages { public: cmTargetCollectLinkLanguages(cmTarget* target, const char* config, - std::set& languages): - Config(config), Languages(languages) { this->Visited.insert(target); } + std::set& languages, + cmTarget* head): + Config(config), Languages(languages), HeadTarget(head) + { this->Visited.insert(target); } + void Visit(cmTarget* target) { if(!target || !this->Visited.insert(target).second) @@ -3034,7 +3046,7 @@ public: } cmTarget::LinkInterface const* iface = - target->GetLinkInterface(this->Config); + target->GetLinkInterface(this->Config, this->HeadTarget); if(!iface) { return; } for(std::vector::const_iterator @@ -3053,26 +3065,30 @@ public: private: const char* Config; std::set& Languages; + cmTarget* HeadTarget; std::set Visited; }; //---------------------------------------------------------------------------- -const char* cmTarget::GetLinkerLanguage(const char* config) +const char* cmTarget::GetLinkerLanguage(const char* config, cmTarget *head) { - const char* lang = this->GetLinkClosure(config)->LinkerLanguage.c_str(); + cmTarget *headTarget = head ? head : this; + const char* lang = this->GetLinkClosure(config, headTarget) + ->LinkerLanguage.c_str(); return *lang? lang : 0; } //---------------------------------------------------------------------------- -cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config) +cmTarget::LinkClosure const* cmTarget::GetLinkClosure(const char* config, + cmTarget *head) { - std::string key = cmSystemTools::UpperCase(config? config : ""); + TargetConfigPair key(head, cmSystemTools::UpperCase(config ? config : "")); cmTargetInternals::LinkClosureMapType::iterator i = this->Internal->LinkClosureMap.find(key); if(i == this->Internal->LinkClosureMap.end()) { LinkClosure lc; - this->ComputeLinkClosure(config, lc); + this->ComputeLinkClosure(config, lc, head); cmTargetInternals::LinkClosureMapType::value_type entry(key, lc); i = this->Internal->LinkClosureMap.insert(entry).first; } @@ -3133,11 +3149,12 @@ public: }; //---------------------------------------------------------------------------- -void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc) +void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc, + cmTarget *head) { // Get languages built in this target. std::set languages; - LinkImplementation const* impl = this->GetLinkImplementation(config); + LinkImplementation const* impl = this->GetLinkImplementation(config, head); for(std::vector::const_iterator li = impl->Languages.begin(); li != impl->Languages.end(); ++li) { @@ -3145,7 +3162,7 @@ void cmTarget::ComputeLinkClosure(const char* config, LinkClosure& lc) } // Add interface languages from linked targets. - cmTargetCollectLinkLanguages cll(this, config, languages); + cmTargetCollectLinkLanguages cll(this, config, languages, head); for(std::vector::const_iterator li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) { @@ -3284,7 +3301,8 @@ bool cmTarget::HasSOName(const char* config) return ((this->GetType() == cmTarget::SHARED_LIBRARY || this->GetType() == cmTarget::MODULE_LIBRARY) && !this->GetPropertyAsBool("NO_SONAME") && - this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config))); + this->Makefile->GetSONameFlag(this->GetLinkerLanguage(config, + this))); } //---------------------------------------------------------------------------- @@ -3293,7 +3311,7 @@ std::string cmTarget::GetSOName(const char* config) if(this->IsImported()) { // Lookup the imported soname. - if(cmTarget::ImportInfo const* info = this->GetImportInfo(config)) + if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this)) { if(info->NoSOName) { @@ -3330,7 +3348,7 @@ bool cmTarget::IsImportedSharedLibWithoutSOName(const char* config) { if(this->IsImported() && this->GetType() == cmTarget::SHARED_LIBRARY) { - if(cmTarget::ImportInfo const* info = this->GetImportInfo(config)) + if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this)) { return info->NoSOName; } @@ -3444,7 +3462,7 @@ std::string cmTarget::NormalGetFullPath(const char* config, bool implib, std::string cmTarget::ImportedGetFullPath(const char* config, bool implib) { std::string result; - if(cmTarget::ImportInfo const* info = this->GetImportInfo(config)) + if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, this)) { result = implib? info->ImportLibrary : info->Location; } @@ -3529,7 +3547,7 @@ void cmTarget::GetFullNameInternal(const char* config, const char* suffixVar = this->GetSuffixVariableInternal(implib); // Check for language-specific default prefix and suffix. - if(const char* ll = this->GetLinkerLanguage(config)) + if(const char* ll = this->GetLinkerLanguage(config, this)) { if(!targetSuffix && suffixVar && *suffixVar) { @@ -3900,7 +3918,7 @@ bool cmTarget::NeedRelinkBeforeInstall(const char* config) } // Check for rpath support on this platform. - if(const char* ll = this->GetLinkerLanguage(config)) + if(const char* ll = this->GetLinkerLanguage(config, this)) { std::string flagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_"; flagVar += ll; @@ -4322,7 +4340,7 @@ bool cmTarget::IsChrpathUsed(const char* config) // Enable if the rpath flag uses a separator and the target uses ELF // binaries. - if(const char* ll = this->GetLinkerLanguage(config)) + if(const char* ll = this->GetLinkerLanguage(config, this)) { std::string sepVar = "CMAKE_SHARED_LIBRARY_RUNTIME_"; sepVar += ll; @@ -4346,7 +4364,7 @@ bool cmTarget::IsChrpathUsed(const char* config) //---------------------------------------------------------------------------- cmTarget::ImportInfo const* -cmTarget::GetImportInfo(const char* config) +cmTarget::GetImportInfo(const char* config, cmTarget *headTarget) { // There is no imported information for non-imported targets. if(!this->IsImported()) @@ -4365,14 +4383,16 @@ cmTarget::GetImportInfo(const char* config) { config_upper = "NOCONFIG"; } + TargetConfigPair key(headTarget, config_upper); typedef cmTargetInternals::ImportInfoMapType ImportInfoMapType; + ImportInfoMapType::const_iterator i = - this->Internal->ImportInfoMap.find(config_upper); + this->Internal->ImportInfoMap.find(key); if(i == this->Internal->ImportInfoMap.end()) { ImportInfo info; - this->ComputeImportInfo(config_upper, info); - ImportInfoMapType::value_type entry(config_upper, info); + this->ComputeImportInfo(config_upper, info, headTarget); + ImportInfoMapType::value_type entry(key, info); i = this->Internal->ImportInfoMap.insert(entry).first; } @@ -4511,8 +4531,10 @@ bool cmTarget::GetMappedConfig(std::string const& desired_config, //---------------------------------------------------------------------------- void cmTarget::ComputeImportInfo(std::string const& desired_config, - ImportInfo& info) + ImportInfo& info, + cmTarget *headTarget) { + (void)headTarget; // This method finds information about an imported target from its // properties. The "IMPORTED_" namespace is reserved for properties // defined by the project exporting the target. @@ -4669,12 +4691,13 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config, } //---------------------------------------------------------------------------- -cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config) +cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config, + cmTarget *head) { // Imported targets have their own link interface. if(this->IsImported()) { - if(cmTarget::ImportInfo const* info = this->GetImportInfo(config)) + if(cmTarget::ImportInfo const* info = this->GetImportInfo(config, head)) { return &info->LinkInterface; } @@ -4690,14 +4713,15 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config) } // Lookup any existing link interface for this configuration. - std::string key = cmSystemTools::UpperCase(config? config : ""); + TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : "")); + cmTargetInternals::LinkInterfaceMapType::iterator i = this->Internal->LinkInterfaceMap.find(key); if(i == this->Internal->LinkInterfaceMap.end()) { // Compute the link interface for this configuration. cmTargetInternals::OptionalLinkInterface iface; - iface.Exists = this->ComputeLinkInterface(config, iface); + iface.Exists = this->ComputeLinkInterface(config, iface, head); // Store the information for this configuration. cmTargetInternals::LinkInterfaceMapType::value_type entry(key, iface); @@ -4708,7 +4732,8 @@ cmTarget::LinkInterface const* cmTarget::GetLinkInterface(const char* config) } //---------------------------------------------------------------------------- -bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface) +bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface, + cmTarget *headTarget) { // Construct the property name suffix for this configuration. std::string suffix = "_"; @@ -4765,7 +4790,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface) { emitted.insert(*li); } - LinkImplementation const* impl = this->GetLinkImplementation(config); + LinkImplementation const* impl = this->GetLinkImplementation(config, + headTarget); for(std::vector::const_iterator li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li) { @@ -4793,7 +4819,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface) else { // The link implementation is the default link interface. - LinkImplementation const* impl = this->GetLinkImplementation(config); + LinkImplementation const* impl = this->GetLinkImplementation(config, + headTarget); iface.Libraries = impl->Libraries; iface.WrongConfigLibraries = impl->WrongConfigLibraries; if(this->GetType() == cmTarget::STATIC_LIBRARY) @@ -4825,7 +4852,7 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface) //---------------------------------------------------------------------------- cmTarget::LinkImplementation const* -cmTarget::GetLinkImplementation(const char* config) +cmTarget::GetLinkImplementation(const char* config, cmTarget *head) { // There is no link implementation for imported targets. if(this->IsImported()) @@ -4834,14 +4861,15 @@ cmTarget::GetLinkImplementation(const char* config) } // Lookup any existing link implementation for this configuration. - std::string key = cmSystemTools::UpperCase(config? config : ""); + TargetConfigPair key(head, cmSystemTools::UpperCase(config? config : "")); + cmTargetInternals::LinkImplMapType::iterator i = this->Internal->LinkImplMap.find(key); if(i == this->Internal->LinkImplMap.end()) { // Compute the link implementation for this configuration. LinkImplementation impl; - this->ComputeLinkImplementation(config, impl); + this->ComputeLinkImplementation(config, impl, head); // Store the information for this configuration. cmTargetInternals::LinkImplMapType::value_type entry(key, impl); @@ -4853,8 +4881,10 @@ cmTarget::GetLinkImplementation(const char* config) //---------------------------------------------------------------------------- void cmTarget::ComputeLinkImplementation(const char* config, - LinkImplementation& impl) + LinkImplementation& impl, + cmTarget *head) { + (void)head; // Compute which library configuration to link. cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config); @@ -4977,16 +5007,19 @@ std::string cmTarget::CheckCMP0004(std::string const& item) //---------------------------------------------------------------------------- cmComputeLinkInformation* -cmTarget::GetLinkInformation(const char* config) +cmTarget::GetLinkInformation(const char* config, cmTarget *head) { + cmTarget *headTarget = head ? head : this; // Lookup any existing information for this configuration. - std::map::iterator - i = this->LinkInformation.find(config?config:""); + TargetConfigPair key(headTarget, + cmSystemTools::UpperCase(config?config:"")); + cmTargetLinkInformationMap::iterator + i = this->LinkInformation.find(key); if(i == this->LinkInformation.end()) { // Compute information for this configuration. cmComputeLinkInformation* info = - new cmComputeLinkInformation(this, config); + new cmComputeLinkInformation(this, config, headTarget); if(!info || !info->Compute()) { delete info; @@ -4994,8 +5027,7 @@ cmTarget::GetLinkInformation(const char* config) } // Store the information for this configuration. - std::map::value_type - entry(config?config:"", info); + 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 52d5ca611..29c73b616 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -25,11 +25,13 @@ class cmSourceFile; class cmGlobalGenerator; class cmComputeLinkInformation; class cmListFileBacktrace; +class cmTarget; struct cmTargetLinkInformationMap: - public std::map + public std::map, cmComputeLinkInformation*> { - typedef std::map derived; + typedef std::map, + cmComputeLinkInformation*> derived; cmTargetLinkInformationMap() {} cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r); ~cmTargetLinkInformationMap(); @@ -258,7 +260,8 @@ public: /** Get the link interface for the given configuration. Returns 0 if the target cannot be linked. */ - LinkInterface const* GetLinkInterface(const char* config); + LinkInterface const* GetLinkInterface(const char* config, + cmTarget *headTarget); /** The link implementation specifies the direct library dependencies needed by the object files of the target. */ @@ -274,7 +277,8 @@ public: // Needed only for OLD behavior of CMP0003. std::vector WrongConfigLibraries; }; - LinkImplementation const* GetLinkImplementation(const char* config); + LinkImplementation const* GetLinkImplementation(const char* config, + cmTarget *head); /** Link information from the transitive closure of the link implementation and the interfaces of its dependencies. */ @@ -286,7 +290,7 @@ public: // Languages whose runtime libraries must be linked. std::vector Languages; }; - LinkClosure const* GetLinkClosure(const char* config); + LinkClosure const* GetLinkClosure(const char* config, cmTarget *head); /** Strip off leading and trailing whitespace from an item named in the link dependencies of this target. */ @@ -331,7 +335,7 @@ public: bool FindSourceFiles(); ///! Return the preferred linker language for this target - const char* GetLinkerLanguage(const char* config = 0); + const char* GetLinkerLanguage(const char* config = 0, cmTarget *head = 0); /** Get the full name of the target according to the settings in its makefile. */ @@ -399,7 +403,8 @@ public: std::string GetInstallNameDirForInstallTree(const char* config, bool for_xcode = false); - cmComputeLinkInformation* GetLinkInformation(const char* config); + cmComputeLinkInformation* GetLinkInformation(const char* config, + cmTarget *head = 0); // Get the properties cmPropertyMap &GetProperties() { return this->Properties; }; @@ -597,16 +602,19 @@ private: // Cache import information from properties for each configuration. struct ImportInfo; - ImportInfo const* GetImportInfo(const char* config); - void ComputeImportInfo(std::string const& desired_config, ImportInfo& info); + ImportInfo const* GetImportInfo(const char* config, + cmTarget *workingTarget); + void ComputeImportInfo(std::string const& desired_config, ImportInfo& info, + cmTarget *head); cmTargetLinkInformationMap LinkInformation; - bool ComputeLinkInterface(const char* config, LinkInterface& iface); + bool ComputeLinkInterface(const char* config, LinkInterface& iface, + cmTarget *head); void ComputeLinkImplementation(const char* config, - LinkImplementation& impl); - void ComputeLinkClosure(const char* config, LinkClosure& lc); + LinkImplementation& impl, cmTarget *head); + void ComputeLinkClosure(const char* config, LinkClosure& lc, cmTarget *head); void ClearLinkMaps(); From 765386279815f208c5f83b1ad2b66776e990feb9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 6 Dec 2012 12:14:03 +0100 Subject: [PATCH 158/170] Add LINK_LIBRARIES property for direct target link dependencies Previously we kept direct link dependencies in OriginalLinkLibraries. The property exposes the information in the CMake language through the get/set_property commands. We preserve the OriginalLinkLibraries value internally to support old APIs like that for CMP0003's OLD behavior, but the property is now authoritative. This follows up from commit d5cf644a (Split link information processing into two steps, 2012-11-01). This will be used later to populate the link interface properties when exporting targets, and will later allow use of generator expressions when linking to libraries with target_link_libraries. Also make targets depend on the (config-specific) union of dependencies. CMake now allows linking to dependencies or not depending on the config. However, generated build systems are not all capable of processing config-specific dependencies, so the targets depend on the union of dependencies for all configs. --- Source/cmComputeTargetDepends.cxx | 40 +++++-- Source/cmTarget.cxx | 103 ++++++++++++++++-- Source/cmTarget.h | 6 + .../target_link_libraries/CMakeLists.txt | 7 ++ .../target_link_libraries/depB.cpp | 6 +- .../target_link_libraries/libgenex.cpp | 7 ++ .../target_link_libraries/libgenex.h | 12 ++ 7 files changed, 164 insertions(+), 17 deletions(-) create mode 100644 Tests/CMakeCommands/target_link_libraries/libgenex.cpp create mode 100644 Tests/CMakeCommands/target_link_libraries/libgenex.h diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index c3a75e4b6..8fd95b9cd 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -200,25 +200,51 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) // Get the depender. cmTarget* depender = this->Targets[depender_index]; - // Loop over all targets linked directly. + // Loop over all targets linked directly in all configs. + // We need to make targets depend on the union of all config-specific + // dependencies in all targets, because the generated build-systems can't + // deal with config-specific dependencies. { - cmTarget::LinkLibraryVectorType const& tlibs = - depender->GetOriginalLinkLibraries(); std::set emitted; + { + std::vector tlibs; + depender->GetDirectLinkLibraries(0, tlibs, depender); // A target should not depend on itself. emitted.insert(depender->GetName()); - for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin(); + for(std::vector::const_iterator lib = tlibs.begin(); lib != tlibs.end(); ++lib) { // Don't emit the same library twice for this target. - if(emitted.insert(lib->first).second) + if(emitted.insert(*lib).second) { - this->AddTargetDepend(depender_index, lib->first.c_str(), true); - this->AddInterfaceDepends(depender_index, lib->first.c_str(), + this->AddTargetDepend(depender_index, lib->c_str(), true); + this->AddInterfaceDepends(depender_index, lib->c_str(), true, emitted); } } } + std::vector configs; + depender->GetMakefile()->GetConfigurations(configs); + for (std::vector::const_iterator it = configs.begin(); + it != configs.end(); ++it) + { + std::vector tlibs; + depender->GetDirectLinkLibraries(it->c_str(), tlibs, depender); + // A target should not depend on itself. + emitted.insert(depender->GetName()); + for(std::vector::const_iterator lib = tlibs.begin(); + lib != tlibs.end(); ++lib) + { + // Don't emit the same library twice for this target. + if(emitted.insert(*lib).second) + { + this->AddTargetDepend(depender_index, lib->c_str(), true); + this->AddInterfaceDepends(depender_index, lib->c_str(), + true, emitted); + } + } + } + } // Loop over all utility dependencies. { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 1338ec491..25054c536 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -519,6 +519,22 @@ void cmTarget::DefineProperties(cmake *cm) "Installing a target with EXCLUDE_FROM_ALL set to true has " "undefined behavior."); + cm->DefineProperty + ("LINK_LIBRARIES", cmProperty::TARGET, + "List of direct link dependencies.", + "This property specifies the list of libraries or targets which will be " + "used for linking. " + "In addition to accepting values from the target_link_libraries " + "command, values may be set directly on any target using the " + "set_property command. " + "\n" + "The target property values are used by the generators to set " + "the link libraries for the compiler. " + "See also the target_link_libraries command.\n" + "Contents of LINK_LIBRARIES may use \"generator expressions\" with " + "the syntax \"$<...>\". " + CM_DOCUMENT_COMMAND_GENERATOR_EXPRESSIONS); + cm->DefineProperty ("INCLUDE_DIRECTORIES", cmProperty::TARGET, "List of preprocessor include file search directories.", @@ -2139,6 +2155,66 @@ bool cmTarget::NameResolvesToFramework(const std::string& libname) NameResolvesToFramework(libname); } +//---------------------------------------------------------------------------- +void cmTarget::GetDirectLinkLibraries(const char *config, + std::vector &libs, cmTarget *head) +{ + const char *prop = this->GetProperty("LINK_LIBRARIES"); + if (prop) + { + cmListFileBacktrace lfbt; + cmGeneratorExpression ge(lfbt); + + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "LINK_LIBRARIES", 0, 0); + cmSystemTools::ExpandListArgument(ge.Parse(prop)->Evaluate(this->Makefile, + config, + false, + head, + &dagChecker), + libs); + } +} + +//---------------------------------------------------------------------------- +std::string cmTarget::GetDebugGeneratorExpressions(const std::string &value, + cmTarget::LinkLibraryType llt) +{ + if (llt == GENERAL) + { + return value; + } + + // Get the list of configurations considered to be DEBUG. + std::vector const& debugConfigs = + this->Makefile->GetCMakeInstance()->GetDebugConfigs(); + + std::string configString = "$"; + + if (debugConfigs.size() > 1) + { + for(std::vector::const_iterator + li = debugConfigs.begin() + 1; li != debugConfigs.end(); ++li) + { + configString += ",$"; + } + configString = "$"; + } + + if (llt == OPTIMIZED) + { + configString = "$"; + } + return "$<" + configString + ":" + value + ">"; +} + +//---------------------------------------------------------------------------- +static std::string targetNameGenex(const char *lib) +{ + return std::string("$"; +} + //---------------------------------------------------------------------------- void cmTarget::AddLinkLibrary(cmMakefile& mf, const char *target, const char* lib, @@ -2149,6 +2225,18 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, { return; } + + { + cmTarget *tgt = this->Makefile->FindTargetToUse(lib); + const bool isNonImportedTarget = tgt && !tgt->IsImported(); + + std::string libName = isNonImportedTarget ? targetNameGenex(lib) + : std::string(lib); + this->AppendProperty("LINK_LIBRARIES", + this->GetDebugGeneratorExpressions(libName, + llt).c_str()); + } + cmTarget::LibraryID tmp; tmp.first = lib; tmp.second = llt; @@ -4884,26 +4972,23 @@ void cmTarget::ComputeLinkImplementation(const char* config, LinkImplementation& impl, cmTarget *head) { - (void)head; // Compute which library configuration to link. cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config); // Collect libraries directly linked in this configuration. - LinkLibraryVectorType const& llibs = this->GetOriginalLinkLibraries(); - for(cmTarget::LinkLibraryVectorType::const_iterator li = llibs.begin(); + std::vector llibs; + this->GetDirectLinkLibraries(config, llibs, head); + for(std::vector::const_iterator li = llibs.begin(); li != llibs.end(); ++li) { // Skip entries that resolve to the target itself or are empty. - std::string item = this->CheckCMP0004(li->first); + std::string item = this->CheckCMP0004(*li); if(item == this->GetName() || item.empty()) { continue; } - if(li->second == cmTarget::GENERAL || li->second == linkType) - { - // The entry is meant for this configuration. - impl.Libraries.push_back(item); - } + // The entry is meant for this configuration. + impl.Libraries.push_back(item); } LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries(); diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 29c73b616..d4069fa01 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -168,6 +168,9 @@ public: return this->LinkLibraries;} const LinkLibraryVectorType &GetOriginalLinkLibraries() const {return this->OriginalLinkLibraries;} + void GetDirectLinkLibraries(const char *config, + std::vector &, + cmTarget *head); /** Compute the link type to use for the given configuration. */ LinkLibraryType ComputeLinkType(const char* config); @@ -622,6 +625,9 @@ private: void ProcessSourceExpression(std::string const& expr); + std::string GetDebugGeneratorExpressions(const std::string &value, + cmTarget::LinkLibraryType llt); + // The cmMakefile instance that owns this target. This should // always be set. cmMakefile* Makefile; diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt index 60b36fc27..63ae675d2 100644 --- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt @@ -34,6 +34,13 @@ generate_export_header(depB) target_link_libraries(depB LINK_PRIVATE depA) +add_library(libgenex SHARED libgenex.cpp) +generate_export_header(libgenex) + +set_property(TARGET depB APPEND PROPERTY + LINK_LIBRARIES $<1:libgenex> +) + add_library(depC SHARED depC.cpp) generate_export_header(depC) diff --git a/Tests/CMakeCommands/target_link_libraries/depB.cpp b/Tests/CMakeCommands/target_link_libraries/depB.cpp index 1bbe38bc2..4f46552d7 100644 --- a/Tests/CMakeCommands/target_link_libraries/depB.cpp +++ b/Tests/CMakeCommands/target_link_libraries/depB.cpp @@ -3,9 +3,13 @@ #include "depA.h" +#include "libgenex.h" + int DepB::foo() { DepA a; - return a.foo(); + LibGenex lg; + + return a.foo() + lg.foo(); } diff --git a/Tests/CMakeCommands/target_link_libraries/libgenex.cpp b/Tests/CMakeCommands/target_link_libraries/libgenex.cpp new file mode 100644 index 000000000..c925c0821 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/libgenex.cpp @@ -0,0 +1,7 @@ + +#include "libgenex.h" + +int LibGenex::foo() +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_link_libraries/libgenex.h b/Tests/CMakeCommands/target_link_libraries/libgenex.h new file mode 100644 index 000000000..733f9b6df --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/libgenex.h @@ -0,0 +1,12 @@ + +#include "libgenex_export.h" + +#ifndef LIBGENEX_H +#define LIBGENEX_H + +struct LIBGENEX_EXPORT LibGenex +{ + int foo(); +}; + +#endif From 9cfe4f1b769597bd9ba179eba46572a9df27f64c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 26 Nov 2012 12:30:00 +0100 Subject: [PATCH 159/170] Allow target_link_libraries with IMPORTED targets. This makes it possible to use: target_link_libraries(foo LINK_INTERFACE_LIBRARIES bar) where foo is an IMPORTED target. Other tll() signatures are not allowed. --- Source/cmTargetLinkLibrariesCommand.cxx | 14 ++++++++++++++ .../target_link_libraries/CMakeLists.txt | 3 +++ 2 files changed, 17 insertions(+) diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx index f42b0f687..0705fb4d6 100644 --- a/Source/cmTargetLinkLibrariesCommand.cxx +++ b/Source/cmTargetLinkLibrariesCommand.cxx @@ -33,6 +33,10 @@ bool cmTargetLinkLibrariesCommand this->Target = this->Makefile->GetCMakeInstance() ->GetGlobalGenerator()->FindTarget(0, args[0].c_str()); + if(!this->Target) + { + this->Target = this->Makefile->FindTargetToUse(args[0].c_str()); + } if(!this->Target) { cmake::MessageType t = cmake::FATAL_ERROR; // fail by default @@ -257,6 +261,16 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib, // Handle normal case first. if(this->CurrentProcessingState != ProcessingLinkInterface) { + if (this->Target->IsImported()) + { + cmOStringStream e; + e << "Imported targets may only be used with the " + "LINK_INTERFACE_LIBRARIES specifier to target_link_libraries."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return; + } + + this->Makefile ->AddLinkLibraryForTarget(this->Target->GetName(), lib, llt); if (this->CurrentProcessingState != ProcessingPublicInterface) diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt index 60b36fc27..e586c28d9 100644 --- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt @@ -29,6 +29,9 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON) add_library(depA SHARED depA.cpp) generate_export_header(depA) +add_library(importedlib UNKNOWN IMPORTED) +target_link_libraries(importedlib LINK_INTERFACE_LIBRARIES depA) + add_library(depB SHARED depB.cpp) generate_export_header(depB) From 9ce1b9ef2946ead0605e766c7dcf1302fe122f3a Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 25 Nov 2012 01:15:44 +0100 Subject: [PATCH 160/170] Add CMAKE_BUILD_INTERFACE_INCLUDES build-variable. This makes set(CMAKE_BUILD_INTERFACE_INCLUDES ON) add the equivalent of set_property(TARGET tgt APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES $ ) to every target. If the headers are in CMAKE_CURRENT_SOURCE_DIR, and the generated headers are in CMAKE_CURRENT_BINARY_DIR, this is a convenient way to build a target bar, which depends on foo, just by using target_link_libraries() and adding the INTERFACE_INCLUDE_DIRECTORIES to the INCLUDE_DIRECTORIES of the target being linked. There will be more-convenient porcelain API to consume the property in the future. --- Source/cmDocumentVariables.cxx | 11 +++++++++++ Source/cmGlobalGenerator.cxx | 17 +++++++++++++++++ .../target_link_libraries/CMakeLists.txt | 7 +++++++ .../target_link_libraries/subdir/CMakeLists.txt | 5 +++++ .../target_link_libraries/subdir/subdirlib.cpp | 7 +++++++ .../target_link_libraries/subdir/subdirlib.h | 12 ++++++++++++ .../target_link_libraries/targetA.cpp | 6 +++++- 7 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 Tests/CMakeCommands/target_link_libraries/subdir/CMakeLists.txt create mode 100644 Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.cpp create mode 100644 Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.h diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index be45e2d27..08b3ef168 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1146,6 +1146,17 @@ void cmDocumentVariables::DefineVariables(cmake* cm) false, "Variables that Control the Build"); + cm->DefineProperty + ("CMAKE_BUILD_INTERFACE_INCLUDES", cmProperty::VARIABLE, + "Automatically add the current source- and build directories " + "to the INTERFACE_INCLUDE_DIRECTORIES.", + "If this variable is enabled, CMake automatically adds for each " + "target ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} " + "to the INTERFACE_INCLUDE_DIRECTORIES." + "By default CMAKE_BUILD_INTERFACE_INCLUDES is OFF.", + false, + "Variables that Control the Build"); + cm->DefineProperty ("CMAKE_INSTALL_RPATH", cmProperty::VARIABLE, "The rpath to use for installed targets.", diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 0f439e9cd..d030aa7ba 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -938,6 +938,23 @@ void cmGlobalGenerator::Generate() (*targets)[tit->first] = tit->second; (*targets)[tit->first].SetMakefile(mf); } + + for ( tit = targets->begin(); tit != targets->end(); ++ tit ) + { + if (mf->IsOn("CMAKE_BUILD_INTERFACE_INCLUDES")) + { + const char *binDir = mf->GetStartOutputDirectory(); + const char *srcDir = mf->GetStartDirectory(); + const std::string dirs = std::string(binDir ? binDir : "") + + std::string(binDir ? ";" : "") + + std::string(srcDir ? srcDir : ""); + if (!dirs.empty()) + { + tit->second.AppendProperty("INTERFACE_INCLUDE_DIRECTORIES", + ("$").c_str()); + } + } + } } // Add generator specific helper commands diff --git a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt index 60b36fc27..29b69d944 100644 --- a/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt +++ b/Tests/CMakeCommands/target_link_libraries/CMakeLists.txt @@ -53,6 +53,13 @@ set_target_properties(targetA PROPERTIES LINK_INTERFACE_LIBRARIES "") assert_property(targetA LINK_INTERFACE_LIBRARIES "") +add_subdirectory(subdir) +target_link_libraries(targetA subdirlib) +set_property(TARGET targetA APPEND PROPERTY + INCLUDE_DIRECTORIES + $ +) + target_link_libraries(targetA depB depC) assert_property(targetA LINK_INTERFACE_LIBRARIES "") diff --git a/Tests/CMakeCommands/target_link_libraries/subdir/CMakeLists.txt b/Tests/CMakeCommands/target_link_libraries/subdir/CMakeLists.txt new file mode 100644 index 000000000..61a1a5988 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/subdir/CMakeLists.txt @@ -0,0 +1,5 @@ + +set(CMAKE_BUILD_INTERFACE_INCLUDES ON) + +add_library(subdirlib SHARED subdirlib.cpp) +generate_export_header(subdirlib) diff --git a/Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.cpp b/Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.cpp new file mode 100644 index 000000000..cd2f1a23a --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.cpp @@ -0,0 +1,7 @@ + +#include "subdirlib.h" + +int SubDirLibObject::foo() const +{ + return 0; +} diff --git a/Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.h b/Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.h new file mode 100644 index 000000000..e386f87b2 --- /dev/null +++ b/Tests/CMakeCommands/target_link_libraries/subdir/subdirlib.h @@ -0,0 +1,12 @@ + +#ifndef SUBDIRLIB_H +#define SUBDIRLIB_H + +#include "subdirlib_export.h" + +struct SUBDIRLIB_EXPORT SubDirLibObject +{ + int foo() const; +}; + +#endif diff --git a/Tests/CMakeCommands/target_link_libraries/targetA.cpp b/Tests/CMakeCommands/target_link_libraries/targetA.cpp index 6ff65b106..559aef7f0 100644 --- a/Tests/CMakeCommands/target_link_libraries/targetA.cpp +++ b/Tests/CMakeCommands/target_link_libraries/targetA.cpp @@ -3,6 +3,8 @@ #include "depC.h" #include "depIfaceOnly.h" +#include "subdirlib.h" + int main(int argc, char **argv) { DepA a; @@ -11,5 +13,7 @@ int main(int argc, char **argv) DepIfaceOnly iface_only; - return a.foo() + b.foo() + c.foo() + iface_only.foo(); + SubDirLibObject sd; + + return a.foo() + b.foo() + c.foo() + iface_only.foo() + sd.foo(); } From c77281061c1b931842d5f0a03fc68b3f16999a5b Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 7 Jan 2013 16:07:49 +0100 Subject: [PATCH 161/170] Add the -Wundef flag when compiling CMake. --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9ad9587e5..e84f8980e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -588,10 +588,10 @@ if(NOT CMake_VERSION_IS_RELEASE) NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS 4.2) set(C_FLAGS_LIST -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security - -Wmissing-format-attribute -fno-common + -Wmissing-format-attribute -fno-common -Wundef ) set(CXX_FLAGS_LIST -Wnon-virtual-dtor -Wcast-align -Wchar-subscripts -Wall -W - -Wshadow -Wpointer-arith -Wformat-security + -Wshadow -Wpointer-arith -Wformat-security -Wundef ) foreach(FLAG_LANG C CXX) From bf5ece51c3827dc05018128fefe8270da88cfefb Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 5 Nov 2012 14:48:42 +0100 Subject: [PATCH 162/170] Keep track of properties used to determine linker libraries. Those properties can't later be implicitly defined by the interface of those link libraries. --- Source/cmGeneratorExpression.cxx | 10 +++++- Source/cmGeneratorExpression.h | 4 +++ Source/cmGeneratorExpressionEvaluator.cxx | 8 +++++ Source/cmGeneratorExpressionEvaluator.h | 1 + Source/cmTarget.cxx | 42 ++++++++++++++++++++++- Source/cmTarget.h | 10 ++++++ 6 files changed, 73 insertions(+), 2 deletions(-) diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 6d003e10f..4063697cd 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -94,7 +94,15 @@ const char *cmCompiledGeneratorExpression::Evaluate( for ( ; it != end; ++it) { - this->Output += (*it)->Evaluate(&context, dagChecker); + const std::string result = (*it)->Evaluate(&context, dagChecker); + this->Output += result; + + for(std::set::const_iterator + p = context.SeenTargetProperties.begin(); + p != context.SeenTargetProperties.end(); ++p) + { + this->SeenTargetProperties[*p] += result + ";"; + } if (context.HadError) { this->Output = ""; diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index dcdfefbad..b58dde52b 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -83,6 +83,9 @@ public: std::set const& GetTargets() const { return this->Targets; } + std::map const& GetSeenTargetProperties() const + { return this->SeenTargetProperties; } + ~cmCompiledGeneratorExpression(); std::string GetInput() const @@ -110,6 +113,7 @@ private: bool NeedsParsing; mutable std::set Targets; + mutable std::map SeenTargetProperties; mutable std::string Output; }; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 82becaf75..f4e413123 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -380,6 +380,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode } } + if (target == context->HeadTarget) + { + // Keep track of the properties seen while processing. + // The evaluation of the LINK_LIBRARIES generator expressions + // will check this to ensure that properties form a DAG. + context->SeenTargetProperties.insert(propertyName); + } + if (propertyName.empty()) { reportError(context, content->GetOriginalExpression(), diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 59804ff95..fb6c7eee5 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -24,6 +24,7 @@ struct cmGeneratorExpressionContext { cmListFileBacktrace Backtrace; std::set Targets; + std::set SeenTargetProperties; cmMakefile *Makefile; const char *Config; cmTarget *HeadTarget; // The target whose property is being evaluated. diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 25054c536..e4adb09c3 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2164,16 +2164,19 @@ void cmTarget::GetDirectLinkLibraries(const char *config, { cmListFileBacktrace lfbt; cmGeneratorExpression ge(lfbt); + const cmsys::auto_ptr cge = ge.Parse(prop); cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(), "LINK_LIBRARIES", 0, 0); - cmSystemTools::ExpandListArgument(ge.Parse(prop)->Evaluate(this->Makefile, + cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, config, false, head, &dagChecker), libs); + + this->AddLinkDependentTargetsForProperties(cge->GetSeenTargetProperties()); } } @@ -4376,6 +4379,43 @@ const char* cmTarget::GetExportMacro() } } +//---------------------------------------------------------------------------- +void cmTarget::GetLinkDependentTargetsForProperty(const std::string &p, + std::set &targets) +{ + const std::map >::const_iterator findIt + = this->LinkDependentProperties.find(p); + if (findIt != this->LinkDependentProperties.end()) + { + targets = findIt->second; + } +} + +//---------------------------------------------------------------------------- +bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p) +{ + return this->LinkImplicitNullProperties.find(p) + != this->LinkImplicitNullProperties.end(); +} + +//---------------------------------------------------------------------------- +void cmTarget::AddLinkDependentTargetsForProperties( + const std::map &map) +{ + for (std::map::const_iterator it = map.begin(); + it != map.end(); ++it) + { + std::vector targets; + cmSystemTools::ExpandListArgument(it->second.c_str(), targets); + this->LinkDependentProperties[it->first].insert(targets.begin(), + targets.end()); + if (!this->GetProperty(it->first.c_str())) + { + this->LinkImplicitNullProperties.insert(it->first); + } + } +} + //---------------------------------------------------------------------------- void cmTarget::GetLanguages(std::set& languages) const { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index d4069fa01..5ce7d53c5 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -487,6 +487,13 @@ public: std::vector GetIncludeDirectories(const char *config); void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry, bool before = false); + + void GetLinkDependentTargetsForProperty(const std::string &p, + std::set &targets); + bool IsNullImpliedByLinkLibraries(const std::string &p); + + void AddLinkDependentTargetsForProperties( + const std::map &map); private: /** * A list of direct dependencies. Use in conjunction with DependencyMap. @@ -596,6 +603,9 @@ private: bool DLLPlatform; bool IsApple; bool IsImportedTarget; + mutable std::map > + LinkDependentProperties; + mutable std::set LinkImplicitNullProperties; // Cache target output paths for each configuration. struct OutputInfo; From 042ecf0471be84ce6c3e6c32dae526fdbd9a3a14 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 6 Jan 2013 13:49:05 +0100 Subject: [PATCH 163/170] Add API to calculate link-interface-dependent bool properties or error. This new method checks that the property FOO on a target is consistent with the INTERFACE_FOO properties of its dependees. If they are not the consistent, an error is reported. 'Consistent' means that iff the property is set, it must have the same boolean value as all other related properties. --- Source/cmTarget.cxx | 128 ++++++++++++++++++++++++++++++++++++++++++++ Source/cmTarget.h | 3 ++ 2 files changed, 131 insertions(+) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index e4adb09c3..c8f9c1ddb 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -4416,6 +4416,134 @@ void cmTarget::AddLinkDependentTargetsForProperties( } } +//---------------------------------------------------------------------------- +bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p, + const char *config) +{ + bool propContent = this->GetPropertyAsBool(p.c_str()); + const bool explicitlySet = this->GetProperties() + .find(p.c_str()) + != this->GetProperties().end(); + std::set dependentTargets; + this->GetLinkDependentTargetsForProperty(p, + dependentTargets); + const bool impliedByUse = + this->IsNullImpliedByLinkLibraries(p); + assert((impliedByUse ^ explicitlySet) + || (!impliedByUse && !explicitlySet)); + + cmComputeLinkInformation *info = this->GetLinkInformation(config); + const cmComputeLinkInformation::ItemVector &deps = info->GetItems(); + bool propInitialized = explicitlySet; + + for(cmComputeLinkInformation::ItemVector::const_iterator li = + deps.begin(); + li != deps.end(); ++li) + { + // An error should be reported if one dependency + // has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other + // has INTERFACE_POSITION_INDEPENDENT_CODE OFF, or if the + // target itself has a POSITION_INDEPENDENT_CODE which disagrees + // with a dependency. + + if (!li->Target) + { + continue; + } + + const bool ifaceIsSet = li->Target->GetProperties() + .find("INTERFACE_" + p) + != li->Target->GetProperties().end(); + const bool ifacePropContent = li->Target->GetPropertyAsBool( + ("INTERFACE_" + p).c_str()); + if (explicitlySet) + { + if (ifaceIsSet) + { + if (propContent != ifacePropContent) + { + cmOStringStream e; + e << "Property " << p << " on target \"" + << this->GetName() << "\" does\nnot match the " + "INTERFACE_" << p << " property requirement\nof " + "dependency \"" << li->Target->GetName() << "\".\n"; + cmSystemTools::Error(e.str().c_str()); + } + else + { + // Agree + continue; + } + } + else + { + // Explicitly set on target and not set in iface. Can't disagree. + continue; + } + } + else if (impliedByUse) + { + if (ifaceIsSet) + { + if (propContent != ifacePropContent) + { + cmOStringStream e; + e << "Property " << p << " on target \"" + << this->GetName() << "\" is\nimplied to be FALSE because it " + "was used to determine the link libraries\nalready. The " + "INTERFACE_" << p << " property on\ndependency \"" + << li->Target->GetName() << "\" is in conflict.\n"; + cmSystemTools::Error(e.str().c_str()); + } + else + { + // Agree + continue; + } + } + else + { + // Implicitly set on target and not set in iface. Can't disagree. + continue; + } + } + else + { + if (ifaceIsSet) + { + if (propInitialized) + { + if (propContent != ifacePropContent) + { + cmOStringStream e; + e << "The INTERFACE_" << p << " property of \"" + << li->Target->GetName() << "\" does\nnot agree with the value " + "of " << p << " already determined\nfor \"" + << this->GetName() << "\".\n"; + cmSystemTools::Error(e.str().c_str()); + } + else + { + // Agree. + continue; + } + } + else + { + propContent = ifacePropContent; + propInitialized = true; + } + } + else + { + // Not set. Nothing to agree on. + continue; + } + } + } + return propContent; +} + //---------------------------------------------------------------------------- void cmTarget::GetLanguages(std::set& languages) const { diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 5ce7d53c5..1188a6a6a 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -494,6 +494,9 @@ public: void AddLinkDependentTargetsForProperties( const std::map &map); + + bool GetLinkInterfaceDependentBoolProperty(const std::string &p, + const char *config); private: /** * A list of direct dependencies. Use in conjunction with DependencyMap. From 9fdfe07411d8846f2adf0e46cf9046238c149d2b Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 8 Jan 2013 14:43:26 -0500 Subject: [PATCH 164/170] KWIML: Teach ABI about 'long long' on older GNU Old GNU compilers do not define __SIZEOF_LONG_LONG__ or __LONG_LONG_MAX__ but do provide a 64-bit 'long long' type. Suggested-by: Rolf Eike Beer --- ABI.h.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ABI.h.in b/ABI.h.in index 7f4772ae5..b71cdfb9f 100644 --- a/ABI.h.in +++ b/ABI.h.in @@ -253,7 +253,9 @@ suppression macro @KWIML@_ABI_NO_VERIFY was defined. # else # define @KWIML@_ABI_SIZEOF_LONG_LONG 0 # endif -# elif defined(__hpux) && !defined(__GNUC__) /* Old HP: no __HP_cc/__HP_aCC above */ +# elif defined(__GNUC__) /* GNU */ +# define @KWIML@_ABI_SIZEOF_LONG_LONG 8 +# elif defined(__hpux) /* Old HP: no __HP_cc/__HP_aCC/__GNUC__ above */ # define @KWIML@_ABI_SIZEOF_LONG_LONG 8 # endif #endif From 30c02f1bcf9c546d82401526cee697cd82b25443 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Wed, 9 Jan 2013 00:01:16 -0500 Subject: [PATCH 165/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 528fa13e6..d1b20971b 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 20130108) +set(CMake_VERSION_TWEAK 20130109) #set(CMake_VERSION_RC 1) From 96c1a1b787155f98265bcac2338b25ad579faca0 Mon Sep 17 00:00:00 2001 From: Kitware Robot Date: Thu, 10 Jan 2013 00:01:20 -0500 Subject: [PATCH 166/170] CMake Nightly Date Stamp --- Source/CMakeVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index d1b20971b..f77d17c3f 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 20130109) +set(CMake_VERSION_TWEAK 20130110) #set(CMake_VERSION_RC 1) From c8ee07d0adade6b838c0ee8e7c2549285a3b6b85 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 31 Dec 2012 00:55:38 +0100 Subject: [PATCH 167/170] FindQt4: Add INTERFACE includes and defines to Qt4 targets --- Modules/FindQt4.cmake | 26 ++++++++++++++++++++++++++ Tests/Qt4Targets/CMakeLists.txt | 11 +++++++++-- Tests/Qt4Targets/main.cpp | 8 ++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/Modules/FindQt4.cmake b/Modules/FindQt4.cmake index 381141c5f..a9e9d82e7 100644 --- a/Modules/FindQt4.cmake +++ b/Modules/FindQt4.cmake @@ -418,6 +418,15 @@ macro (_QT4_ADJUST_LIB_VARS _camelCaseBasename) set_property(TARGET Qt4::${_camelCaseBasename} PROPERTY IMPORTED_LOCATION_DEBUG "${QT_${basename}_LIBRARY_DEBUG}" ) endif() endif () + set_property(TARGET Qt4::${_camelCaseBasename} PROPERTY + INTERFACE_INCLUDE_DIRECTORIES + "${QT_${basename}_INCLUDE_DIR}" + ) + string(REGEX REPLACE "^QT" "" _stemname ${basename}) + set_property(TARGET Qt4::${_camelCaseBasename} PROPERTY + INTERFACE_COMPILE_DEFINITIONS + "QT_${_stemname}_LIB" + ) endif() # If QT_USE_IMPORTED_TARGETS is enabled, the QT_QTFOO_LIBRARY variables are set to point at these @@ -952,6 +961,14 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) ${_PROPERTY} "Qt4::Qt${_DEPEND}" ) + set_property(TARGET Qt4::${_QT_MODULE} APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES + "$" + ) + set_property(TARGET Qt4::${_QT_MODULE} APPEND PROPERTY + INTERFACE_COMPILE_DEFINITIONS + "$" + ) endforeach() endif() endmacro() @@ -968,6 +985,11 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) # Set QT_xyz_LIBRARY variable and add # library include path to QT_INCLUDES _QT4_ADJUST_LIB_VARS(QtCore) + set_property(TARGET Qt4::QtCore APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES + "${QT_MKSPECS_DIR}/default" + ${QT_INCLUDE_DIR} + ) foreach(QT_MODULE ${QT_MODULES}) _QT4_ADJUST_LIB_VARS(${QT_MODULE}) @@ -992,6 +1014,10 @@ if (QT_QMAKE_EXECUTABLE AND QTVERSION) # headers. # Everything depends on QtCore, but that is covered above already _qt4_add_target_depends(Qt3Support Sql Gui Network) + if (TARGET Qt4::Qt3Support) + # An additional define is required for QT3_SUPPORT + set_property(TARGET Qt4::Qt3Support APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS QT3_SUPPORT) + endif() _qt4_add_target_depends(QtDeclarative Script Gui) _qt4_add_target_depends(QtDesigner Gui) _qt4_add_target_depends(QtHelp Gui) diff --git a/Tests/Qt4Targets/CMakeLists.txt b/Tests/Qt4Targets/CMakeLists.txt index 3adff48fd..9bd7a6478 100644 --- a/Tests/Qt4Targets/CMakeLists.txt +++ b/Tests/Qt4Targets/CMakeLists.txt @@ -4,11 +4,18 @@ project(Qt4Targets) find_package(Qt4 REQUIRED) -include_directories(${QT_INCLUDES}) - 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 + $ +) +set_property(TARGET Qt4Targets APPEND PROPERTY + COMPILE_DEFINITIONS + $ +) diff --git a/Tests/Qt4Targets/main.cpp b/Tests/Qt4Targets/main.cpp index f4890fa9e..3c98c99f6 100644 --- a/Tests/Qt4Targets/main.cpp +++ b/Tests/Qt4Targets/main.cpp @@ -4,6 +4,14 @@ #include +#ifndef QT_CORE_LIB +#error Expected QT_CORE_LIB +#endif + +#ifndef QT_GUI_LIB +#error Expected QT_GUI_LIB +#endif + int main(int argc, char **argv) { QApplication app(argc, argv); From 8a37ebec784cefe4f04cb8897c23a014c3930052 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 1 Jan 2013 23:20:04 +0100 Subject: [PATCH 168/170] Add the target_include_directories command. This is a convenience API to populate the corresponding properties. --- Source/cmCommands.cxx | 3 + Source/cmTargetIncludeDirectoriesCommand.cxx | 74 +++++++++ Source/cmTargetIncludeDirectoriesCommand.h | 95 ++++++++++++ Source/cmTargetPropCommandBase.cxx | 144 ++++++++++++++++++ Source/cmTargetPropCommandBase.h | 57 +++++++ .../target_include_directories/CMakeLists.txt | 50 ++++++ .../target_include_directories/consumer.cpp | 27 ++++ .../target_include_directories/main.cpp | 22 +++ Tests/CMakeLists.txt | 1 + 9 files changed, 473 insertions(+) create mode 100644 Source/cmTargetIncludeDirectoriesCommand.cxx create mode 100644 Source/cmTargetIncludeDirectoriesCommand.h create mode 100644 Source/cmTargetPropCommandBase.cxx create mode 100644 Source/cmTargetPropCommandBase.h create mode 100644 Tests/CMakeCommands/target_include_directories/CMakeLists.txt create mode 100644 Tests/CMakeCommands/target_include_directories/consumer.cpp create mode 100644 Tests/CMakeCommands/target_include_directories/main.cpp diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 49ed96795..6b315ea81 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -28,6 +28,8 @@ #include "cmRemoveDefinitionsCommand.cxx" #include "cmSourceGroupCommand.cxx" #include "cmSubdirDependsCommand.cxx" +#include "cmTargetIncludeDirectoriesCommand.cxx" +#include "cmTargetPropCommandBase.cxx" #include "cmUseMangledMesaCommand.cxx" #include "cmUtilitySourceCommand.cxx" #include "cmVariableRequiresCommand.cxx" @@ -66,6 +68,7 @@ void GetPredefinedCommands(std::list& commands.push_back(new cmRemoveDefinitionsCommand); commands.push_back(new cmSourceGroupCommand); commands.push_back(new cmSubdirDependsCommand); + commands.push_back(new cmTargetIncludeDirectoriesCommand); commands.push_back(new cmUseMangledMesaCommand); commands.push_back(new cmUtilitySourceCommand); commands.push_back(new cmVariableRequiresCommand); diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx new file mode 100644 index 000000000..18e2cba4e --- /dev/null +++ b/Source/cmTargetIncludeDirectoriesCommand.cxx @@ -0,0 +1,74 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmTargetIncludeDirectoriesCommand.h" + +#include "cmMakefileIncludeDirectoriesEntry.h" + +//---------------------------------------------------------------------------- +bool cmTargetIncludeDirectoriesCommand +::InitialPass(std::vector const& args, cmExecutionStatus &) +{ + return this->HandleArguments(args, "INCLUDE_DIRECTORIES", PROCESS_BEFORE); +} + +//---------------------------------------------------------------------------- +void cmTargetIncludeDirectoriesCommand +::HandleImportedTargetInvalidScope(const std::string &tgt, + const std::string &scope) +{ + cmOStringStream e; + e << "Cannot specify " << scope << " include directories for imported " + "target \"" << tgt << "\". Include directories can only be " + "specified for an imported target in the INTERFACE mode."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); +} + +//---------------------------------------------------------------------------- +void cmTargetIncludeDirectoriesCommand +::HandleMissingTarget(const std::string &name) +{ + cmOStringStream e; + e << "Cannot specify include directories for target \"" << name << "\" " + "which is not built by this project."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); +} + +//---------------------------------------------------------------------------- +bool cmTargetIncludeDirectoriesCommand +::HandleNonTargetArg(std::string &content, + const std::string &sep, + const std::string &entry, + const std::string &tgt) +{ + if (!cmSystemTools::FileIsFullPath(entry.c_str())) + { + cmOStringStream e; + e << "Cannot specify relative include directory \"" << entry << "\" for " + "target \"" << tgt << "\". Only absolute paths are permitted"; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); + return false; + } + + content += sep + entry; + return true; +} + +//---------------------------------------------------------------------------- +void cmTargetIncludeDirectoriesCommand +::HandleDirectContent(cmTarget *tgt, const std::string &content, + bool prepend) +{ + cmListFileBacktrace lfbt; + this->Makefile->GetBacktrace(lfbt); + cmMakefileIncludeDirectoriesEntry entry(content, lfbt); + tgt->InsertInclude(entry, prepend); +} diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h new file mode 100644 index 000000000..c1957d6d9 --- /dev/null +++ b/Source/cmTargetIncludeDirectoriesCommand.h @@ -0,0 +1,95 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmTargetIncludeDirectoriesCommand_h +#define cmTargetIncludeDirectoriesCommand_h + +#include "cmTargetPropCommandBase.h" + +//---------------------------------------------------------------------------- +class cmTargetIncludeDirectoriesCommand : public cmTargetPropCommandBase +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmTargetIncludeDirectoriesCommand; + } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + virtual bool InitialPass(std::vector const& args, + cmExecutionStatus &status); + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual const char* GetName() const { return "target_include_directories";} + + /** + * Succinct documentation. + */ + virtual const char* GetTerseDocumentation() const + { + return + "Add include directories to a target."; + } + + /** + * More documentation. + */ + virtual const char* GetFullDocumentation() const + { + return + " target_include_directories( [BEFORE] " + " [items1...]\n" + " [ [items2...] ...])\n" + "Specify include directories or targets to use when compiling a given " + "target. " + "The named must have been created by a command such as " + "add_executable or add_library.\n" + "If BEFORE is specified, the content will be prepended to the property " + "instead of being appended.\n" + "The INTERFACE, PUBLIC and PRIVATE keywords are required to specify " + "the scope of the following arguments. PRIVATE and PUBLIC items will " + "populate the INCLUDE_DIRECTORIES property of . PUBLIC and " + "INTERFACE items will populate the INTERFACE_INCLUDE_DIRECTORIES " + "property of . " + "The non-scope arguments specify either include directories or targets " + "to use INTERFACE_INCLUDE_DIRECTORIES from. Any specified include " + "directories must be absolute paths, not relative paths. " + "Repeated calls for the same append items in the order called." + "\n" + ; + } + + cmTypeMacro(cmTargetIncludeDirectoriesCommand, cmCommand); + +private: + virtual void HandleImportedTargetInvalidScope(const std::string &tgt, + const std::string &scope); + virtual void HandleMissingTarget(const std::string &name); + + virtual bool HandleNonTargetArg(std::string &content, + const std::string &sep, + const std::string &entry, + const std::string &tgt); + + virtual void HandleDirectContent(cmTarget *tgt, const std::string &content, + bool prepend); +}; + +#endif diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx new file mode 100644 index 000000000..69aaf1777 --- /dev/null +++ b/Source/cmTargetPropCommandBase.cxx @@ -0,0 +1,144 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmTargetPropCommandBase.h" + +#include "cmGlobalGenerator.h" + +//---------------------------------------------------------------------------- +bool cmTargetPropCommandBase +::HandleArguments(std::vector const& args, const char *prop, + ArgumentFlags flags) +{ + if(args.size() < 3) + { + this->SetError("called with incorrect number of arguments"); + return false; + } + + // Lookup the target for which libraries are specified. + this->Target = + this->Makefile->GetCMakeInstance() + ->GetGlobalGenerator()->FindTarget(0, args[0].c_str()); + if(!this->Target) + { + this->Target = this->Makefile->FindTargetToUse(args[0].c_str()); + } + if(!this->Target) + { + this->HandleMissingTarget(args[0]); + return false; + } + + unsigned int argIndex = 1; + + bool prepend = false; + if ((flags & PROCESS_BEFORE) && args[argIndex] == "BEFORE") + { + if (args.size() < 4) + { + this->SetError("called with incorrect number of arguments"); + return false; + } + prepend = true; + ++argIndex; + } + + this->Property = prop; + + while (argIndex < args.size()) + { + if (!this->ProcessContentArgs(args, argIndex, prepend)) + { + return false; + } + } + return true; +} + +//---------------------------------------------------------------------------- +bool cmTargetPropCommandBase +::ProcessContentArgs(std::vector const& args, + unsigned int &argIndex, bool prepend) +{ + const std::string scope = args[argIndex]; + + if(scope != "PUBLIC" + && scope != "PRIVATE" + && scope != "INTERFACE" ) + { + this->SetError("called with invalid arguments"); + return false; + } + + if(this->Target->IsImported() && scope != "INTERFACE") + { + this->HandleImportedTargetInvalidScope(args[0], scope); + return false; + } + + ++argIndex; + + std::string content; + + std::string sep; + for(unsigned int i=argIndex; i < args.size(); ++i, ++argIndex) + { + if(args[i] == "PUBLIC" + || args[i] == "PRIVATE" + || args[i] == "INTERFACE" ) + { + this->PopulateTargetProperies(scope, content, prepend); + return true; + } + if (this->Makefile->FindTargetToUse(args[i].c_str())) + { + content += sep + "$Property + ">"; + } + else if (!this->HandleNonTargetArg(content, sep, args[i], args[0])) + { + return false; + } + sep = ";"; + } + this->PopulateTargetProperies(scope, content, prepend); + return true; +} + +//---------------------------------------------------------------------------- +void cmTargetPropCommandBase +::PopulateTargetProperies(const std::string &scope, + const std::string &content, bool prepend) +{ + if (scope == "PRIVATE" || scope == "PUBLIC") + { + this->HandleDirectContent(this->Target, content, prepend); + } + if (scope == "INTERFACE" || scope == "PUBLIC") + { + if (prepend) + { + const std::string propName = std::string("INTERFACE_") + this->Property; + const char *propValue = this->Target->GetProperty(propName.c_str()); + const std::string totalContent = content + (propValue + ? std::string(";") + propValue + : std::string()); + this->Target->SetProperty(propName.c_str(), totalContent.c_str()); + } + else + { + this->Target->AppendProperty(("INTERFACE_" + this->Property).c_str(), + content.c_str()); + } + } +} diff --git a/Source/cmTargetPropCommandBase.h b/Source/cmTargetPropCommandBase.h new file mode 100644 index 000000000..90e3bbb7f --- /dev/null +++ b/Source/cmTargetPropCommandBase.h @@ -0,0 +1,57 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmTargetPropCommandBase_h +#define cmTargetPropCommandBase_h + +#include "cmCommand.h" + +class cmTarget; + +//---------------------------------------------------------------------------- +class cmTargetPropCommandBase : public cmCommand +{ +public: + + enum ArgumentFlags { + NO_FLAGS = 0, + PROCESS_BEFORE = 1 + }; + + bool HandleArguments(std::vector const& args, + const char *prop, ArgumentFlags flags = NO_FLAGS); + +private: + virtual void HandleImportedTargetInvalidScope(const std::string &tgt, + const std::string &scope) = 0; + virtual void HandleMissingTarget(const std::string &name) = 0; + + virtual bool HandleNonTargetArg(std::string &content, + const std::string &sep, + const std::string &entry, + const std::string &tgt) = 0; + + virtual void HandleDirectContent(cmTarget *tgt, + const std::string &content, + bool prepend) = 0; + + bool ProcessContentArgs(std::vector const& args, + unsigned int &argIndex, bool prepend); + void PopulateTargetProperies(const std::string &scope, + const std::string &content, bool prepend); + +private: + cmTarget *Target; + std::string Property; +}; + +#endif diff --git a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt new file mode 100644 index 000000000..a0f2ee08c --- /dev/null +++ b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt @@ -0,0 +1,50 @@ +cmake_minimum_required(VERSION 2.8) + +project(target_include_directories) + +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/privateinclude") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/privateinclude/privateinclude.h" "#define PRIVATEINCLUDE_DEFINE\n") + +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/publicinclude") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/publicinclude/publicinclude.h" "#define PUBLICINCLUDE_DEFINE\n") + +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude/interfaceinclude.h" "#define INTERFACEINCLUDE_DEFINE\n") + +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude/importedinterfaceinclude.h" "#define IMPORTEDINTERFACEINCLUDE_DEFINE\n") + +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/poison") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/poison/common.h" "#error Should not be included\n") + +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/cure") +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cure/common.h" "#define CURE_DEFINE\n") + +add_executable(target_include_directories + "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" +) +target_include_directories(target_include_directories + PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/privateinclude" + PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/publicinclude" + INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/interfaceinclude" +) + +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" +) + +add_library(importedlib UNKNOWN IMPORTED) +target_include_directories(importedlib + INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/importedinterfaceinclude" +) + +add_executable(consumer + "${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp" +) + +target_include_directories(consumer + PRIVATE target_include_directories importedlib +) diff --git a/Tests/CMakeCommands/target_include_directories/consumer.cpp b/Tests/CMakeCommands/target_include_directories/consumer.cpp new file mode 100644 index 000000000..6fd61d5b7 --- /dev/null +++ b/Tests/CMakeCommands/target_include_directories/consumer.cpp @@ -0,0 +1,27 @@ + +#include "common.h" +#include "publicinclude.h" +#include "interfaceinclude.h" +#include "importedinterfaceinclude.h" + +#ifdef PRIVATEINCLUDE_DEFINE +#error Unexpected PRIVATEINCLUDE_DEFINE +#endif + +#ifndef PUBLICINCLUDE_DEFINE +#error Expected PUBLICINCLUDE_DEFINE +#endif + +#ifndef INTERFACEINCLUDE_DEFINE +#error Expected INTERFACEINCLUDE_DEFINE +#endif + +#ifndef IMPORTEDINTERFACEINCLUDE_DEFINE +#error Expected IMPORTEDINTERFACEINCLUDE_DEFINE +#endif + +#ifndef CURE_DEFINE +#error Expected CURE_DEFINE +#endif + +int main() { return 0; } diff --git a/Tests/CMakeCommands/target_include_directories/main.cpp b/Tests/CMakeCommands/target_include_directories/main.cpp new file mode 100644 index 000000000..8434b97d8 --- /dev/null +++ b/Tests/CMakeCommands/target_include_directories/main.cpp @@ -0,0 +1,22 @@ + +#include "common.h" +#include "privateinclude.h" +#include "publicinclude.h" + +#ifndef PRIVATEINCLUDE_DEFINE +#error Expected PRIVATEINCLUDE_DEFINE +#endif + +#ifndef PUBLICINCLUDE_DEFINE +#error Expected PUBLICINCLUDE_DEFINE +#endif + +#ifdef INTERFACEINCLUDE_DEFINE +#error Unexpected INTERFACEINCLUDE_DEFINE +#endif + +#ifndef CURE_DEFINE +#error Expected CURE_DEFINE +#endif + +int main() { return 0; } diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index ade6a012a..2dced5fae 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1930,6 +1930,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ) ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries) + ADD_TEST_MACRO(CMakeCommands.target_include_directories target_include_directories) configure_file( "${CMake_SOURCE_DIR}/Tests/CTestTestCrash/test.cmake.in" From fc61a7a746c3c899d42ccff3014686365c36ee11 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Tue, 8 Jan 2013 00:34:41 +0100 Subject: [PATCH 169/170] Add the target_compile_definitions command. This is a convenience API to populate the corresponding properties. --- Source/cmCommands.cxx | 2 + Source/cmTargetCompileDefinitionsCommand.cxx | 57 ++++++++++++ Source/cmTargetCompileDefinitionsCommand.h | 91 +++++++++++++++++++ .../target_compile_definitions/CMakeLists.txt | 26 ++++++ .../target_compile_definitions/consumer.cpp | 18 ++++ .../target_compile_definitions/main.cpp | 14 +++ Tests/CMakeLists.txt | 1 + 7 files changed, 209 insertions(+) create mode 100644 Source/cmTargetCompileDefinitionsCommand.cxx create mode 100644 Source/cmTargetCompileDefinitionsCommand.h create mode 100644 Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt create mode 100644 Tests/CMakeCommands/target_compile_definitions/consumer.cpp create mode 100644 Tests/CMakeCommands/target_compile_definitions/main.cpp diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx index 6b315ea81..227b22678 100644 --- a/Source/cmCommands.cxx +++ b/Source/cmCommands.cxx @@ -28,6 +28,7 @@ #include "cmRemoveDefinitionsCommand.cxx" #include "cmSourceGroupCommand.cxx" #include "cmSubdirDependsCommand.cxx" +#include "cmTargetCompileDefinitionsCommand.cxx" #include "cmTargetIncludeDirectoriesCommand.cxx" #include "cmTargetPropCommandBase.cxx" #include "cmUseMangledMesaCommand.cxx" @@ -69,6 +70,7 @@ void GetPredefinedCommands(std::list& commands.push_back(new cmSourceGroupCommand); commands.push_back(new cmSubdirDependsCommand); commands.push_back(new cmTargetIncludeDirectoriesCommand); + commands.push_back(new cmTargetCompileDefinitionsCommand); commands.push_back(new cmUseMangledMesaCommand); commands.push_back(new cmUtilitySourceCommand); commands.push_back(new cmVariableRequiresCommand); diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx new file mode 100644 index 000000000..492a1b7d0 --- /dev/null +++ b/Source/cmTargetCompileDefinitionsCommand.cxx @@ -0,0 +1,57 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ +#include "cmTargetCompileDefinitionsCommand.h" + +#include "cmMakefileIncludeDirectoriesEntry.h" + +bool cmTargetCompileDefinitionsCommand +::InitialPass(std::vector const& args, cmExecutionStatus &) +{ + return this->HandleArguments(args, "COMPILE_DEFINITIONS"); +} + +void cmTargetCompileDefinitionsCommand +::HandleImportedTargetInvalidScope(const std::string &scope, + const std::string &tgt) +{ + cmOStringStream e; + e << "Cannot specify " << scope << " compile definitions for imported " + "target \"" << tgt << "\". Compile definitions can only be " + "specified for an imported target in the INTERFACE mode."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); +} + +void cmTargetCompileDefinitionsCommand +::HandleMissingTarget(const std::string &name) +{ + cmOStringStream e; + e << "Cannot specify compile definitions for target \"" << name << "\" " + "which is not built by this project."; + this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); +} + +bool cmTargetCompileDefinitionsCommand +::HandleNonTargetArg(std::string &content, + const std::string &sep, + const std::string &entry, + const std::string &) +{ + content += sep + entry; + return true; +} + +void cmTargetCompileDefinitionsCommand +::HandleDirectContent(cmTarget *tgt, const std::string &content, + bool) +{ + tgt->AppendProperty("COMPILE_DEFINITIONS", content.c_str()); +} diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h new file mode 100644 index 000000000..707610e3e --- /dev/null +++ b/Source/cmTargetCompileDefinitionsCommand.h @@ -0,0 +1,91 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2013 Stephen Kelly + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef cmTargetCompileDefinitionsCommand_h +#define cmTargetCompileDefinitionsCommand_h + +#include "cmTargetPropCommandBase.h" + +class cmTargetCompileDefinitionsCommand : public cmTargetPropCommandBase +{ +public: + /** + * This is a virtual constructor for the command. + */ + virtual cmCommand* Clone() + { + return new cmTargetCompileDefinitionsCommand; + } + + /** + * This is called when the command is first encountered in + * the CMakeLists.txt file. + */ + virtual bool InitialPass(std::vector const& args, + cmExecutionStatus &status); + + /** + * The name of the command as specified in CMakeList.txt. + */ + virtual const char* GetName() const { return "target_compile_definitions";} + + /** + * Succinct documentation. + */ + virtual const char* GetTerseDocumentation() const + { + return + "Add compile definitions to a target."; + } + + /** + * More documentation. + */ + virtual const char* GetFullDocumentation() const + { + return + " target_compile_definitions( " + " [items1...]\n" + " [ [items2...] ...])\n" + "Specify compile definitions or targets to use when compiling a given " + "target. " + "The named must have been created by a command such as " + "add_executable or add_library. " + "The INTERFACE, PUBLIC and PRIVATE keywords are required to specify " + "the scope of the following arguments. PRIVATE and PUBLIC items will " + "populate the COMPILE_DEFINITIONS property of . PUBLIC and " + "INTERFACE items will populate the INTERFACE_COMPILE_DEFINITIONS " + "property of . " + "The non-scope arguments specify compile definitions or targets to use " + "INTERFACE_COMPILE_DEFINITIONS from. " + "Repeated calls for the same append items in the order called." + "\n" + ; + } + + cmTypeMacro(cmTargetCompileDefinitionsCommand, cmCommand); + +private: + virtual void HandleImportedTargetInvalidScope(const std::string &scope, + const std::string &tgt); + virtual void HandleMissingTarget(const std::string &name); + + virtual bool HandleNonTargetArg(std::string &content, + const std::string &sep, + const std::string &entry, + const std::string &tgt); + + virtual void HandleDirectContent(cmTarget *tgt, const std::string &content, + bool prepend); +}; + +#endif diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt new file mode 100644 index 000000000..84a23efc3 --- /dev/null +++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt @@ -0,0 +1,26 @@ + +cmake_minimum_required(VERSION 2.8) + +project(target_compile_definitions) + +add_executable(target_compile_definitions + "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp" +) +target_compile_definitions(target_compile_definitions + PRIVATE MY_PRIVATE_DEFINE + PUBLIC MY_PUBLIC_DEFINE + INTERFACE MY_INTERFACE_DEFINE +) + +add_library(importedlib UNKNOWN IMPORTED) +target_compile_definitions(importedlib + INTERFACE MY_IMPORTEDINTERFACE_DEFINE +) + +add_executable(consumer + "${CMAKE_CURRENT_SOURCE_DIR}/consumer.cpp" +) + +target_compile_definitions(consumer + PRIVATE target_compile_definitions importedlib +) diff --git a/Tests/CMakeCommands/target_compile_definitions/consumer.cpp b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp new file mode 100644 index 000000000..e3788ddb2 --- /dev/null +++ b/Tests/CMakeCommands/target_compile_definitions/consumer.cpp @@ -0,0 +1,18 @@ + +#ifdef MY_PRIVATE_DEFINE +#error Unexpected MY_PRIVATE_DEFINE +#endif + +#ifndef MY_PUBLIC_DEFINE +#error Expected MY_PUBLIC_DEFINE +#endif + +#ifndef MY_INTERFACE_DEFINE +#error Expected MY_INTERFACE_DEFINE +#endif + +#ifndef MY_IMPORTEDINTERFACE_DEFINE +#error Expected MY_IMPORTEDINTERFACE_DEFINE +#endif + +int main() { return 0; } diff --git a/Tests/CMakeCommands/target_compile_definitions/main.cpp b/Tests/CMakeCommands/target_compile_definitions/main.cpp new file mode 100644 index 000000000..addb33cf9 --- /dev/null +++ b/Tests/CMakeCommands/target_compile_definitions/main.cpp @@ -0,0 +1,14 @@ + +#ifndef MY_PRIVATE_DEFINE +#error Expected MY_PRIVATE_DEFINE +#endif + +#ifndef MY_PUBLIC_DEFINE +#error Expected MY_PUBLIC_DEFINE +#endif + +#ifdef MY_INTERFACE_DEFINE +#error Unexpected MY_INTERFACE_DEFINE +#endif + +int main() { return 0; } diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 2dced5fae..2f7df01cf 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1931,6 +1931,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries) ADD_TEST_MACRO(CMakeCommands.target_include_directories target_include_directories) + ADD_TEST_MACRO(CMakeCommands.target_compile_definitions target_compile_definitions) configure_file( "${CMake_SOURCE_DIR}/Tests/CTestTestCrash/test.cmake.in" From 3581b96caa1d7bd6c02e85baf72ce28b5128e5e7 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 5 Nov 2012 12:46:26 +0100 Subject: [PATCH 170/170] Process the INTERFACE_PIC property from linked dependencies This allows a dependee to inform a target that it should have its POSITION_INDEPENDENT_CODE property set to ON, or OFF. The value of the POSITION_INDEPENDENT_CODE property, if set, must be consistent with any INTERFACE_POSITION_INDEPENDENT_CODE properties on dependees. Add a test covering the consistency checks on platforms where they run. --- Source/cmGlobalXCodeGenerator.cxx | 6 ++++-- Source/cmLocalGenerator.cxx | 17 ++++++++++++++--- Source/cmLocalGenerator.h | 2 +- Source/cmMakefileTargetGenerator.cxx | 3 ++- Source/cmNinjaTargetGenerator.cxx | 3 ++- Source/cmTarget.cxx | 14 ++++++++++++++ Tests/RunCMake/CMakeLists.txt | 3 +++ .../PositionIndependentCode/CMakeLists.txt | 8 ++++++++ .../Conflict1-result.txt | 1 + .../Conflict1-stderr.txt | 3 +++ .../PositionIndependentCode/Conflict1.cmake | 7 +++++++ .../Conflict2-result.txt | 1 + .../Conflict2-stderr.txt | 3 +++ .../PositionIndependentCode/Conflict2.cmake | 9 +++++++++ .../Conflict3-result.txt | 1 + .../Conflict3-stderr.txt | 4 ++++ .../PositionIndependentCode/Conflict3.cmake | 12 ++++++++++++ .../PositionIndependentCode/RunCMakeTest.cmake | 5 +++++ Tests/RunCMake/PositionIndependentCode/main.cpp | 5 +++++ 19 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 Tests/RunCMake/PositionIndependentCode/CMakeLists.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict1.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict2.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict3.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/main.cpp diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 4c26b829b..2cfe4daba 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1639,14 +1639,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, if(strcmp(lang, "CXX") == 0) { this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName); - this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target, "C"); + this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target, + "C", configName); } // Add language-specific flags. this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName); // Add shared-library flags if needed. - this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target, lang); + this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target, + lang, configName); } else if(binary) { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index b557ca19b..ecf6b413a 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1984,7 +1984,8 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags, //---------------------------------------------------------------------------- void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target, - std::string const& lang) + std::string const& lang, + const char *config) { int targetType = target->GetType(); @@ -1997,8 +1998,18 @@ void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target, } else { - // Add position independendent flags, if needed. - if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE")) + if (target->GetType() == cmTarget::OBJECT_LIBRARY) + { + if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE")) + { + this->AddPositionIndependentFlags(flags, lang, targetType); + } + return; + } + + if (target->GetLinkInterfaceDependentBoolProperty( + "POSITION_INDEPENDENT_CODE", + config)) { this->AddPositionIndependentFlags(flags, lang, targetType); } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 63559d750..b2ff0c48f 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -142,7 +142,7 @@ public: void AddLanguageFlags(std::string& flags, const char* lang, const char* config); void AddCMP0018Flags(std::string &flags, cmTarget* target, - std::string const& lang); + std::string const& lang, const char *config); void AddConfigVariableFlags(std::string& flags, const char* var, const char* config); ///! Append flags to a string. diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 9bf6b7d9e..64fcfcefa 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -268,7 +268,8 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) this->AddFortranFlags(flags); } - this->LocalGenerator->AddCMP0018Flags(flags, this->Target, lang); + this->LocalGenerator->AddCMP0018Flags(flags, this->Target, + lang, this->ConfigName); // Add include directory flags. this->AddIncludeFlags(flags, lang); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 15842e44f..0f484da4c 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -147,7 +147,8 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, // Add shared-library flags if needed. this->LocalGenerator->AddCMP0018Flags(flags, this->Target, - language.c_str()); + language.c_str(), + this->GetConfigName()); // Add include directory flags. { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c8f9c1ddb..2cfb1bfd5 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -877,6 +877,20 @@ void cmTarget::DefineProperties(cmake *cm) "CMAKE_POSITION_INDEPENDENT_CODE if it is set when a target is " "created."); + cm->DefineProperty + ("INTERFACE_POSITION_INDEPENDENT_CODE", cmProperty::TARGET, + "Whether consumers need to create a position-independent target", + "The INTERFACE_POSITION_INDEPENDENT_CODE property informs consumers of " + "this target whether they must set their POSITION_INDEPENDENT_CODE " + "property to ON. If this property is set to ON, then the " + "POSITION_INDEPENDENT_CODE property on all consumers will be set to " + "ON. Similarly, if this property is set to OFF, then the " + "POSITION_INDEPENDENT_CODE property on all consumers will be set to " + "OFF. If this property is undefined, then consumers will determine " + "their POSITION_INDEPENDENT_CODE property by other means. Consumers " + "must ensure that the targets that they link to have a consistent " + "requirement for their INTERFACE_POSITION_INDEPENDENT_CODE property."); + cm->DefineProperty ("POST_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index fec64b57c..9b133b299 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -50,6 +50,9 @@ add_RunCMake_test(GeneratorExpression) add_RunCMake_test(TargetPropertyGeneratorExpressions) add_RunCMake_test(Languages) add_RunCMake_test(ObjectLibrary) +if(NOT WIN32) + add_RunCMake_test(PositionIndependentCode) +endif() add_RunCMake_test(build_command) add_RunCMake_test(find_package) diff --git a/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt b/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt new file mode 100644 index 000000000..22577da4a --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt @@ -0,0 +1,8 @@ + +cmake_minimum_required(VERSION 2.8) +project(${RunCMake_TEST} CXX) + +# MSVC creates extra targets which pollute the stderr unless we set this. +set(CMAKE_SUPPRESS_REGENERATION TRUE) + +include(${RunCMake_TEST}.cmake) diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt new file mode 100644 index 000000000..cb0710986 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt @@ -0,0 +1,3 @@ +CMake Error: Property POSITION_INDEPENDENT_CODE on target "conflict" does +not match the INTERFACE_POSITION_INDEPENDENT_CODE property requirement +of dependency "piciface". diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict1.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict1.cmake new file mode 100644 index 000000000..242bec37a --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict1.cmake @@ -0,0 +1,7 @@ + +add_library(piciface UNKNOWN IMPORTED) +set_property(TARGET piciface PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON) + +add_executable(conflict "main.cpp") +set_property(TARGET conflict PROPERTY POSITION_INDEPENDENT_CODE OFF) +target_link_libraries(conflict piciface) diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt new file mode 100644 index 000000000..ecd04928d --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt @@ -0,0 +1,3 @@ +CMake Error: The INTERFACE_POSITION_INDEPENDENT_CODE property of "picoff" does +not agree with the value of POSITION_INDEPENDENT_CODE already determined +for "conflict". diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict2.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict2.cmake new file mode 100644 index 000000000..215d08dae --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict2.cmake @@ -0,0 +1,9 @@ + +add_library(picon UNKNOWN IMPORTED) +set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON) + +add_library(picoff UNKNOWN IMPORTED) +set_property(TARGET picoff PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE OFF) + +add_executable(conflict "main.cpp") +target_link_libraries(conflict picon picoff) diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt new file mode 100644 index 000000000..0254e5557 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt @@ -0,0 +1,4 @@ +Property POSITION_INDEPENDENT_CODE on target "conflict" is +implied to be FALSE because it was used to determine the link libraries +already. The INTERFACE_POSITION_INDEPENDENT_CODE property on +dependency "picon" is in conflict. diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict3.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict3.cmake new file mode 100644 index 000000000..bf669bf4f --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict3.cmake @@ -0,0 +1,12 @@ + +add_library(picoff UNKNOWN IMPORTED) + +add_library(picon UNKNOWN IMPORTED) +set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON) + +add_executable(conflict "main.cpp") +target_link_libraries(conflict picon) +set_property(TARGET conflict APPEND PROPERTY + LINK_LIBRARIES + $<$>>:picoff> +) diff --git a/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake new file mode 100644 index 000000000..64a340c9c --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(Conflict1) +run_cmake(Conflict2) +run_cmake(Conflict3) diff --git a/Tests/RunCMake/PositionIndependentCode/main.cpp b/Tests/RunCMake/PositionIndependentCode/main.cpp new file mode 100644 index 000000000..31ba48280 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/main.cpp @@ -0,0 +1,5 @@ + +int main(int,char**) +{ + return 0; +}