[Cmake-commits] [cmake-commits] king committed cmFileCommand.cxx 1.105 1.106 cmFileCommand.h 1.35 1.36 cmInstallTargetGenerator.cxx 1.63 1.64 cmInstallTargetGenerator.h 1.24 1.25

cmake-commits at cmake.org cmake-commits at cmake.org
Mon Apr 14 15:02:47 EDT 2008


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

Modified Files:
	cmFileCommand.cxx cmFileCommand.h cmInstallTargetGenerator.cxx 
	cmInstallTargetGenerator.h 
Log Message:
ENH: Improve RPATH behavior during installation.

  - If new RPATH is empty then remove the entry completely
  - Preserve file modification time so installation is not repeated
  - If installed file already exists remove it if its RPATH
    does not match that expected


Index: cmFileCommand.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFileCommand.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -C 2 -d -r1.35 -r1.36
*** cmFileCommand.h	1 Mar 2008 17:51:07 -0000	1.35
--- cmFileCommand.h	14 Apr 2008 19:02:44 -0000	1.36
***************
*** 172,176 ****
    bool HandleCMakePathCommand(std::vector<std::string> const& args,
                                bool nativePath);
!   bool HandleChrpathCommand(std::vector<std::string> const& args);
  
    // file(INSTALL ...) related functions
--- 172,178 ----
    bool HandleCMakePathCommand(std::vector<std::string> const& args,
                                bool nativePath);
!   bool HandleRPathChangeCommand(std::vector<std::string> const& args);
!   bool HandleRPathCheckCommand(std::vector<std::string> const& args);
!   bool HandleRPathRemoveCommand(std::vector<std::string> const& args);
  
    // file(INSTALL ...) related functions

Index: cmInstallTargetGenerator.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmInstallTargetGenerator.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -C 2 -d -r1.24 -r1.25
*** cmInstallTargetGenerator.h	6 Feb 2008 19:20:35 -0000	1.24
--- cmInstallTargetGenerator.h	14 Apr 2008 19:02:44 -0000	1.25
***************
*** 81,84 ****
--- 81,87 ----
                             const char* config,
                             std::string const& toDestDirPath);
+   void AddRPathCheckRule(std::ostream& os, Indent const& indent,
+                          const char* config,
+                          std::string const& toDestDirPath);
    
    void AddStripRule(std::ostream& os, Indent const& indent,

Index: cmInstallTargetGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmInstallTargetGenerator.cxx,v
retrieving revision 1.63
retrieving revision 1.64
diff -C 2 -d -r1.63 -r1.64
*** cmInstallTargetGenerator.cxx	8 Apr 2008 04:06:46 -0000	1.63
--- cmInstallTargetGenerator.cxx	14 Apr 2008 19:02:44 -0000	1.64
***************
*** 334,337 ****
--- 334,363 ----
      }
  
+   // Construct the path of the file on disk after installation on
+   // which tweaks may be performed.
+   std::string toDestDirPath = "$ENV{DESTDIR}";
+   if(toInstallPath[0] != '/' && toInstallPath[0] != '$')
+     {
+     toDestDirPath += "/";
+     }
+   toDestDirPath += toInstallPath;
+ 
+   // Add pre-installation tweaks.
+   if(tweakInstalledFile)
+     {
+     // Collect tweaking rules.
+     cmOStringStream tw;
+     this->AddRPathCheckRule(tw, indent.Next(), config, toDestDirPath);
+     std::string tws = tw.str();
+ 
+     // Add the rules, if any.
+     if(!tws.empty())
+       {
+       os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
+       os << tws;
+       os << indent << "ENDIF(EXISTS \"" << toDestDirPath << "\")\n";
+       }
+     }
+ 
    // Write code to install the target file.
    const char* no_dir_permissions = 0;
***************
*** 345,367 ****
                         indent);
  
