[Cmake-commits] [cmake-commits] hoffman committed cmELF.cxx 1.8 1.8.2.1 cmELF.h 1.4 1.4.2.1 cmFileCommand.cxx 1.103.2.1 1.103.2.2 cmFileCommand.h 1.35 1.35.2.1 cmInstallCommand.cxx 1.45 1.45.2.1 cmInstallCommand.h 1.29 1.29.2.1 cmInstallTargetGenerator.cxx 1.62.2.1 1.62.2.2 cmInstallTargetGenerator.h 1.24 1.24.2.1 cmLocalVisualStudio7Generator.cxx 1.217.2.3 1.217.2.4 cmMakefileLibraryTargetGenerator.cxx 1.58.2.1 1.58.2.2 cmMakefileTargetGenerator.cxx 1.93.2.1 1.93.2.2 cmMessageCommand.cxx 1.22 1.22.2.1 cmPolicies.cxx 1.20.2.3 1.20.2.4 cmPolicies.h 1.10.2.1 1.10.2.2 cmSystemTools.cxx 1.368.2.3 1.368.2.4 cmSystemTools.h 1.150 1.150.2.1 cmTarget.cxx 1.207.2.4 1.207.2.5

cmake-commits at cmake.org cmake-commits at cmake.org
Sun Apr 20 20:44:55 EDT 2008


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

Modified Files:
      Tag: CMake-2-6
	cmELF.cxx cmELF.h cmFileCommand.cxx cmFileCommand.h 
	cmInstallCommand.cxx cmInstallCommand.h 
	cmInstallTargetGenerator.cxx cmInstallTargetGenerator.h 
	cmLocalVisualStudio7Generator.cxx 
	cmMakefileLibraryTargetGenerator.cxx 
	cmMakefileTargetGenerator.cxx cmMessageCommand.cxx 
	cmPolicies.cxx cmPolicies.h cmSystemTools.cxx cmSystemTools.h 
	cmTarget.cxx 
Log Message:
ENH: merge in from main tree


Index: cmSystemTools.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmSystemTools.h,v
retrieving revision 1.150
retrieving revision 1.150.2.1
diff -C 2 -d -r1.150 -r1.150.2.1
*** cmSystemTools.h	2 Mar 2008 19:35:23 -0000	1.150
--- cmSystemTools.h	21 Apr 2008 00:44:53 -0000	1.150.2.1
***************
*** 23,27 ****
  #include <cmsys/Process.h>
  
! 
  
  /** \class cmSystemTools
--- 23,27 ----
  #include <cmsys/Process.h>
  
! class cmSystemToolsFileTime;
  
  /** \class cmSystemTools
***************
*** 364,367 ****
--- 364,373 ----
    static bool CopyFileTime(const char* fromFile, const char* toFile);
  
+   /** Save and restore file times.  */
+   static cmSystemToolsFileTime* FileTimeNew();
+   static void FileTimeDelete(cmSystemToolsFileTime*);
+   static bool FileTimeGet(const char* fname, cmSystemToolsFileTime* t);
+   static bool FileTimeSet(const char* fname, cmSystemToolsFileTime* t);
+ 
    /** Find the directory containing the running executable.  Save it
     in a global location to be queried by GetExecutableDirectory
***************
*** 388,391 ****
--- 394,405 ----
                            std::string* emsg = 0);
  
+   /** Try to remove the RPATH from an ELF binary.  */
+   static bool RemoveRPath(std::string const& file, std::string* emsg = 0);
+ 
+   /** Check whether the RPATH in an ELF binary contains the path
+       given.  */
+   static bool CheckRPath(std::string const& file,
+                          std::string const& newRPath);
+ 
  private:
    static bool s_ForceUnixPaths;

Index: cmPolicies.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmPolicies.h,v
retrieving revision 1.10.2.1
retrieving revision 1.10.2.2
diff -C 2 -d -r1.10.2.1 -r1.10.2.2
*** cmPolicies.h	18 Mar 2008 14:23:54 -0000	1.10.2.1
--- cmPolicies.h	21 Apr 2008 00:44:52 -0000	1.10.2.2
***************
*** 47,50 ****
--- 47,51 ----
      CMP0004, // Libraries linked may not have leading or trailing whitespace
      CMP0005, // Definition value escaping
