[Cmake-commits] [cmake-commits] king committed cmCMakePolicyCommand.h 1.8 1.9 cmFindPackageCommand.cxx 1.57 1.58 cmFindPackageCommand.h 1.27 1.28 cmIncludeCommand.cxx 1.21 1.22 cmIncludeCommand.h 1.17 1.18 cmMakefile.cxx 1.501 1.502 cmMakefile.h 1.252 1.253 cmPolicies.cxx 1.34 1.35 cmPolicies.h 1.20 1.21

cmake-commits at cmake.org cmake-commits at cmake.org
Thu Jan 22 13:18:42 EST 2009


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv2946/Source

Modified Files:
	cmCMakePolicyCommand.h cmFindPackageCommand.cxx 
	cmFindPackageCommand.h cmIncludeCommand.cxx cmIncludeCommand.h 
	cmMakefile.cxx cmMakefile.h cmPolicies.cxx cmPolicies.h 
Log Message:
ENH: Isolate policy changes in included scripts

Isolation of policy changes inside scripts is important for protecting
the including context.  This teaches include() and find_package() to
imply a cmake_policy(PUSH) and cmake_policy(POP) around the scripts they
load, with a NO_POLICY_SCOPE option to disable the behavior.  This also
creates CMake Policy CMP0011 to provide compatibility.  See issue #8192.


Index: cmPolicies.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmPolicies.h,v
retrieving revision 1.20
retrieving revision 1.21
diff -C 2 -d -r1.20 -r1.21
*** cmPolicies.h	22 Jan 2009 15:56:39 -0000	1.20
--- cmPolicies.h	22 Jan 2009 18:18:40 -0000	1.21
***************
*** 52,55 ****
--- 52,56 ----
      CMP0009, // GLOB_RECURSE should not follow symlinks by default
      CMP0010, // Bad variable reference syntax is an error
+     CMP0011, // Strong policy scope for include and find_package
  
      // Always the last entry.  Useful mostly to avoid adding a comma

Index: cmPolicies.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmPolicies.cxx,v
retrieving revision 1.34
retrieving revision 1.35
diff -C 2 -d -r1.34 -r1.35
*** cmPolicies.cxx	24 Sep 2008 12:51:19 -0000	1.34
--- cmPolicies.cxx	22 Jan 2009 18:18:39 -0000	1.35
***************
*** 336,339 ****
--- 336,359 ----
      "The NEW behavior for this policy is to report an error.",
      2,6,3, cmPolicies::WARN);
+ 
+   this->DefinePolicy(
+     CMP0011, "CMP0011",
+     "Included scripts do automatic cmake_policy PUSH and POP.",
+     "In CMake 2.6.2 and below, CMake Policy settings in scripts loaded by "
+     "the include() and find_package() commands would affect the includer.  "
+     "Explicit invocations of cmake_policy(PUSH) and cmake_policy(POP) were "
+     "required to isolate policy changes and protect the includer.  "
+     "While some scripts intend to affect the policies of their includer, "
+     "most do not.  "
+     "In CMake 2.6.3 and above, include() and find_package() by default PUSH "
+     "and POP an entry on the policy stack around an included script, "
+     "but provide a NO_POLICY_SCOPE option to disable it.  "
+     "This policy determines whether or not to imply NO_POLICY_SCOPE for "
+     "compatibility.  "
+     "The OLD behavior for this policy is to imply NO_POLICY_SCOPE for "
+     "include() and find_package() commands.  "
+     "The NEW behavior for this policy is to allow the commands to do their "
+     "default cmake_policy PUSH and POP.",
+     2,6,3, cmPolicies::WARN);
  }
  

Index: cmFindPackageCommand.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFindPackageCommand.h,v
retrieving revision 1.27
retrieving revision 1.28
diff -C 2 -d -r1.27 -r1.28
*** cmFindPackageCommand.h	8 Jan 2009 22:57:52 -0000	1.27
--- cmFindPackageCommand.h	22 Jan 2009 18:18:39 -0000	1.28
***************
*** 83,87 ****
    bool FindFrameworkConfig();
    bool FindAppBundleConfig();
