sdk.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. from abc import ABCMeta, abstractmethod
  2. from oe.utils import execute_pre_post_process
  3. from oe.manifest import *
  4. from oe.package_manager import *
  5. import os
  6. import shutil
  7. import glob
  8. class Sdk(object):
  9. __metaclass__ = ABCMeta
  10. def __init__(self, d, manifest_dir):
  11. self.d = d
  12. self.sdk_output = self.d.getVar('SDK_OUTPUT', True)
  13. self.sdk_native_path = self.d.getVar('SDKPATHNATIVE', True).strip('/')
  14. self.target_path = self.d.getVar('SDKTARGETSYSROOT', True).strip('/')
  15. self.sysconfdir = self.d.getVar('sysconfdir', True).strip('/')
  16. self.sdk_target_sysroot = os.path.join(self.sdk_output, self.target_path)
  17. self.sdk_host_sysroot = self.sdk_output
  18. if manifest_dir is None:
  19. self.manifest_dir = self.d.getVar("SDK_DIR", True)
  20. else:
  21. self.manifest_dir = manifest_dir
  22. bb.utils.remove(self.sdk_output, True)
  23. self.install_order = Manifest.INSTALL_ORDER
  24. @abstractmethod
  25. def _populate(self):
  26. pass
  27. def populate(self):
  28. bb.utils.mkdirhier(self.sdk_output)
  29. # call backend dependent implementation
  30. self._populate()
  31. # Don't ship any libGL in the SDK
  32. bb.utils.remove(os.path.join(self.sdk_output, self.sdk_native_path,
  33. self.d.getVar('libdir_nativesdk', True).strip('/'),
  34. "libGL*"))
  35. # Fix or remove broken .la files
  36. bb.utils.remove(os.path.join(self.sdk_output, self.sdk_native_path,
  37. self.d.getVar('libdir_nativesdk', True).strip('/'),
  38. "*.la"))
  39. # Link the ld.so.cache file into the hosts filesystem
  40. link_name = os.path.join(self.sdk_output, self.sdk_native_path,
  41. self.sysconfdir, "ld.so.cache")
  42. os.symlink("/etc/ld.so.cache", link_name)
  43. execute_pre_post_process(self.d, self.d.getVar('SDK_POSTPROCESS_COMMAND', True))
  44. class RpmSdk(Sdk):
  45. def __init__(self, d, manifest_dir=None):
  46. super(RpmSdk, self).__init__(d, manifest_dir)
  47. self.target_manifest = RpmManifest(d, self.manifest_dir,
  48. Manifest.MANIFEST_TYPE_SDK_TARGET)
  49. self.host_manifest = RpmManifest(d, self.manifest_dir,
  50. Manifest.MANIFEST_TYPE_SDK_HOST)
  51. package_archs = {
  52. 'default': [],
  53. }
  54. target_os = {
  55. 'default': "",
  56. }
  57. package_archs['default'] = self.d.getVar("PACKAGE_ARCHS", True).split()
  58. # arch order is reversed. This ensures the -best- match is
  59. # listed first!
  60. package_archs['default'].reverse()
  61. target_os['default'] = self.d.getVar("TARGET_OS", True).strip()
  62. multilibs = self.d.getVar('MULTILIBS', True) or ""
  63. for ext in multilibs.split():
  64. eext = ext.split(':')
  65. if len(eext) > 1 and eext[0] == 'multilib':
  66. localdata = bb.data.createCopy(self.d)
  67. default_tune_key = "DEFAULTTUNE_virtclass-multilib-" + eext[1]
  68. default_tune = localdata.getVar(default_tune_key, False)
  69. if default_tune:
  70. localdata.setVar("DEFAULTTUNE", default_tune)
  71. bb.data.update_data(localdata)
  72. package_archs[eext[1]] = localdata.getVar('PACKAGE_ARCHS',
  73. True).split()
  74. package_archs[eext[1]].reverse()
  75. target_os[eext[1]] = localdata.getVar("TARGET_OS",
  76. True).strip()
  77. target_providename = ['/bin/sh',
  78. '/bin/bash',
  79. '/usr/bin/env',
  80. '/usr/bin/perl',
  81. 'pkgconfig'
  82. ]
  83. self.target_pm = RpmPM(d,
  84. self.sdk_target_sysroot,
  85. package_archs,
  86. target_os,
  87. self.d.getVar('TARGET_VENDOR', True),
  88. 'target',
  89. target_providename
  90. )
  91. sdk_package_archs = {
  92. 'default': [],
  93. }
  94. sdk_os = {
  95. 'default': "",
  96. }
  97. sdk_package_archs['default'] = self.d.getVar("SDK_PACKAGE_ARCHS",
  98. True).split()
  99. # arch order is reversed. This ensures the -best- match is
  100. # listed first!
  101. sdk_package_archs['default'].reverse()
  102. sdk_os['default'] = self.d.getVar("SDK_OS", True).strip()
  103. sdk_providename = ['/bin/sh',
  104. '/bin/bash',
  105. '/usr/bin/env',
  106. '/usr/bin/perl',
  107. 'pkgconfig',
  108. 'libGL.so()(64bit)',
  109. 'libGL.so'
  110. ]
  111. self.host_pm = RpmPM(d,
  112. self.sdk_host_sysroot,
  113. sdk_package_archs,
  114. sdk_os,
  115. self.d.getVar('SDK_VENDOR', True),
  116. 'host',
  117. sdk_providename
  118. )
  119. def _populate_sysroot(self, pm, manifest):
  120. pkgs_to_install = manifest.parse_initial_manifest()
  121. pm.create_configs()
  122. pm.write_index()
  123. pm.dump_all_available_pkgs()
  124. pm.update()
  125. for pkg_type in self.install_order:
  126. if pkg_type in pkgs_to_install:
  127. pm.install(pkgs_to_install[pkg_type],
  128. [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
  129. def _populate(self):
  130. bb.note("Installing TARGET packages")
  131. self._populate_sysroot(self.target_pm, self.target_manifest)
  132. self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY', True))
  133. execute_pre_post_process(self.d, self.d.getVar("POPULATE_SDK_POST_TARGET_COMMAND", True))
  134. self.target_pm.remove_packaging_data()
  135. bb.note("Installing NATIVESDK packages")
  136. self._populate_sysroot(self.host_pm, self.host_manifest)
  137. execute_pre_post_process(self.d, self.d.getVar("POPULATE_SDK_POST_HOST_COMMAND", True))
  138. self.host_pm.remove_packaging_data()
  139. # Move host RPM library data
  140. native_rpm_state_dir = os.path.join(self.sdk_output,
  141. self.sdk_native_path,
  142. self.d.getVar('localstatedir_nativesdk', True).strip('/'),
  143. "lib",
  144. "rpm"
  145. )
  146. bb.utils.mkdirhier(native_rpm_state_dir)
  147. for f in glob.glob(os.path.join(self.sdk_output,
  148. "var",
  149. "lib",
  150. "rpm",
  151. "*")):
  152. bb.utils.movefile(f, native_rpm_state_dir)
  153. bb.utils.remove(os.path.join(self.sdk_output, "var"), True)
  154. # Move host sysconfig data
  155. native_sysconf_dir = os.path.join(self.sdk_output,
  156. self.sdk_native_path,
  157. self.d.getVar('sysconfdir',
  158. True).strip('/'),
  159. )
  160. bb.utils.mkdirhier(native_sysconf_dir)
  161. for f in glob.glob(os.path.join(self.sdk_output, "etc", "*")):
  162. bb.utils.movefile(f, native_sysconf_dir)
  163. bb.utils.remove(os.path.join(self.sdk_output, "etc"), True)
  164. class OpkgSdk(Sdk):
  165. def __init__(self, d, manifest_dir=None):
  166. super(OpkgSdk, self).__init__(d, manifest_dir)
  167. self.target_conf = self.d.getVar("IPKGCONF_TARGET", True)
  168. self.host_conf = self.d.getVar("IPKGCONF_SDK", True)
  169. self.target_manifest = OpkgManifest(d, self.manifest_dir,
  170. Manifest.MANIFEST_TYPE_SDK_TARGET)
  171. self.host_manifest = OpkgManifest(d, self.manifest_dir,
  172. Manifest.MANIFEST_TYPE_SDK_HOST)
  173. self.target_pm = OpkgPM(d, self.sdk_target_sysroot, self.target_conf,
  174. self.d.getVar("ALL_MULTILIB_PACKAGE_ARCHS", True))
  175. self.host_pm = OpkgPM(d, self.sdk_host_sysroot, self.host_conf,
  176. self.d.getVar("SDK_PACKAGE_ARCHS", True))
  177. def _populate_sysroot(self, pm, manifest):
  178. pkgs_to_install = manifest.parse_initial_manifest()
  179. pm.write_index()
  180. pm.update()
  181. for pkg_type in self.install_order:
  182. if pkg_type in pkgs_to_install:
  183. pm.install(pkgs_to_install[pkg_type],
  184. [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
  185. def _populate(self):
  186. bb.note("Installing TARGET packages")
  187. self._populate_sysroot(self.target_pm, self.target_manifest)
  188. self.target_pm.install_complementary(self.d.getVar('SDKIMAGE_INSTALL_COMPLEMENTARY', True))
  189. execute_pre_post_process(self.d, self.d.getVar("POPULATE_SDK_POST_TARGET_COMMAND", True))
  190. bb.note("Installing NATIVESDK packages")
  191. self._populate_sysroot(self.host_pm, self.host_manifest)
  192. execute_pre_post_process(self.d, self.d.getVar("POPULATE_SDK_POST_HOST_COMMAND", True))
  193. target_sysconfdir = os.path.join(self.sdk_target_sysroot, self.sysconfdir)
  194. host_sysconfdir = os.path.join(self.sdk_host_sysroot, self.sysconfdir)
  195. bb.utils.mkdirhier(target_sysconfdir)
  196. shutil.copy(self.target_conf, target_sysconfdir)
  197. os.chmod(os.path.join(target_sysconfdir,
  198. os.path.basename(self.target_conf)), 0644)
  199. bb.utils.mkdirhier(host_sysconfdir)
  200. shutil.copy(self.host_conf, host_sysconfdir)
  201. os.chmod(os.path.join(host_sysconfdir,
  202. os.path.basename(self.host_conf)), 0644)
  203. native_opkg_state_dir = os.path.join(self.sdk_output, self.sdk_native_path,
  204. self.d.getVar('localstatedir_nativesdk', True).strip('/'),
  205. "lib", "opkg")
  206. bb.utils.mkdirhier(native_opkg_state_dir)
  207. for f in glob.glob(os.path.join(self.sdk_output, "var", "lib", "opkg", "*")):
  208. bb.utils.movefile(f, native_opkg_state_dir)
  209. bb.utils.remove(os.path.join(self.sdk_output, "var"), True)
  210. class DpkgSdk(Sdk):
  211. def __init__(self, d, manifest_dir=None):
  212. super(DpkgSdk, self).__init__(d, manifest_dir)
  213. self.target_conf_dir = os.path.join(self.d.getVar("APTCONF_TARGET", True), "apt")
  214. self.host_conf_dir = os.path.join(self.d.getVar("APTCONF_TARGET", True), "apt-sdk")
  215. self.target_manifest = DpkgManifest(d, self.manifest_dir,
  216. Manifest.MANIFEST_TYPE_SDK_TARGET)
  217. self.host_manifest = DpkgManifest(d, self.manifest_dir,
  218. Manifest.MANIFEST_TYPE_SDK_HOST)
  219. self.target_pm = DpkgPM(d, self.sdk_target_sysroot,
  220. self.d.getVar("PACKAGE_ARCHS", True),
  221. self.d.getVar("DPKG_ARCH", True),
  222. self.target_conf_dir)
  223. self.host_pm = DpkgPM(d, self.sdk_host_sysroot,
  224. self.d.getVar("SDK_PACKAGE_ARCHS", True),
  225. self.d.getVar("DEB_SDK_ARCH", True),
  226. self.host_conf_dir)
  227. def _copy_apt_dir_to(self, dst_dir):
  228. staging_etcdir_native = self.d.getVar("STAGING_ETCDIR_NATIVE", True)
  229. bb.utils.remove(dst_dir, True)
  230. shutil.copytree(os.path.join(staging_etcdir_native, "apt"), dst_dir)
  231. def _populate_sysroot(self, pm, manifest):
  232. pkgs_to_install = manifest.parse_initial_manifest()
  233. pm.write_index()
  234. pm.update()
  235. for pkg_type in self.install_order:
  236. if pkg_type in pkgs_to_install:
  237. pm.install(pkgs_to_install[pkg_type],
  238. [False, True][pkg_type == Manifest.PKG_TYPE_ATTEMPT_ONLY])
  239. def _populate(self):
  240. bb.note("Installing TARGET packages")
  241. self._populate_sysroot(self.target_pm, self.target_manifest)
  242. execute_pre_post_process(self.d, self.d.getVar("POPULATE_SDK_POST_TARGET_COMMAND", True))
  243. self._copy_apt_dir_to(os.path.join(self.sdk_target_sysroot, "etc", "apt"))
  244. bb.note("Installing NATIVESDK packages")
  245. self._populate_sysroot(self.host_pm, self.host_manifest)
  246. execute_pre_post_process(self.d, self.d.getVar("POPULATE_SDK_POST_HOST_COMMAND", True))
  247. self._copy_apt_dir_to(os.path.join(self.sdk_output, self.sdk_native_path,
  248. "etc", "apt"))
  249. native_dpkg_state_dir = os.path.join(self.sdk_output, self.sdk_native_path,
  250. "var", "lib", "dpkg")
  251. bb.utils.mkdirhier(native_dpkg_state_dir)
  252. for f in glob.glob(os.path.join(self.sdk_output, "var", "lib", "dpkg", "*")):
  253. bb.utils.movefile(f, native_dpkg_state_dir)
  254. bb.utils.remove(os.path.join(self.sdk_output, "var"), True)
  255. def populate_sdk(d, manifest_dir=None):
  256. env_bkp = os.environ.copy()
  257. img_type = d.getVar('IMAGE_PKGTYPE', True)
  258. if img_type == "rpm":
  259. RpmSdk(d, manifest_dir).populate()
  260. elif img_type == "ipk":
  261. OpkgSdk(d, manifest_dir).populate()
  262. elif img_type == "deb":
  263. DpkgSdk(d, manifest_dir).populate()
  264. os.environ.clear()
  265. os.environ.update(env_bkp)
  266. if __name__ == "__main__":
  267. pass