Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / controller / python / chip / native / __init__.py
1 import ctypes
2 import glob
3 import os
4 import platform
5
6 NATIVE_LIBRARY_BASE_NAME = "_ChipDeviceCtrl.so"
7
8
9 def _AllDirsToRoot(dir):
10   """Return all parent paths of a directory."""
11   dir = os.path.abspath(dir)
12   while True:
13     yield dir
14     parent = os.path.dirname(dir)
15     if parent == "" or parent == dir:
16       break
17     dir = parent
18
19
20 def FindNativeLibraryPath() -> str:
21   """Find the native CHIP dll/so path."""
22
23   scriptDir = os.path.dirname(os.path.abspath(__file__))
24
25   # When properly installed in the chip package, the Chip Device Manager DLL will
26   # be located in the package root directory, along side the package's
27   # modules.
28   dmDLLPath = os.path.join(
29       os.path.dirname(scriptDir),  # file should be inside 'chip'
30       NATIVE_LIBRARY_BASE_NAME)
31   if os.path.exists(dmDLLPath):
32     return dmDLLPath
33
34   # For the convenience of developers, search the list of parent paths relative to the
35   # running script looking for an CHIP build directory containing the Chip Device
36   # Manager DLL. This makes it possible to import and use the ChipDeviceMgr module
37   # directly from a built copy of the CHIP source tree.
38   buildMachineGlob = "%s-*-%s*" % (platform.machine(),
39                                    platform.system().lower())
40   relDMDLLPathGlob = os.path.join(
41       "build",
42       buildMachineGlob,
43       "src/controller/python/.libs",
44       NATIVE_LIBRARY_BASE_NAME,
45   )
46   for dir in _AllDirsToRoot(scriptDir):
47     dmDLLPathGlob = os.path.join(dir, relDMDLLPathGlob)
48     for dmDLLPath in glob.glob(dmDLLPathGlob):
49       if os.path.exists(dmDLLPath):
50         return dmDLLPath
51
52   raise Exception(
53       "Unable to locate Chip Device Manager DLL (%s); expected location: %s" %
54       (NATIVE_LIBRARY_BASE_NAME, scriptDir))
55
56
57 class NativeLibraryHandleMethodArguments:
58   """Convenience wrapper to set native method argtype and restype for methods."""
59
60   def __init__(self, handle):
61     self.handle = handle
62
63   def Set(self, methodName: str, resultType, argumentTypes: list):
64     method = getattr(self.handle, methodName)
65     method.restype = resultType
66     method.argtype = argumentTypes
67
68
69 _nativeLibraryHandle: ctypes.CDLL = None
70
71
72 def GetLibraryHandle() -> ctypes.CDLL:
73   """Get a memoized handle to the chip native code dll."""
74
75   global _nativeLibraryHandle
76   if _nativeLibraryHandle is None:
77     _nativeLibraryHandle = ctypes.CDLL(FindNativeLibraryPath())
78
79     setter = NativeLibraryHandleMethodArguments(_nativeLibraryHandle)
80
81     setter.Set("pychip_native_init", None, [])
82
83     _nativeLibraryHandle.pychip_native_init()
84
85   return _nativeLibraryHandle