+     CMP0006, // BUNDLE install rules needed for MACOSX_BUNDLE targets
  
      // 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.20.2.3
retrieving revision 1.20.2.4
diff -C 2 -d -r1.20.2.3 -r1.20.2.4
*** cmPolicies.cxx	31 Mar 2008 21:57:41 -0000	1.20.2.3
--- cmPolicies.cxx	21 Apr 2008 00:44:52 -0000	1.20.2.4
***************
*** 252,255 ****
--- 252,273 ----
      "limitations of the escaping implementation.",
      2,6,0, cmPolicies::WARN);
+ 
+   this->DefinePolicy(
+     CMP0006, "CMP0006",
+     "Installing MACOSX_BUNDLE targets requires a BUNDLE DESTINATION.",
+     "This policy determines whether the install(TARGETS) command must be "
+     "given a BUNDLE DESTINATION when asked to install a target with the "
+     "MACOSX_BUNDLE property set.  "
+     "CMake 2.4 and below did not distinguish application bundles from "
+     "normal executables when installing targets.  "
+     "CMake 2.6 provides a BUNDLE option to the install(TARGETS) command "
+     "that specifies rules specific to application bundles on the Mac.  "
+     "Projects should use this option when installing a target with the "
+     "MACOSX_BUNDLE property set.\n"
+     "The OLD behavior for this policy is to fall back to the RUNTIME "
+     "DESTINATION if a BUNDLE DESTINATION is not given.  "
+     "The NEW behavior for this policy is to produce an error if a bundle "
+     "target is installed without a BUNDLE DESTINATION.",
+     2,6,0, cmPolicies::WARN);
  }
  

Index: cmLocalVisualStudio7Generator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmLocalVisualStudio7Generator.cxx,v
retrieving revision 1.217.2.3
retrieving revision 1.217.2.4
diff -C 2 -d -r1.217.2.3 -r1.217.2.4
*** cmLocalVisualStudio7Generator.cxx	8 Apr 2008 16:22:49 -0000	1.217.2.3
--- cmLocalVisualStudio7Generator.cxx	21 Apr 2008 00:44:52 -0000	1.217.2.4
***************
*** 408,411 ****
--- 408,412 ----
    };
    cmLocalVisualStudio7GeneratorOptions(cmLocalVisualStudio7Generator* lg,
+                                        int version,
                                         Tool tool,
                                         cmVS7FlagTable const* extraTable = 0);
***************
*** 440,443 ****
--- 441,445 ----
  private:
    cmLocalVisualStudio7Generator* LocalGenerator;
+   int Version;
  
    // create a map of xml tags to the values they should have in the output
***************
*** 552,556 ****
  
    // Construct a set of build options for this target.
!   Options targetOptions(this, Options::Compiler, this->ExtraFlagTable);
    targetOptions.FixExceptionHandlingDefault();
    targetOptions.Parse(flags.c_str());
--- 554,558 ----
  
    // Construct a set of build options for this target.
!   Options targetOptions(this, this->Version, Options::Compiler, this->ExtraFlagTable);
    targetOptions.FixExceptionHandlingDefault();
    targetOptions.Parse(flags.c_str());
***************
*** 746,750 ****
      extraLinkOptions += targetLinkFlags;
      }
!   Options linkOptions(this, Options::Linker);
    linkOptions.Parse(extraLinkOptions.c_str());
    switch(target.GetType())
--- 748,752 ----
      extraLinkOptions += targetLinkFlags;
      }
!   Options linkOptions(this, this->Version, Options::Linker);
    linkOptions.Parse(extraLinkOptions.c_str());
    switch(target.GetType())
