浏览代码

ENH: some property cleanup and added GetProperty

Ken Martin 18 年之前
父节点
当前提交
509f1fb9cb

+ 2 - 0
Source/cmCommands.cxx

@@ -28,6 +28,7 @@
 #include "cmExportLibraryDependencies.cxx"
 #include "cmFLTKWrapUICommand.cxx"
 #include "cmGetDirectoryPropertyCommand.cxx"
+#include "cmGetPropertyCommand.cxx"
 #include "cmGetTestPropertyCommand.cxx"
 #include "cmIncludeExternalMSProjectCommand.cxx"
 #include "cmInstallCommand.cxx"
@@ -81,6 +82,7 @@ void GetPredefinedCommands(std::list<cmCommand*>&
   commands.push_back(new cmExportLibraryDependenciesCommand);
   commands.push_back(new cmFLTKWrapUICommand);
   commands.push_back(new cmGetDirectoryPropertyCommand);
+  commands.push_back(new cmGetPropertyCommand);
   commands.push_back(new cmGetTestPropertyCommand);
   commands.push_back(new cmIncludeExternalMSProjectCommand);
   commands.push_back(new cmInstallCommand);

+ 8 - 25
Source/cmGetCMakePropertyCommand.cxx

@@ -30,15 +30,11 @@ bool cmGetCMakePropertyCommand::InitialPass(
   
   std::vector<std::string>::size_type cc;
   std::string variable = args[0];
-  std::string output = "";
+  std::string output = "NOTFOUND";
 
-  if ( args[1] == "VARIABLES" || args[1] == "CACHE_VARIABLES" )
+  if ( args[1] == "VARIABLES")
     {
     int cacheonly = 0;
-    if ( args[1] == "CACHE_VARIABLES" )
-      {
-      cacheonly = 1;
-      }
     std::vector<std::string> vars = this->Makefile->GetDefinitions(cacheonly);
     for ( cc = 0; cc < vars.size(); cc ++ )
       {
@@ -49,31 +45,18 @@ bool cmGetCMakePropertyCommand::InitialPass(
       output += vars[cc];
       }
     }
-  else if ( args[1] == "COMMANDS" )
-    {
-    cmake::RegisteredCommandsMap::iterator cmds 
-        = this->Makefile->GetCMakeInstance()->GetCommands()->begin();
-    for (cc=0 ; 
-      cmds != this->Makefile->GetCMakeInstance()->GetCommands()->end(); 
-      ++ cmds )
-      {
-      if ( cc > 0 )
-        {
-        output += ";";
-        }
-      output += cmds->first.c_str();
-      cc++;
-      }
-    }
   else if ( args[1] == "MACROS" )
     {
     this->Makefile->GetListOfMacros(output);
     }
   else
     {
-    std::string emsg = "Unknown CMake property: " + args[1];
-    this->SetError(emsg.c_str());
-    return false;
+    const char *prop = 
+      this->Makefile->GetCMakeInstance()->GetProperty(args[1].c_str());
+    if (prop)
+      {
+      output = prop;
+      }
     }
   this->Makefile->AddDefinition(variable.c_str(), output.c_str());
   

+ 35 - 0
Source/cmMakefile.cxx

@@ -2534,6 +2534,41 @@ void cmMakefile::SetProperty(const char* prop, const char* value)
     {
     return;
     }
+  
+  // handle special props
+  std::string propname = prop;
+  if ( propname == "INCLUDE_DIRECTORIES" )
+    {
+    std::vector<std::string> varArgsExpanded;
+    cmSystemTools::ExpandListArgument(value, varArgsExpanded);
+    this->SetIncludeDirectories(varArgsExpanded);
+    return;
+    }
+
+  if ( propname == "LINK_DIRECTORIES" )
+    {
+    std::vector<std::string> varArgsExpanded;
+    cmSystemTools::ExpandListArgument(value, varArgsExpanded);
+    this->SetLinkDirectories(varArgsExpanded);
+    return;
+    }
+  
+  if ( propname == "INCLUDE_REGULAR_EXPRESSION" )
+    {
+    this->SetIncludeRegularExpression(value);
+    return;
+    }
+
+  if ( propname == "ADDITIONAL_MAKE_CLEAN_FILES" )
+    {
+    // This property is not inherrited
+    if ( strcmp(this->GetCurrentDirectory(), 
+                this->GetStartDirectory()) != 0 )
+      {
+      return;
+      }
+    }
+
   this->Properties.SetProperty(prop,value,cmProperty::DIRECTORY);
 }
 

+ 1 - 29
Source/cmSetDirectoryPropertiesCommand.cxx

@@ -67,35 +67,7 @@ bool cmSetDirectoryPropertiesCommand
         "Commands and macros cannot be set using SET_CMAKE_PROPERTIES";
       return false;
       }
-    else if ( prop == "INCLUDE_DIRECTORIES" )
-      {
-      std::vector<std::string> varArgsExpanded;
-      cmSystemTools::ExpandListArgument(value, varArgsExpanded);
-      mf->SetIncludeDirectories(varArgsExpanded);
-      }
-    else if ( prop == "LINK_DIRECTORIES" )
-      {
-      std::vector<std::string> varArgsExpanded;
-      cmSystemTools::ExpandListArgument(value, varArgsExpanded);
-      mf->SetLinkDirectories(varArgsExpanded);
-      }
-    else if ( prop == "INCLUDE_REGULAR_EXPRESSION" )
-      {
-      mf->SetIncludeRegularExpression(value.c_str());
-      }
-    else
-      {
-      if ( prop == "ADDITIONAL_MAKE_CLEAN_FILES" )
-        {
-        // This property is not inherrited
-        if ( strcmp(mf->GetCurrentDirectory(), 
-                    mf->GetStartDirectory()) != 0 )
-          {
-          continue;
-          }
-        }
-      mf->SetProperty(prop.c_str(), value.c_str());
-      }
+    mf->SetProperty(prop.c_str(), value.c_str());
     }
   
   return true;

