blob: 1f4c982aedafc64689883032e2617a7bca1cfffa [file] [log] [blame]
Brad Bishop316dfdd2018-06-25 12:45:53 -04001# This script is launched on separate task for each python module
2# It checks for dependencies for that specific module and prints
3# them out, the output of this execution will have all dependencies
4# for a specific module, which will be parsed an dealt on create_manifest.py
5#
Andrew Geisslerc926e172021-05-07 16:11:35 -05006# Author: Alejandro Enedino Hernandez Samaniego <alejandro at enedino dot org>
Brad Bishop316dfdd2018-06-25 12:45:53 -04007
Brad Bishop316dfdd2018-06-25 12:45:53 -04008
9import sys
Andrew Geissler635e0e42020-08-21 15:58:33 -050010import os
Brad Bishop316dfdd2018-06-25 12:45:53 -040011
Andrew Geisslerc926e172021-05-07 16:11:35 -050012# We can get a log per module, for all the dependencies that were found, but its messy.
13if '-d' in sys.argv:
14 debug = True
15else:
16 debug = False
17
Brad Bishop316dfdd2018-06-25 12:45:53 -040018# We can get a list of the modules which are currently required to run python
19# so we run python-core and get its modules, we then import what we need
20# and check what modules are currently running, if we substract them from the
21# modules we had initially, we get the dependencies for the module we imported.
22
23# We use importlib to achieve this, so we also need to know what modules importlib needs
24import importlib
25
Andrew Geisslerc926e172021-05-07 16:11:35 -050026core_deps = set(sys.modules)
Brad Bishop316dfdd2018-06-25 12:45:53 -040027
28def fix_path(dep_path):
29 import os
30 # We DONT want the path on our HOST system
Andrew Geisslerc926e172021-05-07 16:11:35 -050031 pivot = 'recipe-sysroot-native'
32 dep_path = dep_path[dep_path.find(pivot)+len(pivot):]
Brad Bishop316dfdd2018-06-25 12:45:53 -040033
34 if '/usr/bin' in dep_path:
35 dep_path = dep_path.replace('/usr/bin''${bindir}')
36
37 # Handle multilib, is there a better way?
38 if '/usr/lib32' in dep_path:
39 dep_path = dep_path.replace('/usr/lib32','${libdir}')
40 if '/usr/lib64' in dep_path:
41 dep_path = dep_path.replace('/usr/lib64','${libdir}')
42 if '/usr/lib' in dep_path:
43 dep_path = dep_path.replace('/usr/lib','${libdir}')
44 if '/usr/include' in dep_path:
45 dep_path = dep_path.replace('/usr/include','${includedir}')
46 if '__init__.' in dep_path:
47 dep_path = os.path.split(dep_path)[0]
48 return dep_path
49
50
51# Module to import was passed as an argument
52current_module = str(sys.argv[1]).rstrip()
Andrew Geisslerc926e172021-05-07 16:11:35 -050053if debug == True:
54 log = open('temp/log_%s' % current_module.strip('.*'),'w')
Brad Bishop316dfdd2018-06-25 12:45:53 -040055 log.write('Module %s generated the following dependencies:\n' % current_module)
Andrew Geissler635e0e42020-08-21 15:58:33 -050056try:
57 m = importlib.import_module(current_module)
58 # handle python packages which may not include all modules in the __init__
59 if os.path.basename(m.__file__) == "__init__.py":
60 modulepath = os.path.dirname(m.__file__)
61 for i in os.listdir(modulepath):
62 if i.startswith("_") or not(i.endswith(".py")):
63 continue
64 submodule = "{}.{}".format(current_module, i[:-3])
65 try:
66 importlib.import_module(submodule)
67 except:
68 pass # ignore all import or other exceptions raised during import
Brad Bishop316dfdd2018-06-25 12:45:53 -040069except ImportError as e:
Andrew Geisslerc926e172021-05-07 16:11:35 -050070 if debug == True:
71 log.write('Module was not found\n')
Brad Bishop316dfdd2018-06-25 12:45:53 -040072 pass
73
74
75# Get current module dependencies, dif will contain a list of specific deps for this module
Andrew Geisslerc926e172021-05-07 16:11:35 -050076module_deps = set(sys.modules)
Brad Bishop316dfdd2018-06-25 12:45:53 -040077
78# We handle the core package (1st pass on create_manifest.py) as a special case
79if current_module == 'python-core-package':
80 dif = core_deps
81else:
82 # We know this is not the core package, so there must be a difference.
83 dif = module_deps-core_deps
84
85
86# Check where each dependency came from
87for item in dif:
Andrew Geisslerc926e172021-05-07 16:11:35 -050088 # Main module returns script filename, __main matches mp_main__ as well
89 if 'main__' in item:
90 continue
91
92 dep_path = ''
Brad Bishop316dfdd2018-06-25 12:45:53 -040093 try:
Andrew Geisslerc926e172021-05-07 16:11:35 -050094 if debug == True:
95 log.write('\nCalling: sys.modules[' + '%s' % item + '].__file__\n')
Brad Bishop316dfdd2018-06-25 12:45:53 -040096 dep_path = sys.modules['%s' % item].__file__
97 except AttributeError as e:
98 # Deals with thread (builtin module) not having __file__ attribute
Andrew Geisslerc926e172021-05-07 16:11:35 -050099 if debug == True:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400100 log.write(item + ' ')
101 log.write(str(e))
102 log.write('\n')
103 pass
104 except NameError as e:
105 # Deals with NameError: name 'dep_path' is not defined
106 # because module is not found (wasn't compiled?), e.g. bddsm
Andrew Geisslerc926e172021-05-07 16:11:35 -0500107 if debug == True:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400108 log.write(item+' ')
109 log.write(str(e))
110 pass
111
Andrew Geisslerc926e172021-05-07 16:11:35 -0500112 if dep_path == '':
113 continue
114 if debug == True:
115 log.write('Dependency path found:\n%s\n' % dep_path)
116
Brad Bishop316dfdd2018-06-25 12:45:53 -0400117 # Site-customize is a special case since we (OpenEmbedded) put it there manually
118 if 'sitecustomize' in dep_path:
119 dep_path = '${libdir}/python${PYTHON_MAJMIN}/sitecustomize.py'
120 # Prints out result, which is what will be used by create_manifest
121 print (dep_path)
122 continue
123
124 dep_path = fix_path(dep_path)
125
126 import sysconfig
Andrew Geisslerc926e172021-05-07 16:11:35 -0500127 soabi = sysconfig.get_config_var('SOABI')
Brad Bishop316dfdd2018-06-25 12:45:53 -0400128 # Check if its a shared library and deconstruct it
129 if soabi in dep_path:
Andrew Geisslerc926e172021-05-07 16:11:35 -0500130 if debug == True:
131 log.write('Shared library found in %s\n' % dep_path)
Brad Bishop316dfdd2018-06-25 12:45:53 -0400132 dep_path = dep_path.replace(soabi,'*')
133 print (dep_path)
134 continue
Andrew Geissler635e0e42020-08-21 15:58:33 -0500135 if "_sysconfigdata" in dep_path:
136 dep_path = dep_path.replace(sysconfig._get_sysconfigdata_name(), "_sysconfigdata*")
Brad Bishop316dfdd2018-06-25 12:45:53 -0400137
Andrew Geisslerc926e172021-05-07 16:11:35 -0500138 if debug == True:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400139 log.write(dep_path+'\n')
140 # Prints out result, which is what will be used by create_manifest
141 print (dep_path)
142
143
Andrew Geisslerc926e172021-05-07 16:11:35 -0500144 cpython_tag = sys.implementation.cache_tag
145 cached = ''
Brad Bishop316dfdd2018-06-25 12:45:53 -0400146 # Theres no naive way to find *.pyc files on python3
147 try:
Andrew Geisslerc926e172021-05-07 16:11:35 -0500148 if debug == True:
149 log.write('\nCalling: sys.modules[' + '%s' % item + '].__cached__\n')
Brad Bishop316dfdd2018-06-25 12:45:53 -0400150 cached = sys.modules['%s' % item].__cached__
151 except AttributeError as e:
152 # Deals with thread (builtin module) not having __cached__ attribute
Andrew Geisslerc926e172021-05-07 16:11:35 -0500153 if debug == True:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400154 log.write(item + ' ')
155 log.write(str(e))
156 log.write('\n')
157 pass
158 except NameError as e:
159 # Deals with NameError: name 'cached' is not defined
Andrew Geisslerc926e172021-05-07 16:11:35 -0500160 if debug == True:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400161 log.write(item+' ')
162 log.write(str(e))
163 pass
164 if cached is not None:
Andrew Geisslerc926e172021-05-07 16:11:35 -0500165 if debug == True:
166 log.write(cached + '\n')
Brad Bishop316dfdd2018-06-25 12:45:53 -0400167 cached = fix_path(cached)
168 cached = cached.replace(cpython_tag,'*')
Andrew Geissler635e0e42020-08-21 15:58:33 -0500169 if "_sysconfigdata" in cached:
170 cached = cached.replace(sysconfig._get_sysconfigdata_name(), "_sysconfigdata*")
Brad Bishop316dfdd2018-06-25 12:45:53 -0400171 print (cached)
172
Andrew Geisslerc926e172021-05-07 16:11:35 -0500173if debug == True:
Brad Bishop316dfdd2018-06-25 12:45:53 -0400174 log.close()