***************
*** 1290,1294 ****
               !fc.CompileDefsConfig.empty())
              {
!             Options fileOptions(this, Options::Compiler,
                                  this->ExtraFlagTable);
              fileOptions.Parse(fc.CompileFlags.c_str());
--- 1292,1296 ----
               !fc.CompileDefsConfig.empty())
              {
!             Options fileOptions(this, this->Version, Options::Compiler,
                                  this->ExtraFlagTable);
              fileOptions.Parse(fc.CompileFlags.c_str());
***************
*** 1763,1769 ****
  cmLocalVisualStudio7GeneratorOptions
  ::cmLocalVisualStudio7GeneratorOptions(cmLocalVisualStudio7Generator* lg,
                                         Tool tool,
                                         cmVS7FlagTable const* extraTable):
!   LocalGenerator(lg), CurrentTool(tool),
    DoingDefine(false), FlagTable(0), ExtraFlagTable(extraTable)
  {
--- 1765,1772 ----
  cmLocalVisualStudio7GeneratorOptions
  ::cmLocalVisualStudio7GeneratorOptions(cmLocalVisualStudio7Generator* lg,
+                                        int version,
                                         Tool tool,
                                         cmVS7FlagTable const* extraTable):
!   LocalGenerator(lg), Version(version), CurrentTool(tool),
    DoingDefine(false), FlagTable(0), ExtraFlagTable(extraTable)
  {
***************
*** 1787,1791 ****
    // the flag to disable exception handling.  When the user does
    // remove the flag we need to override the IDE default of on.
!   this->FlagMap["ExceptionHandling"] = "FALSE";
  }
  
--- 1790,1804 ----
    // the flag to disable exception handling.  When the user does
    // remove the flag we need to override the IDE default of on.
!   switch (this->Version)
!     {
!     case 7:
!     case 71:
!       this->FlagMap["ExceptionHandling"] = "FALSE";
!     break;
! 
!     default:
!       this->FlagMap["ExceptionHandling"] = "0";
!     break;
!     }
  }
  

Index: cmInstallTargetGenerator.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmInstallTargetGenerator.h,v
retrieving revision 1.24
retrieving revision 1.24.2.1
diff -C 2 -d -r1.24 -r1.24.2.1
*** cmInstallTargetGenerator.h	6 Feb 2008 19:20:35 -0000	1.24
--- cmInstallTargetGenerator.h	21 Apr 2008 00:44:52 -0000	1.24.2.1
***************
*** 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: cmSystemTools.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmSystemTools.cxx,v
retrieving revision 1.368.2.3
retrieving revision 1.368.2.4
diff -C 2 -d -r1.368.2.3 -r1.368.2.4
*** cmSystemTools.cxx	9 Apr 2008 18:57:31 -0000	1.368.2.3
--- cmSystemTools.cxx	21 Apr 2008 00:44:52 -0000	1.368.2.4
***************
*** 57,60 ****
--- 57,72 ----
  #endif
  
+ class cmSystemToolsFileTime
+ {
+ public:
+ #if defined(_WIN32) && !defined(__CYGWIN__)
+   FILETIME timeCreation;
+   FILETIME timeLastAccess;
+   FILETIME timeLastWrite;
+ #else
+   struct utimbuf timeBuf;
+ #endif
+ };
+ 
  #if defined(__sgi) && !defined(__GNUC__)
  # pragma set woff 1375 /* base class destructor not virtual */
***************
*** 2112,2115 ****
--- 2124,2188 ----
  
  //----------------------------------------------------------------------------
+ cmSystemToolsFileTime* cmSystemTools::FileTimeNew()
+ {
+   return new cmSystemToolsFileTime;
+ }
+ 
+ //----------------------------------------------------------------------------
+ void cmSystemTools::FileTimeDelete(cmSystemToolsFileTime* t)
+ {
+   delete t;
+ }
+ 
+ //----------------------------------------------------------------------------
+ bool cmSystemTools::FileTimeGet(const char* fname, cmSystemToolsFileTime* t)
+ {
+ #if defined(_WIN32) && !defined(__CYGWIN__)
+   cmSystemToolsWindowsHandle h =
+     CreateFile(fname, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+   if(!h)
+     {
+     return false;
+     }
+   if(!GetFileTime(h, &t->timeCreation, &t->timeLastAccess, &t->timeLastWrite))
+     {
+     return false;
+     }
+ #else
+   struct stat st;
+   if(stat(fname, &st) < 0)
+     {
+     return false;
+     }
+   t->timeBuf.actime = st.st_atime;
+   t->timeBuf.modtime = st.st_mtime;
+ #endif
+   return true;
+ }
+ 
+ //----------------------------------------------------------------------------
+ bool cmSystemTools::FileTimeSet(const char* fname, cmSystemToolsFileTime* t)
+ {
+ #if defined(_WIN32) && !defined(__CYGWIN__)
+   cmSystemToolsWindowsHandle h =
+     CreateFile(fname, GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
+   if(!h)
+     {
+     return false;
+     }
+   if(!SetFileTime(h, &t->timeCreation, &t->timeLastAccess, &t->timeLastWrite))
+     {
+     return false;
+     }
+ #else
+   if(utime(fname, &t->timeBuf) < 0)
+     {
+     return false;
+     }
+ #endif
+   return true;
+ }
+ 
+ //----------------------------------------------------------------------------
  static std::string cmSystemToolsExecutableDirectory;
  void cmSystemTools::FindExecutableDirectory(const char* argv0)
***************
*** 2391,2392 ****
--- 2464,2635 ----
  #endif
  }
+ 
+ //----------------------------------------------------------------------------
+ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
+ {
+ #if defined(CMAKE_USE_ELF_PARSER)
+   unsigned long rpathPosition = 0;
+   unsigned long rpathSize = 0;
+   unsigned long rpathEntryPosition = 0;
+   std::vector<char> bytes;
+   {
+   // Parse the ELF binary.
+   cmELF elf(file.c_str());
+ 
+   // Get the RPATH or RUNPATH entry from it.
+   cmELF::StringEntry const* se = elf.GetRPath();
+   if(!se)
+     {
+     se = elf.GetRunPath();
+     }
+ 
+   if(se)
+     {
+     // Store information about the entry.
+     rpathPosition = se->Position;
+     rpathSize = se->Size;
+     rpathEntryPosition = elf.GetDynamicEntryPosition(se->IndexInSection);
+ 
+     // Get the file range containing the rest of the DYNAMIC table
+     // after the RPATH entry.
+     unsigned long nextEntryPosition =
+       elf.GetDynamicEntryPosition(se->IndexInSection+1);
+     unsigned int count = elf.GetDynamicEntryCount();
+     if(count == 0)
+       {
+       // This should happen only for invalid ELF files where a DT_NULL
+       // appears before the end of the table.
+       if(emsg)
+         {
+         *emsg = "DYNAMIC section contains a DT_NULL before the end.";
+         }
+       return false;
+       }
+     unsigned long nullEntryPosition = elf.GetDynamicEntryPosition(count);
+ 
+     // Allocate and fill a buffer with zeros.
+     bytes.resize(nullEntryPosition - rpathEntryPosition, 0);
+ 
+     // Read the part of the DYNAMIC section header that will move.
+     // The remainder of the buffer will be left with zeros which
+     // represent a DT_NULL entry.
+     if(!elf.ReadBytes(nextEntryPosition,
+                       nullEntryPosition - nextEntryPosition,
+                       &bytes[0]))
+       {
+       if(emsg)
+         {
+         *emsg = "Failed to read DYNAMIC section header.";
+         }
+       return false;
+       }
+     }
+   else
+     {
+     // There is no RPATH or RUNPATH anyway.
+     return true;
+     }
+   }
+ 
+   // Open the file for update.
+   std::ofstream f(file.c_str(),
+                   std::ios::in | std::ios::out | std::ios::binary);
+   if(!f)
+     {
+     if(emsg)
+       {
+       *emsg = "Error opening file for update.";
+       }
+     return false;
+     }
+ 
+   // Write the new DYNAMIC table header.
+   if(!f.seekp(rpathEntryPosition))
+     {
+     if(emsg)
+       {
+       *emsg = "Error seeking to DYNAMIC table header for RPATH.";
+       }
+     return false;
+     }
+   if(!f.write(&bytes[0], bytes.size()))
+     {
+     if(emsg)
+       {
+       *emsg = "Error replacing DYNAMIC table header.";
+       }
+     return false;
+     }
+ 
+   // Fill the RPATH string with zero bytes.
+   if(!f.seekp(rpathPosition))
+     {
+     if(emsg)
+       {
+       *emsg = "Error seeking to RPATH position.";
+       }
+     return false;
+     }
+   for(unsigned long i=0; i < rpathSize; ++i)
+     {
+     f << '\0';
+     }
+ 
+   // Make sure everything was okay.
+   if(f)
+     {
+     return true;
+     }
+   else
+     {
+     if(emsg)
+       {
+       *emsg = "Error writing the empty rpath to the file.";
+       }
+     return false;
+     }
+ #else
+   (void)file;
+   (void)emsg;
+   return false;
+ #endif
+ }
+ 
+ //----------------------------------------------------------------------------
+ bool cmSystemTools::CheckRPath(std::string const& file,
+                                std::string const& newRPath)
+ {
+ #if defined(CMAKE_USE_ELF_PARSER)
+   // Parse the ELF binary.
+   cmELF elf(file.c_str());
+ 
+   // Get the RPATH or RUNPATH entry from it.
+   cmELF::StringEntry const* se = elf.GetRPath();
+   if(!se)
+     {
+     se = elf.GetRunPath();
+     }
+ 
+   // Make sure the current rpath contains the new rpath.
+   if(newRPath.empty())
+     {
+     if(!se)
+       {
+       return true;
+       }
+     }
+   else
+     {
+     if(se &&
+        cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos)
+       {
+       return true;
+       }
+     }
+   return false;
+ #else
+   (void)file;
+   (void)newRPath;
+   return false;
+ #endif
+ }

Index: cmMessageCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMessageCommand.cxx,v
retrieving revision 1.22
retrieving revision 1.22.2.1
diff -C 2 -d -r1.22 -r1.22.2.1
*** cmMessageCommand.cxx	23 Jan 2008 15:27:59 -0000	1.22
--- cmMessageCommand.cxx	21 Apr 2008 00:44:52 -0000	1.22.2.1
***************
*** 61,65 ****
    if (send_error || fatal_error)
      {
!     cmSystemTools::Error(message.c_str());
      }
    else
--- 61,65 ----
    if (send_error || fatal_error)
      {
!     this->Makefile->IssueMessage(cmake::FATAL_ERROR, message.c_str());
      }
    else

Index: cmFileCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFileCommand.cxx,v
retrieving revision 1.103.2.1
retrieving revision 1.103.2.2
diff -C 2 -d -r1.103.2.1 -r1.103.2.2
*** cmFileCommand.cxx	8 Apr 2008 16:22:49 -0000	1.103.2.1
--- cmFileCommand.cxx	21 Apr 2008 00:44:51 -0000	1.103.2.2
***************
*** 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;
  }
  

Index: cmMakefileLibraryTargetGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefileLibraryTargetGenerator.cxx,v
retrieving revision 1.58.2.1
retrieving revision 1.58.2.2
diff -C 2 -d -r1.58.2.1 -r1.58.2.2
*** cmMakefileLibraryTargetGenerator.cxx	8 Apr 2008 16:22:50 -0000	1.58.2.1
--- cmMakefileLibraryTargetGenerator.cxx	21 Apr 2008 00:44:52 -0000	1.58.2.2
***************
*** 725,729 ****
    objdir += this->Target->GetName();
    objdir += ".dir";
!   vars.ObjectDir = objdir.c_str(); 
    vars.Target = targetOutPathReal.c_str();
    std::string linkString = linklibs.str();
--- 725,732 ----
    objdir += this->Target->GetName();
    objdir += ".dir";
!   objdir = this->Convert(objdir.c_str(),
!                          cmLocalGenerator::START_OUTPUT,
!                          cmLocalGenerator::SHELL);
!   vars.ObjectDir = objdir.c_str();
    vars.Target = targetOutPathReal.c_str();
    std::string linkString = linklibs.str();

Index: cmInstallCommand.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmInstallCommand.cxx,v
retrieving revision 1.45
retrieving revision 1.45.2.1
diff -C 2 -d -r1.45 -r1.45.2.1
*** cmInstallCommand.cxx	7 Feb 2008 21:22:00 -0000	1.45
--- cmInstallCommand.cxx	21 Apr 2008 00:44:51 -0000	1.45.2.1
***************
*** 537,541 ****
                                                             false);
              }