+ 40 - 12
Source/cmSetPropertiesCommand.cxx

@@ -80,9 +80,13 @@ bool cmSetPropertiesCommand::InitialPass(
     {
     scope = cmProperty::GLOBAL;
     }
-  else if (args[0] == "DIRECTORY" && numFiles == 1)
+  else if (args[0] == "DIRECTORY" && numFiles >= 1)
     {
     scope = cmProperty::DIRECTORY;
+    if (numFiles == 2)
+      {
+      scopeName = args[1].c_str();
+      }
     }
   else if (args[0] == "TARGET" && numFiles == 2)
     {
@@ -122,16 +126,39 @@ bool cmSetPropertiesCommand::InitialPass(
       break;
     case cmProperty::DIRECTORY:
       {
-      std::string errors;
-      bool ret = 
-        cmSetDirectoryPropertiesCommand::RunCommand(this->Makefile,
-                                                    args.begin() + 2,
-                                                    args.end(),
-                                                    errors);
-      if (!ret)
+      // lookup the makefile from the directory name
+      cmLocalGenerator *lg = this->Makefile->GetLocalGenerator();
+      if (numFiles == 2)
         {
-        this->SetError(errors.c_str());
-        return ret;
+        std::string sd = scopeName;
+        // make sure the start dir is a full path
+        if (!cmSystemTools::FileIsFullPath(sd.c_str()))
+          {
+          sd = this->Makefile->GetStartDirectory();
+          sd += "/";
+          sd += scopeName;
+          }
+        
+        // The local generators are associated with collapsed paths.
+        sd = cmSystemTools::CollapseFullPath(sd.c_str());
+        
+        lg = this->Makefile->GetLocalGenerator()->GetGlobalGenerator()->
+          FindLocalGenerator(sd.c_str());
+        }
+      if (!lg)
+        {
+        this->SetError
+          ("DIRECTORY argument provided but requested directory not found. "
+           "This could be because the directory argument was invalid or, "
+           "it is valid but has not been processed yet.");
+        return false;
+        }
+      
+      for(j= propertyPairs.begin(); j != propertyPairs.end(); ++j)
+        {
+        const char *pn = j->c_str();
+        ++j;
+        lg->GetMakefile()->SetProperty(pn,j->c_str());
         }
       }
       break;
@@ -139,8 +166,9 @@ bool cmSetPropertiesCommand::InitialPass(
       {
       for(j= propertyPairs.begin(); j != propertyPairs.end(); ++j)
         {
-        this->Makefile->GetCMakeInstance()->SetProperty(j->c_str(),
-                                                        (++j)->c_str());
+        const char *pn = j->c_str();
+        ++j;
+        this->Makefile->GetCMakeInstance()->SetProperty(pn, j->c_str());
         }
       }
       break;

+ 34 - 0
Source/cmake.cxx

@@ -3028,6 +3028,40 @@ const char *cmake::GetProperty(const char* prop)
 const char *cmake::GetProperty(const char* prop, cmProperty::ScopeType scope)
 {
   bool chain = false;
+
+  // watch for special properties
+  std::string propname = prop;
+  std::string output = "";
+  if ( propname == "CACHE_VARIABLES" )
+    {
+    cmCacheManager::CacheIterator cit =
+      this->GetCacheManager()->GetCacheIterator();
+    for ( cit.Begin(); !cit.IsAtEnd(); cit.Next() )
+      {
+      if ( output.size() )
+        {
+        output += ";";
+        }
+      output += cit.GetName();
+      }
+    this->SetProperty("CACHE_VARIABLES", output.c_str());
+    }
+  else if ( propname == "COMMANDS" )
+    {
+    cmake::RegisteredCommandsMap::iterator cmds 
+        = this->GetCommands()->begin();
+    for (unsigned int cc=0 ; cmds != this->GetCommands()->end(); ++ cmds )
+      {
+      if ( cc > 0 )
+        {
+        output += ";";
+        }
+      output += cmds->first.c_str();
+      cc++;
+      }
+    this->SetProperty("COMMANDS",output.c_str());
+    }
+  
   return this->Properties.GetPropertyValue(prop, scope, chain);
 }
 

+ 30 - 4
Tests/Properties/CMakeLists.txt

@@ -20,8 +20,34 @@ get_source_file_property(RESULT3 SubDir/properties3.cxx TEST3)
 
 include_directories("${Properties_SOURCE_DIR}" "${Properties_BINARY_DIR}")
 
-if (RESULT1 AND RESULT2 AND RESULT3)
+
+# test generic property interfaces
+define_property(GLOBALTEST GLOBAL "A test property" 
+  "A long description of this test property" 0)
+set_properties(GLOBAL PROPERTIES GLOBALTEST 1)
+set_properties(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+  PROPERTIES DIRECTORYTEST 1)
+set_properties(SOURCE_FILE SubDir/properties3.cxx PROPERTIES SOURCETEST 1)
+get_property(GLOBALRESULT GLOBAL GLOBALTEST)
+get_property(DIRECTORYRESULT DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 
+  DIRECTORYTEST)
+get_property(SOURCE_FILERESULT SOURCE_FILE SubDir/properties3.cxx SOURCETEST)
+
+if (RESULT1 AND RESULT2 AND RESULT3 AND GLOBALRESULT AND 
+    DIRECTORYRESULT AND SOURCE_FILERESULT)
   add_executable (Properties SubDir/properties3.cxx)
-else (RESULT1 AND RESULT2 AND RESULT3)
-  message("Error: test results are TEST1=${TEST1} TEST2=${TEST2} TEST3=${TEST3}")
-endif (RESULT1 AND RESULT2 AND RESULT3)
+else (RESULT1 AND RESULT2 AND RESULT3 AND GLOBALRESULT AND 
+    DIRECTORYRESULT AND SOURCE_FILERESULT)
+  message("Error: test results are RESULT1=${RESULT1} RESULT2=${RESULT2} "
+    "RESULT3=${RESULT3} GLOBALRESULT=${GLOBALRESULT} "
+    "DIRECTORYRESULT=${DIRECTORYRESULT} "
+    "SOURCE_FILERESULT=${SOURCE_FILERESULT}")
+endif (RESULT1 AND RESULT2 AND RESULT3 AND GLOBALRESULT AND 
+  DIRECTORYRESULT AND SOURCE_FILERESULT)
+
+# test the target property
+set_properties(TARGET Properties PROPERTIES TARGETTEST 1)
+get_property(TARGETRESULT TARGET Properties TARGETTEST)
+if (NOT TARGETRESULT)
+    message("Error: target result is TARGETRESULT=${TARGETRESULT}")
+endif (NOT TARGETRESULT)