mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	bpo-41976: Fix the fallback to gcc of ctypes.util.find_library when using gcc>9 (GH-22598)
This commit is contained in:
		
							parent
							
								
									aecf036738
								
							
						
					
					
						commit
						27ac19cca2
					
				
					 3 changed files with 38 additions and 7 deletions
				
			
		| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
import unittest
 | 
					import unittest
 | 
				
			||||||
 | 
					import unittest.mock
 | 
				
			||||||
import os.path
 | 
					import os.path
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import test.support
 | 
					import test.support
 | 
				
			||||||
| 
						 | 
					@ -73,7 +74,7 @@ class Test_OpenGL_libs(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@unittest.skipUnless(sys.platform.startswith('linux'),
 | 
					@unittest.skipUnless(sys.platform.startswith('linux'),
 | 
				
			||||||
                     'Test only valid for Linux')
 | 
					                     'Test only valid for Linux')
 | 
				
			||||||
class LibPathFindTest(unittest.TestCase):
 | 
					class FindLibraryLinux(unittest.TestCase):
 | 
				
			||||||
    def test_find_on_libpath(self):
 | 
					    def test_find_on_libpath(self):
 | 
				
			||||||
        import subprocess
 | 
					        import subprocess
 | 
				
			||||||
        import tempfile
 | 
					        import tempfile
 | 
				
			||||||
| 
						 | 
					@ -112,6 +113,15 @@ class LibPathFindTest(unittest.TestCase):
 | 
				
			||||||
                # LD_LIBRARY_PATH)
 | 
					                # LD_LIBRARY_PATH)
 | 
				
			||||||
                self.assertEqual(find_library(libname), 'lib%s.so' % libname)
 | 
					                self.assertEqual(find_library(libname), 'lib%s.so' % libname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_find_library_with_gcc(self):
 | 
				
			||||||
 | 
					        with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None):
 | 
				
			||||||
 | 
					            self.assertNotEqual(find_library('c'), None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_find_library_with_ld(self):
 | 
				
			||||||
 | 
					        with unittest.mock.patch("ctypes.util._findSoname_ldconfig", lambda *args: None), \
 | 
				
			||||||
 | 
					             unittest.mock.patch("ctypes.util._findLib_gcc", lambda *args: None):
 | 
				
			||||||
 | 
					            self.assertNotEqual(find_library('c'), None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    unittest.main()
 | 
					    unittest.main()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,12 @@ elif os.name == "posix":
 | 
				
			||||||
    # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
 | 
					    # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
 | 
				
			||||||
    import re, tempfile
 | 
					    import re, tempfile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _is_elf(filename):
 | 
				
			||||||
 | 
					        "Return True if the given file is an ELF file"
 | 
				
			||||||
 | 
					        elf_header = b'\x7fELF'
 | 
				
			||||||
 | 
					        with open(filename, 'br') as thefile:
 | 
				
			||||||
 | 
					            return thefile.read(4) == elf_header
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _findLib_gcc(name):
 | 
					    def _findLib_gcc(name):
 | 
				
			||||||
        # Run GCC's linker with the -t (aka --trace) option and examine the
 | 
					        # 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
 | 
					        # library name it prints out. The GCC command will fail because we
 | 
				
			||||||
| 
						 | 
					@ -130,10 +136,17 @@ elif os.name == "posix":
 | 
				
			||||||
                # Raised if the file was already removed, which is the normal
 | 
					                # Raised if the file was already removed, which is the normal
 | 
				
			||||||
                # behaviour of GCC if linking fails
 | 
					                # behaviour of GCC if linking fails
 | 
				
			||||||
                pass
 | 
					                pass
 | 
				
			||||||
        res = re.search(expr, trace)
 | 
					        res = re.findall(expr, trace)
 | 
				
			||||||
        if not res:
 | 
					        if not res:
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
        return os.fsdecode(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 os.fsdecode(file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if sys.platform == "sunos5":
 | 
					    if sys.platform == "sunos5":
 | 
				
			||||||
| 
						 | 
					@ -299,9 +312,14 @@ elif os.name == "posix":
 | 
				
			||||||
                                     stderr=subprocess.PIPE,
 | 
					                                     stderr=subprocess.PIPE,
 | 
				
			||||||
                                     universal_newlines=True)
 | 
					                                     universal_newlines=True)
 | 
				
			||||||
                out, _ = p.communicate()
 | 
					                out, _ = p.communicate()
 | 
				
			||||||
                res = re.search(expr, os.fsdecode(out))
 | 
					                res = re.findall(expr, os.fsdecode(out))
 | 
				
			||||||
                if res:
 | 
					                for file in res:
 | 
				
			||||||
                    result = res.group(0)
 | 
					                    # 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 os.fsdecode(file)
 | 
				
			||||||
            except Exception:
 | 
					            except Exception:
 | 
				
			||||||
                pass  # result will be None
 | 
					                pass  # result will be None
 | 
				
			||||||
            return result
 | 
					            return result
 | 
				
			||||||
| 
						 | 
					@ -309,7 +327,7 @@ elif os.name == "posix":
 | 
				
			||||||
        def find_library(name):
 | 
					        def find_library(name):
 | 
				
			||||||
            # See issue #9998
 | 
					            # See issue #9998
 | 
				
			||||||
            return _findSoname_ldconfig(name) or \
 | 
					            return _findSoname_ldconfig(name) or \
 | 
				
			||||||
                   _get_soname(_findLib_gcc(name) or _findLib_ld(name))
 | 
					                   _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
################################################################
 | 
					################################################################
 | 
				
			||||||
# test code
 | 
					# test code
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					Fixed a bug that was causing :func:`ctypes.util.find_library` to return
 | 
				
			||||||
 | 
					``None`` when triying to locate a library in an environment when gcc>=9 is
 | 
				
			||||||
 | 
					available and ``ldconfig`` is not. Patch by Pablo Galindo
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue