summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Gurr <tgurr@gentoo.org>2008-08-27 21:19:10 +0000
committerTimo Gurr <tgurr@gentoo.org>2008-08-27 21:19:10 +0000
commit6bc00ab6c96f342b427871879ca8f91ad42eb72c (patch)
treebe98ca70bdb45c52dbe193942813938abee1c61b /dev-util/cmake
parentSilence errors from modprobe unix. (diff)
downloadgentoo-2-6bc00ab6c96f342b427871879ca8f91ad42eb72c.tar.gz
gentoo-2-6bc00ab6c96f342b427871879ca8f91ad42eb72c.tar.bz2
gentoo-2-6bc00ab6c96f342b427871879ca8f91ad42eb72c.zip
Version bump. Big thanks to Brad King from kitware, thewtex and Arfrever Frehtes Taifersar Arahesis and everyone else involved. Fixes bug #224901, #232111, #233772 and #235731.
(Portage version: 2.2_rc8/cvs/Linux 2.6.26-gentoo x86_64)
Diffstat (limited to 'dev-util/cmake')
-rw-r--r--dev-util/cmake/ChangeLog11
-rw-r--r--dev-util/cmake/cmake-2.6.1.ebuild131
-rw-r--r--dev-util/cmake/files/cmake-2.6.1-gc-sections.patch172
-rw-r--r--dev-util/cmake/files/cmake-2.6.1-rpath.patch531
4 files changed, 844 insertions, 1 deletions
diff --git a/dev-util/cmake/ChangeLog b/dev-util/cmake/ChangeLog
index 9d41ed393ec1..741a8ef8b4a9 100644
--- a/dev-util/cmake/ChangeLog
+++ b/dev-util/cmake/ChangeLog
@@ -1,6 +1,15 @@
# ChangeLog for dev-util/cmake
# Copyright 2000-2008 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/dev-util/cmake/ChangeLog,v 1.72 2008/05/08 15:53:11 cryos Exp $
+# $Header: /var/cvsroot/gentoo-x86/dev-util/cmake/ChangeLog,v 1.73 2008/08/27 21:19:10 tgurr Exp $
+
+*cmake-2.6.1 (27 Aug 2008)
+
+ 27 Aug 2008; Timo Gurr <tgurr@gentoo.org>
+ +files/cmake-2.6.1-gc-sections.patch, +files/cmake-2.6.1-rpath.patch,
+ +cmake-2.6.1.ebuild:
+ Version bump. Big thanks to Brad King from kitware, thewtex and Arfrever
+ Frehtes Taifersar Arahesis and everyone else involved. Fixes bug #224901,
+ #232111, #233772 and #235731.
*cmake-2.6.0 (08 May 2008)
diff --git a/dev-util/cmake/cmake-2.6.1.ebuild b/dev-util/cmake/cmake-2.6.1.ebuild
new file mode 100644
index 000000000000..411301ccba15
--- /dev/null
+++ b/dev-util/cmake/cmake-2.6.1.ebuild
@@ -0,0 +1,131 @@
+# Copyright 1999-2008 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/dev-util/cmake/cmake-2.6.1.ebuild,v 1.1 2008/08/27 21:19:10 tgurr Exp $
+
+EAPI="1"
+
+inherit elisp-common toolchain-funcs eutils versionator flag-o-matic
+
+MY_PV="${PV/rc/RC-}"
+MY_P="${PN}-$(replace_version_separator 3 - ${MY_PV})"
+
+DESCRIPTION="Cross platform Make"
+HOMEPAGE="http://www.cmake.org/"
+SRC_URI="http://www.cmake.org/files/v$(get_version_component_range 1-2)/${MY_P}.tar.gz"
+
+LICENSE="CMake"
+SLOT="0"
+KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~ppc ~ppc64 ~s390 ~sh ~sparc ~sparc-fbsd ~x86 ~x86-fbsd"
+IUSE="emacs qt4 vim-syntax"
+
+DEPEND=">=net-misc/curl-7.16.4
+ >=dev-libs/expat-2.0.1
+ >=dev-libs/libxml2-2.6.28
+ >=dev-libs/xmlrpc-c-1.06.09
+ emacs? ( virtual/emacs )
+ qt4? ( || ( ( x11-libs/qt-core:4
+ x11-libs/qt-gui:4 )
+ >=x11-libs/qt-4.3:4 ) )
+ vim-syntax? ( || (
+ app-editors/vim
+ app-editors/gvim ) )"
+RDEPEND="${DEPEND}"
+
+SITEFILE="50${PN}-gentoo.el"
+VIMFILE="${PN}.vim"
+
+S="${WORKDIR}/${MY_P}"
+
+pkg_setup() {
+ if ! built_with_use -o dev-libs/xmlrpc-c curl libwww; then
+ echo
+ eerror "${PN} requires dev-libs/xmlrpc-c to be built with either the 'libwww' or"
+ eerror "the 'curl' USE flag or both enabled."
+ eerror "Please re-emerge dev-libs/xmlrpc-c with USE=\"libwww\" or USE=\"curl\"."
+ echo
+ die "Please re-emerge dev-libs/xmlrpc-c with USE=\"libwww\" or USE=\"curl\"."
+ fi
+}
+
+src_unpack() {
+ unpack ${A}
+ cd "${S}"
+
+ # Upstream fix, compatibility with -Wl,--gc-sections, bug #235731
+ epatch "${FILESDIR}/${PN}-2.6.1-gc-sections.patch"
+
+ # Upstream fix, rpath handling security, bug #224901
+ epatch "${FILESDIR}/${PN}-2.6.1-rpath.patch"
+
+ # Link against the shared Python library rather than the static one
+ epatch "${FILESDIR}/${PN}-FindPythonLibs.patch"
+}
+
+src_compile() {
+ if [[ "$(gcc-major-version)" -eq "3" ]] ; then
+ append-flags "-fno-stack-protector"
+ fi
+
+ tc-export CC CXX LD
+
+ local qt_arg
+ if use qt4; then
+ qt_arg="--qt-gui"
+ else
+ qt_arg="--no-qt-gui"
+ fi
+
+ local par_arg
+ echo $MAKEOPTS | egrep -o '(\-j|\-\-jobs)(=?|[[:space:]]*)[[:digit:]]+' > /dev/null
+ if [ $? -eq 0 ]; then
+ par_arg=$(echo $MAKEOPTS | egrep -o '(\-j|\-\-jobs)(=?|[[:space:]]*)[[:digit:]]+' | egrep -o '[[:digit:]]+')
+ par_arg="--parallel=${par_arg}"
+ else
+ par_arg="--parallel=1"
+ fi
+
+ ./bootstrap \
+ --system-libs \
+ --prefix=/usr \
+ --docdir=/share/doc/${PF} \
+ --datadir=/share/${PN} \
+ --mandir=/share/man \
+ "$qt_arg" \
+ "$par_arg" || die "./bootstrap failed"
+
+ emake || die "emake failed."
+ if use emacs; then
+ elisp-compile Docs/cmake-mode.el || die "elisp compile failed"
+ fi
+}
+
+src_test() {
+ emake test || \
+ einfo "note test failure on qtwrapping was expected - nature of portage rather than a true failure"
+}
+
+src_install() {
+ emake install DESTDIR="${D}" || die "install failed"
+ if use emacs; then
+ elisp-install ${PN} Docs/cmake-mode.el Docs/cmake-mode.elc || die "elisp-install failed"
+ elisp-site-file-install "${FILESDIR}/${SITEFILE}"
+ fi
+ if use vim-syntax; then
+ insinto /usr/share/vim/vimfiles/syntax
+ doins "${S}"/Docs/cmake-syntax.vim
+
+ insinto /usr/share/vim/vimfiles/indent
+ doins "${S}"/Docs/cmake-indent.vim
+
+ insinto /usr/share/vim/vimfiles/ftdetect
+ doins "${FILESDIR}/${VIMFILE}"
+ fi
+}
+
+pkg_postinst() {
+ use emacs && elisp-site-regen
+}
+
+pkg_postrm() {
+ use emacs && elisp-site-regen
+}
diff --git a/dev-util/cmake/files/cmake-2.6.1-gc-sections.patch b/dev-util/cmake/files/cmake-2.6.1-gc-sections.patch
new file mode 100644
index 000000000000..325c5a9f7a80
--- /dev/null
+++ b/dev-util/cmake/files/cmake-2.6.1-gc-sections.patch
@@ -0,0 +1,172 @@
+Fix compatibility with -Wl,--gc-sections.
+
+http://www.cmake.org/pipermail/cmake/2008-August/023240.html
+http://www.cmake.org/pipermail/cmake-commits/2008-August/004477.html
+
+--- Modules/CheckTypeSizeC.c.in
++++ Modules/CheckTypeSizeC.c.in
+@@ -29,15 +29,16 @@
+ ('0' + (SIZE % 10)),
+ ']','\0'};
+
+-
+ #ifdef __CLASSIC_C__
+-int main(){
+- int ac;
+- char*av[];
++int main(argc, argv) int argc; char *argv[];
+ #else
+-int main(int ac, char*av[]){
++int main(int argc, char *argv[])
+ #endif
+- return (&info_sizeof[0] != &info_sizeof[0]);
++{
++ int require = 0;
++ require += info_sizeof[argc];
++ (void)argv;
++ return require;
+ }
+
+ #else /* CHECK_TYPE_SIZE_TYPE */
+--- Modules/CMakeCCompilerABI.c
++++ Modules/CMakeCCompilerABI.c
+@@ -12,17 +12,17 @@
+
+ /*--------------------------------------------------------------------------*/
+
+-/* Make sure the information strings are referenced. */
+-#define REQUIRE(x) (&x[0] != &require)
+-
+-int main()
++#ifdef __CLASSIC_C__
++int main(argc, argv) int argc; char *argv[];
++#else
++int main(int argc, char *argv[])
++#endif
+ {
+- const char require = 0;
+- return
+- (
+- REQUIRE(info_sizeof_dptr)
++ int require = 0;
++ require += info_sizeof_dptr[argc];
+ #if defined(ABI_ID)
+- && REQUIRE(info_abi)
++ require += info_abi[argc];
+ #endif
+- );
++ (void)argv;
++ return require;
+ }
+--- Modules/CMakeCCompilerId.c.in
++++ Modules/CMakeCCompilerId.c.in
+@@ -2,15 +2,9 @@
+ # error "A C++ compiler has been selected for C."
+ #endif
+
+-/* Provide main() so the program can link. */
+ #if defined(__18CXX)
+ # define ID_VOID_MAIN
+ #endif
+-#ifdef ID_VOID_MAIN
+-void main() {}
+-#else
+-int main() { return 0; }
+-#endif
+
+ #if defined(__INTEL_COMPILER) || defined(__ICC)
+ # define COMPILER_ID "Intel"
+@@ -82,3 +76,18 @@
+ char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
+
+ @CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@
++
++/*--------------------------------------------------------------------------*/
++
++#ifdef ID_VOID_MAIN
++void main() {}
++#else
++int main(int argc, char* argv[])
++{
++ int require = 0;
++ require += info_compiler[argc];
++ require += info_platform[argc];
++ (void)argv;
++ return require;
++}
++#endif
+--- Modules/CMakeCXXCompilerABI.cpp
++++ Modules/CMakeCXXCompilerABI.cpp
+@@ -8,17 +8,13 @@
+
+ /*--------------------------------------------------------------------------*/
+
+-/* Make sure the information strings are referenced. */
+-#define REQUIRE(x) (&x[0] != &require)
+-
+-int main()
++int main(int argc, char* argv[])
+ {
+- const char require = 0;
+- return
+- (
+- REQUIRE(info_sizeof_dptr)
++ int require = 0;
++ require += info_sizeof_dptr[argc];
+ #if defined(ABI_ID)
+- && REQUIRE(info_abi)
++ require += info_abi[argc];
+ #endif
+- );
++ (void)argv;
++ return require;
+ }
+--- Modules/CMakeCXXCompilerId.cpp.in
++++ Modules/CMakeCXXCompilerId.cpp.in
+@@ -5,9 +5,6 @@
+ # error "A C compiler has been selected for C++."
+ #endif
+
+-/* Provide main() so the program can link. */
+-int main() { return 0; }
+-
+ #if defined(__COMO__)
+ # define COMPILER_ID "Comeau"
+
+@@ -70,3 +67,14 @@
+ char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
+
+ @CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@
++
++/*--------------------------------------------------------------------------*/
++
++int main(int argc, char* argv[])
++{
++ int require = 0;
++ require += info_compiler[argc];
++ require += info_platform[argc];
++ (void)argv;
++ return require;
++}
+--- Modules/TestEndianess.c.in
++++ Modules/TestEndianess.c.in
+@@ -10,11 +10,14 @@
+ const cmakeint16 info_big[] = {0x5448, 0x4953, 0x2049, 0x5320, 0x4249, 0x4720, 0x454e, 0x4449, 0x414e, 0x2e2e, 0x0000};
+
+ #ifdef __CLASSIC_C__
+-int main(){
+- int ac;
+- char*av[];
++int main(argc, argv) int argc; char *argv[];
+ #else
+-int main(int ac, char*av[]){
++int main(int argc, char *argv[])
+ #endif
+- return (&info_little[0] != &info_big[0]);
++{
++ int require = 0;
++ require += info_little[argc];
++ require += info_big[argc];
++ (void)argv;
++ return require;
+ }
diff --git a/dev-util/cmake/files/cmake-2.6.1-rpath.patch b/dev-util/cmake/files/cmake-2.6.1-rpath.patch
new file mode 100644
index 000000000000..d59289ec4e08
--- /dev/null
+++ b/dev-util/cmake/files/cmake-2.6.1-rpath.patch
@@ -0,0 +1,531 @@
+diff --git cmake-2.6.1-orig/Source/cmFileCommand.cxx cmake-2.6.1/Source/cmFileCommand.cxx
+index 6ac6bcc..e8e64a4 100644
+--- cmake-2.6.1-orig/Source/cmFileCommand.cxx
++++ cmake-2.6.1/Source/cmFileCommand.cxx
+@@ -1486,7 +1486,8 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
+ cmSystemToolsFileTime* ft = cmSystemTools::FileTimeNew();
+ bool have_ft = cmSystemTools::FileTimeGet(file, ft);
+ std::string emsg;
+- if(!cmSystemTools::RemoveRPath(file, &emsg))
++ bool removed;
++ if(!cmSystemTools::RemoveRPath(file, &emsg, &removed))
+ {
+ cmOStringStream e;
+ e << "RPATH_REMOVE could not remove RPATH from file:\n"
+@@ -1495,9 +1496,19 @@ cmFileCommand::HandleRPathRemoveCommand(std::vector<std::string> const& args)
+ this->SetError(e.str().c_str());
+ success = false;
+ }
+- if(success && have_ft)
++ if(success)
+ {
+- cmSystemTools::FileTimeSet(file, ft);
++ if(removed)
++ {
++ std::string message = "Removed runtime path from \"";
++ message += file;
++ message += "\"";
++ this->Makefile->DisplayStatus(message.c_str(), -1);
++ }
++ if(have_ft)
++ {
++ cmSystemTools::FileTimeSet(file, ft);
++ }
+ }
+ cmSystemTools::FileTimeDelete(ft);
+ return success;
+diff --git cmake-2.6.1-orig/Source/cmSystemTools.cxx cmake-2.6.1/Source/cmSystemTools.cxx
+index 4e1f945..f333a4c 100644
+--- cmake-2.6.1-orig/Source/cmSystemTools.cxx
++++ cmake-2.6.1/Source/cmSystemTools.cxx
+@@ -26,6 +26,7 @@
+ #if defined(CMAKE_BUILD_WITH_CMAKE)
+ # include <cmsys/Terminal.h>
+ #endif
++#include <cmsys/stl/algorithm>
+
+ #if defined(_WIN32)
+ # include <windows.h>
+@@ -2328,6 +2329,16 @@ std::string::size_type cmSystemToolsFindRPath(std::string const& have,
+ }
+ #endif
+
++#if defined(CMAKE_USE_ELF_PARSER)
++struct cmSystemToolsRPathInfo
++{
++ unsigned long Position;
++ unsigned long Size;
++ std::string Name;
++ std::string Value;
++};
++#endif
++
+ //----------------------------------------------------------------------------
+ bool cmSystemTools::ChangeRPath(std::string const& file,
+ std::string const& oldRPath,
+@@ -2340,37 +2351,71 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
+ {
+ *changed = false;
+ }
+- unsigned long rpathPosition = 0;
+- unsigned long rpathSize = 0;
+- std::string rpathPrefix;
+- std::string rpathSuffix;
++ int rp_count = 0;
++ cmSystemToolsRPathInfo rp[2];
+ {
+ // 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)
++ // Get the RPATH and RUNPATH entries from it.
++ int se_count = 0;
++ cmELF::StringEntry const* se[2] = {0, 0};
++ const char* se_name[2] = {0, 0};
++ if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
+ {
+- se = elf.GetRunPath();
++ se[se_count] = se_rpath;
++ se_name[se_count] = "RPATH";
++ ++se_count;
++ }
++ if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
++ {
++ se[se_count] = se_runpath;
++ se_name[se_count] = "RUNPATH";
++ ++se_count;
++ }
++ if(se_count == 0)
++ {
++ if(newRPath.empty())
++ {
++ // The new rpath is empty and there is no rpath anyway so it is
++ // okay.
++ return true;
++ }
++ else
++ {
++ if(emsg)
++ {
++ *emsg = "No valid ELF RPATH or RUNPATH entry exists in the file; ";
++ *emsg += elf.GetErrorMessage();
++ }
++ return false;
++ }
+ }
+
+- if(se)
++ for(int i=0; i < se_count; ++i)
+ {
++ // If both RPATH and RUNPATH refer to the same string literal it
++ // needs to be changed only once.
++ if(rp_count && rp[0].Position == se[i]->Position)
++ {
++ continue;
++ }
++
+ // Make sure the current rpath contains the old rpath.
+- std::string::size_type pos = cmSystemToolsFindRPath(se->Value, oldRPath);
++ std::string::size_type pos =
++ cmSystemToolsFindRPath(se[i]->Value, oldRPath);
+ if(pos == std::string::npos)
+ {
+ // If it contains the new rpath instead then it is okay.
+- if(cmSystemToolsFindRPath(se->Value, newRPath) != std::string::npos)
++ if(cmSystemToolsFindRPath(se[i]->Value, newRPath) != std::string::npos)
+ {
+- return true;
++ continue;
+ }
+ if(emsg)
+ {
+ cmOStringStream e;
+- e << "The current RPATH is:\n"
+- << " " << se->Value << "\n"
++ e << "The current " << se_name[i] << " is:\n"
++ << " " << se[i]->Value << "\n"
+ << "which does not contain:\n"
+ << " " << oldRPath << "\n"
+ << "as was expected.";
+@@ -2379,47 +2424,43 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
+ return false;
+ }
+
+- // Store information about the entry.
+- rpathPosition = se->Position;
+- rpathSize = se->Size;
++ // Store information about the entry in the file.
++ rp[rp_count].Position = se[i]->Position;
++ rp[rp_count].Size = se[i]->Size;
++ rp[rp_count].Name = se_name[i];
+
+- // Store the part of the path we must preserve.
+- rpathPrefix = se->Value.substr(0, pos);
+- rpathSuffix = se->Value.substr(pos+oldRPath.length(), oldRPath.npos);
+- }
+- else if(newRPath.empty())
+- {
+- // The new rpath is empty and there is no rpath anyway so it is
+- // okay.
+- return true;
+- }
+- else
+- {
+- if(emsg)
++ // Construct the new value which preserves the part of the path
++ // not being changed.
++ rp[rp_count].Value = se[i]->Value.substr(0, pos);
++ rp[rp_count].Value += newRPath;
++ rp[rp_count].Value += se[i]->Value.substr(pos+oldRPath.length(),
++ oldRPath.npos);
++
++ // Make sure there is enough room to store the new rpath and at
++ // least one null terminator.
++ if(rp[rp_count].Size < rp[rp_count].Value.length()+1)
+ {
+- *emsg = "No valid ELF RPATH entry exists in the file; ";
+- *emsg += elf.GetErrorMessage();
++ if(emsg)
++ {
++ *emsg = "The replacement path is too long for the ";
++ *emsg += se_name[i];
++ *emsg += " entry.";
++ }
++ return false;
+ }
+- return false;
++
++ // This entry is ready for update.
++ ++rp_count;
+ }
+ }
+- // Compute the full new rpath.
+- std::string rpath = rpathPrefix;
+- rpath += newRPath;
+- rpath += rpathSuffix;
+
+- // Make sure there is enough room to store the new rpath and at
+- // least one null terminator.
+- if(rpathSize < rpath.length()+1)
++ // If no runtime path needs to be changed, we are done.
++ if(rp_count == 0)
+ {
+- if(emsg)
+- {
+- *emsg = "The replacement RPATH is too long.";
+- }
+- return false;
++ return true;
+ }
+
+- // Open the file for update and seek to the RPATH position.
++ // Open the file for update.
+ std::ofstream f(file.c_str(),
+ std::ios::in | std::ios::out | std::ios::binary);
+ if(!f)
+@@ -2430,40 +2471,49 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
+ }
+ return false;
+ }
+- if(!f.seekp(rpathPosition))
++
++ // Store the new RPATH and RUNPATH strings.
++ for(int i=0; i < rp_count; ++i)
+ {
+- if(emsg)
++ // Seek to the RPATH position.
++ if(!f.seekp(rp[i].Position))
+ {
+- *emsg = "Error seeking to RPATH position.";
++ if(emsg)
++ {
++ *emsg = "Error seeking to ";
++ *emsg += rp[i].Name;
++ *emsg += " position.";
++ }
++ return false;
+ }
+- return false;
+- }
+
+- // Write the new rpath. Follow it with enough null terminators to
+- // fill the string table entry.
+- f << rpath;
+- for(unsigned long i=rpath.length(); i < rpathSize; ++i)
+- {
+- f << '\0';
+- }
++ // Write the new rpath. Follow it with enough null terminators to
++ // fill the string table entry.
++ f << rp[i].Value;
++ for(unsigned long j=rp[i].Value.length(); j < rp[i].Size; ++j)
++ {
++ f << '\0';
++ }
+
+- // Make sure everything was okay.
+- if(f)
+- {
+- if(changed)
++ // Make sure it wrote correctly.
++ if(!f)
+ {
+- *changed = true;
++ if(emsg)
++ {
++ *emsg = "Error writing the new ";
++ *emsg += rp[i].Name;
++ *emsg += " string to the file.";
++ }
++ return false;
+ }
+- return true;
+ }
+- else
++
++ // Everything was updated successfully.
++ if(changed)
+ {
+- if(emsg)
+- {
+- *emsg = "Error writing the new rpath to the file.";
+- }
+- return false;
++ *changed = true;
+ }
++ return true;
+ #else
+ (void)file;
+ (void)oldRPath;
+@@ -2475,57 +2525,95 @@ bool cmSystemTools::ChangeRPath(std::string const& file,
+ }
+
+ //----------------------------------------------------------------------------
+-bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
++bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg,
++ bool* removed)
+ {
+ #if defined(CMAKE_USE_ELF_PARSER)
+- unsigned long rpathPosition = 0;
+- unsigned long rpathSize = 0;
+- unsigned long rpathEntryPosition = 0;
++ if(removed)
++ {
++ *removed = false;
++ }
++ int zeroCount = 0;
++ unsigned long zeroPosition[2] = {0,0};
++ unsigned long zeroSize[2] = {0,0};
++ unsigned long bytesBegin = 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)
++ // Get the RPATH and RUNPATH entries from it and sort them by index
++ // in the dynamic section header.
++ int se_count = 0;
++ cmELF::StringEntry const* se[2] = {0, 0};
++ if(cmELF::StringEntry const* se_rpath = elf.GetRPath())
+ {
+- se = elf.GetRunPath();
++ se[se_count++] = se_rpath;
+ }
+-
+- if(se)
++ if(cmELF::StringEntry const* se_runpath = elf.GetRunPath())
+ {
+- // Store information about the entry.
+- rpathPosition = se->Position;
+- rpathSize = se->Size;
+- rpathEntryPosition = elf.GetDynamicEntryPosition(se->IndexInSection);
++ se[se_count++] = se_runpath;
++ }
++ if(se_count == 0)
++ {
++ // There is no RPATH or RUNPATH anyway.
++ return true;
++ }
++ if(se_count == 2 && se[1]->IndexInSection < se[0]->IndexInSection)
++ {
++ cmsys_stl::swap(se[0], se[1]);
++ }
+
+- // 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)
++ // Get the size of the dynamic section header.
++ 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)
+ {
+- // 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;
++ *emsg = "DYNAMIC section contains a DT_NULL before the end.";
+ }
+- unsigned long nullEntryPosition = elf.GetDynamicEntryPosition(count);
++ return false;
++ }
++
++ // Save information about the string entries to be zeroed.
++ zeroCount = se_count;
++ for(int i=0; i < se_count; ++i)
++ {
++ zeroPosition[i] = se[i]->Position;
++ zeroSize[i] = se[i]->Size;
++ }
++
++ // Get the range of file positions corresponding to each entry and
++ // the rest of the table after them.
++ unsigned long entryBegin[3] = {0,0,0};
++ unsigned long entryEnd[2] = {0,0};
++ for(int i=0; i < se_count; ++i)
++ {
++ entryBegin[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection);
++ entryEnd[i] = elf.GetDynamicEntryPosition(se[i]->IndexInSection+1);
++ }
++ entryBegin[se_count] = elf.GetDynamicEntryPosition(count);
++
++ // The data are to be written over the old table entries starting at
++ // the first one being removed.
++ bytesBegin = entryBegin[0];
++ unsigned long bytesEnd = entryBegin[se_count];
+
+- // Allocate and fill a buffer with zeros.
+- bytes.resize(nullEntryPosition - rpathEntryPosition, 0);
++ // Allocate a buffer to hold the part of the file to be written.
++ // Initialize it with zeros.
++ bytes.resize(bytesEnd - bytesBegin, 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]))
++ // 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.
++ char* data = &bytes[0];
++ for(int i=0; i < se_count; ++i)
++ {
++ // Read data between the entries being removed.
++ unsigned long sz = entryBegin[i+1] - entryEnd[i];
++ if(sz > 0 && !elf.ReadBytes(entryEnd[i], sz, data))
+ {
+ if(emsg)
+ {
+@@ -2533,11 +2621,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
+ }
+ return false;
+ }
+- }
+- else
+- {
+- // There is no RPATH or RUNPATH anyway.
+- return true;
++ data += sz;
+ }
+ }
+
+@@ -2554,7 +2638,7 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
+ }
+
+ // Write the new DYNAMIC table header.
+- if(!f.seekp(rpathEntryPosition))
++ if(!f.seekp(bytesBegin))
+ {
+ if(emsg)
+ {
+@@ -2571,36 +2655,41 @@ bool cmSystemTools::RemoveRPath(std::string const& file, std::string* emsg)
+ return false;
+ }
+
+- // Fill the RPATH string with zero bytes.
+- if(!f.seekp(rpathPosition))
++ // Fill the RPATH and RUNPATH strings with zero bytes.
++ for(int i=0; i < zeroCount; ++i)
+ {
+- if(emsg)
++ if(!f.seekp(zeroPosition[i]))
+ {
+- *emsg = "Error seeking to RPATH position.";
++ if(emsg)
++ {
++ *emsg = "Error seeking to RPATH position.";
++ }
++ return false;
++ }
++ for(unsigned long j=0; j < zeroSize[i]; ++j)
++ {
++ f << '\0';
++ }
++ if(!f)
++ {
++ if(emsg)
++ {
++ *emsg = "Error writing the empty rpath string to the file.";
++ }
++ return false;
+ }
+- return false;
+- }
+- for(unsigned long i=0; i < rpathSize; ++i)
+- {
+- f << '\0';
+ }
+
+- // Make sure everything was okay.
+- if(f)
+- {
+- return true;
+- }
+- else
++ // Everything was updated successfully.
++ if(removed)
+ {
+- if(emsg)
+- {
+- *emsg = "Error writing the empty rpath to the file.";
+- }
+- return false;
++ *removed = true;
+ }
++ return true;
+ #else
+ (void)file;
+ (void)emsg;
++ (void)removed;
+ return false;
+ #endif
+ }
+diff --git cmake-2.6.1-orig/Source/cmSystemTools.h cmake-2.6.1/Source/cmSystemTools.h
+index 493ff71..1ff12bf 100644
+--- cmake-2.6.1-orig/Source/cmSystemTools.h
++++ cmake-2.6.1/Source/cmSystemTools.h
+@@ -396,7 +396,8 @@ public:
+ bool* changed = 0);
+
+ /** Try to remove the RPATH from an ELF binary. */
+- static bool RemoveRPath(std::string const& file, std::string* emsg = 0);
++ static bool RemoveRPath(std::string const& file, std::string* emsg = 0,
++ bool* removed = 0);
+
+ /** Check whether the RPATH in an ELF binary contains the path
+ given. */