!           else
              {
              cmOStringStream e;
--- 537,556 ----
                                                             false);
              }
!           if(!runtimeArgs.GetDestination().empty())
!             {
!             bool failure = false;
!             if(this->CheckCMP0006(failure))
!               {
!               // For CMake 2.4 compatibility fallback to the RUNTIME
!               // properties.
!               bundleGenerator =
!                 CreateInstallTargetGenerator(target, runtimeArgs, false);
!               }
!             else if(failure)
!               {
!               return false;
!               }
!             }
!           if(!bundleGenerator)
              {
              cmOStringStream e;
***************
*** 1285,1286 ****
--- 1300,1332 ----
    return true;
  }
+ 
+ //----------------------------------------------------------------------------
+ bool cmInstallCommand::CheckCMP0006(bool& failure)
+ {
+   switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0006))
+     {
+     case cmPolicies::WARN:
+       {
+       this->Makefile->IssueMessage(
+         cmake::AUTHOR_WARNING,
+         this->Makefile->GetPolicies()->GetPolicyWarning(cmPolicies::CMP0006)
+         );
+       }
+     case cmPolicies::OLD:
+       // OLD behavior is to allow compatibility
+       return true;
+     case cmPolicies::NEW:
+       // NEW behavior is to disallow compatibility
+       break;
+     case cmPolicies::REQUIRED_IF_USED:
+     case cmPolicies::REQUIRED_ALWAYS:
+       failure = true;
+       this->Makefile->IssueMessage(
+         cmake::FATAL_ERROR,
+         this->Makefile->GetPolicies()
+         ->GetRequiredPolicyError(cmPolicies::CMP0006)
+         );
+       break;
+     }
+   return false;
+ }

