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.
- package/BSDmakefile +6 -0
- package/Makefile +16 -0
- package/README.md +14 -11
- package/configure +18 -0
- package/configure.bat +22 -0
- package/dist/native.js +0 -8
- package/lib/application.ts +98 -0
- package/lib/authentication.ts +3 -0
- package/lib/build.py +50 -0
- package/lib/bus.ts +30 -0
- package/lib/cancellable.ts +33 -0
- package/lib/child.ts +15 -0
- package/lib/crash.ts +11 -0
- package/lib/device.ts +329 -0
- package/lib/device_manager.ts +69 -0
- package/lib/endpoint_parameters.ts +56 -0
- package/lib/icon.ts +15 -0
- package/lib/index.ts +311 -0
- package/lib/iostream.ts +78 -0
- package/lib/meson.build +53 -0
- package/lib/native.ts +9 -0
- package/lib/portal_membership.ts +10 -0
- package/lib/portal_service.ts +105 -0
- package/lib/process.ts +57 -0
- package/lib/relay.ts +44 -0
- package/lib/script.ts +352 -0
- package/lib/session.ts +113 -0
- package/lib/signals.ts +45 -0
- package/lib/socket_address.ts +35 -0
- package/lib/spawn.ts +4 -0
- package/lib/system_parameters.ts +78 -0
- package/make.bat +23 -0
- package/meson.build +160 -0
- package/meson.options +11 -0
- package/package.json +27 -6
- package/releng/deps.py +1133 -0
- package/releng/deps.toml +391 -0
- package/releng/devkit-assets/frida-core-example-unix.c +188 -0
- package/releng/devkit-assets/frida-core-example-windows.c +197 -0
- package/releng/devkit-assets/frida-core-example.sln +28 -0
- package/releng/devkit-assets/frida-core-example.vcxproj +157 -0
- package/releng/devkit-assets/frida-core-example.vcxproj.filters +27 -0
- package/releng/devkit-assets/frida-gum-example-unix.c +122 -0
- package/releng/devkit-assets/frida-gum-example-windows.c +132 -0
- package/releng/devkit-assets/frida-gum-example.sln +28 -0
- package/releng/devkit-assets/frida-gum-example.vcxproj +157 -0
- package/releng/devkit-assets/frida-gum-example.vcxproj.filters +27 -0
- package/releng/devkit-assets/frida-gumjs-example-unix.c +84 -0
- package/releng/devkit-assets/frida-gumjs-example-windows.c +91 -0
- package/releng/devkit-assets/frida-gumjs-example.sln +28 -0
- package/releng/devkit-assets/frida-gumjs-example.vcxproj +157 -0
- package/releng/devkit-assets/frida-gumjs-example.vcxproj.filters +27 -0
- package/releng/devkit.py +535 -0
- package/releng/env.py +420 -0
- package/releng/env_android.py +150 -0
- package/releng/env_apple.py +176 -0
- package/releng/env_generic.py +373 -0
- package/releng/frida_version.py +69 -0
- package/releng/machine_file.py +44 -0
- package/releng/machine_spec.py +290 -0
- package/releng/meson/meson.py +27 -0
- package/releng/meson/mesonbuild/__init__.py +0 -0
- package/releng/meson/mesonbuild/_pathlib.py +63 -0
- package/releng/meson/mesonbuild/_typing.py +69 -0
- package/releng/meson/mesonbuild/arglist.py +321 -0
- package/releng/meson/mesonbuild/ast/__init__.py +23 -0
- package/releng/meson/mesonbuild/ast/interpreter.py +441 -0
- package/releng/meson/mesonbuild/ast/introspection.py +374 -0
- package/releng/meson/mesonbuild/ast/postprocess.py +109 -0
- package/releng/meson/mesonbuild/ast/printer.py +620 -0
- package/releng/meson/mesonbuild/ast/visitor.py +161 -0
- package/releng/meson/mesonbuild/backend/__init__.py +0 -0
- package/releng/meson/mesonbuild/backend/backends.py +2047 -0
- package/releng/meson/mesonbuild/backend/ninjabackend.py +3808 -0
- package/releng/meson/mesonbuild/backend/nonebackend.py +26 -0
- package/releng/meson/mesonbuild/backend/vs2010backend.py +2078 -0
- package/releng/meson/mesonbuild/backend/vs2012backend.py +35 -0
- package/releng/meson/mesonbuild/backend/vs2013backend.py +34 -0
- package/releng/meson/mesonbuild/backend/vs2015backend.py +35 -0
- package/releng/meson/mesonbuild/backend/vs2017backend.py +59 -0
- package/releng/meson/mesonbuild/backend/vs2019backend.py +54 -0
- package/releng/meson/mesonbuild/backend/vs2022backend.py +54 -0
- package/releng/meson/mesonbuild/backend/xcodebackend.py +1781 -0
- package/releng/meson/mesonbuild/build.py +3249 -0
- package/releng/meson/mesonbuild/cargo/__init__.py +5 -0
- package/releng/meson/mesonbuild/cargo/builder.py +238 -0
- package/releng/meson/mesonbuild/cargo/cfg.py +274 -0
- package/releng/meson/mesonbuild/cargo/interpreter.py +733 -0
- package/releng/meson/mesonbuild/cargo/manifest.py +227 -0
- package/releng/meson/mesonbuild/cargo/version.py +95 -0
- package/releng/meson/mesonbuild/cmake/__init__.py +28 -0
- package/releng/meson/mesonbuild/cmake/common.py +331 -0
- package/releng/meson/mesonbuild/cmake/data/__init__.py +0 -0
- package/releng/meson/mesonbuild/cmake/data/preload.cmake +82 -0
- package/releng/meson/mesonbuild/cmake/executor.py +241 -0
- package/releng/meson/mesonbuild/cmake/fileapi.py +324 -0
- package/releng/meson/mesonbuild/cmake/generator.py +186 -0
- package/releng/meson/mesonbuild/cmake/interpreter.py +1267 -0
- package/releng/meson/mesonbuild/cmake/toolchain.py +248 -0
- package/releng/meson/mesonbuild/cmake/traceparser.py +814 -0
- package/releng/meson/mesonbuild/cmake/tracetargets.py +161 -0
- package/releng/meson/mesonbuild/compilers/__init__.py +86 -0
- package/releng/meson/mesonbuild/compilers/asm.py +307 -0
- package/releng/meson/mesonbuild/compilers/c.py +788 -0
- package/releng/meson/mesonbuild/compilers/c_function_attributes.py +143 -0
- package/releng/meson/mesonbuild/compilers/compilers.py +1388 -0
- package/releng/meson/mesonbuild/compilers/cpp.py +1035 -0
- package/releng/meson/mesonbuild/compilers/cs.py +136 -0
- package/releng/meson/mesonbuild/compilers/cuda.py +806 -0
- package/releng/meson/mesonbuild/compilers/cython.py +91 -0
- package/releng/meson/mesonbuild/compilers/d.py +861 -0
- package/releng/meson/mesonbuild/compilers/detect.py +1396 -0
- package/releng/meson/mesonbuild/compilers/fortran.py +523 -0
- package/releng/meson/mesonbuild/compilers/java.py +113 -0
- package/releng/meson/mesonbuild/compilers/mixins/__init__.py +0 -0
- package/releng/meson/mesonbuild/compilers/mixins/arm.py +167 -0
- package/releng/meson/mesonbuild/compilers/mixins/ccrx.py +113 -0
- package/releng/meson/mesonbuild/compilers/mixins/clang.py +170 -0
- package/releng/meson/mesonbuild/compilers/mixins/clike.py +1330 -0
- package/releng/meson/mesonbuild/compilers/mixins/compcert.py +117 -0
- package/releng/meson/mesonbuild/compilers/mixins/elbrus.py +93 -0
- package/releng/meson/mesonbuild/compilers/mixins/emscripten.py +89 -0
- package/releng/meson/mesonbuild/compilers/mixins/gnu.py +629 -0
- package/releng/meson/mesonbuild/compilers/mixins/intel.py +167 -0
- package/releng/meson/mesonbuild/compilers/mixins/islinker.py +120 -0
- package/releng/meson/mesonbuild/compilers/mixins/metrowerks.py +279 -0
- package/releng/meson/mesonbuild/compilers/mixins/pgi.py +88 -0
- package/releng/meson/mesonbuild/compilers/mixins/ti.py +130 -0
- package/releng/meson/mesonbuild/compilers/mixins/visualstudio.py +458 -0
- package/releng/meson/mesonbuild/compilers/mixins/xc16.py +111 -0
- package/releng/meson/mesonbuild/compilers/objc.py +120 -0
- package/releng/meson/mesonbuild/compilers/objcpp.py +102 -0
- package/releng/meson/mesonbuild/compilers/rust.py +230 -0
- package/releng/meson/mesonbuild/compilers/swift.py +131 -0
- package/releng/meson/mesonbuild/compilers/vala.py +121 -0
- package/releng/meson/mesonbuild/coredata.py +1532 -0
- package/releng/meson/mesonbuild/dependencies/__init__.py +252 -0
- package/releng/meson/mesonbuild/dependencies/base.py +663 -0
- package/releng/meson/mesonbuild/dependencies/boost.py +1083 -0
- package/releng/meson/mesonbuild/dependencies/cmake.py +656 -0
- package/releng/meson/mesonbuild/dependencies/coarrays.py +80 -0
- package/releng/meson/mesonbuild/dependencies/configtool.py +163 -0
- package/releng/meson/mesonbuild/dependencies/cuda.py +295 -0
- package/releng/meson/mesonbuild/dependencies/data/CMakeLists.txt +102 -0
- package/releng/meson/mesonbuild/dependencies/data/CMakeListsLLVM.txt +204 -0
- package/releng/meson/mesonbuild/dependencies/data/CMakePathInfo.txt +31 -0
- package/releng/meson/mesonbuild/dependencies/data/__init__.py +0 -0
- package/releng/meson/mesonbuild/dependencies/detect.py +225 -0
- package/releng/meson/mesonbuild/dependencies/dev.py +707 -0
- package/releng/meson/mesonbuild/dependencies/dub.py +424 -0
- package/releng/meson/mesonbuild/dependencies/factory.py +146 -0
- package/releng/meson/mesonbuild/dependencies/framework.py +111 -0
- package/releng/meson/mesonbuild/dependencies/hdf5.py +168 -0
- package/releng/meson/mesonbuild/dependencies/misc.py +618 -0
- package/releng/meson/mesonbuild/dependencies/mpi.py +231 -0
- package/releng/meson/mesonbuild/dependencies/pkgconfig.py +570 -0
- package/releng/meson/mesonbuild/dependencies/platform.py +52 -0
- package/releng/meson/mesonbuild/dependencies/python.py +431 -0
- package/releng/meson/mesonbuild/dependencies/qt.py +484 -0
- package/releng/meson/mesonbuild/dependencies/scalapack.py +142 -0
- package/releng/meson/mesonbuild/dependencies/ui.py +281 -0
- package/releng/meson/mesonbuild/depfile.py +82 -0
- package/releng/meson/mesonbuild/envconfig.py +480 -0
- package/releng/meson/mesonbuild/environment.py +987 -0
- package/releng/meson/mesonbuild/interpreter/__init__.py +47 -0
- package/releng/meson/mesonbuild/interpreter/compiler.py +900 -0
- package/releng/meson/mesonbuild/interpreter/dependencyfallbacks.py +386 -0
- package/releng/meson/mesonbuild/interpreter/interpreter.py +3595 -0
- package/releng/meson/mesonbuild/interpreter/interpreterobjects.py +1096 -0
- package/releng/meson/mesonbuild/interpreter/kwargs.py +479 -0
- package/releng/meson/mesonbuild/interpreter/mesonmain.py +487 -0
- package/releng/meson/mesonbuild/interpreter/primitives/__init__.py +29 -0
- package/releng/meson/mesonbuild/interpreter/primitives/array.py +108 -0
- package/releng/meson/mesonbuild/interpreter/primitives/boolean.py +52 -0
- package/releng/meson/mesonbuild/interpreter/primitives/dict.py +88 -0
- package/releng/meson/mesonbuild/interpreter/primitives/integer.py +86 -0
- package/releng/meson/mesonbuild/interpreter/primitives/range.py +38 -0
- package/releng/meson/mesonbuild/interpreter/primitives/string.py +247 -0
- package/releng/meson/mesonbuild/interpreter/type_checking.py +853 -0
- package/releng/meson/mesonbuild/interpreterbase/__init__.py +126 -0
- package/releng/meson/mesonbuild/interpreterbase/_unholder.py +25 -0
- package/releng/meson/mesonbuild/interpreterbase/baseobjects.py +174 -0
- package/releng/meson/mesonbuild/interpreterbase/decorators.py +806 -0
- package/releng/meson/mesonbuild/interpreterbase/disabler.py +35 -0
- package/releng/meson/mesonbuild/interpreterbase/exceptions.py +22 -0
- package/releng/meson/mesonbuild/interpreterbase/helpers.py +67 -0
- package/releng/meson/mesonbuild/interpreterbase/interpreterbase.py +665 -0
- package/releng/meson/mesonbuild/interpreterbase/operator.py +32 -0
- package/releng/meson/mesonbuild/linkers/__init__.py +20 -0
- package/releng/meson/mesonbuild/linkers/base.py +39 -0
- package/releng/meson/mesonbuild/linkers/detect.py +229 -0
- package/releng/meson/mesonbuild/linkers/linkers.py +1614 -0
- package/releng/meson/mesonbuild/mcompile.py +380 -0
- package/releng/meson/mesonbuild/mconf.py +368 -0
- package/releng/meson/mesonbuild/mdevenv.py +234 -0
- package/releng/meson/mesonbuild/mdist.py +376 -0
- package/releng/meson/mesonbuild/mesondata.py +38 -0
- package/releng/meson/mesonbuild/mesonlib.py +23 -0
- package/releng/meson/mesonbuild/mesonmain.py +289 -0
- package/releng/meson/mesonbuild/minit.py +204 -0
- package/releng/meson/mesonbuild/minstall.py +864 -0
- package/releng/meson/mesonbuild/mintro.py +667 -0
- package/releng/meson/mesonbuild/mlog.py +542 -0
- package/releng/meson/mesonbuild/modules/__init__.py +270 -0
- package/releng/meson/mesonbuild/modules/cmake.py +442 -0
- package/releng/meson/mesonbuild/modules/cuda.py +377 -0
- package/releng/meson/mesonbuild/modules/dlang.py +117 -0
- package/releng/meson/mesonbuild/modules/external_project.py +306 -0
- package/releng/meson/mesonbuild/modules/fs.py +323 -0
- package/releng/meson/mesonbuild/modules/gnome.py +2215 -0
- package/releng/meson/mesonbuild/modules/hotdoc.py +487 -0
- package/releng/meson/mesonbuild/modules/i18n.py +405 -0
- package/releng/meson/mesonbuild/modules/icestorm.py +123 -0
- package/releng/meson/mesonbuild/modules/java.py +112 -0
- package/releng/meson/mesonbuild/modules/keyval.py +65 -0
- package/releng/meson/mesonbuild/modules/modtest.py +33 -0
- package/releng/meson/mesonbuild/modules/pkgconfig.py +744 -0
- package/releng/meson/mesonbuild/modules/python.py +556 -0
- package/releng/meson/mesonbuild/modules/python3.py +85 -0
- package/releng/meson/mesonbuild/modules/qt.py +621 -0
- package/releng/meson/mesonbuild/modules/qt4.py +23 -0
- package/releng/meson/mesonbuild/modules/qt5.py +23 -0
- package/releng/meson/mesonbuild/modules/qt6.py +22 -0
- package/releng/meson/mesonbuild/modules/rust.py +355 -0
- package/releng/meson/mesonbuild/modules/simd.py +114 -0
- package/releng/meson/mesonbuild/modules/sourceset.py +291 -0
- package/releng/meson/mesonbuild/modules/wayland.py +151 -0
- package/releng/meson/mesonbuild/modules/windows.py +207 -0
- package/releng/meson/mesonbuild/mparser.py +1114 -0
- package/releng/meson/mesonbuild/msetup.py +365 -0
- package/releng/meson/mesonbuild/msubprojects.py +764 -0
- package/releng/meson/mesonbuild/mtest.py +2201 -0
- package/releng/meson/mesonbuild/munstable_coredata.py +107 -0
- package/releng/meson/mesonbuild/optinterpreter.py +276 -0
- package/releng/meson/mesonbuild/programs.py +367 -0
- package/releng/meson/mesonbuild/rewriter.py +1075 -0
- package/releng/meson/mesonbuild/scripts/__init__.py +10 -0
- package/releng/meson/mesonbuild/scripts/clangformat.py +55 -0
- package/releng/meson/mesonbuild/scripts/clangtidy.py +30 -0
- package/releng/meson/mesonbuild/scripts/cleantrees.py +35 -0
- package/releng/meson/mesonbuild/scripts/cmake_run_ctgt.py +103 -0
- package/releng/meson/mesonbuild/scripts/cmd_or_ps.ps1 +17 -0
- package/releng/meson/mesonbuild/scripts/copy.py +19 -0
- package/releng/meson/mesonbuild/scripts/coverage.py +214 -0
- package/releng/meson/mesonbuild/scripts/delwithsuffix.py +27 -0
- package/releng/meson/mesonbuild/scripts/depfixer.py +495 -0
- package/releng/meson/mesonbuild/scripts/depscan.py +198 -0
- package/releng/meson/mesonbuild/scripts/dirchanger.py +20 -0
- package/releng/meson/mesonbuild/scripts/env2mfile.py +402 -0
- package/releng/meson/mesonbuild/scripts/externalproject.py +106 -0
- package/releng/meson/mesonbuild/scripts/gettext.py +86 -0
- package/releng/meson/mesonbuild/scripts/gtkdochelper.py +286 -0
- package/releng/meson/mesonbuild/scripts/hotdochelper.py +40 -0
- package/releng/meson/mesonbuild/scripts/itstool.py +77 -0
- package/releng/meson/mesonbuild/scripts/meson_exe.py +115 -0
- package/releng/meson/mesonbuild/scripts/msgfmthelper.py +29 -0
- package/releng/meson/mesonbuild/scripts/pycompile.py +54 -0
- package/releng/meson/mesonbuild/scripts/python_info.py +121 -0
- package/releng/meson/mesonbuild/scripts/regen_checker.py +55 -0
- package/releng/meson/mesonbuild/scripts/run_tool.py +58 -0
- package/releng/meson/mesonbuild/scripts/scanbuild.py +57 -0
- package/releng/meson/mesonbuild/scripts/symbolextractor.py +322 -0
- package/releng/meson/mesonbuild/scripts/tags.py +44 -0
- package/releng/meson/mesonbuild/scripts/test_loaded_modules.py +14 -0
- package/releng/meson/mesonbuild/scripts/uninstall.py +41 -0
- package/releng/meson/mesonbuild/scripts/vcstagger.py +35 -0
- package/releng/meson/mesonbuild/scripts/yasm.py +24 -0
- package/releng/meson/mesonbuild/templates/__init__.py +0 -0
- package/releng/meson/mesonbuild/templates/cpptemplates.py +143 -0
- package/releng/meson/mesonbuild/templates/cstemplates.py +90 -0
- package/releng/meson/mesonbuild/templates/ctemplates.py +126 -0
- package/releng/meson/mesonbuild/templates/cudatemplates.py +143 -0
- package/releng/meson/mesonbuild/templates/dlangtemplates.py +109 -0
- package/releng/meson/mesonbuild/templates/fortrantemplates.py +101 -0
- package/releng/meson/mesonbuild/templates/javatemplates.py +94 -0
- package/releng/meson/mesonbuild/templates/mesontemplates.py +70 -0
- package/releng/meson/mesonbuild/templates/objcpptemplates.py +126 -0
- package/releng/meson/mesonbuild/templates/objctemplates.py +126 -0
- package/releng/meson/mesonbuild/templates/rusttemplates.py +79 -0
- package/releng/meson/mesonbuild/templates/samplefactory.py +41 -0
- package/releng/meson/mesonbuild/templates/sampleimpl.py +160 -0
- package/releng/meson/mesonbuild/templates/valatemplates.py +82 -0
- package/releng/meson/mesonbuild/utils/__init__.py +0 -0
- package/releng/meson/mesonbuild/utils/core.py +166 -0
- package/releng/meson/mesonbuild/utils/platform.py +27 -0
- package/releng/meson/mesonbuild/utils/posix.py +32 -0
- package/releng/meson/mesonbuild/utils/universal.py +2445 -0
- package/releng/meson/mesonbuild/utils/vsenv.py +126 -0
- package/releng/meson/mesonbuild/utils/win32.py +29 -0
- package/releng/meson/mesonbuild/wrap/__init__.py +59 -0
- package/releng/meson/mesonbuild/wrap/wrap.py +846 -0
- package/releng/meson/mesonbuild/wrap/wraptool.py +198 -0
- package/releng/meson-scripts/BSDmakefile +6 -0
- package/releng/meson-scripts/Makefile +16 -0
- package/releng/meson-scripts/configure +18 -0
- package/releng/meson-scripts/configure.bat +22 -0
- package/releng/meson-scripts/make.bat +23 -0
- package/releng/meson_configure.py +506 -0
- package/releng/meson_make.py +131 -0
- package/releng/mkdevkit.py +107 -0
- package/releng/mkfatmacho.py +54 -0
- package/releng/post-process-oabi.py +97 -0
- package/releng/progress.py +14 -0
- package/releng/sync-from-upstream.py +185 -0
- package/releng/tomlkit/tomlkit/__init__.py +59 -0
- package/releng/tomlkit/tomlkit/_compat.py +22 -0
- package/releng/tomlkit/tomlkit/_types.py +83 -0
- package/releng/tomlkit/tomlkit/_utils.py +158 -0
- package/releng/tomlkit/tomlkit/api.py +308 -0
- package/releng/tomlkit/tomlkit/container.py +875 -0
- package/releng/tomlkit/tomlkit/exceptions.py +227 -0
- package/releng/tomlkit/tomlkit/items.py +1967 -0
- package/releng/tomlkit/tomlkit/parser.py +1141 -0
- package/releng/tomlkit/tomlkit/py.typed +0 -0
- package/releng/tomlkit/tomlkit/source.py +180 -0
- package/releng/tomlkit/tomlkit/toml_char.py +52 -0
- package/releng/tomlkit/tomlkit/toml_document.py +7 -0
- package/releng/tomlkit/tomlkit/toml_file.py +58 -0
- package/releng/winenv.py +140 -0
- package/scripts/adjust-version.py +19 -0
- package/scripts/detect-version.py +40 -0
- package/scripts/fetch-abi-bits.py +343 -0
- package/scripts/install.js +23 -0
- package/scripts/package.py +15 -0
- package/src/addon.cc +76 -0
- package/src/application.cc +148 -0
- package/src/application.h +31 -0
- package/src/authentication.cc +174 -0
- package/src/authentication.h +24 -0
- package/src/bus.cc +167 -0
- package/src/bus.h +33 -0
- package/src/cancellable.cc +117 -0
- package/src/cancellable.h +31 -0
- package/src/child.cc +150 -0
- package/src/child.h +32 -0
- package/src/crash.cc +122 -0
- package/src/crash.h +30 -0
- package/src/device.cc +1302 -0
- package/src/device.h +55 -0
- package/src/device_manager.cc +362 -0
- package/src/device_manager.h +35 -0
- package/src/endpoint_parameters.cc +171 -0
- package/src/endpoint_parameters.h +28 -0
- package/src/glib_context.cc +62 -0
- package/src/glib_context.h +29 -0
- package/src/glib_object.cc +25 -0
- package/src/glib_object.h +37 -0
- package/src/iostream.cc +247 -0
- package/src/iostream.h +30 -0
- package/src/meson.build +26 -0
- package/src/operation.h +94 -0
- package/src/portal_membership.cc +100 -0
- package/src/portal_membership.h +26 -0
- package/src/portal_service.cc +401 -0
- package/src/portal_service.h +40 -0
- package/src/process.cc +135 -0
- package/src/process.h +30 -0
- package/src/relay.cc +139 -0
- package/src/relay.h +31 -0
- package/src/runtime.cc +443 -0
- package/src/runtime.h +64 -0
- package/src/script.cc +301 -0
- package/src/script.h +36 -0
- package/src/session.cc +860 -0
- package/src/session.h +42 -0
- package/src/signals.cc +334 -0
- package/src/signals.h +47 -0
- package/src/spawn.cc +95 -0
- package/src/spawn.h +27 -0
- package/src/usage_monitor.h +117 -0
- package/src/uv_context.cc +118 -0
- package/src/uv_context.h +40 -0
- package/src/win_delay_load_hook.cc +63 -0
- package/subprojects/frida-core.wrap +8 -0
- package/subprojects/nan.wrap +9 -0
- package/subprojects/packagefiles/nan.patch +13 -0
- package/test/data/index.ts +13 -0
- package/test/data/unixvictim-linux-x86 +0 -0
- package/test/data/unixvictim-linux-x86_64 +0 -0
- package/test/data/unixvictim-macos +0 -0
- package/test/device.ts +27 -0
- package/test/device_manager.ts +16 -0
- package/test/labrat.ts +32 -0
- package/test/script.ts +176 -0
- package/test/session.ts +73 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,814 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Copyright 2019 The Meson development team
|
|
3
|
+
|
|
4
|
+
# This class contains the basic functionality needed to run any interpreter
|
|
5
|
+
# or an interpreter-based tool.
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from .common import CMakeException
|
|
9
|
+
from .generator import parse_generator_expressions
|
|
10
|
+
from .. import mlog
|
|
11
|
+
from ..mesonlib import version_compare
|
|
12
|
+
|
|
13
|
+
import typing as T
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from functools import lru_cache
|
|
16
|
+
import re
|
|
17
|
+
import json
|
|
18
|
+
import textwrap
|
|
19
|
+
|
|
20
|
+
if T.TYPE_CHECKING:
|
|
21
|
+
from ..environment import Environment
|
|
22
|
+
|
|
23
|
+
class CMakeTraceLine:
|
|
24
|
+
def __init__(self, file_str: str, line: int, func: str, args: T.List[str]) -> None:
|
|
25
|
+
self.file = CMakeTraceLine._to_path(file_str)
|
|
26
|
+
self.line = line
|
|
27
|
+
self.func = func.lower()
|
|
28
|
+
self.args = args
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
@lru_cache(maxsize=None)
|
|
32
|
+
def _to_path(file_str: str) -> Path:
|
|
33
|
+
return Path(file_str)
|
|
34
|
+
|
|
35
|
+
def __repr__(self) -> str:
|
|
36
|
+
s = 'CMake TRACE: {0}:{1} {2}({3})'
|
|
37
|
+
return s.format(self.file, self.line, self.func, self.args)
|
|
38
|
+
|
|
39
|
+
class CMakeCacheEntry(T.NamedTuple):
|
|
40
|
+
value: T.List[str]
|
|
41
|
+
type: str
|
|
42
|
+
|
|
43
|
+
class CMakeTarget:
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
46
|
+
name: str,
|
|
47
|
+
target_type: str,
|
|
48
|
+
properties: T.Optional[T.Dict[str, T.List[str]]] = None,
|
|
49
|
+
imported: bool = False,
|
|
50
|
+
tline: T.Optional[CMakeTraceLine] = None
|
|
51
|
+
):
|
|
52
|
+
if properties is None:
|
|
53
|
+
properties = {}
|
|
54
|
+
self.name = name
|
|
55
|
+
self.type = target_type
|
|
56
|
+
self.properties = properties
|
|
57
|
+
self.imported = imported
|
|
58
|
+
self.tline = tline
|
|
59
|
+
self.depends: T.List[str] = []
|
|
60
|
+
self.current_bin_dir: T.Optional[Path] = None
|
|
61
|
+
self.current_src_dir: T.Optional[Path] = None
|
|
62
|
+
|
|
63
|
+
def __repr__(self) -> str:
|
|
64
|
+
s = 'CMake TARGET:\n -- name: {}\n -- type: {}\n -- imported: {}\n -- properties: {{\n{} }}\n -- tline: {}'
|
|
65
|
+
propSTR = ''
|
|
66
|
+
for i in self.properties:
|
|
67
|
+
propSTR += " '{}': {}\n".format(i, self.properties[i])
|
|
68
|
+
return s.format(self.name, self.type, self.imported, propSTR, self.tline)
|
|
69
|
+
|
|
70
|
+
def strip_properties(self) -> None:
|
|
71
|
+
# Strip the strings in the properties
|
|
72
|
+
if not self.properties:
|
|
73
|
+
return
|
|
74
|
+
for key, val in self.properties.items():
|
|
75
|
+
self.properties[key] = [x.strip() for x in val]
|
|
76
|
+
assert all(';' not in x for x in self.properties[key])
|
|
77
|
+
|
|
78
|
+
class CMakeGeneratorTarget(CMakeTarget):
|
|
79
|
+
def __init__(self, name: str) -> None:
|
|
80
|
+
super().__init__(name, 'CUSTOM', {})
|
|
81
|
+
self.outputs: T.List[Path] = []
|
|
82
|
+
self._outputs_str: T.List[str] = []
|
|
83
|
+
self.command: T.List[T.List[str]] = []
|
|
84
|
+
self.working_dir: T.Optional[Path] = None
|
|
85
|
+
|
|
86
|
+
class CMakeTraceParser:
|
|
87
|
+
def __init__(self, cmake_version: str, build_dir: Path, env: 'Environment', permissive: bool = True) -> None:
|
|
88
|
+
self.vars: T.Dict[str, T.List[str]] = {}
|
|
89
|
+
self.vars_by_file: T.Dict[Path, T.Dict[str, T.List[str]]] = {}
|
|
90
|
+
self.targets: T.Dict[str, CMakeTarget] = {}
|
|
91
|
+
self.cache: T.Dict[str, CMakeCacheEntry] = {}
|
|
92
|
+
|
|
93
|
+
self.explicit_headers: T.Set[Path] = set()
|
|
94
|
+
|
|
95
|
+
# T.List of targes that were added with add_custom_command to generate files
|
|
96
|
+
self.custom_targets: T.List[CMakeGeneratorTarget] = []
|
|
97
|
+
|
|
98
|
+
self.env = env
|
|
99
|
+
self.permissive = permissive
|
|
100
|
+
self.cmake_version = cmake_version
|
|
101
|
+
self.trace_file = 'cmake_trace.txt'
|
|
102
|
+
self.trace_file_path = build_dir / self.trace_file
|
|
103
|
+
self.trace_format = 'json-v1' if version_compare(cmake_version, '>=3.17') else 'human'
|
|
104
|
+
|
|
105
|
+
self.errors: T.List[str] = []
|
|
106
|
+
|
|
107
|
+
# State for delayed command execution. Delayed command execution is realised
|
|
108
|
+
# with a custom CMake file that overrides some functions and adds some
|
|
109
|
+
# introspection information to the trace.
|
|
110
|
+
self.delayed_commands: T.List[str] = []
|
|
111
|
+
self.stored_commands: T.List[CMakeTraceLine] = []
|
|
112
|
+
|
|
113
|
+
# All supported functions
|
|
114
|
+
self.functions: T.Dict[str, T.Callable[[CMakeTraceLine], None]] = {
|
|
115
|
+
'set': self._cmake_set,
|
|
116
|
+
'unset': self._cmake_unset,
|
|
117
|
+
'add_executable': self._cmake_add_executable,
|
|
118
|
+
'add_library': self._cmake_add_library,
|
|
119
|
+
'add_custom_command': self._cmake_add_custom_command,
|
|
120
|
+
'add_custom_target': self._cmake_add_custom_target,
|
|
121
|
+
'set_property': self._cmake_set_property,
|
|
122
|
+
'set_target_properties': self._cmake_set_target_properties,
|
|
123
|
+
'target_compile_definitions': self._cmake_target_compile_definitions,
|
|
124
|
+
'target_compile_options': self._cmake_target_compile_options,
|
|
125
|
+
'target_include_directories': self._cmake_target_include_directories,
|
|
126
|
+
'target_link_libraries': self._cmake_target_link_libraries,
|
|
127
|
+
'target_link_options': self._cmake_target_link_options,
|
|
128
|
+
'add_dependencies': self._cmake_add_dependencies,
|
|
129
|
+
'message': self._cmake_message,
|
|
130
|
+
|
|
131
|
+
# Special functions defined in the preload script.
|
|
132
|
+
# These functions do nothing in the CMake code, but have special
|
|
133
|
+
# meaning here in the trace parser.
|
|
134
|
+
'meson_ps_execute_delayed_calls': self._meson_ps_execute_delayed_calls,
|
|
135
|
+
'meson_ps_reload_vars': self._meson_ps_reload_vars,
|
|
136
|
+
'meson_ps_disabled_function': self._meson_ps_disabled_function,
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if version_compare(self.cmake_version, '<3.17.0'):
|
|
140
|
+
mlog.deprecation(textwrap.dedent(f'''\
|
|
141
|
+
CMake support for versions <3.17 is deprecated since Meson 0.62.0.
|
|
142
|
+
|
|
|
143
|
+
| However, Meson was only able to find CMake {self.cmake_version}.
|
|
144
|
+
|
|
|
145
|
+
| Support for all CMake versions below 3.17.0 will be removed once
|
|
146
|
+
| newer CMake versions are more widely adopted. If you encounter
|
|
147
|
+
| any errors please try upgrading CMake to a newer version first.
|
|
148
|
+
'''), once=True)
|
|
149
|
+
|
|
150
|
+
def trace_args(self) -> T.List[str]:
|
|
151
|
+
arg_map = {
|
|
152
|
+
'human': ['--trace', '--trace-expand'],
|
|
153
|
+
'json-v1': ['--trace-expand', '--trace-format=json-v1'],
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
base_args = ['--no-warn-unused-cli']
|
|
157
|
+
if not self.requires_stderr():
|
|
158
|
+
base_args += [f'--trace-redirect={self.trace_file}']
|
|
159
|
+
|
|
160
|
+
return arg_map[self.trace_format] + base_args
|
|
161
|
+
|
|
162
|
+
def requires_stderr(self) -> bool:
|
|
163
|
+
return version_compare(self.cmake_version, '<3.16')
|
|
164
|
+
|
|
165
|
+
def parse(self, trace: T.Optional[str] = None) -> None:
|
|
166
|
+
# First load the trace (if required)
|
|
167
|
+
if not self.requires_stderr():
|
|
168
|
+
if not self.trace_file_path.exists and not self.trace_file_path.is_file():
|
|
169
|
+
raise CMakeException(f'CMake: Trace file "{self.trace_file_path!s}" not found')
|
|
170
|
+
trace = self.trace_file_path.read_text(errors='ignore', encoding='utf-8')
|
|
171
|
+
if not trace:
|
|
172
|
+
raise CMakeException('CMake: The CMake trace was not provided or is empty')
|
|
173
|
+
|
|
174
|
+
# Second parse the trace
|
|
175
|
+
lexer1 = None
|
|
176
|
+
if self.trace_format == 'human':
|
|
177
|
+
lexer1 = self._lex_trace_human(trace)
|
|
178
|
+
elif self.trace_format == 'json-v1':
|
|
179
|
+
lexer1 = self._lex_trace_json(trace)
|
|
180
|
+
else:
|
|
181
|
+
raise CMakeException(f'CMake: Internal error: Invalid trace format {self.trace_format}. Expected [human, json-v1]')
|
|
182
|
+
|
|
183
|
+
# Primary pass -- parse everything
|
|
184
|
+
for l in lexer1:
|
|
185
|
+
# store the function if its execution should be delayed
|
|
186
|
+
if l.func in self.delayed_commands:
|
|
187
|
+
self.stored_commands += [l]
|
|
188
|
+
continue
|
|
189
|
+
|
|
190
|
+
# "Execute" the CMake function if supported
|
|
191
|
+
fn = self.functions.get(l.func, None)
|
|
192
|
+
if fn:
|
|
193
|
+
fn(l)
|
|
194
|
+
|
|
195
|
+
# Evaluate generator expressions
|
|
196
|
+
strlist_gen: T.Callable[[T.List[str]], T.List[str]] = lambda strlist: parse_generator_expressions(';'.join(strlist), self).split(';') if strlist else []
|
|
197
|
+
pathlist_gen: T.Callable[[T.List[str]], T.List[Path]] = lambda strlist: [Path(x) for x in parse_generator_expressions(';'.join(strlist), self).split(';')] if strlist else []
|
|
198
|
+
|
|
199
|
+
self.vars = {k: strlist_gen(v) for k, v in self.vars.items()}
|
|
200
|
+
self.vars_by_file = {
|
|
201
|
+
p: {k: strlist_gen(v) for k, v in d.items()}
|
|
202
|
+
for p, d in self.vars_by_file.items()
|
|
203
|
+
}
|
|
204
|
+
self.explicit_headers = {Path(parse_generator_expressions(str(x), self)) for x in self.explicit_headers}
|
|
205
|
+
self.cache = {
|
|
206
|
+
k: CMakeCacheEntry(
|
|
207
|
+
strlist_gen(v.value),
|
|
208
|
+
v.type
|
|
209
|
+
)
|
|
210
|
+
for k, v in self.cache.items()
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
for tgt in self.targets.values():
|
|
214
|
+
tgtlist_gen: T.Callable[[T.List[str], CMakeTarget], T.List[str]] = lambda strlist, t: parse_generator_expressions(';'.join(strlist), self, context_tgt=t).split(';') if strlist else []
|
|
215
|
+
tgt.name = parse_generator_expressions(tgt.name, self, context_tgt=tgt)
|
|
216
|
+
tgt.type = parse_generator_expressions(tgt.type, self, context_tgt=tgt)
|
|
217
|
+
tgt.properties = {
|
|
218
|
+
k: tgtlist_gen(v, tgt) for k, v in tgt.properties.items()
|
|
219
|
+
} if tgt.properties is not None else None
|
|
220
|
+
tgt.depends = tgtlist_gen(tgt.depends, tgt)
|
|
221
|
+
|
|
222
|
+
for ctgt in self.custom_targets:
|
|
223
|
+
ctgt.outputs = pathlist_gen(ctgt._outputs_str)
|
|
224
|
+
temp = ctgt.command
|
|
225
|
+
ctgt.command = [strlist_gen(x) for x in ctgt.command]
|
|
226
|
+
for command, src in zip(ctgt.command, temp):
|
|
227
|
+
if command[0] == "":
|
|
228
|
+
raise CMakeException(
|
|
229
|
+
"We evaluated the cmake variable '{}' to an empty string, which is not a valid path to an executable.".format(src[0])
|
|
230
|
+
)
|
|
231
|
+
ctgt.working_dir = Path(parse_generator_expressions(str(ctgt.working_dir), self)) if ctgt.working_dir is not None else None
|
|
232
|
+
|
|
233
|
+
# Postprocess
|
|
234
|
+
for tgt in self.targets.values():
|
|
235
|
+
tgt.strip_properties()
|
|
236
|
+
|
|
237
|
+
def get_first_cmake_var_of(self, var_list: T.List[str]) -> T.List[str]:
|
|
238
|
+
# Return the first found CMake variable in list var_list
|
|
239
|
+
for i in var_list:
|
|
240
|
+
if i in self.vars:
|
|
241
|
+
return self.vars[i]
|
|
242
|
+
|
|
243
|
+
return []
|
|
244
|
+
|
|
245
|
+
def get_cmake_var(self, var: str) -> T.List[str]:
|
|
246
|
+
# Return the value of the CMake variable var or an empty list if var does not exist
|
|
247
|
+
if var in self.vars:
|
|
248
|
+
return self.vars[var]
|
|
249
|
+
|
|
250
|
+
return []
|
|
251
|
+
|
|
252
|
+
def var_to_str(self, var: str) -> T.Optional[str]:
|
|
253
|
+
if var in self.vars and self.vars[var]:
|
|
254
|
+
return self.vars[var][0]
|
|
255
|
+
|
|
256
|
+
return None
|
|
257
|
+
|
|
258
|
+
def _str_to_bool(self, expr: T.Union[str, T.List[str]]) -> bool:
|
|
259
|
+
if not expr:
|
|
260
|
+
return False
|
|
261
|
+
if isinstance(expr, list):
|
|
262
|
+
expr_str = expr[0]
|
|
263
|
+
else:
|
|
264
|
+
expr_str = expr
|
|
265
|
+
expr_str = expr_str.upper()
|
|
266
|
+
return expr_str not in ['0', 'OFF', 'NO', 'FALSE', 'N', 'IGNORE'] and not expr_str.endswith('NOTFOUND')
|
|
267
|
+
|
|
268
|
+
def var_to_bool(self, var: str) -> bool:
|
|
269
|
+
return self._str_to_bool(self.vars.get(var, []))
|
|
270
|
+
|
|
271
|
+
def _gen_exception(self, function: str, error: str, tline: CMakeTraceLine) -> None:
|
|
272
|
+
# Generate an exception if the parser is not in permissive mode
|
|
273
|
+
|
|
274
|
+
if self.permissive:
|
|
275
|
+
mlog.debug(f'CMake trace warning: {function}() {error}\n{tline}')
|
|
276
|
+
return None
|
|
277
|
+
raise CMakeException(f'CMake: {function}() {error}\n{tline}')
|
|
278
|
+
|
|
279
|
+
def _cmake_set(self, tline: CMakeTraceLine) -> None:
|
|
280
|
+
"""Handler for the CMake set() function in all varieties.
|
|
281
|
+
|
|
282
|
+
comes in three flavors:
|
|
283
|
+
set(<var> <value> [PARENT_SCOPE])
|
|
284
|
+
set(<var> <value> CACHE <type> <docstring> [FORCE])
|
|
285
|
+
set(ENV{<var>} <value>)
|
|
286
|
+
|
|
287
|
+
We don't support the ENV variant, and any uses of it will be ignored
|
|
288
|
+
silently. the other two variates are supported, with some caveats:
|
|
289
|
+
- we don't properly handle scoping, so calls to set() inside a
|
|
290
|
+
function without PARENT_SCOPE set could incorrectly shadow the
|
|
291
|
+
outer scope.
|
|
292
|
+
- We don't honor the type of CACHE arguments
|
|
293
|
+
"""
|
|
294
|
+
# DOC: https://cmake.org/cmake/help/latest/command/set.html
|
|
295
|
+
|
|
296
|
+
cache_type = None
|
|
297
|
+
cache_force = 'FORCE' in tline.args
|
|
298
|
+
try:
|
|
299
|
+
cache_idx = tline.args.index('CACHE')
|
|
300
|
+
cache_type = tline.args[cache_idx + 1]
|
|
301
|
+
except (ValueError, IndexError):
|
|
302
|
+
pass
|
|
303
|
+
|
|
304
|
+
# 1st remove PARENT_SCOPE and CACHE from args
|
|
305
|
+
args = []
|
|
306
|
+
for i in tline.args:
|
|
307
|
+
if not i or i == 'PARENT_SCOPE':
|
|
308
|
+
continue
|
|
309
|
+
|
|
310
|
+
# Discard everything after the CACHE keyword
|
|
311
|
+
if i == 'CACHE':
|
|
312
|
+
break
|
|
313
|
+
|
|
314
|
+
args.append(i)
|
|
315
|
+
|
|
316
|
+
if len(args) < 1:
|
|
317
|
+
return self._gen_exception('set', 'requires at least one argument', tline)
|
|
318
|
+
|
|
319
|
+
# Now that we've removed extra arguments all that should be left is the
|
|
320
|
+
# variable identifier and the value, join the value back together to
|
|
321
|
+
# ensure spaces in the value are correctly handled. This assumes that
|
|
322
|
+
# variable names don't have spaces. Please don't do that...
|
|
323
|
+
identifier = args.pop(0)
|
|
324
|
+
value = ' '.join(args)
|
|
325
|
+
|
|
326
|
+
# Write to the CMake cache instead
|
|
327
|
+
if cache_type:
|
|
328
|
+
# Honor how the CMake FORCE parameter works
|
|
329
|
+
if identifier not in self.cache or cache_force:
|
|
330
|
+
self.cache[identifier] = CMakeCacheEntry(value.split(';'), cache_type)
|
|
331
|
+
|
|
332
|
+
if not value:
|
|
333
|
+
# Same as unset
|
|
334
|
+
if identifier in self.vars:
|
|
335
|
+
del self.vars[identifier]
|
|
336
|
+
else:
|
|
337
|
+
self.vars[identifier] = value.split(';')
|
|
338
|
+
self.vars_by_file.setdefault(tline.file, {})[identifier] = value.split(';')
|
|
339
|
+
|
|
340
|
+
def _cmake_unset(self, tline: CMakeTraceLine) -> None:
|
|
341
|
+
# DOC: https://cmake.org/cmake/help/latest/command/unset.html
|
|
342
|
+
if len(tline.args) < 1:
|
|
343
|
+
return self._gen_exception('unset', 'requires at least one argument', tline)
|
|
344
|
+
|
|
345
|
+
if tline.args[0] in self.vars:
|
|
346
|
+
del self.vars[tline.args[0]]
|
|
347
|
+
|
|
348
|
+
def _cmake_add_executable(self, tline: CMakeTraceLine) -> None:
|
|
349
|
+
# DOC: https://cmake.org/cmake/help/latest/command/add_executable.html
|
|
350
|
+
args = list(tline.args) # Make a working copy
|
|
351
|
+
|
|
352
|
+
# Make sure the exe is imported
|
|
353
|
+
is_imported = True
|
|
354
|
+
if 'IMPORTED' not in args:
|
|
355
|
+
return self._gen_exception('add_executable', 'non imported executables are not supported', tline)
|
|
356
|
+
|
|
357
|
+
args.remove('IMPORTED')
|
|
358
|
+
|
|
359
|
+
if len(args) < 1:
|
|
360
|
+
return self._gen_exception('add_executable', 'requires at least 1 argument', tline)
|
|
361
|
+
|
|
362
|
+
self.targets[args[0]] = CMakeTarget(args[0], 'EXECUTABLE', {}, tline=tline, imported=is_imported)
|
|
363
|
+
|
|
364
|
+
def _cmake_add_library(self, tline: CMakeTraceLine) -> None:
|
|
365
|
+
# DOC: https://cmake.org/cmake/help/latest/command/add_library.html
|
|
366
|
+
args = list(tline.args) # Make a working copy
|
|
367
|
+
|
|
368
|
+
# Make sure the lib is imported
|
|
369
|
+
if 'INTERFACE' in args:
|
|
370
|
+
args.remove('INTERFACE')
|
|
371
|
+
|
|
372
|
+
if len(args) < 1:
|
|
373
|
+
return self._gen_exception('add_library', 'interface library name not specified', tline)
|
|
374
|
+
|
|
375
|
+
self.targets[args[0]] = CMakeTarget(args[0], 'INTERFACE', {}, tline=tline, imported='IMPORTED' in args)
|
|
376
|
+
elif 'IMPORTED' in args:
|
|
377
|
+
args.remove('IMPORTED')
|
|
378
|
+
|
|
379
|
+
# Now, only look at the first two arguments (target_name and target_type) and ignore the rest
|
|
380
|
+
if len(args) < 2:
|
|
381
|
+
return self._gen_exception('add_library', 'requires at least 2 arguments', tline)
|
|
382
|
+
|
|
383
|
+
self.targets[args[0]] = CMakeTarget(args[0], args[1], {}, tline=tline, imported=True)
|
|
384
|
+
elif 'ALIAS' in args:
|
|
385
|
+
args.remove('ALIAS')
|
|
386
|
+
|
|
387
|
+
# Now, only look at the first two arguments (target_name and target_ref) and ignore the rest
|
|
388
|
+
if len(args) < 2:
|
|
389
|
+
return self._gen_exception('add_library', 'requires at least 2 arguments', tline)
|
|
390
|
+
|
|
391
|
+
# Simulate the ALIAS with INTERFACE_LINK_LIBRARIES
|
|
392
|
+
self.targets[args[0]] = CMakeTarget(args[0], 'ALIAS', {'INTERFACE_LINK_LIBRARIES': [args[1]]}, tline=tline)
|
|
393
|
+
elif 'OBJECT' in args:
|
|
394
|
+
return self._gen_exception('add_library', 'OBJECT libraries are not supported', tline)
|
|
395
|
+
else:
|
|
396
|
+
self.targets[args[0]] = CMakeTarget(args[0], 'NORMAL', {}, tline=tline)
|
|
397
|
+
|
|
398
|
+
def _cmake_add_custom_command(self, tline: CMakeTraceLine, name: T.Optional[str] = None) -> None:
|
|
399
|
+
# DOC: https://cmake.org/cmake/help/latest/command/add_custom_command.html
|
|
400
|
+
args = self._flatten_args(list(tline.args)) # Commands can be passed as ';' separated lists
|
|
401
|
+
|
|
402
|
+
if not args:
|
|
403
|
+
return self._gen_exception('add_custom_command', 'requires at least 1 argument', tline)
|
|
404
|
+
|
|
405
|
+
# Skip the second function signature
|
|
406
|
+
if args[0] == 'TARGET':
|
|
407
|
+
return self._gen_exception('add_custom_command', 'TARGET syntax is currently not supported', tline)
|
|
408
|
+
|
|
409
|
+
magic_keys = ['OUTPUT', 'COMMAND', 'MAIN_DEPENDENCY', 'DEPENDS', 'BYPRODUCTS',
|
|
410
|
+
'IMPLICIT_DEPENDS', 'WORKING_DIRECTORY', 'COMMENT', 'DEPFILE',
|
|
411
|
+
'JOB_POOL', 'VERBATIM', 'APPEND', 'USES_TERMINAL', 'COMMAND_EXPAND_LISTS']
|
|
412
|
+
|
|
413
|
+
target = CMakeGeneratorTarget(name)
|
|
414
|
+
|
|
415
|
+
def handle_output(key: str, target: CMakeGeneratorTarget) -> None:
|
|
416
|
+
target._outputs_str += [key]
|
|
417
|
+
|
|
418
|
+
def handle_command(key: str, target: CMakeGeneratorTarget) -> None:
|
|
419
|
+
if key == 'ARGS':
|
|
420
|
+
return
|
|
421
|
+
target.command[-1] += [key]
|
|
422
|
+
|
|
423
|
+
def handle_depends(key: str, target: CMakeGeneratorTarget) -> None:
|
|
424
|
+
target.depends += [key]
|
|
425
|
+
|
|
426
|
+
working_dir = None
|
|
427
|
+
|
|
428
|
+
def handle_working_dir(key: str, target: CMakeGeneratorTarget) -> None:
|
|
429
|
+
nonlocal working_dir
|
|
430
|
+
if working_dir is None:
|
|
431
|
+
working_dir = key
|
|
432
|
+
else:
|
|
433
|
+
working_dir += ' '
|
|
434
|
+
working_dir += key
|
|
435
|
+
|
|
436
|
+
fn = None
|
|
437
|
+
|
|
438
|
+
for i in args:
|
|
439
|
+
if i in magic_keys:
|
|
440
|
+
if i == 'OUTPUT':
|
|
441
|
+
fn = handle_output
|
|
442
|
+
elif i == 'DEPENDS':
|
|
443
|
+
fn = handle_depends
|
|
444
|
+
elif i == 'WORKING_DIRECTORY':
|
|
445
|
+
fn = handle_working_dir
|
|
446
|
+
elif i == 'COMMAND':
|
|
447
|
+
fn = handle_command
|
|
448
|
+
target.command += [[]]
|
|
449
|
+
else:
|
|
450
|
+
fn = None
|
|
451
|
+
continue
|
|
452
|
+
|
|
453
|
+
if fn is not None:
|
|
454
|
+
fn(i, target)
|
|
455
|
+
|
|
456
|
+
cbinary_dir = self.var_to_str('MESON_PS_CMAKE_CURRENT_BINARY_DIR')
|
|
457
|
+
csource_dir = self.var_to_str('MESON_PS_CMAKE_CURRENT_SOURCE_DIR')
|
|
458
|
+
|
|
459
|
+
target.working_dir = Path(working_dir) if working_dir else None
|
|
460
|
+
target.current_bin_dir = Path(cbinary_dir) if cbinary_dir else None
|
|
461
|
+
target.current_src_dir = Path(csource_dir) if csource_dir else None
|
|
462
|
+
target._outputs_str = self._guess_files(target._outputs_str)
|
|
463
|
+
target.depends = self._guess_files(target.depends)
|
|
464
|
+
target.command = [self._guess_files(x) for x in target.command]
|
|
465
|
+
|
|
466
|
+
self.custom_targets += [target]
|
|
467
|
+
if name:
|
|
468
|
+
self.targets[name] = target
|
|
469
|
+
|
|
470
|
+
def _cmake_add_custom_target(self, tline: CMakeTraceLine) -> None:
|
|
471
|
+
# DOC: https://cmake.org/cmake/help/latest/command/add_custom_target.html
|
|
472
|
+
# We only the first parameter (the target name) is interesting
|
|
473
|
+
if len(tline.args) < 1:
|
|
474
|
+
return self._gen_exception('add_custom_target', 'requires at least one argument', tline)
|
|
475
|
+
|
|
476
|
+
# It's pretty much the same as a custom command
|
|
477
|
+
self._cmake_add_custom_command(tline, tline.args[0])
|
|
478
|
+
|
|
479
|
+
def _cmake_set_property(self, tline: CMakeTraceLine) -> None:
|
|
480
|
+
# DOC: https://cmake.org/cmake/help/latest/command/set_property.html
|
|
481
|
+
args = list(tline.args)
|
|
482
|
+
|
|
483
|
+
scope = args.pop(0)
|
|
484
|
+
|
|
485
|
+
append = False
|
|
486
|
+
targets = []
|
|
487
|
+
while args:
|
|
488
|
+
curr = args.pop(0)
|
|
489
|
+
# XXX: APPEND_STRING is specifically *not* supposed to create a
|
|
490
|
+
# list, is treating them as aliases really okay?
|
|
491
|
+
if curr in {'APPEND', 'APPEND_STRING'}:
|
|
492
|
+
append = True
|
|
493
|
+
continue
|
|
494
|
+
|
|
495
|
+
if curr == 'PROPERTY':
|
|
496
|
+
break
|
|
497
|
+
|
|
498
|
+
targets += curr.split(';')
|
|
499
|
+
|
|
500
|
+
if not args:
|
|
501
|
+
return self._gen_exception('set_property', 'failed to parse argument list', tline)
|
|
502
|
+
|
|
503
|
+
if len(args) == 1:
|
|
504
|
+
# Tries to set property to nothing so nothing has to be done
|
|
505
|
+
return
|
|
506
|
+
|
|
507
|
+
identifier = args.pop(0)
|
|
508
|
+
if self.trace_format == 'human':
|
|
509
|
+
value = ' '.join(args).split(';')
|
|
510
|
+
else:
|
|
511
|
+
value = [y for x in args for y in x.split(';')]
|
|
512
|
+
if not value:
|
|
513
|
+
return
|
|
514
|
+
|
|
515
|
+
def do_target(t: str) -> None:
|
|
516
|
+
if t not in self.targets:
|
|
517
|
+
return self._gen_exception('set_property', f'TARGET {t} not found', tline)
|
|
518
|
+
|
|
519
|
+
tgt = self.targets[t]
|
|
520
|
+
if identifier not in tgt.properties:
|
|
521
|
+
tgt.properties[identifier] = []
|
|
522
|
+
|
|
523
|
+
if append:
|
|
524
|
+
tgt.properties[identifier] += value
|
|
525
|
+
else:
|
|
526
|
+
tgt.properties[identifier] = value
|
|
527
|
+
|
|
528
|
+
def do_source(src: str) -> None:
|
|
529
|
+
if identifier != 'HEADER_FILE_ONLY' or not self._str_to_bool(value):
|
|
530
|
+
return
|
|
531
|
+
|
|
532
|
+
current_src_dir = self.var_to_str('MESON_PS_CMAKE_CURRENT_SOURCE_DIR')
|
|
533
|
+
if not current_src_dir:
|
|
534
|
+
mlog.warning(textwrap.dedent('''\
|
|
535
|
+
CMake trace: set_property(SOURCE) called before the preload script was loaded.
|
|
536
|
+
Unable to determine CMAKE_CURRENT_SOURCE_DIR. This can lead to build errors.
|
|
537
|
+
'''))
|
|
538
|
+
current_src_dir = '.'
|
|
539
|
+
|
|
540
|
+
cur_p = Path(current_src_dir)
|
|
541
|
+
src_p = Path(src)
|
|
542
|
+
|
|
543
|
+
if not src_p.is_absolute():
|
|
544
|
+
src_p = cur_p / src_p
|
|
545
|
+
self.explicit_headers.add(src_p)
|
|
546
|
+
|
|
547
|
+
if scope == 'TARGET':
|
|
548
|
+
for i in targets:
|
|
549
|
+
do_target(i)
|
|
550
|
+
elif scope == 'SOURCE':
|
|
551
|
+
files = self._guess_files(targets)
|
|
552
|
+
for i in files:
|
|
553
|
+
do_source(i)
|
|
554
|
+
|
|
555
|
+
def _cmake_set_target_properties(self, tline: CMakeTraceLine) -> None:
|
|
556
|
+
# DOC: https://cmake.org/cmake/help/latest/command/set_target_properties.html
|
|
557
|
+
args = list(tline.args)
|
|
558
|
+
|
|
559
|
+
targets = []
|
|
560
|
+
while args:
|
|
561
|
+
curr = args.pop(0)
|
|
562
|
+
if curr == 'PROPERTIES':
|
|
563
|
+
break
|
|
564
|
+
|
|
565
|
+
targets.append(curr)
|
|
566
|
+
|
|
567
|
+
# Now we need to try to reconstitute the original quoted format of the
|
|
568
|
+
# arguments, as a property value could have spaces in it. Unlike
|
|
569
|
+
# set_property() this is not context free. There are two approaches I
|
|
570
|
+
# can think of, both have drawbacks:
|
|
571
|
+
#
|
|
572
|
+
# 1. Assume that the property will be capitalized ([A-Z_]), this is
|
|
573
|
+
# convention but cmake doesn't require it.
|
|
574
|
+
# 2. Maintain a copy of the list here: https://cmake.org/cmake/help/latest/manual/cmake-properties.7.html#target-properties
|
|
575
|
+
#
|
|
576
|
+
# Neither of these is awesome for obvious reasons. I'm going to try
|
|
577
|
+
# option 1 first and fall back to 2, as 1 requires less code and less
|
|
578
|
+
# synchronization for cmake changes.
|
|
579
|
+
#
|
|
580
|
+
# With the JSON output format, introduced in CMake 3.17, spaces are
|
|
581
|
+
# handled properly and we don't have to do either options
|
|
582
|
+
|
|
583
|
+
arglist: T.List[T.Tuple[str, T.List[str]]] = []
|
|
584
|
+
if self.trace_format == 'human':
|
|
585
|
+
name = args.pop(0)
|
|
586
|
+
values: T.List[str] = []
|
|
587
|
+
prop_regex = re.compile(r'^[A-Z_]+$')
|
|
588
|
+
for a in args:
|
|
589
|
+
if prop_regex.match(a):
|
|
590
|
+
if values:
|
|
591
|
+
arglist.append((name, ' '.join(values).split(';')))
|
|
592
|
+
name = a
|
|
593
|
+
values = []
|
|
594
|
+
else:
|
|
595
|
+
values.append(a)
|
|
596
|
+
if values:
|
|
597
|
+
arglist.append((name, ' '.join(values).split(';')))
|
|
598
|
+
else:
|
|
599
|
+
arglist = [(x[0], x[1].split(';')) for x in zip(args[::2], args[1::2])]
|
|
600
|
+
|
|
601
|
+
for name, value in arglist:
|
|
602
|
+
for i in targets:
|
|
603
|
+
if i not in self.targets:
|
|
604
|
+
return self._gen_exception('set_target_properties', f'TARGET {i} not found', tline)
|
|
605
|
+
|
|
606
|
+
self.targets[i].properties[name] = value
|
|
607
|
+
|
|
608
|
+
def _cmake_add_dependencies(self, tline: CMakeTraceLine) -> None:
|
|
609
|
+
# DOC: https://cmake.org/cmake/help/latest/command/add_dependencies.html
|
|
610
|
+
args = list(tline.args)
|
|
611
|
+
|
|
612
|
+
if len(args) < 2:
|
|
613
|
+
return self._gen_exception('add_dependencies', 'takes at least 2 arguments', tline)
|
|
614
|
+
|
|
615
|
+
target = self.targets.get(args[0])
|
|
616
|
+
if not target:
|
|
617
|
+
return self._gen_exception('add_dependencies', 'target not found', tline)
|
|
618
|
+
|
|
619
|
+
for i in args[1:]:
|
|
620
|
+
target.depends += i.split(';')
|
|
621
|
+
|
|
622
|
+
def _cmake_target_compile_definitions(self, tline: CMakeTraceLine) -> None:
|
|
623
|
+
# DOC: https://cmake.org/cmake/help/latest/command/target_compile_definitions.html
|
|
624
|
+
self._parse_common_target_options('target_compile_definitions', 'COMPILE_DEFINITIONS', 'INTERFACE_COMPILE_DEFINITIONS', tline)
|
|
625
|
+
|
|
626
|
+
def _cmake_target_compile_options(self, tline: CMakeTraceLine) -> None:
|
|
627
|
+
# DOC: https://cmake.org/cmake/help/latest/command/target_compile_options.html
|
|
628
|
+
self._parse_common_target_options('target_compile_options', 'COMPILE_OPTIONS', 'INTERFACE_COMPILE_OPTIONS', tline)
|
|
629
|
+
|
|
630
|
+
def _cmake_target_include_directories(self, tline: CMakeTraceLine) -> None:
|
|
631
|
+
# DOC: https://cmake.org/cmake/help/latest/command/target_include_directories.html
|
|
632
|
+
self._parse_common_target_options('target_include_directories', 'INCLUDE_DIRECTORIES', 'INTERFACE_INCLUDE_DIRECTORIES', tline, ignore=['SYSTEM', 'BEFORE'], paths=True)
|
|
633
|
+
|
|
634
|
+
def _cmake_target_link_options(self, tline: CMakeTraceLine) -> None:
|
|
635
|
+
# DOC: https://cmake.org/cmake/help/latest/command/target_link_options.html
|
|
636
|
+
self._parse_common_target_options('target_link_options', 'LINK_OPTIONS', 'INTERFACE_LINK_OPTIONS', tline)
|
|
637
|
+
|
|
638
|
+
def _cmake_target_link_libraries(self, tline: CMakeTraceLine) -> None:
|
|
639
|
+
# DOC: https://cmake.org/cmake/help/latest/command/target_link_libraries.html
|
|
640
|
+
self._parse_common_target_options('target_link_options', 'LINK_LIBRARIES', 'INTERFACE_LINK_LIBRARIES', tline)
|
|
641
|
+
|
|
642
|
+
def _cmake_message(self, tline: CMakeTraceLine) -> None:
|
|
643
|
+
# DOC: https://cmake.org/cmake/help/latest/command/message.html
|
|
644
|
+
args = list(tline.args)
|
|
645
|
+
|
|
646
|
+
if len(args) < 1:
|
|
647
|
+
return self._gen_exception('message', 'takes at least 1 argument', tline)
|
|
648
|
+
|
|
649
|
+
if args[0].upper().strip() not in ['FATAL_ERROR', 'SEND_ERROR']:
|
|
650
|
+
return
|
|
651
|
+
|
|
652
|
+
self.errors += [' '.join(args[1:])]
|
|
653
|
+
|
|
654
|
+
def _parse_common_target_options(self, func: str, private_prop: str, interface_prop: str, tline: CMakeTraceLine, ignore: T.Optional[T.List[str]] = None, paths: bool = False) -> None:
|
|
655
|
+
if ignore is None:
|
|
656
|
+
ignore = ['BEFORE']
|
|
657
|
+
|
|
658
|
+
args = list(tline.args)
|
|
659
|
+
|
|
660
|
+
if len(args) < 1:
|
|
661
|
+
return self._gen_exception(func, 'requires at least one argument', tline)
|
|
662
|
+
|
|
663
|
+
target = args[0]
|
|
664
|
+
if target not in self.targets:
|
|
665
|
+
return self._gen_exception(func, f'TARGET {target} not found', tline)
|
|
666
|
+
|
|
667
|
+
interface = []
|
|
668
|
+
private = []
|
|
669
|
+
|
|
670
|
+
mode = 'PUBLIC'
|
|
671
|
+
for i in args[1:]:
|
|
672
|
+
if i in ignore:
|
|
673
|
+
continue
|
|
674
|
+
|
|
675
|
+
if i in {'INTERFACE', 'LINK_INTERFACE_LIBRARIES', 'PUBLIC', 'PRIVATE', 'LINK_PUBLIC', 'LINK_PRIVATE'}:
|
|
676
|
+
mode = i
|
|
677
|
+
continue
|
|
678
|
+
|
|
679
|
+
if mode in {'INTERFACE', 'LINK_INTERFACE_LIBRARIES', 'PUBLIC', 'LINK_PUBLIC'}:
|
|
680
|
+
interface += i.split(';')
|
|
681
|
+
|
|
682
|
+
if mode in {'PUBLIC', 'PRIVATE', 'LINK_PRIVATE'}:
|
|
683
|
+
private += i.split(';')
|
|
684
|
+
|
|
685
|
+
if paths:
|
|
686
|
+
interface = self._guess_files(interface)
|
|
687
|
+
private = self._guess_files(private)
|
|
688
|
+
|
|
689
|
+
interface = [x for x in interface if x]
|
|
690
|
+
private = [x for x in private if x]
|
|
691
|
+
|
|
692
|
+
for j in [(private_prop, private), (interface_prop, interface)]:
|
|
693
|
+
if not j[0] in self.targets[target].properties:
|
|
694
|
+
self.targets[target].properties[j[0]] = []
|
|
695
|
+
|
|
696
|
+
self.targets[target].properties[j[0]] += j[1]
|
|
697
|
+
|
|
698
|
+
def _meson_ps_execute_delayed_calls(self, tline: CMakeTraceLine) -> None:
|
|
699
|
+
for l in self.stored_commands:
|
|
700
|
+
fn = self.functions.get(l.func, None)
|
|
701
|
+
if fn:
|
|
702
|
+
fn(l)
|
|
703
|
+
|
|
704
|
+
# clear the stored commands
|
|
705
|
+
self.stored_commands = []
|
|
706
|
+
|
|
707
|
+
def _meson_ps_reload_vars(self, tline: CMakeTraceLine) -> None:
|
|
708
|
+
self.delayed_commands = self.get_cmake_var('MESON_PS_DELAYED_CALLS')
|
|
709
|
+
|
|
710
|
+
def _meson_ps_disabled_function(self, tline: CMakeTraceLine) -> None:
|
|
711
|
+
args = list(tline.args)
|
|
712
|
+
if not args:
|
|
713
|
+
mlog.error('Invalid preload.cmake script! At least one argument to `meson_ps_disabled_function` is expected')
|
|
714
|
+
return
|
|
715
|
+
mlog.warning(f'The CMake function "{args[0]}" was disabled to avoid compatibility issues with Meson.')
|
|
716
|
+
|
|
717
|
+
def _lex_trace_human(self, trace: str) -> T.Generator[CMakeTraceLine, None, None]:
|
|
718
|
+
# The trace format is: '<file>(<line>): <func>(<args -- can contain \n> )\n'
|
|
719
|
+
reg_tline = re.compile(r'\s*(.*\.(cmake|txt))\(([0-9]+)\):\s*(\w+)\(([\s\S]*?) ?\)\s*\n', re.MULTILINE)
|
|
720
|
+
reg_other = re.compile(r'[^\n]*\n')
|
|
721
|
+
loc = 0
|
|
722
|
+
while loc < len(trace):
|
|
723
|
+
mo_file_line = reg_tline.match(trace, loc)
|
|
724
|
+
if not mo_file_line:
|
|
725
|
+
skip_match = reg_other.match(trace, loc)
|
|
726
|
+
if not skip_match:
|
|
727
|
+
print(trace[loc:])
|
|
728
|
+
raise CMakeException('Failed to parse CMake trace')
|
|
729
|
+
|
|
730
|
+
loc = skip_match.end()
|
|
731
|
+
continue
|
|
732
|
+
|
|
733
|
+
loc = mo_file_line.end()
|
|
734
|
+
|
|
735
|
+
file = mo_file_line.group(1)
|
|
736
|
+
line = mo_file_line.group(3)
|
|
737
|
+
func = mo_file_line.group(4)
|
|
738
|
+
args = mo_file_line.group(5)
|
|
739
|
+
argl = args.split(' ')
|
|
740
|
+
argl = [a.strip() for a in argl]
|
|
741
|
+
|
|
742
|
+
yield CMakeTraceLine(file, int(line), func, argl)
|
|
743
|
+
|
|
744
|
+
def _lex_trace_json(self, trace: str) -> T.Generator[CMakeTraceLine, None, None]:
|
|
745
|
+
lines = trace.splitlines(keepends=False)
|
|
746
|
+
lines.pop(0) # The first line is the version
|
|
747
|
+
for i in lines:
|
|
748
|
+
data = json.loads(i)
|
|
749
|
+
assert isinstance(data['file'], str)
|
|
750
|
+
assert isinstance(data['line'], int)
|
|
751
|
+
assert isinstance(data['cmd'], str)
|
|
752
|
+
assert isinstance(data['args'], list)
|
|
753
|
+
args = data['args']
|
|
754
|
+
for j in args:
|
|
755
|
+
assert isinstance(j, str)
|
|
756
|
+
yield CMakeTraceLine(data['file'], data['line'], data['cmd'], args)
|
|
757
|
+
|
|
758
|
+
def _flatten_args(self, args: T.List[str]) -> T.List[str]:
|
|
759
|
+
# Split lists in arguments
|
|
760
|
+
res: T.List[str] = []
|
|
761
|
+
for i in args:
|
|
762
|
+
res += i.split(';')
|
|
763
|
+
return res
|
|
764
|
+
|
|
765
|
+
def _guess_files(self, broken_list: T.List[str]) -> T.List[str]:
|
|
766
|
+
# Nothing has to be done for newer formats
|
|
767
|
+
if self.trace_format != 'human':
|
|
768
|
+
return broken_list
|
|
769
|
+
|
|
770
|
+
# Try joining file paths that contain spaces
|
|
771
|
+
|
|
772
|
+
reg_start = re.compile(r'^([A-Za-z]:)?/(.*/)*[^./]+$')
|
|
773
|
+
reg_end = re.compile(r'^.*\.[a-zA-Z]+$')
|
|
774
|
+
|
|
775
|
+
fixed_list: T.List[str] = []
|
|
776
|
+
curr_str: T.Optional[str] = None
|
|
777
|
+
path_found = False
|
|
778
|
+
|
|
779
|
+
for i in broken_list:
|
|
780
|
+
if curr_str is None:
|
|
781
|
+
curr_str = i
|
|
782
|
+
path_found = False
|
|
783
|
+
elif Path(curr_str).is_file():
|
|
784
|
+
# Abort concatenation if curr_str is an existing file
|
|
785
|
+
fixed_list += [curr_str]
|
|
786
|
+
curr_str = i
|
|
787
|
+
path_found = False
|
|
788
|
+
elif not reg_start.match(curr_str):
|
|
789
|
+
# Abort concatenation if curr_str no longer matches the regex
|
|
790
|
+
fixed_list += [curr_str]
|
|
791
|
+
curr_str = i
|
|
792
|
+
path_found = False
|
|
793
|
+
elif reg_end.match(i):
|
|
794
|
+
# File detected
|
|
795
|
+
curr_str = f'{curr_str} {i}'
|
|
796
|
+
fixed_list += [curr_str]
|
|
797
|
+
curr_str = None
|
|
798
|
+
path_found = False
|
|
799
|
+
elif Path(f'{curr_str} {i}').exists():
|
|
800
|
+
# Path detected
|
|
801
|
+
curr_str = f'{curr_str} {i}'
|
|
802
|
+
path_found = True
|
|
803
|
+
elif path_found:
|
|
804
|
+
# Add path to fixed_list after ensuring the whole path is in curr_str
|
|
805
|
+
fixed_list += [curr_str]
|
|
806
|
+
curr_str = i
|
|
807
|
+
path_found = False
|
|
808
|
+
else:
|
|
809
|
+
curr_str = f'{curr_str} {i}'
|
|
810
|
+
path_found = False
|
|
811
|
+
|
|
812
|
+
if curr_str:
|
|
813
|
+
fixed_list += [curr_str]
|
|
814
|
+
return fixed_list
|