frida 16.2.0 → 16.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. package/BSDmakefile +6 -0
  2. package/Makefile +16 -0
  3. package/README.md +14 -11
  4. package/configure +18 -0
  5. package/configure.bat +22 -0
  6. package/dist/native.js +0 -8
  7. package/lib/application.ts +98 -0
  8. package/lib/authentication.ts +3 -0
  9. package/lib/build.py +50 -0
  10. package/lib/bus.ts +30 -0
  11. package/lib/cancellable.ts +33 -0
  12. package/lib/child.ts +15 -0
  13. package/lib/crash.ts +11 -0
  14. package/lib/device.ts +329 -0
  15. package/lib/device_manager.ts +69 -0
  16. package/lib/endpoint_parameters.ts +56 -0
  17. package/lib/icon.ts +15 -0
  18. package/lib/index.ts +311 -0
  19. package/lib/iostream.ts +78 -0
  20. package/lib/meson.build +53 -0
  21. package/lib/native.ts +9 -0
  22. package/lib/portal_membership.ts +10 -0
  23. package/lib/portal_service.ts +105 -0
  24. package/lib/process.ts +57 -0
  25. package/lib/relay.ts +44 -0
  26. package/lib/script.ts +352 -0
  27. package/lib/session.ts +113 -0
  28. package/lib/signals.ts +45 -0
  29. package/lib/socket_address.ts +35 -0
  30. package/lib/spawn.ts +4 -0
  31. package/lib/system_parameters.ts +78 -0
  32. package/make.bat +23 -0
  33. package/meson.build +160 -0
  34. package/meson.options +11 -0
  35. package/package.json +27 -6
  36. package/releng/deps.py +1133 -0
  37. package/releng/deps.toml +391 -0
  38. package/releng/devkit-assets/frida-core-example-unix.c +188 -0
  39. package/releng/devkit-assets/frida-core-example-windows.c +197 -0
  40. package/releng/devkit-assets/frida-core-example.sln +28 -0
  41. package/releng/devkit-assets/frida-core-example.vcxproj +157 -0
  42. package/releng/devkit-assets/frida-core-example.vcxproj.filters +27 -0
  43. package/releng/devkit-assets/frida-gum-example-unix.c +122 -0
  44. package/releng/devkit-assets/frida-gum-example-windows.c +132 -0
  45. package/releng/devkit-assets/frida-gum-example.sln +28 -0
  46. package/releng/devkit-assets/frida-gum-example.vcxproj +157 -0
  47. package/releng/devkit-assets/frida-gum-example.vcxproj.filters +27 -0
  48. package/releng/devkit-assets/frida-gumjs-example-unix.c +84 -0
  49. package/releng/devkit-assets/frida-gumjs-example-windows.c +91 -0
  50. package/releng/devkit-assets/frida-gumjs-example.sln +28 -0
  51. package/releng/devkit-assets/frida-gumjs-example.vcxproj +157 -0
  52. package/releng/devkit-assets/frida-gumjs-example.vcxproj.filters +27 -0
  53. package/releng/devkit.py +535 -0
  54. package/releng/env.py +420 -0
  55. package/releng/env_android.py +150 -0
  56. package/releng/env_apple.py +176 -0
  57. package/releng/env_generic.py +373 -0
  58. package/releng/frida_version.py +69 -0
  59. package/releng/machine_file.py +44 -0
  60. package/releng/machine_spec.py +290 -0
  61. package/releng/meson/meson.py +27 -0
  62. package/releng/meson/mesonbuild/__init__.py +0 -0
  63. package/releng/meson/mesonbuild/_pathlib.py +63 -0
  64. package/releng/meson/mesonbuild/_typing.py +69 -0
  65. package/releng/meson/mesonbuild/arglist.py +321 -0
  66. package/releng/meson/mesonbuild/ast/__init__.py +23 -0
  67. package/releng/meson/mesonbuild/ast/interpreter.py +441 -0
  68. package/releng/meson/mesonbuild/ast/introspection.py +374 -0
  69. package/releng/meson/mesonbuild/ast/postprocess.py +109 -0
  70. package/releng/meson/mesonbuild/ast/printer.py +620 -0
  71. package/releng/meson/mesonbuild/ast/visitor.py +161 -0
  72. package/releng/meson/mesonbuild/backend/__init__.py +0 -0
  73. package/releng/meson/mesonbuild/backend/backends.py +2047 -0
  74. package/releng/meson/mesonbuild/backend/ninjabackend.py +3808 -0
  75. package/releng/meson/mesonbuild/backend/nonebackend.py +26 -0
  76. package/releng/meson/mesonbuild/backend/vs2010backend.py +2078 -0
  77. package/releng/meson/mesonbuild/backend/vs2012backend.py +35 -0
  78. package/releng/meson/mesonbuild/backend/vs2013backend.py +34 -0
  79. package/releng/meson/mesonbuild/backend/vs2015backend.py +35 -0
  80. package/releng/meson/mesonbuild/backend/vs2017backend.py +59 -0
  81. package/releng/meson/mesonbuild/backend/vs2019backend.py +54 -0
  82. package/releng/meson/mesonbuild/backend/vs2022backend.py +54 -0
  83. package/releng/meson/mesonbuild/backend/xcodebackend.py +1781 -0
  84. package/releng/meson/mesonbuild/build.py +3249 -0
  85. package/releng/meson/mesonbuild/cargo/__init__.py +5 -0
  86. package/releng/meson/mesonbuild/cargo/builder.py +238 -0
  87. package/releng/meson/mesonbuild/cargo/cfg.py +274 -0
  88. package/releng/meson/mesonbuild/cargo/interpreter.py +733 -0
  89. package/releng/meson/mesonbuild/cargo/manifest.py +227 -0
  90. package/releng/meson/mesonbuild/cargo/version.py +95 -0
  91. package/releng/meson/mesonbuild/cmake/__init__.py +28 -0
  92. package/releng/meson/mesonbuild/cmake/common.py +331 -0
  93. package/releng/meson/mesonbuild/cmake/data/__init__.py +0 -0
  94. package/releng/meson/mesonbuild/cmake/data/preload.cmake +82 -0
  95. package/releng/meson/mesonbuild/cmake/executor.py +241 -0
  96. package/releng/meson/mesonbuild/cmake/fileapi.py +324 -0
  97. package/releng/meson/mesonbuild/cmake/generator.py +186 -0
  98. package/releng/meson/mesonbuild/cmake/interpreter.py +1267 -0
  99. package/releng/meson/mesonbuild/cmake/toolchain.py +248 -0
  100. package/releng/meson/mesonbuild/cmake/traceparser.py +814 -0
  101. package/releng/meson/mesonbuild/cmake/tracetargets.py +161 -0
  102. package/releng/meson/mesonbuild/compilers/__init__.py +86 -0
  103. package/releng/meson/mesonbuild/compilers/asm.py +307 -0
  104. package/releng/meson/mesonbuild/compilers/c.py +788 -0
  105. package/releng/meson/mesonbuild/compilers/c_function_attributes.py +143 -0
  106. package/releng/meson/mesonbuild/compilers/compilers.py +1388 -0
  107. package/releng/meson/mesonbuild/compilers/cpp.py +1035 -0
  108. package/releng/meson/mesonbuild/compilers/cs.py +136 -0
  109. package/releng/meson/mesonbuild/compilers/cuda.py +806 -0
  110. package/releng/meson/mesonbuild/compilers/cython.py +91 -0
  111. package/releng/meson/mesonbuild/compilers/d.py +861 -0
  112. package/releng/meson/mesonbuild/compilers/detect.py +1396 -0
  113. package/releng/meson/mesonbuild/compilers/fortran.py +523 -0
  114. package/releng/meson/mesonbuild/compilers/java.py +113 -0
  115. package/releng/meson/mesonbuild/compilers/mixins/__init__.py +0 -0
  116. package/releng/meson/mesonbuild/compilers/mixins/arm.py +167 -0
  117. package/releng/meson/mesonbuild/compilers/mixins/ccrx.py +113 -0
  118. package/releng/meson/mesonbuild/compilers/mixins/clang.py +170 -0
  119. package/releng/meson/mesonbuild/compilers/mixins/clike.py +1330 -0
  120. package/releng/meson/mesonbuild/compilers/mixins/compcert.py +117 -0
  121. package/releng/meson/mesonbuild/compilers/mixins/elbrus.py +93 -0
  122. package/releng/meson/mesonbuild/compilers/mixins/emscripten.py +89 -0
  123. package/releng/meson/mesonbuild/compilers/mixins/gnu.py +629 -0
  124. package/releng/meson/mesonbuild/compilers/mixins/intel.py +167 -0
  125. package/releng/meson/mesonbuild/compilers/mixins/islinker.py +120 -0
  126. package/releng/meson/mesonbuild/compilers/mixins/metrowerks.py +279 -0
  127. package/releng/meson/mesonbuild/compilers/mixins/pgi.py +88 -0
  128. package/releng/meson/mesonbuild/compilers/mixins/ti.py +130 -0
  129. package/releng/meson/mesonbuild/compilers/mixins/visualstudio.py +458 -0
  130. package/releng/meson/mesonbuild/compilers/mixins/xc16.py +111 -0
  131. package/releng/meson/mesonbuild/compilers/objc.py +120 -0
  132. package/releng/meson/mesonbuild/compilers/objcpp.py +102 -0
  133. package/releng/meson/mesonbuild/compilers/rust.py +230 -0
  134. package/releng/meson/mesonbuild/compilers/swift.py +131 -0
  135. package/releng/meson/mesonbuild/compilers/vala.py +121 -0
  136. package/releng/meson/mesonbuild/coredata.py +1532 -0
  137. package/releng/meson/mesonbuild/dependencies/__init__.py +252 -0
  138. package/releng/meson/mesonbuild/dependencies/base.py +663 -0
  139. package/releng/meson/mesonbuild/dependencies/boost.py +1083 -0
  140. package/releng/meson/mesonbuild/dependencies/cmake.py +656 -0
  141. package/releng/meson/mesonbuild/dependencies/coarrays.py +80 -0
  142. package/releng/meson/mesonbuild/dependencies/configtool.py +163 -0
  143. package/releng/meson/mesonbuild/dependencies/cuda.py +295 -0
  144. package/releng/meson/mesonbuild/dependencies/data/CMakeLists.txt +102 -0
  145. package/releng/meson/mesonbuild/dependencies/data/CMakeListsLLVM.txt +204 -0
  146. package/releng/meson/mesonbuild/dependencies/data/CMakePathInfo.txt +31 -0
  147. package/releng/meson/mesonbuild/dependencies/data/__init__.py +0 -0
  148. package/releng/meson/mesonbuild/dependencies/detect.py +225 -0
  149. package/releng/meson/mesonbuild/dependencies/dev.py +707 -0
  150. package/releng/meson/mesonbuild/dependencies/dub.py +424 -0
  151. package/releng/meson/mesonbuild/dependencies/factory.py +146 -0
  152. package/releng/meson/mesonbuild/dependencies/framework.py +111 -0
  153. package/releng/meson/mesonbuild/dependencies/hdf5.py +168 -0
  154. package/releng/meson/mesonbuild/dependencies/misc.py +618 -0
  155. package/releng/meson/mesonbuild/dependencies/mpi.py +231 -0
  156. package/releng/meson/mesonbuild/dependencies/pkgconfig.py +570 -0
  157. package/releng/meson/mesonbuild/dependencies/platform.py +52 -0
  158. package/releng/meson/mesonbuild/dependencies/python.py +431 -0
  159. package/releng/meson/mesonbuild/dependencies/qt.py +484 -0
  160. package/releng/meson/mesonbuild/dependencies/scalapack.py +142 -0
  161. package/releng/meson/mesonbuild/dependencies/ui.py +281 -0
  162. package/releng/meson/mesonbuild/depfile.py +82 -0
  163. package/releng/meson/mesonbuild/envconfig.py +480 -0
  164. package/releng/meson/mesonbuild/environment.py +987 -0
  165. package/releng/meson/mesonbuild/interpreter/__init__.py +47 -0
  166. package/releng/meson/mesonbuild/interpreter/compiler.py +900 -0
  167. package/releng/meson/mesonbuild/interpreter/dependencyfallbacks.py +386 -0
  168. package/releng/meson/mesonbuild/interpreter/interpreter.py +3595 -0
  169. package/releng/meson/mesonbuild/interpreter/interpreterobjects.py +1096 -0
  170. package/releng/meson/mesonbuild/interpreter/kwargs.py +479 -0
  171. package/releng/meson/mesonbuild/interpreter/mesonmain.py +487 -0
  172. package/releng/meson/mesonbuild/interpreter/primitives/__init__.py +29 -0
  173. package/releng/meson/mesonbuild/interpreter/primitives/array.py +108 -0
  174. package/releng/meson/mesonbuild/interpreter/primitives/boolean.py +52 -0
  175. package/releng/meson/mesonbuild/interpreter/primitives/dict.py +88 -0
  176. package/releng/meson/mesonbuild/interpreter/primitives/integer.py +86 -0
  177. package/releng/meson/mesonbuild/interpreter/primitives/range.py +38 -0
  178. package/releng/meson/mesonbuild/interpreter/primitives/string.py +247 -0
  179. package/releng/meson/mesonbuild/interpreter/type_checking.py +853 -0
  180. package/releng/meson/mesonbuild/interpreterbase/__init__.py +126 -0
  181. package/releng/meson/mesonbuild/interpreterbase/_unholder.py +25 -0
  182. package/releng/meson/mesonbuild/interpreterbase/baseobjects.py +174 -0
  183. package/releng/meson/mesonbuild/interpreterbase/decorators.py +806 -0
  184. package/releng/meson/mesonbuild/interpreterbase/disabler.py +35 -0
  185. package/releng/meson/mesonbuild/interpreterbase/exceptions.py +22 -0
  186. package/releng/meson/mesonbuild/interpreterbase/helpers.py +67 -0
  187. package/releng/meson/mesonbuild/interpreterbase/interpreterbase.py +665 -0
  188. package/releng/meson/mesonbuild/interpreterbase/operator.py +32 -0
  189. package/releng/meson/mesonbuild/linkers/__init__.py +20 -0
  190. package/releng/meson/mesonbuild/linkers/base.py +39 -0
  191. package/releng/meson/mesonbuild/linkers/detect.py +229 -0
  192. package/releng/meson/mesonbuild/linkers/linkers.py +1614 -0
  193. package/releng/meson/mesonbuild/mcompile.py +380 -0
  194. package/releng/meson/mesonbuild/mconf.py +368 -0
  195. package/releng/meson/mesonbuild/mdevenv.py +234 -0
  196. package/releng/meson/mesonbuild/mdist.py +376 -0
  197. package/releng/meson/mesonbuild/mesondata.py +38 -0
  198. package/releng/meson/mesonbuild/mesonlib.py +23 -0
  199. package/releng/meson/mesonbuild/mesonmain.py +289 -0
  200. package/releng/meson/mesonbuild/minit.py +204 -0
  201. package/releng/meson/mesonbuild/minstall.py +864 -0
  202. package/releng/meson/mesonbuild/mintro.py +667 -0
  203. package/releng/meson/mesonbuild/mlog.py +542 -0
  204. package/releng/meson/mesonbuild/modules/__init__.py +270 -0
  205. package/releng/meson/mesonbuild/modules/cmake.py +442 -0
  206. package/releng/meson/mesonbuild/modules/cuda.py +377 -0
  207. package/releng/meson/mesonbuild/modules/dlang.py +117 -0
  208. package/releng/meson/mesonbuild/modules/external_project.py +306 -0
  209. package/releng/meson/mesonbuild/modules/fs.py +323 -0
  210. package/releng/meson/mesonbuild/modules/gnome.py +2215 -0
  211. package/releng/meson/mesonbuild/modules/hotdoc.py +487 -0
  212. package/releng/meson/mesonbuild/modules/i18n.py +405 -0
  213. package/releng/meson/mesonbuild/modules/icestorm.py +123 -0
  214. package/releng/meson/mesonbuild/modules/java.py +112 -0
  215. package/releng/meson/mesonbuild/modules/keyval.py +65 -0
  216. package/releng/meson/mesonbuild/modules/modtest.py +33 -0
  217. package/releng/meson/mesonbuild/modules/pkgconfig.py +744 -0
  218. package/releng/meson/mesonbuild/modules/python.py +556 -0
  219. package/releng/meson/mesonbuild/modules/python3.py +85 -0
  220. package/releng/meson/mesonbuild/modules/qt.py +621 -0
  221. package/releng/meson/mesonbuild/modules/qt4.py +23 -0
  222. package/releng/meson/mesonbuild/modules/qt5.py +23 -0
  223. package/releng/meson/mesonbuild/modules/qt6.py +22 -0
  224. package/releng/meson/mesonbuild/modules/rust.py +355 -0
  225. package/releng/meson/mesonbuild/modules/simd.py +114 -0
  226. package/releng/meson/mesonbuild/modules/sourceset.py +291 -0
  227. package/releng/meson/mesonbuild/modules/wayland.py +151 -0
  228. package/releng/meson/mesonbuild/modules/windows.py +207 -0
  229. package/releng/meson/mesonbuild/mparser.py +1114 -0
  230. package/releng/meson/mesonbuild/msetup.py +365 -0
  231. package/releng/meson/mesonbuild/msubprojects.py +764 -0
  232. package/releng/meson/mesonbuild/mtest.py +2201 -0
  233. package/releng/meson/mesonbuild/munstable_coredata.py +107 -0
  234. package/releng/meson/mesonbuild/optinterpreter.py +276 -0
  235. package/releng/meson/mesonbuild/programs.py +367 -0
  236. package/releng/meson/mesonbuild/rewriter.py +1075 -0
  237. package/releng/meson/mesonbuild/scripts/__init__.py +10 -0
  238. package/releng/meson/mesonbuild/scripts/clangformat.py +55 -0
  239. package/releng/meson/mesonbuild/scripts/clangtidy.py +30 -0
  240. package/releng/meson/mesonbuild/scripts/cleantrees.py +35 -0
  241. package/releng/meson/mesonbuild/scripts/cmake_run_ctgt.py +103 -0
  242. package/releng/meson/mesonbuild/scripts/cmd_or_ps.ps1 +17 -0
  243. package/releng/meson/mesonbuild/scripts/copy.py +19 -0
  244. package/releng/meson/mesonbuild/scripts/coverage.py +214 -0
  245. package/releng/meson/mesonbuild/scripts/delwithsuffix.py +27 -0
  246. package/releng/meson/mesonbuild/scripts/depfixer.py +495 -0
  247. package/releng/meson/mesonbuild/scripts/depscan.py +198 -0
  248. package/releng/meson/mesonbuild/scripts/dirchanger.py +20 -0
  249. package/releng/meson/mesonbuild/scripts/env2mfile.py +402 -0
  250. package/releng/meson/mesonbuild/scripts/externalproject.py +106 -0
  251. package/releng/meson/mesonbuild/scripts/gettext.py +86 -0
  252. package/releng/meson/mesonbuild/scripts/gtkdochelper.py +286 -0
  253. package/releng/meson/mesonbuild/scripts/hotdochelper.py +40 -0
  254. package/releng/meson/mesonbuild/scripts/itstool.py +77 -0
  255. package/releng/meson/mesonbuild/scripts/meson_exe.py +115 -0
  256. package/releng/meson/mesonbuild/scripts/msgfmthelper.py +29 -0
  257. package/releng/meson/mesonbuild/scripts/pycompile.py +54 -0
  258. package/releng/meson/mesonbuild/scripts/python_info.py +121 -0
  259. package/releng/meson/mesonbuild/scripts/regen_checker.py +55 -0
  260. package/releng/meson/mesonbuild/scripts/run_tool.py +58 -0
  261. package/releng/meson/mesonbuild/scripts/scanbuild.py +57 -0
  262. package/releng/meson/mesonbuild/scripts/symbolextractor.py +322 -0
  263. package/releng/meson/mesonbuild/scripts/tags.py +44 -0
  264. package/releng/meson/mesonbuild/scripts/test_loaded_modules.py +14 -0
  265. package/releng/meson/mesonbuild/scripts/uninstall.py +41 -0
  266. package/releng/meson/mesonbuild/scripts/vcstagger.py +35 -0
  267. package/releng/meson/mesonbuild/scripts/yasm.py +24 -0
  268. package/releng/meson/mesonbuild/templates/__init__.py +0 -0
  269. package/releng/meson/mesonbuild/templates/cpptemplates.py +143 -0
  270. package/releng/meson/mesonbuild/templates/cstemplates.py +90 -0
  271. package/releng/meson/mesonbuild/templates/ctemplates.py +126 -0
  272. package/releng/meson/mesonbuild/templates/cudatemplates.py +143 -0
  273. package/releng/meson/mesonbuild/templates/dlangtemplates.py +109 -0
  274. package/releng/meson/mesonbuild/templates/fortrantemplates.py +101 -0
  275. package/releng/meson/mesonbuild/templates/javatemplates.py +94 -0
  276. package/releng/meson/mesonbuild/templates/mesontemplates.py +70 -0
  277. package/releng/meson/mesonbuild/templates/objcpptemplates.py +126 -0
  278. package/releng/meson/mesonbuild/templates/objctemplates.py +126 -0
  279. package/releng/meson/mesonbuild/templates/rusttemplates.py +79 -0
  280. package/releng/meson/mesonbuild/templates/samplefactory.py +41 -0
  281. package/releng/meson/mesonbuild/templates/sampleimpl.py +160 -0
  282. package/releng/meson/mesonbuild/templates/valatemplates.py +82 -0
  283. package/releng/meson/mesonbuild/utils/__init__.py +0 -0
  284. package/releng/meson/mesonbuild/utils/core.py +166 -0
  285. package/releng/meson/mesonbuild/utils/platform.py +27 -0
  286. package/releng/meson/mesonbuild/utils/posix.py +32 -0
  287. package/releng/meson/mesonbuild/utils/universal.py +2445 -0
  288. package/releng/meson/mesonbuild/utils/vsenv.py +126 -0
  289. package/releng/meson/mesonbuild/utils/win32.py +29 -0
  290. package/releng/meson/mesonbuild/wrap/__init__.py +59 -0
  291. package/releng/meson/mesonbuild/wrap/wrap.py +846 -0
  292. package/releng/meson/mesonbuild/wrap/wraptool.py +198 -0
  293. package/releng/meson-scripts/BSDmakefile +6 -0
  294. package/releng/meson-scripts/Makefile +16 -0
  295. package/releng/meson-scripts/configure +18 -0
  296. package/releng/meson-scripts/configure.bat +22 -0
  297. package/releng/meson-scripts/make.bat +23 -0
  298. package/releng/meson_configure.py +506 -0
  299. package/releng/meson_make.py +131 -0
  300. package/releng/mkdevkit.py +107 -0
  301. package/releng/mkfatmacho.py +54 -0
  302. package/releng/post-process-oabi.py +97 -0
  303. package/releng/progress.py +14 -0
  304. package/releng/sync-from-upstream.py +185 -0
  305. package/releng/tomlkit/tomlkit/__init__.py +59 -0
  306. package/releng/tomlkit/tomlkit/_compat.py +22 -0
  307. package/releng/tomlkit/tomlkit/_types.py +83 -0
  308. package/releng/tomlkit/tomlkit/_utils.py +158 -0
  309. package/releng/tomlkit/tomlkit/api.py +308 -0
  310. package/releng/tomlkit/tomlkit/container.py +875 -0
  311. package/releng/tomlkit/tomlkit/exceptions.py +227 -0
  312. package/releng/tomlkit/tomlkit/items.py +1967 -0
  313. package/releng/tomlkit/tomlkit/parser.py +1141 -0
  314. package/releng/tomlkit/tomlkit/py.typed +0 -0
  315. package/releng/tomlkit/tomlkit/source.py +180 -0
  316. package/releng/tomlkit/tomlkit/toml_char.py +52 -0
  317. package/releng/tomlkit/tomlkit/toml_document.py +7 -0
  318. package/releng/tomlkit/tomlkit/toml_file.py +58 -0
  319. package/releng/winenv.py +140 -0
  320. package/scripts/adjust-version.py +19 -0
  321. package/scripts/detect-version.py +40 -0
  322. package/scripts/fetch-abi-bits.py +343 -0
  323. package/scripts/install.js +23 -0
  324. package/scripts/package.py +15 -0
  325. package/src/addon.cc +76 -0
  326. package/src/application.cc +148 -0
  327. package/src/application.h +31 -0
  328. package/src/authentication.cc +174 -0
  329. package/src/authentication.h +24 -0
  330. package/src/bus.cc +167 -0
  331. package/src/bus.h +33 -0
  332. package/src/cancellable.cc +117 -0
  333. package/src/cancellable.h +31 -0
  334. package/src/child.cc +150 -0
  335. package/src/child.h +32 -0
  336. package/src/crash.cc +122 -0
  337. package/src/crash.h +30 -0
  338. package/src/device.cc +1302 -0
  339. package/src/device.h +55 -0
  340. package/src/device_manager.cc +362 -0
  341. package/src/device_manager.h +35 -0
  342. package/src/endpoint_parameters.cc +171 -0
  343. package/src/endpoint_parameters.h +28 -0
  344. package/src/glib_context.cc +62 -0
  345. package/src/glib_context.h +29 -0
  346. package/src/glib_object.cc +25 -0
  347. package/src/glib_object.h +37 -0
  348. package/src/iostream.cc +247 -0
  349. package/src/iostream.h +30 -0
  350. package/src/meson.build +26 -0
  351. package/src/operation.h +94 -0
  352. package/src/portal_membership.cc +100 -0
  353. package/src/portal_membership.h +26 -0
  354. package/src/portal_service.cc +401 -0
  355. package/src/portal_service.h +40 -0
  356. package/src/process.cc +135 -0
  357. package/src/process.h +30 -0
  358. package/src/relay.cc +139 -0
  359. package/src/relay.h +31 -0
  360. package/src/runtime.cc +443 -0
  361. package/src/runtime.h +64 -0
  362. package/src/script.cc +301 -0
  363. package/src/script.h +36 -0
  364. package/src/session.cc +860 -0
  365. package/src/session.h +42 -0
  366. package/src/signals.cc +334 -0
  367. package/src/signals.h +47 -0
  368. package/src/spawn.cc +95 -0
  369. package/src/spawn.h +27 -0
  370. package/src/usage_monitor.h +117 -0
  371. package/src/uv_context.cc +118 -0
  372. package/src/uv_context.h +40 -0
  373. package/src/win_delay_load_hook.cc +63 -0
  374. package/subprojects/frida-core.wrap +8 -0
  375. package/subprojects/nan.wrap +9 -0
  376. package/subprojects/packagefiles/nan.patch +13 -0
  377. package/test/data/index.ts +13 -0
  378. package/test/data/unixvictim-linux-x86 +0 -0
  379. package/test/data/unixvictim-linux-x86_64 +0 -0
  380. package/test/data/unixvictim-macos +0 -0
  381. package/test/device.ts +27 -0
  382. package/test/device_manager.ts +16 -0
  383. package/test/labrat.ts +32 -0
  384. package/test/script.ts +176 -0
  385. package/test/session.ts +73 -0
  386. package/tsconfig.json +18 -0