Index: cmInstallTargetGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmInstallTargetGenerator.cxx,v
retrieving revision 1.62.2.1
retrieving revision 1.62.2.2
diff -C 2 -d -r1.62.2.1 -r1.62.2.2
*** cmInstallTargetGenerator.cxx	8 Apr 2008 16:22:49 -0000	1.62.2.1
--- cmInstallTargetGenerator.cxx	21 Apr 2008 00:44:51 -0000	1.62.2.2
***************
*** 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: cmMakefileTargetGenerator.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmMakefileTargetGenerator.cxx,v
retrieving revision 1.93.2.1
retrieving revision 1.93.2.2
diff -C 2 -d -r1.93.2.1 -r1.93.2.2
*** cmMakefileTargetGenerator.cxx	8 Apr 2008 16:22:50 -0000	1.93.2.1
--- cmMakefileTargetGenerator.cxx	21 Apr 2008 00:44:52 -0000	1.93.2.2
***************
*** 335,340 ****
    cmSystemTools::MakeDirectory(macdir.c_str());
  
!   // Record use of this content location.
!   this->MacContentFolders.insert(pkgloc);
  
    // Get the input file location.
--- 335,345 ----
    cmSystemTools::MakeDirectory(macdir.c_str());
  
!   // Record use of this content location.  Only the first level
!   // directory is needed.
!   {
!   std::string loc = pkgloc;
!   loc = loc.substr(0, loc.find('/'));
!   this->MacContentFolders.insert(loc);
!   }
  
    // Get the input file location.