!   // Construct the path of the file on disk after installation on
!   // which tweaks may be performed.
!   std::string toDestDirPath = "$ENV{DESTDIR}";
!   if(toInstallPath[0] != '/' && toInstallPath[0] != '$')
!     {
!     toDestDirPath += "/";
!     }
!   toDestDirPath += toInstallPath;
! 
!   // TODO:
!   //   - Skip IF(EXISTS) checks if nothing is done with the installed file
    if(tweakInstalledFile)
      {
!     os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
!     this->AddInstallNamePatchRule(os, indent.Next(), config, toDestDirPath);
!     this->AddChrpathPatchRule(os, indent.Next(), config, toDestDirPath);
!     this->AddRanlibRule(os, indent.Next(), type, toDestDirPath);
!     this->AddStripRule(os, indent.Next(), type, toDestDirPath);
!     os << indent << "ENDIF(EXISTS \"" << toDestDirPath << "\")\n";
      }
  }
--- 371,392 ----
                         indent);
  
!   // Add post-installation tweaks.
    if(tweakInstalledFile)
      {
!     // Collect tweaking rules.
!     cmOStringStream tw;
!     this->AddInstallNamePatchRule(tw, indent.Next(), config, toDestDirPath);
!     this->AddChrpathPatchRule(tw, indent.Next(), config, toDestDirPath);
!     this->AddRanlibRule(tw, indent.Next(), type, toDestDirPath);
!     this->AddStripRule(tw, indent.Next(), type, toDestDirPath);
!     std::string tws = tw.str();
! 
!     // Add the rules, if any.
!     if(!tws.empty())
!       {
!       os << indent << "IF(EXISTS \"" << toDestDirPath << "\")\n";
!       os << tws;
!       os << indent << "ENDIF(EXISTS \"" << toDestDirPath << "\")\n";
!       }
      }
  }
***************
*** 551,554 ****
--- 576,610 ----
  void
  cmInstallTargetGenerator
+ ::AddRPathCheckRule(std::ostream& os, Indent const& indent,
+                     const char* config, std::string const& toDestDirPath)
+ {
+   // Skip the chrpath if the target does not need it.
+   if(this->ImportLibrary || !this->Target->IsChrpathUsed())
+     {
+     return;
+     }
+ 
+   // Get the link information for this target.
+   // It can provide the RPATH.
+   cmComputeLinkInformation* cli = this->Target->GetLinkInformation(config);
+   if(!cli)
+     {
+     return;
+     }
+ 
+   // Get the install RPATH from the link information.
+   std::string newRpath = cli->GetChrpathString();
+ 
+   // Write a rule to remove the installed file if its rpath is not the
+   // new rpath.  This is needed for existing build/install trees when
+   // the installed rpath changes but the file is not rebuilt.
+   os << indent << "FILE(RPATH_CHECK\n"
+      << indent << "     FILE \"" << toDestDirPath << "\"\n"
+      << indent << "     RPATH \"" << newRpath << "\")\n";
+ }
+ 
+ //----------------------------------------------------------------------------
+ void
+ cmInstallTargetGenerator
  ::AddChrpathPatchRule(std::ostream& os, Indent const& indent,
                        const char* config, std::string const& toDestDirPath)
***************
*** 581,587 ****
  
    // Write a rule to run chrpath to set the install-tree RPATH
!   os << indent << "FILE(CHRPATH FILE \"" << toDestDirPath << "\"\n"
!      << indent << "     OLD_RPATH \"" << oldRpath << "\"\n"
!      << indent << "     NEW_RPATH \"" << newRpath << "\")\n";
  }
  
--- 637,652 ----
  
    // Write a rule to run chrpath to set the install-tree RPATH
!   if(newRpath.empty())
!     {
!     os << indent << "FILE(RPATH_REMOVE\n"
!        << indent << "     FILE \"" << toDestDirPath << "\")\n";
!     }
!   else
!     {
!     os << indent << "FILE(RPATH_CHANGE\n"
!        << indent << "     FILE \"" << toDestDirPath << "\"\n"
!        << indent << "     OLD_RPATH \"" << oldRpath << "\"\n"
!        << indent << "     NEW_RPATH \"" << newRpath << "\")\n";
!     }
  }
  

