frida 16.2.1 → 16.2.3

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,1396 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright 2012-2022 The Meson development team
3
+
4
+ from __future__ import annotations
5
+
6
+ from ..mesonlib import (
7
+ MesonException, EnvironmentException, MachineChoice, join_args,
8
+ search_version, is_windows, Popen_safe, Popen_safe_logged, windows_proof_rm,
9
+ )
10
+ from ..envconfig import BinaryTable
11
+ from .. import mlog
12
+
13
+ from ..linkers import guess_win_linker, guess_nix_linker
14
+
15
+ import subprocess
16
+ import platform
17
+ import re
18
+ import shutil
19
+ import tempfile
20
+ import os
21
+ import typing as T
22
+
23
+ if T.TYPE_CHECKING:
24
+ from .compilers import Compiler
25
+ from .c import CCompiler
26
+ from .cpp import CPPCompiler
27
+ from .fortran import FortranCompiler
28
+ from .rust import RustCompiler
29
+ from ..linkers.linkers import StaticLinker, DynamicLinker
30
+ from ..environment import Environment
31
+
32
+
33
+ # Default compilers and linkers
34
+ # =============================
35
+
36
+ defaults: T.Dict[str, T.List[str]] = {}
37
+
38
+ # List of potential compilers.
39
+ if is_windows():
40
+ # Intel C and C++ compiler is icl on Windows, but icc and icpc elsewhere.
41
+ # Search for icl before cl, since Intel "helpfully" provides a
42
+ # cl.exe that returns *exactly the same thing* that microsofts
43
+ # cl.exe does, and if icl is present, it's almost certainly what
44
+ # you want.
45
+ defaults['c'] = ['icl', 'cl', 'cc', 'gcc', 'clang', 'clang-cl', 'pgcc']
46
+ # There is currently no pgc++ for Windows, only for Mac and Linux.
47
+ defaults['cpp'] = ['icl', 'cl', 'c++', 'g++', 'clang++', 'clang-cl']
48
+ defaults['fortran'] = ['ifort', 'gfortran', 'flang', 'pgfortran', 'g95']
49
+ # Clang and clang++ are valid, but currently unsupported.
50
+ defaults['objc'] = ['cc', 'gcc']
51
+ defaults['objcpp'] = ['c++', 'g++']
52
+ defaults['cs'] = ['csc', 'mcs']
53
+ else:
54
+ if platform.machine().lower() == 'e2k':
55
+ defaults['c'] = ['cc', 'gcc', 'lcc', 'clang']
56
+ defaults['cpp'] = ['c++', 'g++', 'l++', 'clang++']
57
+ defaults['objc'] = ['clang']
58
+ defaults['objcpp'] = ['clang++']
59
+ else:
60
+ defaults['c'] = ['cc', 'gcc', 'clang', 'nvc', 'pgcc', 'icc', 'icx']
61
+ defaults['cpp'] = ['c++', 'g++', 'clang++', 'nvc++', 'pgc++', 'icpc', 'icpx']
62
+ defaults['objc'] = ['cc', 'gcc', 'clang']
63
+ defaults['objcpp'] = ['c++', 'g++', 'clang++']
64
+ defaults['fortran'] = ['gfortran', 'flang', 'nvfortran', 'pgfortran', 'ifort', 'ifx', 'g95']
65
+ defaults['cs'] = ['mcs', 'csc']
66
+ defaults['d'] = ['ldc2', 'ldc', 'gdc', 'dmd']
67
+ defaults['java'] = ['javac']
68
+ defaults['cuda'] = ['nvcc']
69
+ defaults['rust'] = ['rustc']
70
+ defaults['swift'] = ['swiftc']
71
+ defaults['vala'] = ['valac']
72
+ defaults['cython'] = ['cython', 'cython3'] # Official name is cython, but Debian renamed it to cython3.
73
+ defaults['static_linker'] = ['ar', 'gar']
74
+ defaults['strip'] = ['strip']
75
+ defaults['vs_static_linker'] = ['lib']
76
+ defaults['clang_cl_static_linker'] = ['llvm-lib']
77
+ defaults['cuda_static_linker'] = ['nvlink']
78
+ defaults['gcc_static_linker'] = ['gcc-ar']
79
+ defaults['clang_static_linker'] = ['llvm-ar']
80
+ defaults['nasm'] = ['nasm', 'yasm']
81
+
82
+
83
+ def compiler_from_language(env: 'Environment', lang: str, for_machine: MachineChoice) -> T.Optional[Compiler]:
84
+ lang_map: T.Dict[str, T.Callable[['Environment', MachineChoice], Compiler]] = {
85
+ 'c': detect_c_compiler,
86
+ 'cpp': detect_cpp_compiler,
87
+ 'objc': detect_objc_compiler,
88
+ 'cuda': detect_cuda_compiler,
89
+ 'objcpp': detect_objcpp_compiler,
90
+ 'java': detect_java_compiler,
91
+ 'cs': detect_cs_compiler,
92
+ 'vala': detect_vala_compiler,
93
+ 'd': detect_d_compiler,
94
+ 'rust': detect_rust_compiler,
95
+ 'fortran': detect_fortran_compiler,
96
+ 'swift': detect_swift_compiler,
97
+ 'cython': detect_cython_compiler,
98
+ 'nasm': detect_nasm_compiler,
99
+ 'masm': detect_masm_compiler,
100
+ }
101
+ return lang_map[lang](env, for_machine) if lang in lang_map else None
102
+
103
+ def detect_compiler_for(env: 'Environment', lang: str, for_machine: MachineChoice, skip_sanity_check: bool, subproject: str) -> T.Optional[Compiler]:
104
+ comp = compiler_from_language(env, lang, for_machine)
105
+ if comp is None:
106
+ return comp
107
+ assert comp.for_machine == for_machine
108
+ env.coredata.process_compiler_options(lang, comp, env, subproject)
109
+ if not skip_sanity_check:
110
+ comp.sanity_check(env.get_scratch_dir(), env)
111
+ env.coredata.compilers[comp.for_machine][lang] = comp
112
+ return comp
113
+
114
+
115
+ # Helpers
116
+ # =======
117
+
118
+ def _get_compilers(env: 'Environment', lang: str, for_machine: MachineChoice) -> T.Tuple[T.List[T.List[str]], T.List[str]]:
119
+ '''
120
+ The list of compilers is detected in the exact same way for
121
+ C, C++, ObjC, ObjC++, Fortran, CS so consolidate it here.
122
+ '''
123
+ value = env.lookup_binary_entry(for_machine, lang)
124
+ if value is not None:
125
+ comp, ccache = BinaryTable.parse_entry(value)
126
+ # Return value has to be a list of compiler 'choices'
127
+ compilers = [comp]
128
+ else:
129
+ if not env.machines.matches_build_machine(for_machine):
130
+ raise EnvironmentException(f'{lang!r} compiler binary not defined in cross or native file')
131
+ compilers = [[x] for x in defaults[lang]]
132
+ ccache = BinaryTable.detect_compiler_cache()
133
+
134
+ return compilers, ccache
135
+
136
+ def _handle_exceptions(
137
+ exceptions: T.Mapping[str, T.Union[Exception, str]],
138
+ binaries: T.List[T.List[str]],
139
+ bintype: str = 'compiler') -> T.NoReturn:
140
+ errmsg = f'Unknown {bintype}(s): {binaries}'
141
+ if exceptions:
142
+ errmsg += '\nThe following exception(s) were encountered:'
143
+ for c, e in exceptions.items():
144
+ errmsg += f'\nRunning `{c}` gave "{e}"'
145
+ raise EnvironmentException(errmsg)
146
+
147
+
148
+ # Linker specific
149
+ # ===============
150
+
151
+ def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker:
152
+ from . import d
153
+ from ..linkers import linkers
154
+ linker = env.lookup_binary_entry(compiler.for_machine, 'ar')
155
+ if linker is not None:
156
+ trials = [linker]
157
+ else:
158
+ default_linkers = [[l] for l in defaults['static_linker']]
159
+ if compiler.language == 'cuda':
160
+ trials = [defaults['cuda_static_linker']] + default_linkers
161
+ elif compiler.get_argument_syntax() == 'msvc':
162
+ trials = [defaults['vs_static_linker'], defaults['clang_cl_static_linker']]
163
+ elif compiler.id == 'gcc':
164
+ # Use gcc-ar if available; needed for LTO
165
+ trials = [defaults['gcc_static_linker']] + default_linkers
166
+ elif compiler.id == 'clang':
167
+ # Use llvm-ar if available; needed for LTO
168
+ llvm_ar = defaults['clang_static_linker']
169
+ # Extract the version major of the compiler to use as a suffix
170
+ suffix = compiler.version.split('.')[0]
171
+ # Prefer suffixed llvm-ar first, then unsuffixed then the defaults
172
+ trials = [[f'{llvm_ar[0]}-{suffix}'], llvm_ar] + default_linkers
173
+ elif compiler.language == 'd':
174
+ # Prefer static linkers over linkers used by D compilers
175
+ if is_windows():
176
+ trials = [defaults['vs_static_linker'], defaults['clang_cl_static_linker'], compiler.get_linker_exelist()]
177
+ else:
178
+ trials = default_linkers
179
+ elif compiler.id == 'intel-cl' and compiler.language == 'c': # why not cpp? Is this a bug?
180
+ # Intel has it's own linker that acts like microsoft's lib
181
+ trials = [['xilib']]
182
+ elif is_windows() and compiler.id == 'pgi': # this handles cpp / nvidia HPC, in addition to just c/fortran
183
+ trials = [['ar']] # For PGI on Windows, "ar" is just a wrapper calling link/lib.
184
+ elif is_windows() and compiler.id == 'nasm':
185
+ # This may well be LINK.EXE if it's under a MSVC environment
186
+ trials = [defaults['vs_static_linker'], defaults['clang_cl_static_linker']] + default_linkers
187
+ else:
188
+ trials = default_linkers
189
+ popen_exceptions = {}
190
+ for linker in trials:
191
+ linker_name = os.path.basename(linker[0])
192
+
193
+ if any(os.path.basename(x) in {'lib', 'lib.exe', 'llvm-lib', 'llvm-lib.exe', 'xilib', 'xilib.exe'} for x in linker):
194
+ arg = '/?'
195
+ elif linker_name in {'ar2000', 'ar2000.exe', 'ar430', 'ar430.exe', 'armar', 'armar.exe', 'ar6x', 'ar6x.exe'}:
196
+ arg = '?'
197
+ else:
198
+ arg = '--version'
199
+ try:
200
+ p, out, err = Popen_safe_logged(linker + [arg], msg='Detecting archiver via')
201
+ except OSError as e:
202
+ popen_exceptions[join_args(linker + [arg])] = e
203
+ continue
204
+ if "xilib: executing 'lib'" in err:
205
+ return linkers.IntelVisualStudioLinker(linker, getattr(compiler, 'machine', None))
206
+ if '/OUT:' in out.upper() or '/OUT:' in err.upper():
207
+ return linkers.VisualStudioLinker(linker, getattr(compiler, 'machine', None))
208
+ if 'ar-Error-Unknown switch: --version' in err:
209
+ return linkers.PGIStaticLinker(linker)
210
+ if p.returncode == 0 and 'armar' in linker_name:
211
+ return linkers.ArmarLinker(linker)
212
+ if 'DMD32 D Compiler' in out or 'DMD64 D Compiler' in out:
213
+ assert isinstance(compiler, d.DCompiler)
214
+ return linkers.DLinker(linker, compiler.arch)
215
+ if 'LDC - the LLVM D compiler' in out:
216
+ assert isinstance(compiler, d.DCompiler)
217
+ return linkers.DLinker(linker, compiler.arch, rsp_syntax=compiler.rsp_file_syntax())
218
+ if 'GDC' in out and ' based on D ' in out:
219
+ assert isinstance(compiler, d.DCompiler)
220
+ return linkers.DLinker(linker, compiler.arch)
221
+ if err.startswith('Renesas') and 'rlink' in linker_name:
222
+ return linkers.CcrxLinker(linker)
223
+ if out.startswith('GNU ar') and 'xc16-ar' in linker_name:
224
+ return linkers.Xc16Linker(linker)
225
+ if "--> error: bad option 'e'" in err: # TI
226
+ if 'ar2000' in linker_name:
227
+ return linkers.C2000Linker(linker)
228
+ else:
229
+ return linkers.TILinker(linker)
230
+ if 'Texas Instruments Incorporated' in out:
231
+ if 'ar6000' in linker_name:
232
+ return linkers.C6000Linker(linker)
233
+ if out.startswith('The CompCert'):
234
+ return linkers.CompCertLinker(linker)
235
+ if out.strip().startswith('Metrowerks') or out.strip().startswith('Freescale'):
236
+ if 'ARM' in out:
237
+ return linkers.MetrowerksStaticLinkerARM(linker)
238
+ else:
239
+ return linkers.MetrowerksStaticLinkerEmbeddedPowerPC(linker)
240
+ if p.returncode == 0:
241
+ return linkers.ArLinker(compiler.for_machine, linker)
242
+ if p.returncode == 1 and err.startswith('usage'): # OSX
243
+ return linkers.AppleArLinker(compiler.for_machine, linker)
244
+ if p.returncode == 1 and err.startswith('Usage'): # AIX
245
+ return linkers.AIXArLinker(linker)
246
+ if p.returncode == 1 and err.startswith('ar: bad option: --'): # Solaris
247
+ return linkers.ArLinker(compiler.for_machine, linker)
248
+ _handle_exceptions(popen_exceptions, trials, 'linker')
249
+ raise EnvironmentException('Unreachable code (exception to make mypy happy)')
250
+
251
+
252
+ # Compilers
253
+ # =========
254
+
255
+
256
+ def _detect_c_or_cpp_compiler(env: 'Environment', lang: str, for_machine: MachineChoice, *, override_compiler: T.Optional[T.List[str]] = None) -> Compiler:
257
+ """Shared implementation for finding the C or C++ compiler to use.
258
+
259
+ the override_compiler option is provided to allow compilers which use
260
+ the compiler (GCC or Clang usually) as their shared linker, to find
261
+ the linker they need.
262
+ """
263
+ from . import c, cpp
264
+ from ..linkers import linkers
265
+ popen_exceptions: T.Dict[str, T.Union[Exception, str]] = {}
266
+ compilers, ccache = _get_compilers(env, lang, for_machine)
267
+ if override_compiler is not None:
268
+ compilers = [override_compiler]
269
+ is_cross = env.is_cross_build(for_machine)
270
+ info = env.machines[for_machine]
271
+ cls: T.Union[T.Type[CCompiler], T.Type[CPPCompiler]]
272
+ lnk: T.Union[T.Type[StaticLinker], T.Type[DynamicLinker]]
273
+
274
+ for compiler in compilers:
275
+ if isinstance(compiler, str):
276
+ compiler = [compiler]
277
+ compiler_name = os.path.basename(compiler[0])
278
+
279
+ if any(os.path.basename(x) in {'cl', 'cl.exe', 'clang-cl', 'clang-cl.exe'} for x in compiler):
280
+ # Watcom C provides it's own cl.exe clone that mimics an older
281
+ # version of Microsoft's compiler. Since Watcom's cl.exe is
282
+ # just a wrapper, we skip using it if we detect its presence
283
+ # so as not to confuse Meson when configuring for MSVC.
284
+ #
285
+ # Additionally the help text of Watcom's cl.exe is paged, and
286
+ # the binary will not exit without human intervention. In
287
+ # practice, Meson will block waiting for Watcom's cl.exe to
288
+ # exit, which requires user input and thus will never exit.
289
+ if 'WATCOM' in os.environ:
290
+ def sanitize(p: str) -> str:
291
+ return os.path.normcase(os.path.abspath(p))
292
+
293
+ watcom_cls = [sanitize(os.path.join(os.environ['WATCOM'], 'BINNT', 'cl')),
294
+ sanitize(os.path.join(os.environ['WATCOM'], 'BINNT', 'cl.exe')),
295
+ sanitize(os.path.join(os.environ['WATCOM'], 'BINNT64', 'cl')),
296
+ sanitize(os.path.join(os.environ['WATCOM'], 'BINNT64', 'cl.exe'))]
297
+ found_cl = sanitize(shutil.which('cl'))
298
+ if found_cl in watcom_cls:
299
+ mlog.debug('Skipping unsupported cl.exe clone at:', found_cl)
300
+ continue
301
+ arg = '/?'
302
+ elif 'armcc' in compiler_name:
303
+ arg = '--vsn'
304
+ elif 'ccrx' in compiler_name:
305
+ arg = '-v'
306
+ elif 'xc16' in compiler_name:
307
+ arg = '--version'
308
+ elif 'ccomp' in compiler_name:
309
+ arg = '-version'
310
+ elif compiler_name in {'cl2000', 'cl2000.exe', 'cl430', 'cl430.exe', 'armcl', 'armcl.exe', 'cl6x', 'cl6x.exe'}:
311
+ # TI compiler
312
+ arg = '-version'
313
+ elif compiler_name in {'icl', 'icl.exe'}:
314
+ # if you pass anything to icl you get stuck in a pager
315
+ arg = ''
316
+ else:
317
+ arg = '--version'
318
+
319
+ cmd = compiler + [arg]
320
+ try:
321
+ p, out, err = Popen_safe_logged(cmd, msg='Detecting compiler via')
322
+ except OSError as e:
323
+ popen_exceptions[join_args(cmd)] = e
324
+ continue
325
+
326
+ if 'ccrx' in compiler_name:
327
+ out = err
328
+
329
+ full_version = out.split('\n', 1)[0]
330
+ version = search_version(out)
331
+
332
+ guess_gcc_or_lcc: T.Optional[str] = None
333
+ if 'Free Software Foundation' in out or out.startswith('xt-'):
334
+ guess_gcc_or_lcc = 'gcc'
335
+ if 'e2k' in out and 'lcc' in out:
336
+ guess_gcc_or_lcc = 'lcc'
337
+ if 'Microchip Technology' in out:
338
+ # this output has "Free Software Foundation" in its version
339
+ guess_gcc_or_lcc = None
340
+
341
+ if guess_gcc_or_lcc:
342
+ defines = _get_gnu_compiler_defines(compiler)
343
+ if not defines:
344
+ popen_exceptions[join_args(compiler)] = 'no pre-processor defines'
345
+ continue
346
+
347
+ if guess_gcc_or_lcc == 'lcc':
348
+ version = _get_lcc_version_from_defines(defines)
349
+ cls = c.ElbrusCCompiler if lang == 'c' else cpp.ElbrusCPPCompiler
350
+ else:
351
+ version = _get_gnu_version_from_defines(defines)
352
+ cls = c.GnuCCompiler if lang == 'c' else cpp.GnuCPPCompiler
353
+
354
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
355
+
356
+ return cls(
357
+ ccache, compiler, version, for_machine, is_cross,
358
+ info, defines=defines, full_version=full_version,
359
+ linker=linker)
360
+
361
+ if 'Emscripten' in out:
362
+ cls = c.EmscriptenCCompiler if lang == 'c' else cpp.EmscriptenCPPCompiler
363
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
364
+
365
+ # emcc requires a file input in order to pass arguments to the
366
+ # linker. It'll exit with an error code, but still print the
367
+ # linker version.
368
+ with tempfile.NamedTemporaryFile(suffix='.c') as f:
369
+ cmd = compiler + [cls.LINKER_PREFIX + "--version", f.name]
370
+ _, o, _ = Popen_safe(cmd)
371
+
372
+ linker = linkers.WASMDynamicLinker(
373
+ compiler, for_machine, cls.LINKER_PREFIX,
374
+ [], version=search_version(o))
375
+ return cls(
376
+ ccache, compiler, version, for_machine, is_cross, info,
377
+ linker=linker, full_version=full_version)
378
+
379
+ if 'Arm C/C++/Fortran Compiler' in out:
380
+ arm_ver_match = re.search(r'version (\d+)\.(\d+)\.?(\d+)? \(build number (\d+)\)', out)
381
+ assert arm_ver_match is not None, 'for mypy' # because mypy *should* be complaining that this could be None
382
+ version = '.'.join([x for x in arm_ver_match.groups() if x is not None])
383
+ if lang == 'c':
384
+ cls = c.ArmLtdClangCCompiler
385
+ elif lang == 'cpp':
386
+ cls = cpp.ArmLtdClangCPPCompiler
387
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
388
+ return cls(
389
+ ccache, compiler, version, for_machine, is_cross, info,
390
+ linker=linker)
391
+ if 'armclang' in out:
392
+ # The compiler version is not present in the first line of output,
393
+ # instead it is present in second line, startswith 'Component:'.
394
+ # So, searching for the 'Component' in out although we know it is
395
+ # present in second line, as we are not sure about the
396
+ # output format in future versions
397
+ arm_ver_match = re.search('.*Component.*', out)
398
+ if arm_ver_match is None:
399
+ popen_exceptions[join_args(compiler)] = 'version string not found'
400
+ continue
401
+ arm_ver_str = arm_ver_match.group(0)
402
+ # Override previous values
403
+ version = search_version(arm_ver_str)
404
+ full_version = arm_ver_str
405
+ cls = c.ArmclangCCompiler if lang == 'c' else cpp.ArmclangCPPCompiler
406
+ linker = linkers.ArmClangDynamicLinker(for_machine, version=version)
407
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
408
+ return cls(
409
+ ccache, compiler, version, for_machine, is_cross, info,
410
+ full_version=full_version, linker=linker)
411
+ if 'CL.EXE COMPATIBILITY' in out:
412
+ # if this is clang-cl masquerading as cl, detect it as cl, not
413
+ # clang
414
+ arg = '--version'
415
+ try:
416
+ p, out, err = Popen_safe(compiler + [arg])
417
+ except OSError as e:
418
+ popen_exceptions[join_args(compiler + [arg])] = e
419
+ version = search_version(out)
420
+ match = re.search('^Target: (.*?)-', out, re.MULTILINE)
421
+ if match:
422
+ target = match.group(1)
423
+ else:
424
+ target = 'unknown target'
425
+ cls = c.ClangClCCompiler if lang == 'c' else cpp.ClangClCPPCompiler
426
+ linker = guess_win_linker(env, ['lld-link'], cls, version, for_machine)
427
+ return cls(
428
+ compiler, version, for_machine, is_cross, info, target,
429
+ linker=linker)
430
+
431
+ # must be detected here before clang because TI compilers contain 'clang' in their output and so that they can be detected as 'clang'
432
+ ti_compilers = {
433
+ 'TMS320C2000 C/C++': (c.C2000CCompiler, cpp.C2000CPPCompiler, linkers.C2000DynamicLinker),
434
+ 'TMS320C6x C/C++': (c.C6000CCompiler, cpp.C6000CPPCompiler, linkers.C6000DynamicLinker),
435
+ 'TI ARM C/C++ Compiler': (c.TICCompiler, cpp.TICPPCompiler, linkers.TIDynamicLinker),
436
+ 'MSP430 C/C++': (c.TICCompiler, cpp.TICPPCompiler, linkers.TIDynamicLinker)
437
+ }
438
+ for indentifier, compiler_classes in ti_compilers.items():
439
+ if indentifier in out:
440
+ cls = compiler_classes[0] if lang == 'c' else compiler_classes[1]
441
+ lnk = compiler_classes[2]
442
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
443
+ linker = lnk(compiler, for_machine, version=version)
444
+ return cls(
445
+ ccache, compiler, version, for_machine, is_cross, info,
446
+ full_version=full_version, linker=linker)
447
+
448
+ if 'clang' in out or 'Clang' in out:
449
+ linker = None
450
+
451
+ defines = _get_clang_compiler_defines(compiler)
452
+
453
+ # Even if the for_machine is darwin, we could be using vanilla
454
+ # clang.
455
+ if 'Apple' in out:
456
+ cls = c.AppleClangCCompiler if lang == 'c' else cpp.AppleClangCPPCompiler
457
+ else:
458
+ cls = c.ClangCCompiler if lang == 'c' else cpp.ClangCPPCompiler
459
+
460
+ if 'windows' in out or env.machines[for_machine].is_windows():
461
+ # If we're in a MINGW context this actually will use a gnu
462
+ # style ld, but for clang on "real" windows we'll use
463
+ # either link.exe or lld-link.exe
464
+ try:
465
+ linker = guess_win_linker(env, compiler, cls, version, for_machine, invoked_directly=False)
466
+ except MesonException:
467
+ pass
468
+ if linker is None:
469
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
470
+
471
+ return cls(
472
+ ccache, compiler, version, for_machine, is_cross, info,
473
+ defines=defines, full_version=full_version, linker=linker)
474
+
475
+ if 'Intel(R) C++ Intel(R)' in err:
476
+ version = search_version(err)
477
+ target = 'x86' if 'IA-32' in err else 'x86_64'
478
+ cls = c.IntelClCCompiler if lang == 'c' else cpp.IntelClCPPCompiler
479
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
480
+ linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
481
+ return cls(
482
+ compiler, version, for_machine, is_cross, info, target,
483
+ linker=linker)
484
+ if 'Intel(R) oneAPI DPC++/C++ Compiler for applications' in err:
485
+ version = search_version(err)
486
+ target = 'x86' if 'IA-32' in err else 'x86_64'
487
+ cls = c.IntelLLVMClCCompiler if lang == 'c' else cpp.IntelLLVMClCPPCompiler
488
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
489
+ linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
490
+ return cls(
491
+ compiler, version, for_machine, is_cross, info, target,
492
+ linker=linker)
493
+ if 'Microsoft' in out or 'Microsoft' in err:
494
+ # Latest versions of Visual Studio print version
495
+ # number to stderr but earlier ones print version
496
+ # on stdout. Why? Lord only knows.
497
+ # Check both outputs to figure out version.
498
+ for lookat in [err, out]:
499
+ version = search_version(lookat)
500
+ if version != 'unknown version':
501
+ break
502
+ else:
503
+ raise EnvironmentException(f'Failed to detect MSVC compiler version: stderr was\n{err!r}')
504
+ cl_signature = lookat.split('\n', maxsplit=1)[0]
505
+ match = re.search(r'.*(x86|x64|ARM|ARM64)([^_A-Za-z0-9]|$)', cl_signature)
506
+ if match:
507
+ target = match.group(1)
508
+ else:
509
+ m = f'Failed to detect MSVC compiler target architecture: \'cl /?\' output is\n{cl_signature}'
510
+ raise EnvironmentException(m)
511
+ cls = c.VisualStudioCCompiler if lang == 'c' else cpp.VisualStudioCPPCompiler
512
+ linker = guess_win_linker(env, ['link'], cls, version, for_machine)
513
+ # As of this writing, CCache does not support MSVC but sccache does.
514
+ if 'sccache' not in ccache:
515
+ ccache = []
516
+ return cls(
517
+ ccache, compiler, version, for_machine, is_cross, info, target,
518
+ full_version=cl_signature, linker=linker)
519
+ if 'PGI Compilers' in out:
520
+ cls = c.PGICCompiler if lang == 'c' else cpp.PGICPPCompiler
521
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
522
+ linker = linkers.PGIDynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version)
523
+ return cls(
524
+ ccache, compiler, version, for_machine, is_cross,
525
+ info, linker=linker)
526
+ if 'NVIDIA Compilers and Tools' in out:
527
+ cls = c.NvidiaHPC_CCompiler if lang == 'c' else cpp.NvidiaHPC_CPPCompiler
528
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
529
+ linker = linkers.NvidiaHPC_DynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version)
530
+ return cls(
531
+ ccache, compiler, version, for_machine, is_cross,
532
+ info, linker=linker)
533
+ if '(ICC)' in out:
534
+ cls = c.IntelCCompiler if lang == 'c' else cpp.IntelCPPCompiler
535
+ l = guess_nix_linker(env, compiler, cls, version, for_machine)
536
+ return cls(
537
+ ccache, compiler, version, for_machine, is_cross, info,
538
+ full_version=full_version, linker=l)
539
+ if 'Intel(R) oneAPI' in out:
540
+ cls = c.IntelLLVMCCompiler if lang == 'c' else cpp.IntelLLVMCPPCompiler
541
+ l = guess_nix_linker(env, compiler, cls, version, for_machine)
542
+ return cls(
543
+ ccache, compiler, version, for_machine, is_cross, info,
544
+ full_version=full_version, linker=l)
545
+ if 'ARM' in out and not ('Metrowerks' in out or 'Freescale' in out):
546
+ cls = c.ArmCCompiler if lang == 'c' else cpp.ArmCPPCompiler
547
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
548
+ linker = linkers.ArmDynamicLinker(for_machine, version=version)
549
+ return cls(
550
+ ccache, compiler, version, for_machine, is_cross,
551
+ info, full_version=full_version, linker=linker)
552
+ if 'RX Family' in out:
553
+ cls = c.CcrxCCompiler if lang == 'c' else cpp.CcrxCPPCompiler
554
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
555
+ linker = linkers.CcrxDynamicLinker(for_machine, version=version)
556
+ return cls(
557
+ ccache, compiler, version, for_machine, is_cross, info,
558
+ full_version=full_version, linker=linker)
559
+
560
+ if 'Microchip Technology' in out:
561
+ cls = c.Xc16CCompiler
562
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
563
+ linker = linkers.Xc16DynamicLinker(for_machine, version=version)
564
+ return cls(
565
+ ccache, compiler, version, for_machine, is_cross, info,
566
+ full_version=full_version, linker=linker)
567
+
568
+ if 'CompCert' in out:
569
+ cls = c.CompCertCCompiler
570
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
571
+ linker = linkers.CompCertDynamicLinker(for_machine, version=version)
572
+ return cls(
573
+ ccache, compiler, version, for_machine, is_cross, info,
574
+ full_version=full_version, linker=linker)
575
+
576
+ if 'Metrowerks C/C++' in out or 'Freescale C/C++' in out:
577
+ if 'ARM' in out:
578
+ cls = c.MetrowerksCCompilerARM if lang == 'c' else cpp.MetrowerksCPPCompilerARM
579
+ lnk = linkers.MetrowerksLinkerARM
580
+ else:
581
+ cls = c.MetrowerksCCompilerEmbeddedPowerPC if lang == 'c' else cpp.MetrowerksCPPCompilerEmbeddedPowerPC
582
+ lnk = linkers.MetrowerksLinkerEmbeddedPowerPC
583
+
584
+ mwcc_ver_match = re.search(r'Version (\d+)\.(\d+)\.?(\d+)? build (\d+)', out)
585
+ assert mwcc_ver_match is not None, 'for mypy' # because mypy *should* be complaning that this could be None
586
+ compiler_version = '.'.join(x for x in mwcc_ver_match.groups() if x is not None)
587
+
588
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
589
+ ld = env.lookup_binary_entry(for_machine, cls.language + '_ld')
590
+
591
+ if ld is not None:
592
+ _, o_ld, _ = Popen_safe(ld + ['--version'])
593
+
594
+ mwld_ver_match = re.search(r'Version (\d+)\.(\d+)\.?(\d+)? build (\d+)', o_ld)
595
+ assert mwld_ver_match is not None, 'for mypy' # because mypy *should* be complaning that this could be None
596
+ linker_version = '.'.join(x for x in mwld_ver_match.groups() if x is not None)
597
+
598
+ linker = lnk(ld, for_machine, version=linker_version)
599
+ else:
600
+ raise EnvironmentException(f'Failed to detect linker for {cls.id!r} compiler. Please update your cross file(s).')
601
+
602
+ return cls(
603
+ ccache, compiler, compiler_version, for_machine, is_cross, info,
604
+ full_version=full_version, linker=linker)
605
+
606
+ _handle_exceptions(popen_exceptions, compilers)
607
+ raise EnvironmentException(f'Unknown compiler {compilers}')
608
+
609
+ def detect_c_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
610
+ return _detect_c_or_cpp_compiler(env, 'c', for_machine)
611
+
612
+ def detect_cpp_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
613
+ return _detect_c_or_cpp_compiler(env, 'cpp', for_machine)
614
+
615
+ def detect_cuda_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
616
+ from .cuda import CudaCompiler
617
+ from ..linkers.linkers import CudaLinker
618
+ popen_exceptions = {}
619
+ is_cross = env.is_cross_build(for_machine)
620
+ compilers, ccache = _get_compilers(env, 'cuda', for_machine)
621
+ info = env.machines[for_machine]
622
+ for compiler in compilers:
623
+ arg = '--version'
624
+ try:
625
+ p, out, err = Popen_safe_logged(compiler + [arg], msg='Detecting compiler via')
626
+ except OSError as e:
627
+ popen_exceptions[join_args(compiler + [arg])] = e
628
+ continue
629
+ # Example nvcc printout:
630
+ #
631
+ # nvcc: NVIDIA (R) Cuda compiler driver
632
+ # Copyright (c) 2005-2018 NVIDIA Corporation
633
+ # Built on Sat_Aug_25_21:08:01_CDT_2018
634
+ # Cuda compilation tools, release 10.0, V10.0.130
635
+ #
636
+ # search_version() first finds the "10.0" after "release",
637
+ # rather than the more precise "10.0.130" after "V".
638
+ # The patch version number is occasionally important; For
639
+ # instance, on Linux,
640
+ # - CUDA Toolkit 8.0.44 requires NVIDIA Driver 367.48
641
+ # - CUDA Toolkit 8.0.61 requires NVIDIA Driver 375.26
642
+ # Luckily, the "V" also makes it very simple to extract
643
+ # the full version:
644
+ version = out.strip().rsplit('V', maxsplit=1)[-1]
645
+ cpp_compiler = detect_cpp_compiler(env, for_machine)
646
+ cls = CudaCompiler
647
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
648
+ linker = CudaLinker(compiler, for_machine, CudaCompiler.LINKER_PREFIX, [], version=CudaLinker.parse_version())
649
+ return cls(ccache, compiler, version, for_machine, is_cross, host_compiler=cpp_compiler, info=info, linker=linker)
650
+ raise EnvironmentException(f'Could not find suitable CUDA compiler: "{"; ".join([" ".join(c) for c in compilers])}"')
651
+
652
+ def detect_fortran_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
653
+ from . import fortran
654
+ from ..linkers import linkers
655
+ popen_exceptions: T.Dict[str, T.Union[Exception, str]] = {}
656
+ compilers, ccache = _get_compilers(env, 'fortran', for_machine)
657
+ is_cross = env.is_cross_build(for_machine)
658
+ info = env.machines[for_machine]
659
+ cls: T.Type[FortranCompiler]
660
+ for compiler in compilers:
661
+ for arg in ['--version', '-V']:
662
+ try:
663
+ p, out, err = Popen_safe_logged(compiler + [arg], msg='Detecting compiler via')
664
+ except OSError as e:
665
+ popen_exceptions[join_args(compiler + [arg])] = e
666
+ continue
667
+
668
+ version = search_version(out)
669
+ full_version = out.split('\n', 1)[0]
670
+
671
+ guess_gcc_or_lcc: T.Optional[str] = None
672
+ if 'GNU Fortran' in out:
673
+ guess_gcc_or_lcc = 'gcc'
674
+ if 'e2k' in out and 'lcc' in out:
675
+ guess_gcc_or_lcc = 'lcc'
676
+
677
+ if guess_gcc_or_lcc:
678
+ defines = _get_gnu_compiler_defines(compiler)
679
+ if not defines:
680
+ popen_exceptions[join_args(compiler)] = 'no pre-processor defines'
681
+ continue
682
+ if guess_gcc_or_lcc == 'lcc':
683
+ version = _get_lcc_version_from_defines(defines)
684
+ cls = fortran.ElbrusFortranCompiler
685
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
686
+ return cls(
687
+ compiler, version, for_machine, is_cross, info,
688
+ defines, full_version=full_version, linker=linker)
689
+ else:
690
+ version = _get_gnu_version_from_defines(defines)
691
+ cls = fortran.GnuFortranCompiler
692
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
693
+ return cls(
694
+ compiler, version, for_machine, is_cross, info,
695
+ defines, full_version=full_version, linker=linker)
696
+
697
+ if 'Arm C/C++/Fortran Compiler' in out:
698
+ cls = fortran.ArmLtdFlangFortranCompiler
699
+ arm_ver_match = re.search(r'version (\d+)\.(\d+)\.?(\d+)? \(build number (\d+)\)', out)
700
+ assert arm_ver_match is not None, 'for mypy' # because mypy *should* be complaining that this could be None
701
+ version = '.'.join([x for x in arm_ver_match.groups() if x is not None])
702
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
703
+ return cls(
704
+ compiler, version, for_machine, is_cross, info,
705
+ linker=linker)
706
+ if 'G95' in out:
707
+ cls = fortran.G95FortranCompiler
708
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
709
+ return cls(
710
+ compiler, version, for_machine, is_cross, info,
711
+ full_version=full_version, linker=linker)
712
+
713
+ if 'Sun Fortran' in err:
714
+ version = search_version(err)
715
+ cls = fortran.SunFortranCompiler
716
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
717
+ return cls(
718
+ compiler, version, for_machine, is_cross, info,
719
+ full_version=full_version, linker=linker)
720
+
721
+ if 'Intel(R) Fortran Compiler for applications' in err:
722
+ version = search_version(err)
723
+ target = 'x86' if 'IA-32' in err else 'x86_64'
724
+ cls = fortran.IntelLLVMClFortranCompiler
725
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
726
+ linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
727
+ return cls(
728
+ compiler, version, for_machine, is_cross, info,
729
+ target, linker=linker)
730
+
731
+ if 'Intel(R) Visual Fortran' in err or 'Intel(R) Fortran' in err:
732
+ version = search_version(err)
733
+ target = 'x86' if 'IA-32' in err else 'x86_64'
734
+ cls = fortran.IntelClFortranCompiler
735
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
736
+ linker = linkers.XilinkDynamicLinker(for_machine, [], version=version)
737
+ return cls(
738
+ compiler, version, for_machine, is_cross, info,
739
+ target, linker=linker)
740
+
741
+ if 'ifort (IFORT)' in out:
742
+ cls = fortran.IntelFortranCompiler
743
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
744
+ return cls(
745
+ compiler, version, for_machine, is_cross, info,
746
+ full_version=full_version, linker=linker)
747
+
748
+ if 'ifx (IFORT)' in out or 'ifx (IFX)' in out:
749
+ cls = fortran.IntelLLVMFortranCompiler
750
+ linker = guess_nix_linker(env, compiler, cls, version, for_machine)
751
+ return cls(
752
+ compiler, version, for_machine, is_cross, info,
753
+ full_version=full_version, linker=linker)
754
+
755
+ if 'PathScale EKOPath(tm)' in err:
756
+ return fortran.PathScaleFortranCompiler(
757
+ compiler, version, for_machine, is_cross, info,
758
+ full_version=full_version)
759
+
760
+ if 'PGI Compilers' in out:
761
+ cls = fortran.PGIFortranCompiler
762
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
763
+ linker = linkers.PGIDynamicLinker(compiler, for_machine,
764
+ cls.LINKER_PREFIX, [], version=version)
765
+ return cls(
766
+ compiler, version, for_machine, is_cross, info,
767
+ full_version=full_version, linker=linker)
768
+
769
+ if 'NVIDIA Compilers and Tools' in out:
770
+ cls = fortran.NvidiaHPC_FortranCompiler
771
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
772
+ linker = linkers.PGIDynamicLinker(compiler, for_machine,
773
+ cls.LINKER_PREFIX, [], version=version)
774
+ return cls(
775
+ compiler, version, for_machine, is_cross, info,
776
+ full_version=full_version, linker=linker)
777
+
778
+ if 'flang' in out or 'clang' in out:
779
+ cls = fortran.FlangFortranCompiler
780
+ linker = None
781
+ if 'windows' in out or env.machines[for_machine].is_windows():
782
+ # If we're in a MINGW context this actually will use a gnu
783
+ # style ld, but for flang on "real" windows we'll use
784
+ # either link.exe or lld-link.exe
785
+ try:
786
+ linker = guess_win_linker(
787
+ env, compiler, cls, version,
788
+ for_machine, invoked_directly=False
789
+ )
790
+ except MesonException:
791
+ pass
792
+ if linker is None:
793
+ linker = guess_nix_linker(env, compiler, cls,
794
+ version, for_machine)
795
+ return cls(
796
+ compiler, version, for_machine, is_cross, info,
797
+ full_version=full_version, linker=linker)
798
+
799
+ if 'Open64 Compiler Suite' in err:
800
+ cls = fortran.Open64FortranCompiler
801
+ linker = guess_nix_linker(env,
802
+ compiler, cls, version, for_machine)
803
+ return cls(
804
+ compiler, version, for_machine, is_cross, info,
805
+ full_version=full_version, linker=linker)
806
+
807
+ if 'NAG Fortran' in err:
808
+ full_version = err.split('\n', 1)[0]
809
+ version = full_version.split()[-1]
810
+ cls = fortran.NAGFortranCompiler
811
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
812
+ linker = linkers.NAGDynamicLinker(
813
+ compiler, for_machine, cls.LINKER_PREFIX, [],
814
+ version=version)
815
+ return cls(
816
+ compiler, version, for_machine, is_cross, info,
817
+ full_version=full_version, linker=linker)
818
+
819
+ _handle_exceptions(popen_exceptions, compilers)
820
+ raise EnvironmentException('Unreachable code (exception to make mypy happy)')
821
+
822
+ def detect_objc_compiler(env: 'Environment', for_machine: MachineChoice) -> 'Compiler':
823
+ return _detect_objc_or_objcpp_compiler(env, 'objc', for_machine)
824
+
825
+ def detect_objcpp_compiler(env: 'Environment', for_machine: MachineChoice) -> 'Compiler':
826
+ return _detect_objc_or_objcpp_compiler(env, 'objcpp', for_machine)
827
+
828
+ def _detect_objc_or_objcpp_compiler(env: 'Environment', lang: str, for_machine: MachineChoice) -> 'Compiler':
829
+ from . import objc, objcpp
830
+ popen_exceptions: T.Dict[str, T.Union[Exception, str]] = {}
831
+ compilers, ccache = _get_compilers(env, lang, for_machine)
832
+ is_cross = env.is_cross_build(for_machine)
833
+ info = env.machines[for_machine]
834
+ comp: T.Union[T.Type[objc.ObjCCompiler], T.Type[objcpp.ObjCPPCompiler]]
835
+
836
+ for compiler in compilers:
837
+ arg = ['--version']
838
+ try:
839
+ p, out, err = Popen_safe_logged(compiler + arg, msg='Detecting compiler via')
840
+ except OSError as e:
841
+ popen_exceptions[join_args(compiler + arg)] = e
842
+ continue
843
+ version = search_version(out)
844
+ if 'Free Software Foundation' in out:
845
+ defines = _get_gnu_compiler_defines(compiler)
846
+ if not defines:
847
+ popen_exceptions[join_args(compiler)] = 'no pre-processor defines'
848
+ continue
849
+ version = _get_gnu_version_from_defines(defines)
850
+ comp = objc.GnuObjCCompiler if lang == 'objc' else objcpp.GnuObjCPPCompiler
851
+ linker = guess_nix_linker(env, compiler, comp, version, for_machine)
852
+ return comp(
853
+ ccache, compiler, version, for_machine, is_cross, info,
854
+ defines, linker=linker)
855
+ if 'clang' in out:
856
+ linker = None
857
+ defines = _get_clang_compiler_defines(compiler)
858
+ if not defines:
859
+ popen_exceptions[join_args(compiler)] = 'no pre-processor defines'
860
+ continue
861
+ if 'Apple' in out:
862
+ comp = objc.AppleClangObjCCompiler if lang == 'objc' else objcpp.AppleClangObjCPPCompiler
863
+ else:
864
+ comp = objc.ClangObjCCompiler if lang == 'objc' else objcpp.ClangObjCPPCompiler
865
+ if 'windows' in out or env.machines[for_machine].is_windows():
866
+ # If we're in a MINGW context this actually will use a gnu style ld
867
+ try:
868
+ linker = guess_win_linker(env, compiler, comp, version, for_machine)
869
+ except MesonException:
870
+ pass
871
+
872
+ if not linker:
873
+ linker = guess_nix_linker(env, compiler, comp, version, for_machine)
874
+ return comp(
875
+ ccache, compiler, version, for_machine,
876
+ is_cross, info, linker=linker, defines=defines)
877
+ _handle_exceptions(popen_exceptions, compilers)
878
+ raise EnvironmentException('Unreachable code (exception to make mypy happy)')
879
+
880
+ def detect_java_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
881
+ from .java import JavaCompiler
882
+ exelist = env.lookup_binary_entry(for_machine, 'java')
883
+ info = env.machines[for_machine]
884
+ if exelist is None:
885
+ # TODO support fallback
886
+ exelist = [defaults['java'][0]]
887
+
888
+ try:
889
+ p, out, err = Popen_safe_logged(exelist + ['-version'], msg='Detecting compiler via')
890
+ except OSError:
891
+ raise EnvironmentException('Could not execute Java compiler: {}'.format(join_args(exelist)))
892
+ if 'javac' in out or 'javac' in err:
893
+ version = search_version(err if 'javac' in err else out)
894
+ if not version or version == 'unknown version':
895
+ parts = (err if 'javac' in err else out).split()
896
+ if len(parts) > 1:
897
+ version = parts[1]
898
+ comp_class = JavaCompiler
899
+ env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
900
+ return comp_class(exelist, version, for_machine, info)
901
+ raise EnvironmentException('Unknown compiler: ' + join_args(exelist))
902
+
903
+ def detect_cs_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
904
+ from . import cs
905
+ compilers, ccache = _get_compilers(env, 'cs', for_machine)
906
+ popen_exceptions = {}
907
+ info = env.machines[for_machine]
908
+ for comp in compilers:
909
+ try:
910
+ p, out, err = Popen_safe_logged(comp + ['--version'], msg='Detecting compiler via')
911
+ except OSError as e:
912
+ popen_exceptions[join_args(comp + ['--version'])] = e
913
+ continue
914
+
915
+ version = search_version(out)
916
+ cls: T.Type[cs.CsCompiler]
917
+ if 'Mono' in out:
918
+ cls = cs.MonoCompiler
919
+ elif "Visual C#" in out:
920
+ cls = cs.VisualStudioCsCompiler
921
+ else:
922
+ continue
923
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
924
+ return cls(comp, version, for_machine, info)
925
+
926
+ _handle_exceptions(popen_exceptions, compilers)
927
+ raise EnvironmentException('Unreachable code (exception to make mypy happy)')
928
+
929
+ def detect_cython_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
930
+ """Search for a cython compiler."""
931
+ from .cython import CythonCompiler
932
+ compilers, _ = _get_compilers(env, 'cython', MachineChoice.BUILD)
933
+ is_cross = env.is_cross_build(for_machine)
934
+ info = env.machines[for_machine]
935
+
936
+ popen_exceptions: T.Dict[str, Exception] = {}
937
+ for comp in compilers:
938
+ try:
939
+ _, out, err = Popen_safe_logged(comp + ['-V'], msg='Detecting compiler via')
940
+ except OSError as e:
941
+ popen_exceptions[join_args(comp + ['-V'])] = e
942
+ continue
943
+
944
+ version: T.Optional[str] = None
945
+ # 3.0
946
+ if 'Cython' in out:
947
+ version = search_version(out)
948
+ # older
949
+ elif 'Cython' in err:
950
+ version = search_version(err)
951
+ if version is not None:
952
+ comp_class = CythonCompiler
953
+ env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
954
+ return comp_class([], comp, version, for_machine, info, is_cross=is_cross)
955
+ _handle_exceptions(popen_exceptions, compilers)
956
+ raise EnvironmentException('Unreachable code (exception to make mypy happy)')
957
+
958
+ def detect_vala_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
959
+ from .vala import ValaCompiler
960
+ exelist = env.lookup_binary_entry(for_machine, 'vala')
961
+ is_cross = env.is_cross_build(for_machine)
962
+ info = env.machines[for_machine]
963
+ if exelist is None:
964
+ # TODO support fallback
965
+ exelist = [defaults['vala'][0]]
966
+
967
+ try:
968
+ p, out = Popen_safe_logged(exelist + ['--version'], msg='Detecting compiler via')[0:2]
969
+ except OSError:
970
+ raise EnvironmentException('Could not execute Vala compiler: {}'.format(join_args(exelist)))
971
+ version = search_version(out)
972
+ if 'Vala' in out:
973
+ comp_class = ValaCompiler
974
+ env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
975
+ return comp_class(exelist, version, for_machine, is_cross, info)
976
+ raise EnvironmentException('Unknown compiler: ' + join_args(exelist))
977
+
978
+ def detect_rust_compiler(env: 'Environment', for_machine: MachineChoice) -> RustCompiler:
979
+ from . import rust
980
+ from ..linkers import linkers
981
+ popen_exceptions: T.Dict[str, Exception] = {}
982
+ compilers, _ = _get_compilers(env, 'rust', for_machine)
983
+ is_cross = env.is_cross_build(for_machine)
984
+ info = env.machines[for_machine]
985
+
986
+ cc = detect_c_compiler(env, for_machine)
987
+ is_link_exe = isinstance(cc.linker, linkers.VisualStudioLikeLinkerMixin)
988
+ override = env.lookup_binary_entry(for_machine, 'rust_ld')
989
+
990
+ for compiler in compilers:
991
+ arg = ['--version']
992
+ try:
993
+ out = Popen_safe_logged(compiler + arg, msg='Detecting compiler via')[1]
994
+ except OSError as e:
995
+ popen_exceptions[join_args(compiler + arg)] = e
996
+ continue
997
+
998
+ version = search_version(out)
999
+ cls: T.Type[RustCompiler] = rust.RustCompiler
1000
+
1001
+ # Clippy is a wrapper around rustc, but it doesn't have rustc in it's
1002
+ # output. We can otherwise treat it as rustc.
1003
+ if 'clippy' in out:
1004
+ # clippy returns its own version and not the rustc version by
1005
+ # default so try harder here to get the correct version.
1006
+ # Also replace the whole output with the rustc output in
1007
+ # case this is later used for other purposes.
1008
+ arg = ['--rustc', '--version']
1009
+ try:
1010
+ out = Popen_safe(compiler + arg)[1]
1011
+ except OSError as e:
1012
+ popen_exceptions[join_args(compiler + arg)] = e
1013
+ continue
1014
+ version = search_version(out)
1015
+
1016
+ cls = rust.ClippyRustCompiler
1017
+
1018
+ if 'rustc' in out:
1019
+ # On Linux and mac rustc will invoke gcc (clang for mac
1020
+ # presumably) and it can do this windows, for dynamic linking.
1021
+ # this means the easiest way to C compiler for dynamic linking.
1022
+ # figure out what linker to use is to just get the value of the
1023
+ # C compiler and use that as the basis of the rust linker.
1024
+ # However, there are two things we need to change, if CC is not
1025
+ # the default use that, and second add the necessary arguments
1026
+ # to rust to use -fuse-ld
1027
+
1028
+ if any(a.startswith('linker=') for a in compiler):
1029
+ mlog.warning(
1030
+ 'Please do not put -C linker= in your compiler '
1031
+ 'command, set rust_ld=command in your cross file '
1032
+ 'or use the RUSTC_LD environment variable, otherwise meson '
1033
+ 'will override your selection.')
1034
+
1035
+ compiler = compiler.copy() # avoid mutating the original list
1036
+
1037
+ if override is None:
1038
+ extra_args: T.Dict[str, T.Union[str, bool]] = {}
1039
+ always_args: T.List[str] = []
1040
+ if is_link_exe:
1041
+ compiler.extend(cls.use_linker_args(cc.linker.exelist[0], ''))
1042
+ extra_args['direct'] = True
1043
+ extra_args['machine'] = cc.linker.machine
1044
+ else:
1045
+ exelist = cc.linker.exelist + cc.linker.get_always_args()
1046
+ if os.path.basename(exelist[0]) in {'ccache', 'sccache'}:
1047
+ del exelist[0]
1048
+ c = exelist.pop(0)
1049
+ compiler.extend(cls.use_linker_args(c, ''))
1050
+
1051
+ # Also ensure that we pass any extra arguments to the linker
1052
+ for l in exelist:
1053
+ compiler.extend(['-C', f'link-arg={l}'])
1054
+
1055
+ # This trickery with type() gets us the class of the linker
1056
+ # so we can initialize a new copy for the Rust Compiler
1057
+ # TODO rewrite this without type: ignore
1058
+ assert cc.linker is not None, 'for mypy'
1059
+ if is_link_exe:
1060
+ linker = type(cc.linker)(for_machine, always_args, exelist=cc.linker.exelist, # type: ignore
1061
+ version=cc.linker.version, **extra_args) # type: ignore
1062
+ else:
1063
+ linker = type(cc.linker)(compiler, for_machine, cc.LINKER_PREFIX,
1064
+ always_args=always_args, version=cc.linker.version,
1065
+ **extra_args)
1066
+ elif 'link' in override[0]:
1067
+ linker = guess_win_linker(env,
1068
+ override, cls, version, for_machine, use_linker_prefix=False)
1069
+ # rustc takes linker arguments without a prefix, and
1070
+ # inserts the correct prefix itself.
1071
+ assert isinstance(linker, linkers.VisualStudioLikeLinkerMixin)
1072
+ linker.direct = True
1073
+ compiler.extend(cls.use_linker_args(linker.exelist[0], ''))
1074
+ else:
1075
+ # On linux and macos rust will invoke the c compiler for
1076
+ # linking, on windows it will use lld-link or link.exe.
1077
+ # we will simply ask for the C compiler that corresponds to
1078
+ # it, and use that.
1079
+ cc = _detect_c_or_cpp_compiler(env, 'c', for_machine, override_compiler=override)
1080
+ linker = cc.linker
1081
+
1082
+ # Of course, we're not going to use any of that, we just
1083
+ # need it to get the proper arguments to pass to rustc
1084
+ c = linker.exelist[1] if linker.exelist[0].endswith('ccache') else linker.exelist[0]
1085
+ compiler.extend(cls.use_linker_args(c, ''))
1086
+
1087
+ env.coredata.add_lang_args(cls.language, cls, for_machine, env)
1088
+ return cls(
1089
+ compiler, version, for_machine, is_cross, info,
1090
+ linker=linker)
1091
+
1092
+ _handle_exceptions(popen_exceptions, compilers)
1093
+ raise EnvironmentException('Unreachable code (exception to make mypy happy)')
1094
+
1095
+ def detect_d_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
1096
+ from . import c, d
1097
+ info = env.machines[for_machine]
1098
+
1099
+ # Detect the target architecture, required for proper architecture handling on Windows.
1100
+ # MSVC compiler is required for correct platform detection.
1101
+ c_compiler = {'c': detect_c_compiler(env, for_machine)}
1102
+ is_msvc = isinstance(c_compiler['c'], c.VisualStudioCCompiler)
1103
+ if not is_msvc:
1104
+ c_compiler = {}
1105
+
1106
+ # Import here to avoid circular imports
1107
+ from ..environment import detect_cpu_family
1108
+ arch = detect_cpu_family(c_compiler)
1109
+ if is_msvc and arch == 'x86':
1110
+ arch = 'x86_mscoff'
1111
+
1112
+ popen_exceptions = {}
1113
+ is_cross = env.is_cross_build(for_machine)
1114
+ compilers, ccache = _get_compilers(env, 'd', for_machine)
1115
+ cls: T.Type[d.DCompiler]
1116
+ for exelist in compilers:
1117
+ # Search for a D compiler.
1118
+ # We prefer LDC over GDC unless overridden with the DC
1119
+ # environment variable because LDC has a much more
1120
+ # up to date language version at time (2016).
1121
+ if os.path.basename(exelist[-1]).startswith(('ldmd', 'gdmd')):
1122
+ raise EnvironmentException(
1123
+ f'Meson does not support {exelist[-1]} as it is only a DMD frontend for another compiler.'
1124
+ 'Please provide a valid value for DC or unset it so that Meson can resolve the compiler by itself.')
1125
+ try:
1126
+ p, out = Popen_safe(exelist + ['--version'])[0:2]
1127
+ except OSError as e:
1128
+ popen_exceptions[join_args(exelist + ['--version'])] = e
1129
+ continue
1130
+ version = search_version(out)
1131
+ full_version = out.split('\n', 1)[0]
1132
+
1133
+ if 'LLVM D compiler' in out:
1134
+ cls = d.LLVMDCompiler
1135
+ # LDC seems to require a file
1136
+ # We cannot use NamedTemporaryFile on windows, its documented
1137
+ # to not work for our uses. So, just use mkstemp and only have
1138
+ # one path for simplicity.
1139
+ o, f = tempfile.mkstemp('.d')
1140
+ os.close(o)
1141
+
1142
+ try:
1143
+ if info.is_windows() or info.is_cygwin():
1144
+ objfile = os.path.basename(f)[:-1] + 'obj'
1145
+ linker = guess_win_linker(env,
1146
+ exelist,
1147
+ cls, full_version, for_machine,
1148
+ use_linker_prefix=True, invoked_directly=False,
1149
+ extra_args=[f])
1150
+ else:
1151
+ # LDC writes an object file to the current working directory.
1152
+ # Clean it up.
1153
+ objfile = os.path.basename(f)[:-1] + 'o'
1154
+ linker = guess_nix_linker(env,
1155
+ exelist, cls, full_version, for_machine,
1156
+ extra_args=[f])
1157
+ finally:
1158
+ windows_proof_rm(f)
1159
+ windows_proof_rm(objfile)
1160
+
1161
+ return cls(
1162
+ exelist, version, for_machine, info, arch,
1163
+ full_version=full_version, linker=linker, version_output=out)
1164
+ elif 'gdc' in out:
1165
+ cls = d.GnuDCompiler
1166
+ linker = guess_nix_linker(env, exelist, cls, version, for_machine)
1167
+ return cls(
1168
+ exelist, version, for_machine, info, arch,
1169
+ is_cross=is_cross, full_version=full_version, linker=linker)
1170
+ elif 'The D Language Foundation' in out or 'Digital Mars' in out:
1171
+ cls = d.DmdDCompiler
1172
+ # DMD seems to require a file
1173
+ # We cannot use NamedTemporaryFile on windows, its documented
1174
+ # to not work for our uses. So, just use mkstemp and only have
1175
+ # one path for simplicity.
1176
+ o, f = tempfile.mkstemp('.d')
1177
+ os.close(o)
1178
+
1179
+ # DMD as different detection logic for x86 and x86_64
1180
+ arch_arg = '-m64' if arch == 'x86_64' else '-m32'
1181
+
1182
+ try:
1183
+ if info.is_windows() or info.is_cygwin():
1184
+ objfile = os.path.basename(f)[:-1] + 'obj'
1185
+ linker = guess_win_linker(env,
1186
+ exelist, cls, full_version, for_machine,
1187
+ invoked_directly=False, extra_args=[f, arch_arg])
1188
+ else:
1189
+ objfile = os.path.basename(f)[:-1] + 'o'
1190
+ linker = guess_nix_linker(env,
1191
+ exelist, cls, full_version, for_machine,
1192
+ extra_args=[f, arch_arg])
1193
+ finally:
1194
+ windows_proof_rm(f)
1195
+ windows_proof_rm(objfile)
1196
+
1197
+ return cls(
1198
+ exelist, version, for_machine, info, arch,
1199
+ full_version=full_version, linker=linker)
1200
+ raise EnvironmentException('Unknown compiler: ' + join_args(exelist))
1201
+
1202
+ _handle_exceptions(popen_exceptions, compilers)
1203
+ raise EnvironmentException('Unreachable code (exception to make mypy happy)')
1204
+
1205
+ def detect_swift_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
1206
+ from .swift import SwiftCompiler
1207
+ exelist = env.lookup_binary_entry(for_machine, 'swift')
1208
+ is_cross = env.is_cross_build(for_machine)
1209
+ info = env.machines[for_machine]
1210
+ if exelist is None:
1211
+ # TODO support fallback
1212
+ exelist = [defaults['swift'][0]]
1213
+
1214
+ try:
1215
+ p, _, err = Popen_safe_logged(exelist + ['-v'], msg='Detecting compiler via')
1216
+ except OSError:
1217
+ raise EnvironmentException('Could not execute Swift compiler: {}'.format(join_args(exelist)))
1218
+ version = search_version(err)
1219
+ if 'Swift' in err:
1220
+ # As for 5.0.1 swiftc *requires* a file to check the linker:
1221
+ with tempfile.NamedTemporaryFile(suffix='.swift') as f:
1222
+ cls = SwiftCompiler
1223
+
1224
+ outhandle, outfile = tempfile.mkstemp('.out')
1225
+ os.close(outhandle)
1226
+
1227
+ try:
1228
+ linker = guess_nix_linker(env,
1229
+ exelist, cls, version, for_machine,
1230
+ extra_args=[f.name, '-o', outfile])
1231
+ finally:
1232
+ windows_proof_rm(outfile)
1233
+ return cls(
1234
+ exelist, version, for_machine, is_cross, info, linker=linker)
1235
+
1236
+ raise EnvironmentException('Unknown compiler: ' + join_args(exelist))
1237
+
1238
+ def detect_nasm_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
1239
+ from .asm import NasmCompiler, YasmCompiler, MetrowerksAsmCompilerARM, MetrowerksAsmCompilerEmbeddedPowerPC
1240
+ compilers, _ = _get_compilers(env, 'nasm', for_machine)
1241
+ is_cross = env.is_cross_build(for_machine)
1242
+
1243
+ # We need a C compiler to properly detect the machine info and linker
1244
+ cc = detect_c_compiler(env, for_machine)
1245
+ if not is_cross:
1246
+ from ..environment import detect_machine_info
1247
+ info = detect_machine_info({'c': cc})
1248
+ else:
1249
+ info = env.machines[for_machine]
1250
+
1251
+ popen_exceptions: T.Dict[str, Exception] = {}
1252
+ for comp in compilers:
1253
+ if comp == ['nasm'] and is_windows() and not shutil.which(comp[0]):
1254
+ # nasm is not in PATH on Windows by default
1255
+ default_path = os.path.join(os.environ['ProgramFiles'], 'NASM')
1256
+ comp[0] = shutil.which(comp[0], path=default_path) or comp[0]
1257
+ try:
1258
+ output = Popen_safe_logged(comp + ['--version'], msg='Detecting compiler via')[1]
1259
+ except OSError as e:
1260
+ popen_exceptions[' '.join(comp + ['--version'])] = e
1261
+ continue
1262
+
1263
+ version = search_version(output)
1264
+ if 'NASM' in output:
1265
+ comp_class = NasmCompiler
1266
+ env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
1267
+ return comp_class([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
1268
+ elif 'yasm' in output:
1269
+ comp_class = YasmCompiler
1270
+ env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
1271
+ return comp_class([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
1272
+ elif 'Metrowerks' in output or 'Freescale' in output:
1273
+ if 'ARM' in output:
1274
+ comp_class_mwasmarm = MetrowerksAsmCompilerARM
1275
+ env.coredata.add_lang_args(comp_class_mwasmarm.language, comp_class_mwasmarm, for_machine, env)
1276
+ return comp_class_mwasmarm([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
1277
+ else:
1278
+ comp_class_mwasmeppc = MetrowerksAsmCompilerEmbeddedPowerPC
1279
+ env.coredata.add_lang_args(comp_class_mwasmeppc.language, comp_class_mwasmeppc, for_machine, env)
1280
+ return comp_class_mwasmeppc([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
1281
+
1282
+ _handle_exceptions(popen_exceptions, compilers)
1283
+ raise EnvironmentException('Unreachable code (exception to make mypy happy)')
1284
+
1285
+ def detect_masm_compiler(env: 'Environment', for_machine: MachineChoice) -> Compiler:
1286
+ # We need a C compiler to properly detect the machine info and linker
1287
+ is_cross = env.is_cross_build(for_machine)
1288
+ cc = detect_c_compiler(env, for_machine)
1289
+ if not is_cross:
1290
+ from ..environment import detect_machine_info
1291
+ info = detect_machine_info({'c': cc})
1292
+ else:
1293
+ info = env.machines[for_machine]
1294
+
1295
+ from .asm import MasmCompiler, MasmARMCompiler
1296
+ comp_class: T.Type[Compiler]
1297
+ if info.cpu_family == 'x86':
1298
+ comp = ['ml']
1299
+ comp_class = MasmCompiler
1300
+ arg = '/?'
1301
+ elif info.cpu_family == 'x86_64':
1302
+ comp = ['ml64']
1303
+ comp_class = MasmCompiler
1304
+ arg = '/?'
1305
+ elif info.cpu_family == 'arm':
1306
+ comp = ['armasm']
1307
+ comp_class = MasmARMCompiler
1308
+ arg = '-h'
1309
+ elif info.cpu_family == 'aarch64':
1310
+ comp = ['armasm64']
1311
+ comp_class = MasmARMCompiler
1312
+ arg = '-h'
1313
+ else:
1314
+ raise EnvironmentException(f'Platform {info.cpu_family} not supported by MASM')
1315
+
1316
+ popen_exceptions: T.Dict[str, Exception] = {}
1317
+ try:
1318
+ output = Popen_safe(comp + [arg])[2]
1319
+ version = search_version(output)
1320
+ env.coredata.add_lang_args(comp_class.language, comp_class, for_machine, env)
1321
+ return comp_class([], comp, version, for_machine, info, cc.linker, is_cross=is_cross)
1322
+ except OSError as e:
1323
+ popen_exceptions[' '.join(comp + [arg])] = e
1324
+ _handle_exceptions(popen_exceptions, [comp])
1325
+ raise EnvironmentException('Unreachable code (exception to make mypy happy)')
1326
+
1327
+ # GNU/Clang defines and version
1328
+ # =============================
1329
+
1330
+ def _get_gnu_compiler_defines(compiler: T.List[str]) -> T.Dict[str, str]:
1331
+ """
1332
+ Detect GNU compiler platform type (Apple, MinGW, Unix)
1333
+ """
1334
+ # Arguments to output compiler pre-processor defines to stdout
1335
+ # gcc, g++, and gfortran all support these arguments
1336
+ args = compiler + ['-E', '-dM', '-']
1337
+ mlog.debug(f'Running command: {join_args(args)}')
1338
+ p, output, error = Popen_safe(args, write='', stdin=subprocess.PIPE)
1339
+ if p.returncode != 0:
1340
+ raise EnvironmentException('Unable to detect GNU compiler type:\n'
1341
+ f'Compiler stdout:\n{output}\n-----\n'
1342
+ f'Compiler stderr:\n{error}\n-----\n')
1343
+ # Parse several lines of the type:
1344
+ # `#define ___SOME_DEF some_value`
1345
+ # and extract `___SOME_DEF`
1346
+ defines: T.Dict[str, str] = {}
1347
+ for line in output.split('\n'):
1348
+ if not line:
1349
+ continue
1350
+ d, *rest = line.split(' ', 2)
1351
+ if d != '#define':
1352
+ continue
1353
+ if len(rest) == 1:
1354
+ defines[rest[0]] = ''
1355
+ if len(rest) == 2:
1356
+ defines[rest[0]] = rest[1]
1357
+ return defines
1358
+
1359
+ def _get_clang_compiler_defines(compiler: T.List[str]) -> T.Dict[str, str]:
1360
+ """
1361
+ Get the list of Clang pre-processor defines
1362
+ """
1363
+ args = compiler + ['-E', '-dM', '-']
1364
+ mlog.debug(f'Running command: {join_args(args)}')
1365
+ p, output, error = Popen_safe(args, write='', stdin=subprocess.PIPE)
1366
+ if p.returncode != 0:
1367
+ raise EnvironmentException('Unable to get clang pre-processor defines:\n'
1368
+ f'Compiler stdout:\n{output}\n-----\n'
1369
+ f'Compiler stderr:\n{error}\n-----\n')
1370
+ defines: T.Dict[str, str] = {}
1371
+ for line in output.split('\n'):
1372
+ if not line:
1373
+ continue
1374
+ d, *rest = line.split(' ', 2)
1375
+ if d != '#define':
1376
+ continue
1377
+ if len(rest) == 1:
1378
+ defines[rest[0]] = ''
1379
+ if len(rest) == 2:
1380
+ defines[rest[0]] = rest[1]
1381
+ return defines
1382
+
1383
+ def _get_gnu_version_from_defines(defines: T.Dict[str, str]) -> str:
1384
+ dot = '.'
1385
+ major = defines.get('__GNUC__', '0')
1386
+ minor = defines.get('__GNUC_MINOR__', '0')
1387
+ patch = defines.get('__GNUC_PATCHLEVEL__', '0')
1388
+ return dot.join((major, minor, patch))
1389
+
1390
+ def _get_lcc_version_from_defines(defines: T.Dict[str, str]) -> str:
1391
+ dot = '.'
1392
+ generation_and_major = defines.get('__LCC__', '100')
1393
+ generation = generation_and_major[:1]
1394
+ major = generation_and_major[1:]
1395
+ minor = defines.get('__LCC_MINOR__', '0')
1396
+ return dot.join((generation, major, minor))