@@ -0,0 +1,733 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright © 2022-2024 Intel Corporation
3
+
4
+ """Interpreter for converting Cargo Toml definitions to Meson AST
5
+
6
+ There are some notable limits here. We don't even try to convert something with
7
+ a build.rs: there's so few limits on what Cargo allows a build.rs (basically
8
+ none), and no good way for us to convert them. In that case, an actual meson
9
+ port will be required.
10
+ """
11
+
12
+ from __future__ import annotations
13
+ import dataclasses
14
+ import glob
15
+ import importlib
16
+ import itertools
17
+ import json
18
+ import os
19
+ import shutil
20
+ import collections
21
+ import typing as T
22
+
23
+ from . import builder
24
+ from . import version
25
+ from ..mesonlib import MesonException, Popen_safe, OptionKey
26
+ from .. import coredata
27
+
28
+ if T.TYPE_CHECKING:
29
+ from types import ModuleType
30
+
31
+ from . import manifest
32
+ from .. import mparser
33
+ from ..environment import Environment
34
+ from ..coredata import KeyedOptionDictType
35
+
36
+ # tomllib is present in python 3.11, before that it is a pypi module called tomli,
37
+ # we try to import tomllib, then tomli,
38
+ # TODO: add a fallback to toml2json?
39
+ tomllib: T.Optional[ModuleType] = None
40
+ toml2json: T.Optional[str] = None
41
+ for t in ['tomllib', 'tomli']:
42
+ try:
43
+ tomllib = importlib.import_module(t)
44
+ break
45
+ except ImportError:
46
+ pass
47
+ else:
48
+ # TODO: it would be better to use an Executable here, which could be looked
49
+ # up in the cross file or provided by a wrap. However, that will have to be
50
+ # passed in externally, since we don't have (and I don't think we should),
51
+ # have access to the `Environment` for that in this module.
52
+ toml2json = shutil.which('toml2json')
53
+
54
+
55
+ def load_toml(filename: str) -> T.Dict[object, object]:
56
+ if tomllib:
57
+ with open(filename, 'rb') as f:
58
+ raw = tomllib.load(f)
59
+ else:
60
+ if toml2json is None:
61
+ raise MesonException('Could not find an implementation of tomllib, nor toml2json')
62
+
63
+ p, out, err = Popen_safe([toml2json, filename])
64
+ if p.returncode != 0:
65
+ raise MesonException('toml2json failed to decode output\n', err)
66
+
67
+ raw = json.loads(out)
68
+
69
+ if not isinstance(raw, dict):
70
+ raise MesonException("Cargo.toml isn't a dictionary? How did that happen?")
71
+
72
+ return raw
73
+
74
+
75
+ def fixup_meson_varname(name: str) -> str:
76
+ """Fixup a meson variable name
77
+
78
+ :param name: The name to fix
79
+ :return: the fixed name
80
+ """
81
+ return name.replace('-', '_')
82
+
83
+
84
+ # Pylance can figure out that these do not, in fact, overlap, but mypy can't
85
+ @T.overload
86
+ def _fixup_raw_mappings(d: manifest.BuildTarget) -> manifest.FixedBuildTarget: ... # type: ignore
87
+
88
+ @T.overload
89
+ def _fixup_raw_mappings(d: manifest.LibTarget) -> manifest.FixedLibTarget: ... # type: ignore
90
+
91
+ @T.overload
92
+ def _fixup_raw_mappings(d: manifest.Dependency) -> manifest.FixedDependency: ...
93
+
94
+ def _fixup_raw_mappings(d: T.Union[manifest.BuildTarget, manifest.LibTarget, manifest.Dependency]
95
+ ) -> T.Union[manifest.FixedBuildTarget, manifest.FixedLibTarget,
96
+ manifest.FixedDependency]:
97
+ """Fixup raw cargo mappings to ones more suitable for python to consume.
98
+
99
+ This does the following:
100
+ * replaces any `-` with `_`, cargo likes the former, but python dicts make
101
+ keys with `-` in them awkward to work with
102
+ * Convert Dependndency versions from the cargo format to something meson
103
+ understands
104
+
105
+ :param d: The mapping to fix
106
+ :return: the fixed string
107
+ """
108
+ raw = {fixup_meson_varname(k): v for k, v in d.items()}
109
+ if 'version' in raw:
110
+ assert isinstance(raw['version'], str), 'for mypy'
111
+ raw['version'] = version.convert(raw['version'])
112
+ return T.cast('T.Union[manifest.FixedBuildTarget, manifest.FixedLibTarget, manifest.FixedDependency]', raw)
113
+
114
+
115
+ @dataclasses.dataclass
116
+ class Package:
117
+
118
+ """Representation of a Cargo Package entry, with defaults filled in."""
119
+
120
+ name: str
121
+ version: str
122
+ description: T.Optional[str] = None
123
+ resolver: T.Optional[str] = None
124
+ authors: T.List[str] = dataclasses.field(default_factory=list)
125
+ edition: manifest.EDITION = '2015'
126
+ rust_version: T.Optional[str] = None
127
+ documentation: T.Optional[str] = None
128
+ readme: T.Optional[str] = None
129
+ homepage: T.Optional[str] = None
130
+ repository: T.Optional[str] = None
131
+ license: T.Optional[str] = None
132
+ license_file: T.Optional[str] = None
133
+ keywords: T.List[str] = dataclasses.field(default_factory=list)
134
+ categories: T.List[str] = dataclasses.field(default_factory=list)
135
+ workspace: T.Optional[str] = None
136
+ build: T.Optional[str] = None
137
+ links: T.Optional[str] = None
138
+ exclude: T.List[str] = dataclasses.field(default_factory=list)
139
+ include: T.List[str] = dataclasses.field(default_factory=list)
140
+ publish: bool = True
141
+ metadata: T.Dict[str, T.Dict[str, str]] = dataclasses.field(default_factory=dict)
142
+ default_run: T.Optional[str] = None
143
+ autobins: bool = True
144
+ autoexamples: bool = True
145
+ autotests: bool = True
146
+ autobenches: bool = True
147
+
148
+
149
+ @dataclasses.dataclass
150
+ class Dependency:
151
+
152
+ """Representation of a Cargo Dependency Entry."""
153
+
154
+ name: dataclasses.InitVar[str]
155
+ version: T.List[str]
156
+ registry: T.Optional[str] = None
157
+ git: T.Optional[str] = None
158
+ branch: T.Optional[str] = None
159
+ rev: T.Optional[str] = None
160
+ path: T.Optional[str] = None
161
+ optional: bool = False
162
+ package: str = ''
163
+ default_features: bool = True
164
+ features: T.List[str] = dataclasses.field(default_factory=list)
165
+ api: str = dataclasses.field(init=False)
166
+
167
+ def __post_init__(self, name: str) -> None:
168
+ self.package = self.package or name
169
+ # Extract wanted API version from version constraints.
170
+ api = set()
171
+ for v in self.version:
172
+ if v.startswith(('>=', '==')):
173
+ api.add(_version_to_api(v[2:].strip()))
174
+ elif v.startswith('='):
175
+ api.add(_version_to_api(v[1:].strip()))
176
+ if not api:
177
+ self.api = '0'
178
+ elif len(api) == 1:
179
+ self.api = api.pop()
180
+ else:
181
+ raise MesonException(f'Cannot determine minimum API version from {self.version}.')
182
+
183
+ @classmethod
184
+ def from_raw(cls, name: str, raw: manifest.DependencyV) -> Dependency:
185
+ """Create a dependency from a raw cargo dictionary"""
186
+ if isinstance(raw, str):
187
+ return cls(name, version.convert(raw))
188
+ return cls(name, **_fixup_raw_mappings(raw))
189
+
190
+
191
+ @dataclasses.dataclass
192
+ class BuildTarget:
193
+
194
+ name: str
195
+ crate_type: T.List[manifest.CRATE_TYPE] = dataclasses.field(default_factory=lambda: ['lib'])
196
+ path: dataclasses.InitVar[T.Optional[str]] = None
197
+
198
+ # https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-test-field
199
+ # True for lib, bin, test
200
+ test: bool = True
201
+
202
+ # https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-doctest-field
203
+ # True for lib
204
+ doctest: bool = False
205
+
206
+ # https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-bench-field
207
+ # True for lib, bin, benchmark
208
+ bench: bool = True
209
+
210
+ # https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-doc-field
211
+ # True for libraries and binaries
212
+ doc: bool = False
213
+
214
+ harness: bool = True
215
+ edition: manifest.EDITION = '2015'
216
+ required_features: T.List[str] = dataclasses.field(default_factory=list)
217
+ plugin: bool = False
218
+
219
+
220
+ @dataclasses.dataclass
221
+ class Library(BuildTarget):
222
+
223
+ """Representation of a Cargo Library Entry."""
224
+
225
+ doctest: bool = True
226
+ doc: bool = True
227
+ path: str = os.path.join('src', 'lib.rs')
228
+ proc_macro: bool = False
229
+ crate_type: T.List[manifest.CRATE_TYPE] = dataclasses.field(default_factory=lambda: ['lib'])
230
+ doc_scrape_examples: bool = True
231
+
232
+
233
+ @dataclasses.dataclass
234
+ class Binary(BuildTarget):
235
+
236
+ """Representation of a Cargo Bin Entry."""
237
+
238
+ doc: bool = True
239
+
240
+
241
+ @dataclasses.dataclass
242
+ class Test(BuildTarget):
243
+
244
+ """Representation of a Cargo Test Entry."""
245
+
246
+ bench: bool = True
247
+
248
+
249
+ @dataclasses.dataclass
250
+ class Benchmark(BuildTarget):
251
+
252
+ """Representation of a Cargo Benchmark Entry."""
253
+
254
+ test: bool = True
255
+
256
+
257
+ @dataclasses.dataclass
258
+ class Example(BuildTarget):
259
+
260
+ """Representation of a Cargo Example Entry."""
261
+
262
+ crate_type: T.List[manifest.CRATE_TYPE] = dataclasses.field(default_factory=lambda: ['bin'])
263
+
264
+
265
+ @dataclasses.dataclass
266
+ class Manifest:
267
+
268
+ """Cargo Manifest definition.
269
+
270
+ Most of these values map up to the Cargo Manifest, but with default values
271
+ if not provided.
272
+
273
+ Cargo subprojects can contain what Meson wants to treat as multiple,
274
+ interdependent, subprojects.
275
+
276
+ :param subdir: the subdirectory that this cargo project is in
277
+ :param path: the path within the cargo subproject.
278
+ """
279
+
280
+ package: Package
281
+ dependencies: T.Dict[str, Dependency]
282
+ dev_dependencies: T.Dict[str, Dependency]
283
+ build_dependencies: T.Dict[str, Dependency]
284
+ lib: Library
285
+ bin: T.List[Binary]
286
+ test: T.List[Test]
287
+ bench: T.List[Benchmark]
288
+ example: T.List[Example]
289
+ features: T.Dict[str, T.List[str]]
290
+ target: T.Dict[str, T.Dict[str, Dependency]]
291
+ subdir: str
292
+ path: str = ''
293
+
294
+ def __post_init__(self) -> None:
295
+ self.features.setdefault('default', [])
296
+
297
+
298
+ def _convert_manifest(raw_manifest: manifest.Manifest, subdir: str, path: str = '') -> Manifest:
299
+ # This cast is a bit of a hack to deal with proc-macro
300
+ lib = _fixup_raw_mappings(raw_manifest.get('lib', {}))
301
+
302
+ # We need to set the name field if it's not set manually,
303
+ # including if other fields are set in the lib section
304
+ lib.setdefault('name', raw_manifest['package']['name'])
305
+
306
+ pkg = T.cast('manifest.FixedPackage',
307
+ {fixup_meson_varname(k): v for k, v in raw_manifest['package'].items()})
308
+
309
+ return Manifest(
310
+ Package(**pkg),
311
+ {k: Dependency.from_raw(k, v) for k, v in raw_manifest.get('dependencies', {}).items()},
312
+ {k: Dependency.from_raw(k, v) for k, v in raw_manifest.get('dev-dependencies', {}).items()},
313
+ {k: Dependency.from_raw(k, v) for k, v in raw_manifest.get('build-dependencies', {}).items()},
314
+ Library(**lib),
315
+ [Binary(**_fixup_raw_mappings(b)) for b in raw_manifest.get('bin', {})],
316
+ [Test(**_fixup_raw_mappings(b)) for b in raw_manifest.get('test', {})],
317
+ [Benchmark(**_fixup_raw_mappings(b)) for b in raw_manifest.get('bench', {})],
318
+ [Example(**_fixup_raw_mappings(b)) for b in raw_manifest.get('example', {})],
319
+ raw_manifest.get('features', {}),
320
+ {k: {k2: Dependency.from_raw(k2, v2) for k2, v2 in v.get('dependencies', {}).items()}
321
+ for k, v in raw_manifest.get('target', {}).items()},
322
+ subdir,
323
+ path,
324
+ )
325
+
326
+
327
+ def _load_manifests(subdir: str) -> T.Dict[str, Manifest]:
328
+ filename = os.path.join(subdir, 'Cargo.toml')
329
+ raw = load_toml(filename)
330
+
331
+ manifests: T.Dict[str, Manifest] = {}
332
+
333
+ raw_manifest: T.Union[manifest.Manifest, manifest.VirtualManifest]
334
+ if 'package' in raw:
335
+ raw_manifest = T.cast('manifest.Manifest', raw)
336
+ manifest_ = _convert_manifest(raw_manifest, subdir)
337
+ manifests[manifest_.package.name] = manifest_
338
+ else:
339
+ raw_manifest = T.cast('manifest.VirtualManifest', raw)
340
+
341
+ if 'workspace' in raw_manifest:
342
+ # XXX: need to verify that python glob and cargo globbing are the
343
+ # same and probably write a glob implementation. Blarg
344
+
345
+ # We need to chdir here to make the glob work correctly
346
+ pwd = os.getcwd()
347
+ os.chdir(subdir)
348
+ members: T.Iterable[str]
349
+ try:
350
+ members = itertools.chain.from_iterable(
351
+ glob.glob(m) for m in raw_manifest['workspace']['members'])
352
+ finally:
353
+ os.chdir(pwd)
354
+ if 'exclude' in raw_manifest['workspace']:
355
+ members = (x for x in members if x not in raw_manifest['workspace']['exclude'])
356
+
357
+ for m in members:
358
+ filename = os.path.join(subdir, m, 'Cargo.toml')
359
+ raw = load_toml(filename)
360
+
361
+ raw_manifest = T.cast('manifest.Manifest', raw)
362
+ man = _convert_manifest(raw_manifest, subdir, m)
363
+ manifests[man.package.name] = man
364
+
365
+ return manifests
366
+
367
+
368
+ def _version_to_api(version: str) -> str:
369
+ # x.y.z -> x
370
+ # 0.x.y -> 0.x
371
+ # 0.0.x -> 0
372
+ vers = version.split('.')
373
+ if int(vers[0]) != 0:
374
+ return vers[0]
375
+ elif len(vers) >= 2 and int(vers[1]) != 0:
376
+ return f'0.{vers[1]}'
377
+ return '0'
378
+
379
+
380
+ def _dependency_name(package_name: str, api: str) -> str:
381
+ basename = package_name[:-3] if package_name.endswith('-rs') else package_name
382
+ return f'{basename}-{api}-rs'
383
+
384
+
385
+ def _dependency_varname(package_name: str) -> str:
386
+ return f'{fixup_meson_varname(package_name)}_dep'
387
+
388
+
389
+ _OPTION_NAME_PREFIX = 'feature-'
390
+
391
+
392
+ def _option_name(feature: str) -> str:
393
+ # Add a prefix to avoid collision with Meson reserved options (e.g. "debug")
394
+ return _OPTION_NAME_PREFIX + feature
395
+
396
+
397
+ def _options_varname(depname: str) -> str:
398
+ return f'{fixup_meson_varname(depname)}_options'
399
+
400
+
401
+ def _extra_args_varname() -> str:
402
+ return 'extra_args'
403
+
404
+
405
+ def _extra_deps_varname() -> str:
406
+ return 'extra_deps'
407
+
408
+
409
+ def _create_project(cargo: Manifest, build: builder.Builder) -> T.List[mparser.BaseNode]:
410
+ """Create a function call
411
+
412
+ :param cargo: The Manifest to generate from
413
+ :param build: The AST builder
414
+ :return: a list nodes
415
+ """
416
+ args: T.List[mparser.BaseNode] = []
417
+ args.extend([
418
+ build.string(cargo.package.name),
419
+ build.string('rust'),
420
+ ])
421
+ kwargs: T.Dict[str, mparser.BaseNode] = {
422
+ 'version': build.string(cargo.package.version),
423
+ # Always assume that the generated meson is using the latest features
424
+ # This will warn when when we generate deprecated code, which is helpful
425
+ # for the upkeep of the module
426
+ 'meson_version': build.string(f'>= {coredata.stable_version}'),
427
+ 'default_options': build.array([build.string(f'rust_std={cargo.package.edition}')]),
428
+ }
429
+ if cargo.package.license:
430
+ kwargs['license'] = build.string(cargo.package.license)
431
+ elif cargo.package.license_file:
432
+ kwargs['license_files'] = build.string(cargo.package.license_file)
433
+
434
+ return [build.function('project', args, kwargs)]
435
+
436
+
437
+ def _process_feature(cargo: Manifest, feature: str) -> T.Tuple[T.Set[str], T.Dict[str, T.Set[str]], T.Set[str]]:
438
+ # Set of features that must also be enabled if this feature is enabled.
439
+ features: T.Set[str] = set()
440
+ # Map dependency name to a set of features that must also be enabled on that
441
+ # dependency if this feature is enabled.
442
+ dep_features: T.Dict[str, T.Set[str]] = collections.defaultdict(set)
443
+ # Set of dependencies that are required if this feature is enabled.
444
+ required_deps: T.Set[str] = set()
445
+ # Set of features that must be processed recursively.
446
+ to_process: T.Set[str] = {feature}
447
+ while to_process:
448
+ f = to_process.pop()
449
+ if '/' in f:
450
+ dep, dep_f = f.split('/', 1)
451
+ if dep[-1] == '?':
452
+ dep = dep[:-1]
453
+ else:
454
+ required_deps.add(dep)
455
+ dep_features[dep].add(dep_f)
456
+ elif f.startswith('dep:'):
457
+ required_deps.add(f[4:])
458
+ elif f not in features:
459
+ features.add(f)
460
+ to_process.update(cargo.features.get(f, []))
461
+ # A feature can also be a dependency
462
+ if f in cargo.dependencies:
463
+ required_deps.add(f)
464
+ return features, dep_features, required_deps
465
+
466
+
467
+ def _create_features(cargo: Manifest, build: builder.Builder) -> T.List[mparser.BaseNode]:
468
+ # https://doc.rust-lang.org/cargo/reference/features.html#the-features-section
469
+
470
+ # Declare a dict that map enabled features to true. One for current project
471
+ # and one per dependency.
472
+ ast: T.List[mparser.BaseNode] = []
473
+ ast.append(build.assign(build.dict({}), 'features'))
474
+ for depname in cargo.dependencies:
475
+ ast.append(build.assign(build.dict({}), _options_varname(depname)))
476
+
477
+ # Declare a dict that map required dependencies to true
478
+ ast.append(build.assign(build.dict({}), 'required_deps'))
479
+
480
+ for feature in cargo.features:
481
+ # if get_option(feature)
482
+ # required_deps += {'dep': true, ...}
483
+ # features += {'foo': true, ...}
484
+ # xxx_options += {'feature-foo': true, ...}
485
+ # ...
486
+ # endif
487
+ features, dep_features, required_deps = _process_feature(cargo, feature)
488
+ lines: T.List[mparser.BaseNode] = [
489
+ build.plusassign(
490
+ build.dict({build.string(d): build.bool(True) for d in required_deps}),
491
+ 'required_deps'),
492
+ build.plusassign(
493
+ build.dict({build.string(f): build.bool(True) for f in features}),
494
+ 'features'),
495
+ ]
496
+ for depname, enabled_features in dep_features.items():
497
+ lines.append(build.plusassign(
498
+ build.dict({build.string(_option_name(f)): build.bool(True) for f in enabled_features}),
499
+ _options_varname(depname)))
500
+
501
+ ast.append(build.if_(build.function('get_option', [build.string(_option_name(feature))]), build.block(lines)))
502
+
503
+ ast.append(build.function('message', [
504
+ build.string('Enabled features:'),
505
+ build.method('keys', build.identifier('features'))],
506
+ ))
507
+
508
+ return ast
509
+
510
+
511
+ def _create_dependencies(cargo: Manifest, build: builder.Builder) -> T.List[mparser.BaseNode]:
512
+ ast: T.List[mparser.BaseNode] = []
513
+ for name, dep in cargo.dependencies.items():
514
+ # xxx_options += {'feature-default': true, ...}
515
+ extra_options: T.Dict[mparser.BaseNode, mparser.BaseNode] = {
516
+ build.string(_option_name('default')): build.bool(dep.default_features),
517
+ }
518
+ for f in dep.features:
519
+ extra_options[build.string(_option_name(f))] = build.bool(True)
520
+ ast.append(build.plusassign(build.dict(extra_options), _options_varname(name)))
521
+
522
+ kw = {
523
+ 'version': build.array([build.string(s) for s in dep.version]),
524
+ 'default_options': build.identifier(_options_varname(name)),
525
+ }
526
+ if dep.optional:
527
+ kw['required'] = build.method('get', build.identifier('required_deps'), [
528
+ build.string(name), build.bool(False)
529
+ ])
530
+
531
+ # Lookup for this dependency with the features we want in default_options kwarg.
532
+ #
533
+ # However, this subproject could have been previously configured with a
534
+ # different set of features. Cargo collects the set of features globally
535
+ # but Meson can only use features enabled by the first call that triggered
536
+ # the configuration of that subproject.
537
+ #
538
+ # Verify all features that we need are actually enabled for that dependency,
539
+ # otherwise abort with an error message. The user has to set the corresponding
540
+ # option manually with -Dxxx-rs:feature-yyy=true, or the main project can do
541
+ # that in its project(..., default_options: ['xxx-rs:feature-yyy=true']).
542
+ ast.extend([
543
+ # xxx_dep = dependency('xxx', version : ..., default_options : xxx_options)
544
+ build.assign(
545
+ build.function(
546
+ 'dependency',
547
+ [build.string(_dependency_name(dep.package, dep.api))],
548
+ kw,
549
+ ),
550
+ _dependency_varname(dep.package),
551
+ ),
552
+ # if xxx_dep.found()
553
+ build.if_(build.method('found', build.identifier(_dependency_varname(dep.package))), build.block([
554
+ # actual_features = xxx_dep.get_variable('features', default_value : '').split(',')
555
+ build.assign(
556
+ build.method(
557
+ 'split',
558
+ build.method(
559
+ 'get_variable',
560
+ build.identifier(_dependency_varname(dep.package)),
561
+ [build.string('features')],
562
+ {'default_value': build.string('')}
563
+ ),
564
+ [build.string(',')],
565
+ ),
566
+ 'actual_features'
567
+ ),
568
+ # needed_features = []
569
+ # foreach f, _ : xxx_options
570
+ # needed_features += f.substring(8)
571
+ # endforeach
572
+ build.assign(build.array([]), 'needed_features'),
573
+ build.foreach(['f', 'enabled'], build.identifier(_options_varname(name)), build.block([
574
+ build.if_(build.identifier('enabled'), build.block([
575
+ build.plusassign(
576
+ build.method('substring', build.identifier('f'), [build.number(len(_OPTION_NAME_PREFIX))]),
577
+ 'needed_features'),
578
+ ])),
579
+ ])),
580
+ # foreach f : needed_features
581
+ # if f not in actual_features
582
+ # error()
583
+ # endif
584
+ # endforeach
585
+ build.foreach(['f'], build.identifier('needed_features'), build.block([
586
+ build.if_(build.not_in(build.identifier('f'), build.identifier('actual_features')), build.block([
587
+ build.function('error', [
588
+ build.string('Dependency'),
589
+ build.string(_dependency_name(dep.package, dep.api)),
590
+ build.string('previously configured with features'),
591
+ build.identifier('actual_features'),
592
+ build.string('but need'),
593
+ build.identifier('needed_features'),
594
+ ])
595
+ ]))
596
+ ])),
597
+ ])),
598
+ ])
599
+ return ast
600
+
601
+
602
+ def _create_meson_subdir(cargo: Manifest, build: builder.Builder) -> T.List[mparser.BaseNode]:
603
+ # Allow Cargo subprojects to add extra Rust args in meson/meson.build file.
604
+ # This is used to replace build.rs logic.
605
+
606
+ # extra_args = []
607
+ # extra_deps = []
608
+ # fs = import('fs')
609
+ # if fs.is_dir('meson')
610
+ # subdir('meson')
611
+ # endif
612
+ return [
613
+ build.assign(build.array([]), _extra_args_varname()),
614
+ build.assign(build.array([]), _extra_deps_varname()),
615
+ build.assign(build.function('import', [build.string('fs')]), 'fs'),
616
+ build.if_(build.method('is_dir', build.identifier('fs'), [build.string('meson')]),
617
+ build.block([build.function('subdir', [build.string('meson')])]))
618
+ ]
619
+
620
+
621
+ def _create_lib(cargo: Manifest, build: builder.Builder, crate_type: manifest.CRATE_TYPE) -> T.List[mparser.BaseNode]:
622
+ dependencies: T.List[mparser.BaseNode] = []
623
+ dependency_map: T.Dict[mparser.BaseNode, mparser.BaseNode] = {}
624
+ for name, dep in cargo.dependencies.items():
625
+ dependencies.append(build.identifier(_dependency_varname(dep.package)))
626
+ if name != dep.package:
627
+ dependency_map[build.string(fixup_meson_varname(dep.package))] = build.string(name)
628
+
629
+ rust_args: T.List[mparser.BaseNode] = [
630
+ build.identifier('features_args'),
631
+ build.identifier(_extra_args_varname())
632
+ ]
633
+
634
+ dependencies.append(build.identifier(_extra_deps_varname()))
635
+
636
+ posargs: T.List[mparser.BaseNode] = [
637
+ build.string(fixup_meson_varname(cargo.package.name)),
638
+ build.string(cargo.lib.path),
639
+ ]
640
+
641
+ kwargs: T.Dict[str, mparser.BaseNode] = {
642
+ 'dependencies': build.array(dependencies),
643
+ 'rust_dependency_map': build.dict(dependency_map),
644
+ 'rust_args': build.array(rust_args),
645
+ }
646
+
647
+ lib: mparser.BaseNode
648
+ if cargo.lib.proc_macro or crate_type == 'proc-macro':
649
+ lib = build.method('proc_macro', build.identifier('rust'), posargs, kwargs)
650
+ else:
651
+ if crate_type in {'lib', 'rlib', 'staticlib'}:
652
+ target_type = 'static_library'
653
+ elif crate_type in {'dylib', 'cdylib'}:
654
+ target_type = 'shared_library'
655
+ else:
656
+ raise MesonException(f'Unsupported crate type {crate_type}')
657
+ if crate_type in {'staticlib', 'cdylib'}:
658
+ kwargs['rust_abi'] = build.string('c')
659
+ lib = build.function(target_type, posargs, kwargs)
660
+
661
+ # features_args = []
662
+ # foreach f, _ : features
663
+ # features_args += ['--cfg', 'feature="' + f + '"']
664
+ # endforeach
665
+ # lib = xxx_library()
666
+ # dep = declare_dependency()
667
+ # meson.override_dependency()
668
+ return [
669
+ build.assign(build.array([]), 'features_args'),
670
+ build.foreach(['f', '_'], build.identifier('features'), build.block([
671
+ build.plusassign(
672
+ build.array([
673
+ build.string('--cfg'),
674
+ build.plus(build.string('feature="'), build.plus(build.identifier('f'), build.string('"'))),
675
+ ]),
676
+ 'features_args')
677
+ ])
678
+ ),
679
+ build.assign(lib, 'lib'),
680
+ build.assign(
681
+ build.function(
682
+ 'declare_dependency',
683
+ kw={
684
+ 'link_with': build.identifier('lib'),
685
+ 'variables': build.dict({
686
+ build.string('features'): build.method('join', build.string(','), [build.method('keys', build.identifier('features'))]),
687
+ })
688
+ },
689
+ ),
690
+ 'dep'
691
+ ),
692
+ build.method(
693
+ 'override_dependency',
694
+ build.identifier('meson'),
695
+ [
696
+ build.string(_dependency_name(cargo.package.name, _version_to_api(cargo.package.version))),
697
+ build.identifier('dep'),
698
+ ],
699
+ ),
700
+ ]
701
+
702
+
703
+ def interpret(subp_name: str, subdir: str, env: Environment) -> T.Tuple[mparser.CodeBlockNode, KeyedOptionDictType]:
704
+ # subp_name should be in the form "foo-0.1-rs"
705
+ package_name = subp_name.rsplit('-', 2)[0]
706
+ manifests = _load_manifests(os.path.join(env.source_dir, subdir))
707
+ cargo = manifests.get(package_name)
708
+ if not cargo:
709
+ raise MesonException(f'Cargo package {package_name!r} not found in {subdir}')
710
+
711
+ filename = os.path.join(cargo.subdir, cargo.path, 'Cargo.toml')
712
+ build = builder.Builder(filename)
713
+
714
+ # Generate project options
715
+ options: T.Dict[OptionKey, coredata.UserOption] = {}
716
+ for feature in cargo.features:
717
+ key = OptionKey(_option_name(feature), subproject=subp_name)
718
+ enabled = feature == 'default'
719
+ options[key] = coredata.UserBooleanOption(key.name, f'Cargo {feature} feature', enabled)
720
+
721
+ ast = _create_project(cargo, build)
722
+ ast += [build.assign(build.function('import', [build.string('rust')]), 'rust')]
723
+ ast += _create_features(cargo, build)
724
+ ast += _create_dependencies(cargo, build)
725
+ ast += _create_meson_subdir(cargo, build)
726
+
727
+ # Libs are always auto-discovered and there's no other way to handle them,
728
+ # which is unfortunate for reproducability
729
+ if os.path.exists(os.path.join(env.source_dir, cargo.subdir, cargo.path, cargo.lib.path)):
730
+ for crate_type in cargo.lib.crate_type:
731
+ ast.extend(_create_lib(cargo, build, crate_type))
732
+
733
+ return build.block(ast), options