***************
*** 615,618 ****
--- 620,626 ----
    vars.Object = shellObj.c_str();
    std::string objectDir = cmSystemTools::GetFilenamePath(obj);
+   objectDir = this->Convert(objectDir.c_str(),
+                             cmLocalGenerator::START_OUTPUT,
+                             cmLocalGenerator::SHELL);
    vars.ObjectDir = objectDir.c_str();
    vars.Flags = flags.c_str();

Index: cmFileCommand.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmFileCommand.h,v
retrieving revision 1.35
retrieving revision 1.35.2.1
diff -C 2 -d -r1.35 -r1.35.2.1
*** cmFileCommand.h	1 Mar 2008 17:51:07 -0000	1.35
--- cmFileCommand.h	21 Apr 2008 00:44:51 -0000	1.35.2.1
***************
*** 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: cmInstallCommand.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmInstallCommand.h,v
retrieving revision 1.29
retrieving revision 1.29.2.1
diff -C 2 -d -r1.29 -r1.29.2.1
*** cmInstallCommand.h	4 Feb 2008 22:03:48 -0000	1.29
--- cmInstallCommand.h	21 Apr 2008 00:44:51 -0000	1.29.2.1
***************
*** 110,126 ****
        "The TARGETS form specifies rules for installing targets from a "
        "project.  There are five kinds of target files that may be "
!       "installed: archive, library, runtime, framework, and bundle.  "
  
!       "Executables are treated as runtime targets, except that those "
!       "marked with the MACOSX_BUNDLE property are treated as bundle "
        "targets on OS X. "
!       "Static libraries are always treated as archive targets. "
!       "Module libraries are always treated as library targets. "
!       "For non-DLL platforms shared libraries are treated as library "
        "targets, except that those marked with the FRAMEWORK property "
