diff options
author | Timo Gurr <tgurr@gentoo.org> | 2008-08-27 21:19:10 +0000 |
---|---|---|
committer | Timo Gurr <tgurr@gentoo.org> | 2008-08-27 21:19:10 +0000 |
commit | 6bc00ab6c96f342b427871879ca8f91ad42eb72c (patch) | |
tree | be98ca70bdb45c52dbe193942813938abee1c61b /dev-util/cmake | |
parent | Silence errors from modprobe unix. (diff) | |
download | gentoo-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/ChangeLog | 11 | ||||
-rw-r--r-- | dev-util/cmake/cmake-2.6.1.ebuild | 131 | ||||
-rw-r--r-- | dev-util/cmake/files/cmake-2.6.1-gc-sections.patch | 172 | ||||
-rw-r--r-- | dev-util/cmake/files/cmake-2.6.1-rpath.patch | 531 |
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. */ |