!   bool ReadListFile(const char* f);
    void StoreVersionFound();
  
--- 83,88 ----
    bool FindFrameworkConfig();
    bool FindAppBundleConfig();
!   enum PolicyScopeRule { NoPolicyScope, DoPolicyScope };
!   bool ReadListFile(const char* f, PolicyScopeRule psr);
    void StoreVersionFound();
  
***************
*** 133,136 ****
--- 134,138 ----
    bool DebugMode;
    bool UseLib64Paths;
+   bool PolicyScope;
    std::vector<std::string> Names;
    std::vector<std::string> Configs;

Index: cmMakefile.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefile.h,v
retrieving revision 1.252
retrieving revision 1.253
diff -C 2 -d -r1.252 -r1.253
*** cmMakefile.h	22 Jan 2009 18:16:47 -0000	1.252
--- cmMakefile.h	22 Jan 2009 18:18:39 -0000	1.253
***************
*** 85,89 ****
    bool ReadListFile(const char* listfile, 
                      const char* external= 0, 
!                     std::string* fullPath= 0); 
  
    /**
--- 85,90 ----
    bool ReadListFile(const char* listfile, 
                      const char* external= 0, 
!                     std::string* fullPath= 0,
!                     bool noPolicyScope = true);
  
    /**

Index: cmIncludeCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmIncludeCommand.cxx,v
retrieving revision 1.21
retrieving revision 1.22
diff -C 2 -d -r1.21 -r1.22
*** cmIncludeCommand.cxx	8 Mar 2008 14:27:44 -0000	1.21
--- cmIncludeCommand.cxx	22 Jan 2009 18:18:39 -0000	1.22
***************
*** 29,32 ****
--- 29,33 ----
      }
    bool optional = false;
+   bool noPolicyScope = false;
    std::string fname = args[0];
    std::string resultVarName;
***************
*** 61,64 ****
--- 62,69 ----
          }
        }
+     else if(args[i] == "NO_POLICY_SCOPE")
+       {
+       noPolicyScope = true;
+       }
        else if(i > 1)  // compat.: in previous cmake versions the second 
                        // parameter was ignore if it wasn't "OPTIONAL"
***************
*** 85,89 ****
    bool readit = 
      this->Makefile->ReadListFile( this->Makefile->GetCurrentListFile(), 
!                                   fname.c_str(), &fullFilePath );
    
    // add the location of the included file if a result variable was given
--- 90,95 ----
    bool readit = 
      this->Makefile->ReadListFile( this->Makefile->GetCurrentListFile(), 
!                                   fname.c_str(), &fullFilePath,
!                                   noPolicyScope);
    
    // add the location of the included file if a result variable was given

Index: cmCMakePolicyCommand.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmCMakePolicyCommand.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -C 2 -d -r1.8 -r1.9
*** cmCMakePolicyCommand.h	22 Jan 2009 18:16:47 -0000	1.8
--- cmCMakePolicyCommand.h	22 Jan 2009 18:18:39 -0000	1.9
***************
*** 118,121 ****
--- 118,124 ----
        "A new entry on the policy stack is managed automatically for each "
        "subdirectory to protect its parents and siblings.  "
+       "CMake also manages a new entry for scripts loaded by include() and "
+       "find_package() commands except when invoked with the NO_POLICY_SCOPE "
+       "option (see also policy CMP0011).  "
        "The cmake_policy command provides an interface to manage custom "
        "entries on the policy stack:\n"

Index: cmFindPackageCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFindPackageCommand.cxx,v
retrieving revision 1.57
retrieving revision 1.58
diff -C 2 -d -r1.57 -r1.58
*** cmFindPackageCommand.cxx	22 Jan 2009 15:56:58 -0000	1.57
--- cmFindPackageCommand.cxx	22 Jan 2009 18:18:39 -0000	1.58
***************
*** 65,68 ****
--- 65,69 ----
    this->DebugMode = false;
    this->UseLib64Paths = false;
+   this->PolicyScope = true;
    this->VersionMajor = 0;
    this->VersionMinor = 0;
***************
*** 78,82 ****
    this->CommandDocumentation =
      "  find_package(<package> [version] [EXACT] [QUIET]\n"
!     "               [[REQUIRED|COMPONENTS] [components...]])\n"
      "Finds and loads settings from an external project.  "
      "<package>_FOUND will be set to indicate whether the package was found.  "
--- 79,84 ----
    this->CommandDocumentation =
      "  find_package(<package> [version] [EXACT] [QUIET]\n"
!     "               [[REQUIRED|COMPONENTS] [components...]]\n"
!     "               [NO_POLICY_SCOPE])\n"
      "Finds and loads settings from an external project.  "
      "<package>_FOUND will be set to indicate whether the package was found.  "
***************
*** 117,120 ****
--- 119,123 ----
      "  find_package(<package> [version] [EXACT] [QUIET]\n"
      "               [[REQUIRED|COMPONENTS] [components...]] [NO_MODULE]\n"
+     "               [NO_POLICY_SCOPE]\n"
      "               [NAMES name1 [name2 ...]]\n"
      "               [CONFIGS config1 [config2 ...]]\n"
***************
*** 291,294 ****
--- 294,302 ----
    this->CommandDocumentation += this->GenericDocumentationRootPath;
    this->CommandDocumentation += this->GenericDocumentationPathsOrder;
+   this->CommandDocumentation +=
+     "\n"
+     "See the cmake_policy() command documentation for discussion of the "
+     "NO_POLICY_SCOPE option."
+     ;
  }
  
***************
*** 407,410 ****
--- 415,424 ----
        doing = DoingConfigs;
        }
+     else if(args[i] == "NO_POLICY_SCOPE")
+       {
+       this->PolicyScope = false;
+       this->Compatibility_1_6 = false;
+       doing = DoingNone;
+       }
      else if(args[i] == "NO_CMAKE_BUILDS_PATH")
        {
***************
*** 676,680 ****
      var += "_FIND_MODULE";
      this->Makefile->AddDefinition(var.c_str(), "1");
!     bool result = this->ReadListFile(mfile.c_str());
      this->Makefile->RemoveDefinition(var.c_str());
      return result;
--- 690,694 ----
      var += "_FIND_MODULE";
      this->Makefile->AddDefinition(var.c_str(), "1");
!     bool result = this->ReadListFile(mfile.c_str(), DoPolicyScope);
      this->Makefile->RemoveDefinition(var.c_str());
      return result;
***************
*** 754,758 ****
  
      // Parse the configuration file.
!     if(this->ReadListFile(this->FileFound.c_str()))
        {
        // The package has been found.
--- 768,772 ----
  
      // Parse the configuration file.
!     if(this->ReadListFile(this->FileFound.c_str(), DoPolicyScope))
        {
        // The package has been found.
***************
*** 964,970 ****
  
  //----------------------------------------------------------------------------
! bool cmFindPackageCommand::ReadListFile(const char* f)
  {
!   if(this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(),f))
      {
      return true;
--- 978,985 ----
  
  //----------------------------------------------------------------------------
! bool cmFindPackageCommand::ReadListFile(const char* f, PolicyScopeRule psr)
  {
!   if(this->Makefile->ReadListFile(this->Makefile->GetCurrentListFile(), f, 0,
!                                   !this->PolicyScope || psr == NoPolicyScope))
      {
      return true;
***************
*** 1305,1311 ****
    this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_COUNT", buf);
  
!   // Load the version check file.
    bool suitable = false;
!   if(this->ReadListFile(version_file.c_str()))
      {
      // Check the output variables.
--- 1320,1327 ----
    this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_COUNT", buf);
  
!   // Load the version check file.  Pass NoPolicyScope because we do
!   // our own policy push/pop independent of CMP0011.
    bool suitable = false;
!   if(this->ReadListFile(version_file.c_str(), NoPolicyScope))
      {
      // Check the output variables.

Index: cmMakefile.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefile.cxx,v
retrieving revision 1.501
retrieving revision 1.502
diff -C 2 -d -r1.501 -r1.502
*** cmMakefile.cxx	22 Jan 2009 18:16:47 -0000	1.501
--- cmMakefile.cxx	22 Jan 2009 18:18:39 -0000	1.502
***************
*** 449,464 ****
  {
  public:
!   IncludeScope(cmMakefile* mf);
    ~IncludeScope();
    void Quiet() { this->ReportError = false; }
  private:
    cmMakefile* Makefile;
    bool ReportError;
  };
  
  //----------------------------------------------------------------------------
! cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf):
!   Makefile(mf), ReportError(true)
  {
    // The included file cannot pop our policy scope.
    this->Makefile->PushPolicyBarrier();
--- 449,499 ----
  {
  public:
!   IncludeScope(cmMakefile* mf, const char* fname, bool noPolicyScope);
    ~IncludeScope();
    void Quiet() { this->ReportError = false; }
  private:
    cmMakefile* Makefile;
+   const char* File;
+   bool NoPolicyScope;
+   bool CheckCMP0011;
    bool ReportError;
+   void EnforceCMP0011();
  };
  
  //----------------------------------------------------------------------------
! cmMakefile::IncludeScope::IncludeScope(cmMakefile* mf, const char* fname,
!                                        bool noPolicyScope):
!   Makefile(mf), File(fname), NoPolicyScope(noPolicyScope),
!   CheckCMP0011(false), ReportError(true)
  {
+   if(!this->NoPolicyScope)
+     {
+     // Check CMP0011 to determine the policy scope type.
+     switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
+       {
+       case cmPolicies::WARN:
+         // We need to push a scope to detect whether the script sets
+         // any policies that would affect the includer and therefore
+         // requires a warning.  We use a weak scope to simulate OLD
+         // behavior by allowing policy changes to affect the includer.
+         this->Makefile->PushPolicy(true);
+         this->CheckCMP0011 = true;
+         break;
+       case cmPolicies::OLD:
+         // OLD behavior is to not push a scope at all.
+         this->NoPolicyScope = true;
+         break;
+       case cmPolicies::REQUIRED_IF_USED:
+       case cmPolicies::REQUIRED_ALWAYS:
+         // We should never make this policy required, but we handle it
+         // here just in case.
+         this->CheckCMP0011 = true;
+       case cmPolicies::NEW:
+         // NEW behavior is to push a (strong) scope.
+         this->Makefile->PushPolicy();
+         break;
+       }
+     }
+ 
    // The included file cannot pop our policy scope.
    this->Makefile->PushPolicyBarrier();
***************
*** 470,473 ****
--- 505,569 ----
    // Enforce matching policy scopes inside the included file.
    this->Makefile->PopPolicyBarrier(this->ReportError);
+ 
+   if(!this->NoPolicyScope)
+     {
+     // If we need to enforce policy CMP0011 then the top entry is the
+     // one we pushed above.  If the entry is empty, then the included
+     // script did not set any policies that might affect the includer so
+     // we do not need to enforce the policy.
+     if(this->CheckCMP0011 && this->Makefile->PolicyStack.back().empty())
+       {
+       this->CheckCMP0011 = false;
+       }
+ 
+     // Pop the scope we pushed for the script.
+     this->Makefile->PopPolicy();
+ 
+     // We enforce the policy after the script's policy stack entry has
+     // been removed.
+     if(this->CheckCMP0011)
+       {
+       this->EnforceCMP0011();
+       }
+     }
+ }
+ 
+ //----------------------------------------------------------------------------
+ void cmMakefile::IncludeScope::EnforceCMP0011()
+ {
+   // We check the setting of this policy again because the included
+   // script might actually set this policy for its includer.
+   cmPolicies* policies = this->Makefile->GetPolicies();
+   switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0011))
+     {
+     case cmPolicies::WARN:
+       // Warn because the user did not set this policy.
+       {
+       cmOStringStream w;
+       w << policies->GetPolicyWarning(cmPolicies::CMP0011) << "\n"
+         << "The included script\n  " << this->File << "\n"
+         << "affects policy settings.  "
+         << "CMake is implying the NO_POLICY_SCOPE option for compatibility, "
+         << "so the effects are applied to the including context.";
+       this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+       }
+       break;
+     case cmPolicies::REQUIRED_IF_USED:
+     case cmPolicies::REQUIRED_ALWAYS:
+       {
+       cmOStringStream e;
+       e << policies->GetRequiredPolicyError(cmPolicies::CMP0011) << "\n"
+         << "The included script\n  " << this->File << "\n"
+         << "affects policy settings, so it requires this policy to be set.";
+       this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
+       }
+       break;
+     case cmPolicies::OLD:
+     case cmPolicies::NEW:
+       // The script set this policy.  We assume the purpose of the
+       // script is to initialize policies for its includer, and since
+       // the policy is now set for later scripts, we do not warn.
+       break;
+     }
  }
  
***************
*** 477,481 ****
  bool cmMakefile::ReadListFile(const char* filename_in,
                                const char *external_in,
!                               std::string* fullPath)
  {
    std::string currentParentFile
--- 573,578 ----
  bool cmMakefile::ReadListFile(const char* filename_in,
                                const char *external_in,
!                               std::string* fullPath,
!                               bool noPolicyScope)
  {
    std::string currentParentFile
***************
*** 565,569 ****
    {
    LexicalPushPop lexScope(this);
!   IncludeScope incScope(this);
  
    // Run the parsed commands.
--- 662,666 ----
    {
    LexicalPushPop lexScope(this);
!   IncludeScope incScope(this, filenametoread, noPolicyScope);
  
    // Run the parsed commands.

Index: cmIncludeCommand.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmIncludeCommand.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -C 2 -d -r1.17 -r1.18
*** cmIncludeCommand.h	23 Jan 2008 15:27:59 -0000	1.17
--- cmIncludeCommand.h	22 Jan 2009 18:18:39 -0000	1.18
***************
*** 70,75 ****
      {
      return
!       "  include(file1 [OPTIONAL] [RESULT_VARIABLE <VAR>])\n"
!       "  include(module [OPTIONAL] [RESULT_VARIABLE <VAR>])\n"
        "Reads CMake listfile code from the given file.  Commands in the file "
        "are processed immediately as if they were written in place of the "
--- 70,75 ----
      {
      return
!       "  include(<file|module> [OPTIONAL] [RESULT_VARIABLE <VAR>]\n"
!       "                        [NO_POLICY_SCOPE])\n"
        "Reads CMake listfile code from the given file.  Commands in the file "
        "are processed immediately as if they were written in place of the "
***************
*** 79,83 ****
        "has been included or NOTFOUND if it failed.\n"
        "If a module is specified instead of a file, the file with name "
!       "<modulename>.cmake is searched in the CMAKE_MODULE_PATH.";
      }
    
--- 79,87 ----
        "has been included or NOTFOUND if it failed.\n"
        "If a module is specified instead of a file, the file with name "
!       "<modulename>.cmake is searched in the CMAKE_MODULE_PATH."
!       "\n"
!       "See the cmake_policy() command documentation for discussion of the "
!       "NO_POLICY_SCOPE option."
!       ;
      }
    



More information about the Cmake-commits mailing list