!       "are treated as framework targets on OS X.  "
        "For DLL platforms the DLL part of a shared library is treated as "
!       "a runtime target and the corresponding import library is treated as "
!       "an archive target. "
        "All Windows-based systems including Cygwin are DLL platforms. "
        "The ARCHIVE, LIBRARY, RUNTIME, and FRAMEWORK "
--- 110,126 ----
        "The TARGETS form specifies rules for installing targets from a "
        "project.  There are five kinds of target files that may be "
!       "installed: ARCHIVE, LIBRARY, RUNTIME, FRAMEWORK, and BUNDLE.  "
  
!       "Executables are treated as RUNTIME targets, except that those "
!       "marked with the MACOSX_BUNDLE property are treated as BUNDLE "
        "targets on OS X. "
!       "Static libraries are always treated as ARCHIVE targets. "
!       "Module libraries are always treated as LIBRARY targets. "
!       "For non-DLL platforms shared libraries are treated as LIBRARY "
        "targets, except that those marked with the FRAMEWORK property "
!       "are treated as FRAMEWORK targets on OS X.  "
        "For DLL platforms the DLL part of a shared library is treated as "
!       "a RUNTIME target and the corresponding import library is treated as "
!       "an ARCHIVE target. "
        "All Windows-based systems including Cygwin are DLL platforms. "
        "The ARCHIVE, LIBRARY, RUNTIME, and FRAMEWORK "
***************
*** 347,350 ****
--- 347,351 ----
                           const std::vector<std::string>& relFiles,
                           std::vector<std::string>& absFiles);
+   bool CheckCMP0006(bool& failure);
  };
  

Index: cmELF.h
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmELF.h,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -C 2 -d -r1.4 -r1.4.2.1
*** cmELF.h	2 Mar 2008 21:19:40 -0000	1.4
--- cmELF.h	21 Apr 2008 00:44:51 -0000	1.4.2.1
***************
*** 69,72 ****
--- 69,75 ----
      // allocated for one or more null terminators.
      unsigned long Size;
+ 
+     // The index of the section entry referencing the string.
+     int IndexInSection;
    };
  
***************
*** 77,80 ****
--- 80,94 ----
    unsigned int GetNumberOfSections() const;
  
+   /** Get the number of DYNAMIC section entries before the first
+       DT_NULL.  Returns zero on error.  */
+   unsigned int GetDynamicEntryCount() const;
+ 
+   /** Get the position of a DYNAMIC section header entry.  Returns
+       zero on error.  */
+   unsigned long GetDynamicEntryPosition(int index) const;
+ 
+   /** Read bytes from the file.  */
+   bool ReadBytes(unsigned long pos, unsigned long size, char* buf) const;
+ 
    /** Get the SONAME field if any.  */
    bool GetSOName(std::string& soname);

Index: cmTarget.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmTarget.cxx,v
retrieving revision 1.207.2.4
retrieving revision 1.207.2.5
diff -C 2 -d -r1.207.2.4 -r1.207.2.5
*** cmTarget.cxx	8 Apr 2008 16:22:51 -0000	1.207.2.4
--- cmTarget.cxx	21 Apr 2008 00:44:53 -0000	1.207.2.5
***************
*** 135,140 ****
       "A postfix that will be applied to this target when build debug.",
       "A property on a target that specifies a postfix to add to the "
!      "target name when built in debug mode. For example foo.dll "
!      "versus fooD.dll");
  
    cm->DefineProperty
--- 135,140 ----
       "A postfix that will be applied to this target when build debug.",
       "A property on a target that specifies a postfix to add to the "
!      "target name when built in debug mode. For example \"foo.dll\" "
!      "versus \"fooD.dll\".  Ignored for Mac Frameworks and App Bundles.");
  
    cm->DefineProperty
***************
*** 2312,2315 ****
--- 2312,2321 ----
      configProp += "_POSTFIX";
      configPostfix = this->GetProperty(configProp.c_str());
+     // Mac application bundles and frameworks have no postfix.
+     if(configPostfix &&
+        (this->IsAppBundleOnApple() || this->IsFrameworkOnApple()))
+       {
+       configPostfix = 0;
+       }
      }
    const char* prefixVar = this->GetPrefixVariableInternal(type, implib);