Index: cmFileCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFileCommand.cxx,v
retrieving revision 1.105
retrieving revision 1.106
diff -C 2 -d -r1.105 -r1.106
*** cmFileCommand.cxx	7 Apr 2008 14:55:51 -0000	1.105
--- cmFileCommand.cxx	14 Apr 2008 19:02:44 -0000	1.106
***************
*** 113,119 ****
      return this->HandleInstallCommand(args);
      }
!   else if ( subCommand == "CHRPATH" )
      {
!     return this->HandleChrpathCommand(args);
      }
    else if ( subCommand == "RELATIVE_PATH" )
--- 113,127 ----
      return this->HandleInstallCommand(args);
      }
!   else if ( subCommand == "RPATH_CHANGE" || subCommand == "CHRPATH" )
      {
!     return this->HandleRPathChangeCommand(args);
!     }
!   else if ( subCommand == "RPATH_CHECK" )
!     {
!     return this->HandleRPathCheckCommand(args);
!     }
!   else if ( subCommand == "RPATH_REMOVE" )
!     {
!     return this->HandleRPathRemoveCommand(args);
      }
    else if ( subCommand == "RELATIVE_PATH" )
***************
*** 1333,1337 ****
  
  //----------------------------------------------------------------------------
! bool cmFileCommand::HandleChrpathCommand(std::vector<std::string> const& args)
  {
    // Evaluate arguments.
--- 1341,1346 ----
  
  //----------------------------------------------------------------------------
! bool
! cmFileCommand::HandleRPathChangeCommand(std::vector<std::string> const& args)
  {
    // Evaluate arguments.
***************
*** 1373,1377 ****
        {
        cmOStringStream e;
!       e << "CHRPATH given unknown argument " << args[i];
        this->SetError(e.str().c_str());
        return false;
--- 1382,1386 ----
        {
        cmOStringStream e;
!       e << "RPATH_CHANGE given unknown argument " << args[i];
        this->SetError(e.str().c_str());
        return false;
***************
*** 1380,1394 ****
    if(!file)
      {
!     this->SetError("CHRPATH not given FILE option.");
      return false;
      }
    if(!oldRPath)
      {
!     this->SetError("CHRPATH not given OLD_RPATH option.");
      return false;
      }
    if(!newRPath)
      {
!     this->SetError("CHRPATH not given NEW_RPATH option.");
      return false;
      }
--- 1389,1403 ----
    if(!file)
      {
!     this->SetError("RPATH_CHANGE not given FILE option.");
      return false;
      }
    if(!oldRPath)
      {
!     this->SetError("RPATH_CHANGE not given OLD_RPATH option.");
      return false;
      }
    if(!newRPath)
      {
!     this->SetError("RPATH_CHANGE not given NEW_RPATH option.");
      return false;
      }
***************
*** 1396,1412 ****
      {
      cmOStringStream e;
!     e << "CHRPATH given FILE \"" << file << "\" that does not exist.";
      this->SetError(e.str().c_str());
      return false;
      }
    std::string emsg;
!   if(cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg))
!     {
!     return true;
!     }
!   else
      {
      cmOStringStream e;
!     e << "CHRPATH could not write new RPATH:\n"
        << "  " << newRPath << "\n"
        << "to the file:\n"
--- 1405,1420 ----
      {
      cmOStringStream e;
!     e << "RPATH_CHANGE given FILE \"" << file << "\" that does not exist.";
      this->SetError(e.str().c_str());
      return false;
      }
+   bool success = true;
+   cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
+   bool have_ft = cmSystemTools::FileTimeGet(file, ft);
    std::string emsg;
!   if(!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg))
      {
      cmOStringStream e;
!     e << "RPATH_CHANGE could not write new RPATH:\n"
        << "  " << newRPath << "\n"
        << "to the file:\n"
***************
*** 1414,1419 ****
--- 1422,1553 ----
        << emsg;
      this->SetError(e.str().c_str());
+     success = false;
+     }
+   if(success && have_ft)
+     {
+     cmSystemTools::FileTimeSet(file, ft);
+     }
+   cmSystemTools::FileTimeDelete(ft);
+   return success;
+ }
+ 
+ //----------------------------------------------------------------------------
+ bool
+ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
+ {
+   // Evaluate arguments.
+   const char* file = 0;
+   enum Doing { DoingNone, DoingFile };
+   Doing doing = DoingNone;
+   for(unsigned int i=1; i < args.size(); ++i)
+     {
+     if(args[i] == "FILE")
+       {
+       doing = DoingFile;
+       }
+     else if(doing == DoingFile)
+       {
+       file = args[i].c_str();
+       doing = DoingNone;
+       }
+     else
+       {
+       cmOStringStream e;
+       e << "RPATH_REMOVE given unknown argument " << args[i];
+       this->SetError(e.str().c_str());
+       return false;
+       }
+     }
+   if(!file)
+     {
+     this->SetError("RPATH_REMOVE not given FILE option.");
+     return false;
+     }
+   if(!cmSystemTools::FileExists(file, true))
+     {
+     cmOStringStream e;
+     e << "RPATH_REMOVE given FILE \"" << file << "\" that does not exist.";
+     this->SetError(e.str().c_str());
+     return false;
+     }
+   bool success = true;
+   cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
+   bool have_ft = cmSystemTools::FileTimeGet(file, ft);
+   std::string emsg;
+   if(!cmSystemTools::RemoveRPath(file, &emsg))
+     {
+     cmOStringStream e;
+     e << "RPATH_REMOVE could not remove RPATH from file:\n"
+       << "  " << file << "\n"
+       << emsg;
+     this->SetError(e.str().c_str());
+     success = false;
+     }
+   if(success && have_ft)
+     {
+     cmSystemTools::FileTimeSet(file, ft);
+     }
+   cmSystemTools::FileTimeDelete(ft);
+   return success;
+ }
+ 
+ //----------------------------------------------------------------------------
+ bool
+ cmFileCommand::HandleRPathCheckCommand(std::vector<std::string> const& args)
+ {
+   // Evaluate arguments.
+   const char* file = 0;
+   const char* rpath = 0;
+   enum Doing { DoingNone, DoingFile, DoingRPath };
+   Doing doing = DoingNone;
+   for(unsigned int i=1; i < args.size(); ++i)
+     {
+     if(args[i] == "RPATH")
+       {
+       doing = DoingRPath;
+       }
+     else if(args[i] == "FILE")
+       {
+       doing = DoingFile;
+       }
+     else if(doing == DoingFile)
+       {
+       file = args[i].c_str();
+       doing = DoingNone;
+       }
+     else if(doing == DoingRPath)
+       {
+       rpath = args[i].c_str();
+       doing = DoingNone;
+       }
+     else
+       {
+       cmOStringStream e;
+       e << "RPATH_CHECK given unknown argument " << args[i];
+       this->SetError(e.str().c_str());
+       return false;
+       }
+     }
+   if(!file)
+     {
+     this->SetError("RPATH_CHECK not given FILE option.");
+     return false;
+     }
+   if(!rpath)
+     {
+     this->SetError("RPATH_CHECK not given RPATH option.");
      return false;
      }
+ 
+   // If the file exists but does not have the desired RPath then
+   // delete it.  This is used during installation to re-install a file
+   // if its RPath will change.
+   if(cmSystemTools::FileExists(file, true) &&
+      !cmSystemTools::CheckRPath(file, rpath))
+     {
+     cmSystemTools::RemoveFile(file);
+     }
+ 
+   return true;
  }
  



More information about the Cmake-commits mailing list