From 349585e7787e84cf1fe745665a08cbf4d4f477d5 Mon Sep 17 00:00:00 2001 From: Orivej Desh Date: Wed, 6 Jan 2021 09:28:43 +0000 Subject: [PATCH] python2: fix ctypes.util.find_library with gcc10 Fixes #108243 --- .../python/cpython/2.7/default.nix | 3 + .../cpython/2.7/find_library-gcc10.patch | 79 +++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 pkgs/development/interpreters/python/cpython/2.7/find_library-gcc10.patch diff --git a/pkgs/development/interpreters/python/cpython/2.7/default.nix b/pkgs/development/interpreters/python/cpython/2.7/default.nix index e6ab1f218795..4c0501aebcd2 100644 --- a/pkgs/development/interpreters/python/cpython/2.7/default.nix +++ b/pkgs/development/interpreters/python/cpython/2.7/default.nix @@ -114,6 +114,9 @@ let # libuuid, slowing down program startup a lot). ./no-ldconfig.patch + # Fix ctypes.util.find_library with gcc10. + ./find_library-gcc10.patch + ] ++ optionals stdenv.hostPlatform.isCygwin [ ./2.5.2-ctypes-util-find_library.patch ./2.5.2-tkinter-x11.patch diff --git a/pkgs/development/interpreters/python/cpython/2.7/find_library-gcc10.patch b/pkgs/development/interpreters/python/cpython/2.7/find_library-gcc10.patch new file mode 100644 index 000000000000..4627baf119c1 --- /dev/null +++ b/pkgs/development/interpreters/python/cpython/2.7/find_library-gcc10.patch @@ -0,0 +1,79 @@ +Backport https://github.com/python/cpython/commit/82df3b3071bb003247c33eac4670775e9883c994 +and https://github.com/python/cpython/commit/27ac19cca2c639caaf6fedf3632fe6beb265f24f + +Fixes the check phase of python2Packages.cffi. + +--- a/Lib/ctypes/util.py ++++ b/Lib/ctypes/util.py +@@ -87,6 +87,12 @@ elif os.name == "posix": + # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump + import re, tempfile, errno + ++ def _is_elf(filename): ++ "Return True if the given file is an ELF file" ++ elf_header = b'\x7fELF' ++ with open(filename, 'rb') as thefile: ++ return thefile.read(4) == elf_header ++ + def _findLib_gcc(name): + # Run GCC's linker with the -t (aka --trace) option and examine the + # library name it prints out. The GCC command will fail because we +@@ -110,10 +116,17 @@ elif os.name == "posix": + # the normal behaviour of GCC if linking fails + if e.errno != errno.ENOENT: + raise +- res = re.search(expr, trace) ++ res = re.findall(expr, trace) + if not res: + return None +- return res.group(0) ++ ++ for file in res: ++ # Check if the given file is an elf file: gcc can report ++ # some files that are linker scripts and not actual ++ # shared objects. See bpo-41976 for more details ++ if not _is_elf(file): ++ continue ++ return file + + + if sys.platform == "sunos5": +@@ -237,8 +250,37 @@ elif os.name == "posix": + def _findSoname_ldconfig(name): + return None + ++ def _findLib_ld(name): ++ # See issue #9998 for why this is needed ++ expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) ++ cmd = ['ld', '-t'] ++ libpath = os.environ.get('LD_LIBRARY_PATH') ++ if libpath: ++ for d in libpath.split(':'): ++ cmd.extend(['-L', d]) ++ cmd.extend(['-o', os.devnull, '-l%s' % name]) ++ result = None ++ try: ++ p = subprocess.Popen(cmd, stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE, ++ universal_newlines=True) ++ out, _ = p.communicate() ++ res = re.findall(expr, out) ++ for file in res: ++ # Check if the given file is an elf file: gcc can report ++ # some files that are linker scripts and not actual ++ # shared objects. See bpo-41976 for more details ++ if not _is_elf(file): ++ continue ++ return file ++ except Exception: ++ pass # result will be None ++ return result ++ + def find_library(name): +- return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name)) ++ # See issue #9998 ++ return _findSoname_ldconfig(name) or \ ++ _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name)) + + ################################################################ + # test code