Index: cmELF.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmELF.cxx,v
retrieving revision 1.8
retrieving revision 1.8.2.1
diff -C 2 -d -r1.8 -r1.8.2.1
*** cmELF.cxx	3 Mar 2008 13:48:37 -0000	1.8
--- cmELF.cxx	21 Apr 2008 00:44:51 -0000	1.8.2.1
***************
*** 99,105 ****
--- 99,114 ----
    // Forward to the per-class implementation.
    virtual unsigned int GetNumberOfSections() const = 0;
+   virtual unsigned int GetDynamicEntryCount() = 0;
+   virtual unsigned long GetDynamicEntryPosition(int j) = 0;
    virtual StringEntry const* GetDynamicSectionString(int tag) = 0;
    virtual void PrintInfo(std::ostream& os) const = 0;
  
+   bool ReadBytes(unsigned long pos, unsigned long size, char* buf)
+     {
+     this->Stream.seekg(pos);
+     this->Stream.read(buf, size);
+     return this->Stream?true:false;
+     }
+ 
    // Lookup the SONAME in the DYNAMIC section.
    StringEntry const* GetSOName()
***************
*** 202,205 ****
--- 211,218 ----
      }
  
+   // Get the file position and size of a dynamic section entry.
+   virtual unsigned int GetDynamicEntryCount();
+   virtual unsigned long GetDynamicEntryPosition(int j);
+ 
    // Lookup a string from the dynamic section with the given tag.
    virtual StringEntry const* GetDynamicSectionString(int tag);
***************
*** 553,556 ****
--- 566,603 ----
  //----------------------------------------------------------------------------
  template <class Types>
+ unsigned int cmELFInternalImpl<Types>::GetDynamicEntryCount()
+ {
+   if(!this->LoadDynamicSection())
+     {
+     return 0;
+     }
+   for(unsigned int i = 0; i < this->DynamicSectionEntries.size(); ++i)
+     {
+     if(this->DynamicSectionEntries[i].d_tag == DT_NULL)
+       {
+       return i;
+       }
+     }
+   return this->DynamicSectionEntries.size();
+ }
+ 
+ //----------------------------------------------------------------------------
+ template <class Types>
+ unsigned long cmELFInternalImpl<Types>::GetDynamicEntryPosition(int j)
+ {
+   if(!this->LoadDynamicSection())
+     {
+     return 0;
+     }
+   if(j < 0 || j >= static_cast<int>(this->DynamicSectionEntries.size()))
+     {
+     return 0;
+     }
+   ELF_Shdr const& sec = this->SectionHeaders[this->DynamicSectionIndex];
+   return sec.sh_offset + sec.sh_entsize*j;
+ }
+ 
+ //----------------------------------------------------------------------------
+ template <class Types>
  cmELF::StringEntry const*
  cmELFInternalImpl<Types>::GetDynamicSectionString(int tag)
***************
*** 572,575 ****
--- 619,623 ----
    se.Position = 0;
    se.Size = 0;
+   se.IndexInSection = -1;
  
    // Try reading the dynamic section.
***************
*** 642,645 ****
--- 690,694 ----
        se.Position = static_cast<unsigned long>(strtab.sh_offset + first);
        se.Size = last - first;
+       se.IndexInSection = di - this->DynamicSectionEntries.begin();
        return &se;
        }
***************
*** 763,766 ****
--- 812,854 ----
  
  //----------------------------------------------------------------------------
+ unsigned int cmELF::GetDynamicEntryCount() const
+ {
+   if(this->Valid())
+     {
+     return this->Internal->GetDynamicEntryCount();
+     }
+   else
+     {
+     return 0;
+     }
+ }
+ 
+ //----------------------------------------------------------------------------
+ unsigned long cmELF::GetDynamicEntryPosition(int index) const
+ {
+   if(this->Valid())
+     {
+     return this->Internal->GetDynamicEntryPosition(index);
+     }
+   else
+     {
+     return 0;
+     }
+ }
+ 
+ //----------------------------------------------------------------------------
+ bool cmELF::ReadBytes(unsigned long pos, unsigned long size, char* buf) const
+ {
+   if(this->Valid())
+     {
+     return this->Internal->ReadBytes(pos, size, buf);
+     }
+   else
+     {
+     return false;
+     }
+ }
+ 
+ //----------------------------------------------------------------------------
  bool cmELF::GetSOName(std::string& soname)
  {



More information about the Cmake-commits mailing list