pkg-python.mk 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. ################################################################################
  2. # Python package infrastructure
  3. #
  4. # This file implements an infrastructure that eases development of
  5. # package .mk files for Python packages. It should be used for all
  6. # packages that use Python setup.py/setuptools as their build system.
  7. #
  8. # See the Buildroot documentation for details on the usage of this
  9. # infrastructure
  10. #
  11. # In terms of implementation, this Python infrastructure requires the
  12. # .mk file to only specify metadata information about the package:
  13. # name, version, download URL, etc.
  14. #
  15. # We still allow the package .mk file to override what the different
  16. # steps are doing, if needed. For example, if <PKG>_BUILD_CMDS is
  17. # already defined, it is used as the list of commands to perform to
  18. # build the package, instead of the default Python behaviour. The
  19. # package can also define some post operation hooks.
  20. #
  21. ################################################################################
  22. ifeq ($(BR2_arm)$(BR2_armeb),y)
  23. PKG_PYTHON_ARCH = arm
  24. else
  25. PKG_PYTHON_ARCH = $(ARCH)
  26. endif
  27. PKG_PYTHON_HOST_PLATFORM = linux-$(PKG_PYTHON_ARCH)
  28. # basename does not evaluate if a file exists, so we must check to ensure
  29. # the _sysconfigdata__linux_*.py file exists. The "|| true" is added to return
  30. # an empty string if the file does not exist.
  31. PKG_PYTHON_SYSCONFIGDATA_PATH = $(PYTHON3_PATH)/_sysconfigdata__linux_*.py
  32. PKG_PYTHON_SYSCONFIGDATA_NAME = `{ [ -e $(PKG_PYTHON_SYSCONFIGDATA_PATH) ] && basename $(PKG_PYTHON_SYSCONFIGDATA_PATH) .py; } || true`
  33. # Target python packages
  34. PKG_PYTHON_ENV = \
  35. _PYTHON_HOST_PLATFORM="$(PKG_PYTHON_HOST_PLATFORM)" \
  36. _PYTHON_PROJECT_BASE="$(PYTHON3_DIR)" \
  37. _PYTHON_SYSCONFIGDATA_NAME="$(PKG_PYTHON_SYSCONFIGDATA_NAME)" \
  38. PATH=$(BR_PATH) \
  39. $(TARGET_CONFIGURE_OPTS) \
  40. PYTHONPATH="$(PYTHON3_PATH)" \
  41. PYTHONNOUSERSITE=1
  42. # Host python packages
  43. HOST_PKG_PYTHON_ENV = \
  44. PATH=$(BR_PATH) \
  45. PYTHONNOUSERSITE=1 \
  46. $(HOST_CONFIGURE_OPTS)
  47. # Target pep517-based packages
  48. PKG_PYTHON_PEP517_ENV = \
  49. $(PKG_PYTHON_ENV)
  50. PKG_PYTHON_PEP517_BUILD_CMD = \
  51. -m build -n -w
  52. PKG_PYTHON_PEP517_INSTALL_OPTS = \
  53. --interpreter=/usr/bin/python \
  54. --script-kind=posix
  55. PKG_PYTHON_PEP517_INSTALL_TARGET_CMD = \
  56. $(TOPDIR)/support/scripts/pyinstaller.py \
  57. dist/* \
  58. $(PKG_PYTHON_PEP517_INSTALL_OPTS) \
  59. --purelib=$(TARGET_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages \
  60. --headers=$(TARGET_DIR)/usr/include/python$(PYTHON3_VERSION_MAJOR) \
  61. --scripts=$(TARGET_DIR)/usr/bin \
  62. --data=$(TARGET_DIR)
  63. PKG_PYTHON_PEP517_INSTALL_STAGING_CMD = \
  64. $(TOPDIR)/support/scripts/pyinstaller.py \
  65. dist/* \
  66. $(PKG_PYTHON_PEP517_INSTALL_OPTS) \
  67. --purelib=$(STAGING_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages \
  68. --headers=$(STAGING_DIR)/usr/include/python$(PYTHON3_VERSION_MAJOR) \
  69. --scripts=$(STAGING_DIR)/usr/bin \
  70. --data=$(STAGING_DIR)
  71. PKG_PYTHON_PEP517_DEPENDENCIES = \
  72. host-python-pypa-build \
  73. host-python-installer
  74. # Host pep517-based packages
  75. HOST_PKG_PYTHON_PEP517_ENV = \
  76. $(HOST_PKG_PYTHON_ENV)
  77. HOST_PKG_PYTHON_PEP517_BUILD_CMD = \
  78. -m build -n -w
  79. HOST_PKG_PYTHON_PEP517_INSTALL_CMD = \
  80. $(TOPDIR)/support/scripts/pyinstaller.py \
  81. dist/* \
  82. --interpreter=$(HOST_DIR)/bin/python \
  83. --script-kind=posix \
  84. --purelib=$(HOST_DIR)/lib/python$(PYTHON3_VERSION_MAJOR)/site-packages \
  85. --headers=$(HOST_DIR)/include/python$(PYTHON3_VERSION_MAJOR) \
  86. --scripts=$(HOST_DIR)/bin \
  87. --data=$(HOST_DIR)
  88. # Target setuptools-based packages
  89. PKG_PYTHON_SETUPTOOLS_ENV = \
  90. $(PKG_PYTHON_PEP517_ENV)
  91. PKG_PYTHON_SETUPTOOLS_BUILD_CMD = \
  92. $(PKG_PYTHON_PEP517_BUILD_CMD)
  93. PKG_PYTHON_SETUPTOOLS_INSTALL_OPTS = \
  94. --install-headers=/usr/include/python$(PYTHON3_VERSION_MAJOR) \
  95. --prefix=/usr \
  96. --executable=/usr/bin/python \
  97. --single-version-externally-managed
  98. PKG_PYTHON_SETUPTOOLS_INSTALL_TARGET_CMD = \
  99. $(PKG_PYTHON_PEP517_INSTALL_TARGET_CMD)
  100. PKG_PYTHON_SETUPTOOLS_INSTALL_STAGING_CMD = \
  101. $(PKG_PYTHON_PEP517_INSTALL_STAGING_CMD)
  102. PKG_PYTHON_SETUPTOOLS_DEPENDENCIES = \
  103. $(PKG_PYTHON_PEP517_DEPENDENCIES) \
  104. host-python-setuptools
  105. # Host setuptools-based packages
  106. HOST_PKG_PYTHON_SETUPTOOLS_ENV = \
  107. $(HOST_PKG_PYTHON_PEP517_ENV)
  108. HOST_PKG_PYTHON_SETUPTOOLS_BUILD_CMD = \
  109. $(HOST_PKG_PYTHON_PEP517_BUILD_CMD)
  110. HOST_PKG_PYTHON_SETUPTOOLS_INSTALL_CMD = \
  111. $(HOST_PKG_PYTHON_PEP517_INSTALL_CMD)
  112. # Target setuptools-rust-based packages
  113. PKG_PYTHON_SETUPTOOLS_RUST_ENV = \
  114. $(PKG_PYTHON_SETUPTOOLS_ENV) \
  115. $(PKG_CARGO_ENV) \
  116. PYO3_CROSS_LIB_DIR="$(STAGING_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)"
  117. PKG_PYTHON_SETUPTOOLS_RUST_BUILD_CMD = \
  118. $(PKG_PYTHON_SETUPTOOLS_BUILD_CMD)
  119. PKG_PYTHON_SETUPTOOLS_RUST_INSTALL_TARGET_CMD = \
  120. $(PKG_PYTHON_SETUPTOOLS_INSTALL_TARGET_CMD)
  121. PKG_PYTHON_SETUPTOOLS_RUST_INSTALL_STAGING_CMD = \
  122. $(PKG_PYTHON_SETUPTOOLS_INSTALL_STAGING_CMD)
  123. PKG_PYTHON_SETUPTOOLS_RUST_DEPENDENCIES = \
  124. $(PKG_PYTHON_SETUPTOOLS_DEPENDENCIES) \
  125. host-python-setuptools-rust
  126. # Host setuptools-rust-based packages
  127. HOST_PKG_PYTHON_SETUPTOOLS_RUST_ENV = \
  128. $(HOST_PKG_PYTHON_SETUPTOOLS_ENV) \
  129. $(HOST_PKG_CARGO_ENV) \
  130. PYO3_CROSS_LIB_DIR="$(HOST_DIR)/lib/python$(PYTHON3_VERSION_MAJOR)"
  131. HOST_PKG_PYTHON_SETUPTOOLS_RUST_BUILD_CMD = \
  132. $(HOST_PKG_PYTHON_SETUPTOOLS_BUILD_CMD)
  133. HOST_PKG_PYTHON_SETUPTOOLS_RUST_INSTALL_CMD = \
  134. $(HOST_PKG_PYTHON_SETUPTOOLS_INSTALL_CMD)
  135. # Target flit packages
  136. PKG_PYTHON_FLIT_ENV = \
  137. $(PKG_PYTHON_PEP517_ENV)
  138. PKG_PYTHON_FLIT_BUILD_CMD = \
  139. $(PKG_PYTHON_PEP517_BUILD_CMD)
  140. PKG_PYTHON_FLIT_INSTALL_TARGET_CMD = \
  141. $(PKG_PYTHON_PEP517_INSTALL_TARGET_CMD)
  142. PKG_PYTHON_FLIT_INSTALL_STAGING_CMD = \
  143. $(PKG_PYTHON_PEP517_INSTALL_STAGING_CMD)
  144. PKG_PYTHON_FLIT_DEPENDENCIES = \
  145. $(PKG_PYTHON_PEP517_DEPENDENCIES) \
  146. host-python-flit-core
  147. # Host flit packages
  148. HOST_PKG_PYTHON_FLIT_ENV = \
  149. $(HOST_PKG_PYTHON_PEP517_ENV)
  150. HOST_PKG_PYTHON_FLIT_BUILD_CMD = \
  151. $(HOST_PKG_PYTHON_PEP517_BUILD_CMD)
  152. HOST_PKG_PYTHON_FLIT_INSTALL_CMD = \
  153. $(HOST_PKG_PYTHON_PEP517_INSTALL_CMD)
  154. # Host flit-bootstrap packages
  155. HOST_PKG_PYTHON_FLIT_BOOTSTRAP_ENV = \
  156. $(HOST_PKG_PYTHON_PEP517_ENV)
  157. HOST_PKG_PYTHON_FLIT_BOOTSTRAP_BUILD_CMD = \
  158. -m flit_core.wheel
  159. HOST_PKG_PYTHON_FLIT_BOOTSTRAP_INSTALL_CMD = \
  160. $(HOST_PKG_PYTHON_PEP517_INSTALL_CMD)
  161. # Target hatch packages
  162. PKG_PYTHON_HATCH_ENV = \
  163. $(PKG_PYTHON_PEP517_ENV)
  164. PKG_PYTHON_HATCH_BUILD_CMD = \
  165. $(PKG_PYTHON_PEP517_BUILD_CMD)
  166. PKG_PYTHON_HATCH_INSTALL_TARGET_CMD = \
  167. $(PKG_PYTHON_PEP517_INSTALL_TARGET_CMD)
  168. PKG_PYTHON_HATCH_INSTALL_STAGING_CMD = \
  169. $(PKG_PYTHON_PEP517_INSTALL_STAGING_CMD)
  170. PKG_PYTHON_HATCH_DEPENDENCIES = \
  171. $(PKG_PYTHON_PEP517_DEPENDENCIES) \
  172. host-python-hatchling
  173. # Host hatch packages
  174. HOST_PKG_PYTHON_HATCH_ENV = \
  175. $(HOST_PKG_PYTHON_PEP517_ENV)
  176. HOST_PKG_PYTHON_HATCH_BUILD_CMD = \
  177. $(HOST_PKG_PYTHON_PEP517_BUILD_CMD)
  178. HOST_PKG_PYTHON_HATCH_INSTALL_CMD = \
  179. $(HOST_PKG_PYTHON_PEP517_INSTALL_CMD)
  180. # Target maturin packages
  181. PKG_PYTHON_MATURIN_ENV = \
  182. $(PKG_PYTHON_PEP517_ENV) \
  183. $(PKG_CARGO_ENV) \
  184. PYO3_CROSS_LIB_DIR="$(STAGING_DIR)/usr/lib/python$(PYTHON3_VERSION_MAJOR)"
  185. PKG_PYTHON_MATURIN_BUILD_CMD = \
  186. $(PKG_PYTHON_PEP517_BUILD_CMD)
  187. PKG_PYTHON_MATURIN_INSTALL_TARGET_CMD = \
  188. $(PKG_PYTHON_PEP517_INSTALL_TARGET_CMD)
  189. PKG_PYTHON_MATURIN_INSTALL_STAGING_CMD = \
  190. $(PKG_PYTHON_PEP517_INSTALL_STAGING_CMD)
  191. PKG_PYTHON_MATURIN_DEPENDENCIES = \
  192. $(PKG_PYTHON_PEP517_DEPENDENCIES) \
  193. host-python-maturin
  194. # Host maturin packages
  195. HOST_PKG_PYTHON_MATURIN_ENV = \
  196. $(HOST_PKG_PYTHON_PEP517_ENV) \
  197. $(HOST_PKG_CARGO_ENV) \
  198. PYO3_CROSS_LIB_DIR="$(HOST_DIR)/lib/python$(PYTHON3_VERSION_MAJOR)"
  199. HOST_PKG_PYTHON_MATURIN_BUILD_CMD = \
  200. $(HOST_PKG_PYTHON_PEP517_BUILD_CMD)
  201. HOST_PKG_PYTHON_MATURIN_INSTALL_CMD = \
  202. $(HOST_PKG_PYTHON_PEP517_INSTALL_CMD)
  203. # Target poetry packages
  204. PKG_PYTHON_POETRY_ENV = \
  205. $(PKG_PYTHON_PEP517_ENV)
  206. PKG_PYTHON_POETRY_BUILD_CMD = \
  207. $(PKG_PYTHON_PEP517_BUILD_CMD)
  208. PKG_PYTHON_POETRY_INSTALL_TARGET_CMD = \
  209. $(PKG_PYTHON_PEP517_INSTALL_TARGET_CMD)
  210. PKG_PYTHON_POETRY_INSTALL_STAGING_CMD = \
  211. $(PKG_PYTHON_PEP517_INSTALL_STAGING_CMD)
  212. PKG_PYTHON_POETRY_DEPENDENCIES = \
  213. $(PKG_PYTHON_PEP517_DEPENDENCIES) \
  214. host-python-poetry-core
  215. # Host poetry packages
  216. HOST_PKG_PYTHON_POETRY_ENV = \
  217. $(HOST_PKG_PYTHON_PEP517_ENV)
  218. HOST_PKG_PYTHON_POETRY_BUILD_CMD = \
  219. $(HOST_PKG_PYTHON_PEP517_BUILD_CMD)
  220. HOST_PKG_PYTHON_POETRY_INSTALL_CMD = \
  221. $(HOST_PKG_PYTHON_PEP517_INSTALL_CMD)
  222. ################################################################################
  223. # inner-python-package -- defines how the configuration, compilation
  224. # and installation of a Python package should be done, implements a
  225. # few hooks to tune the build process and calls the generic package
  226. # infrastructure to generate the necessary make targets
  227. #
  228. # argument 1 is the lowercase package name
  229. # argument 2 is the uppercase package name, including a HOST_ prefix
  230. # for host packages
  231. # argument 3 is the uppercase package name, without the HOST_ prefix
  232. # for host packages
  233. # argument 4 is the type (target or host)
  234. ################################################################################
  235. define inner-python-package
  236. ifndef $(2)_SETUP_TYPE
  237. ifdef $(3)_SETUP_TYPE
  238. $(2)_SETUP_TYPE = $$($(3)_SETUP_TYPE)
  239. else
  240. $$(error "$(2)_SETUP_TYPE must be set")
  241. endif
  242. endif
  243. $(2)_SETUP_TYPE_UPPER = $$(call UPPERCASE,$$($(2)_SETUP_TYPE))
  244. ifneq ($$(filter-out setuptools setuptools-rust pep517 flit flit-bootstrap hatch maturin poetry,$$($(2)_SETUP_TYPE)),)
  245. $$(error "Invalid $(2)_SETUP_TYPE. Valid options are 'maturin', 'setuptools', 'setuptools-rust', 'pep517', 'flit', 'hatch' or 'poetry'.")
  246. endif
  247. ifeq ($(4)-$$($(2)_SETUP_TYPE),target-flit-bootstrap)
  248. $$(error flit-bootstrap setup type only supported for host packages)
  249. endif
  250. # We need to vendor the Cargo crates at download time for pyo3 based
  251. # packages.
  252. #
  253. ifneq ($$(filter maturin setuptools-rust,$$($(2)_SETUP_TYPE)),)
  254. ifeq ($(4),target)
  255. $(2)_DL_ENV = $$(PKG_CARGO_ENV)
  256. else
  257. $(2)_DL_ENV = $$(HOST_PKG_CARGO_ENV)
  258. endif
  259. ifndef $(2)_CARGO_MANIFEST_PATH
  260. ifdef $(3)_CARGO_MANIFEST_PATH
  261. $(2)_DOWNLOAD_POST_PROCESS_OPTS += -m$$($(3)_CARGO_MANIFEST_PATH)
  262. else
  263. ifneq ($$($(2)_SUBDIR),)
  264. $(2)_DOWNLOAD_POST_PROCESS_OPTS += -m$$($(2)_SUBDIR)/Cargo.toml
  265. endif
  266. endif
  267. else
  268. $(2)_DOWNLOAD_POST_PROCESS_OPTS += -m$$($(2)_CARGO_MANIFEST_PATH)
  269. endif
  270. endif
  271. # Target packages need both the python interpreter on the target (for
  272. # runtime) and the python interpreter on the host (for
  273. # compilation). However, host packages only need the python
  274. # interpreter on the host.
  275. #
  276. ifeq ($(4),target)
  277. $(2)_DEPENDENCIES += host-python3 python3
  278. else
  279. $(2)_DEPENDENCIES += host-python3
  280. endif # ($(4),target)
  281. # Setup type specific dependencies are the same whether we are
  282. # building for the host or the target.
  283. #
  284. ifeq ($$($(2)_SETUP_TYPE),flit-bootstrap)
  285. # Don't add dependency on host-python-installer for
  286. # host-python-installer itself, and its dependencies.
  287. ifeq ($$(filter host-python-flit-core host-python-installer,$(1)),)
  288. $(2)_DEPENDENCIES += host-python-installer
  289. endif
  290. else
  291. $(2)_DEPENDENCIES += $$(PKG_PYTHON_$$($(2)_SETUP_TYPE_UPPER)_DEPENDENCIES)
  292. endif
  293. # Pyo3 based packages(setuptools-rust and maturin) will need rust
  294. # toolchain dependencies for the host Python interpreter (both host
  295. # and target).
  296. #
  297. ifneq ($$(filter maturin setuptools-rust,$$($(2)_SETUP_TYPE)),)
  298. $(2)_DEPENDENCIES += host-rustc
  299. $(2)_DOWNLOAD_POST_PROCESS = cargo
  300. $(2)_DOWNLOAD_DEPENDENCIES = host-rustc
  301. endif # SETUP_TYPE
  302. ifeq ($(4),target)
  303. #
  304. # Build step. Only define it if not already defined by the package .mk
  305. # file.
  306. #
  307. ifndef $(2)_BUILD_CMDS
  308. define $(2)_BUILD_CMDS
  309. (cd $$($$(PKG)_BUILDDIR)/; \
  310. $$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_ENV) \
  311. $$($$(PKG)_ENV) \
  312. $$(HOST_DIR)/bin/python3 \
  313. $$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_BUILD_CMD) \
  314. $$($$(PKG)_BUILD_OPTS))
  315. endef
  316. endif
  317. #
  318. # Target installation step. Only define it if not already defined by
  319. # the package .mk file.
  320. #
  321. ifndef $(2)_INSTALL_TARGET_CMDS
  322. define $(2)_INSTALL_TARGET_CMDS
  323. (cd $$($$(PKG)_BUILDDIR)/; \
  324. $$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_ENV) \
  325. $$($$(PKG)_ENV) \
  326. $$(HOST_DIR)/bin/python3 \
  327. $$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_INSTALL_TARGET_CMD) \
  328. $$($$(PKG)_INSTALL_TARGET_OPTS))
  329. endef
  330. endif
  331. #
  332. # Staging installation step. Only define it if not already defined by
  333. # the package .mk file.
  334. #
  335. ifndef $(2)_INSTALL_STAGING_CMDS
  336. define $(2)_INSTALL_STAGING_CMDS
  337. (cd $$($$(PKG)_BUILDDIR)/; \
  338. $$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_ENV) \
  339. $$($$(PKG)_ENV) \
  340. $$(HOST_DIR)/bin/python3 \
  341. $$(PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_INSTALL_STAGING_CMD) \
  342. $$($$(PKG)_INSTALL_STAGING_OPTS))
  343. endef
  344. endif
  345. else # host
  346. #
  347. # Host build step. Only define it if not already defined by the package .mk
  348. # file.
  349. #
  350. ifndef $(2)_BUILD_CMDS
  351. define $(2)_BUILD_CMDS
  352. (cd $$($$(PKG)_BUILDDIR)/; \
  353. $$(HOST_PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_ENV) \
  354. $$($$(PKG)_ENV) \
  355. $$(HOST_DIR)/bin/python3 \
  356. $$(HOST_PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_BUILD_CMD) \
  357. $$($$(PKG)_BUILD_OPTS))
  358. endef
  359. endif
  360. #
  361. # Host installation step. Only define it if not already defined by the
  362. # package .mk file.
  363. #
  364. ifndef $(2)_INSTALL_CMDS
  365. define $(2)_INSTALL_CMDS
  366. (cd $$($$(PKG)_BUILDDIR)/; \
  367. $$(HOST_PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_ENV) \
  368. $$($$(PKG)_ENV) \
  369. $$(HOST_DIR)/bin/python3 \
  370. $$(HOST_PKG_PYTHON_$$($$(PKG)_SETUP_TYPE_UPPER)_INSTALL_CMD) \
  371. $$($$(PKG)_INSTALL_OPTS))
  372. endef
  373. endif
  374. endif # host / target
  375. # Call the generic package infrastructure to generate the necessary
  376. # make targets
  377. $(call inner-generic-package,$(1),$(2),$(3),$(4))
  378. endef
  379. ################################################################################
  380. # python-package -- the target generator macro for Python packages
  381. ################################################################################
  382. python-package = $(call inner-python-package,$(pkgname),$(call UPPERCASE,$(pkgname)),$(call UPPERCASE,$(pkgname)),target)
  383. host-python-package = $(call inner-python-package,host-$(pkgname),$(call UPPERCASE,host-$(pkgname)),$(call UPPERCASE,$(pkgname)),host)