]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-71052: Implement `ctypes.util.find_library` on Android (GH-116379)
authorMalcolm Smith <smith@chaquo.com>
Thu, 21 Mar 2024 13:20:57 +0000 (13:20 +0000)
committerGitHub <noreply@github.com>
Thu, 21 Mar 2024 13:20:57 +0000 (14:20 +0100)
Doc/library/ctypes.rst
Lib/ctypes/util.py
Lib/test/test_ctypes/test_find.py
Misc/NEWS.d/next/Library/2024-03-05-19-56-29.gh-issue-71052.PMDK--.rst [new file with mode: 0644]

index 36976470b5a46885c1c0e9e7c81b77b8c9b05049..9f7d6456e623a22745ff65a08c1689e261ed0d3f 100644 (file)
@@ -1334,8 +1334,9 @@ Here are some examples::
    'libbz2.so.1.0'
    >>>
 
-On macOS, :func:`~ctypes.util.find_library` tries several predefined naming schemes and paths
-to locate the library, and returns a full pathname if successful::
+On macOS and Android, :func:`~ctypes.util.find_library` uses the system's
+standard naming schemes and paths to locate the library, and returns a full
+pathname if successful::
 
    >>> from ctypes.util import find_library
    >>> find_library("c")
index 12d7428fe9a776e7d2157e3a3034412f5b5c9758..117bf06cb01013b221a94282a3bf4cf8878488c8 100644 (file)
@@ -89,6 +89,15 @@ elif sys.platform.startswith("aix"):
 
     from ctypes._aix import find_library
 
+elif sys.platform == "android":
+    def find_library(name):
+        directory = "/system/lib"
+        if "64" in os.uname().machine:
+            directory += "64"
+
+        fname = f"{directory}/lib{name}.so"
+        return fname if os.path.isfile(fname) else None
+
 elif os.name == "posix":
     # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump
     import re, tempfile
index 7732ff37308848058c355defb7e7e38614ed4243..85b28617d2d75492fbb71890158f929d71407f71 100644 (file)
@@ -129,5 +129,28 @@ class FindLibraryLinux(unittest.TestCase):
         self.assertIsNone(find_library("libc"))
 
 
+@unittest.skipUnless(sys.platform == 'android', 'Test only valid for Android')
+class FindLibraryAndroid(unittest.TestCase):
+    def test_find(self):
+        for name in [
+            "c", "m",  # POSIX
+            "z",  # Non-POSIX, but present on Linux
+            "log",  # Not present on Linux
+        ]:
+            with self.subTest(name=name):
+                path = find_library(name)
+                self.assertIsInstance(path, str)
+                self.assertEqual(
+                    os.path.dirname(path),
+                    "/system/lib64" if "64" in os.uname().machine
+                    else "/system/lib")
+                self.assertEqual(os.path.basename(path), f"lib{name}.so")
+                self.assertTrue(os.path.isfile(path), path)
+
+        for name in ["libc", "nonexistent"]:
+            with self.subTest(name=name):
+                self.assertIsNone(find_library(name))
+
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/Misc/NEWS.d/next/Library/2024-03-05-19-56-29.gh-issue-71052.PMDK--.rst b/Misc/NEWS.d/next/Library/2024-03-05-19-56-29.gh-issue-71052.PMDK--.rst
new file mode 100644 (file)
index 0000000..ddca54c
--- /dev/null
@@ -0,0 +1 @@
+Implement :func:`ctypes.util.find_library` on Android.