Compare commits

9 Commits
Author SHA1 Message Date
Ariska f8357220fc mac ver 2026-07-08 08:08:53 +07:00
ariska f7961b8e70 secure chat addon 2026-07-07 16:47:11 +07:00
AriskaandCursor c156efc882 mac commit
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 16:40:34 +07:00
ariska a6a4375281 secure chat addon 2026-07-07 16:35:55 +07:00
Ariska 0715f5d66d mac add 2026-07-07 13:09:44 +07:00
ariska 05ad514cc5 secure chat addon and stun 2026-07-07 13:04:41 +07:00
ariska e6f0e58ed3 secure chat addon and stun 2026-07-06 15:11:44 +07:00
ariska 65b97fe9af secure chat addon and stun 2026-07-06 14:41:11 +07:00
ariska e42358d04c secure chat addon and stun 2026-07-06 08:28:58 +07:00
1573 changed files with 298149 additions and 92 deletions

No files matched your search

+247
View File
@@ -0,0 +1,247 @@
<#
.Synopsis
Activate a Python virtual environment for the current PowerShell session.
.Description
Pushes the python executable for a virtual environment to the front of the
$Env:PATH environment variable and sets the prompt to signify that you are
in a Python virtual environment. Makes use of the command line switches as
well as the `pyvenv.cfg` file values present in the virtual environment.
.Parameter VenvDir
Path to the directory that contains the virtual environment to activate. The
default value for this is the parent of the directory that the Activate.ps1
script is located within.
.Parameter Prompt
The prompt prefix to display when this virtual environment is activated. By
default, this prompt is the name of the virtual environment folder (VenvDir)
surrounded by parentheses and followed by a single space (ie. '(.venv) ').
.Example
Activate.ps1
Activates the Python virtual environment that contains the Activate.ps1 script.
.Example
Activate.ps1 -Verbose
Activates the Python virtual environment that contains the Activate.ps1 script,
and shows extra information about the activation as it executes.
.Example
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
Activates the Python virtual environment located in the specified location.
.Example
Activate.ps1 -Prompt "MyPython"
Activates the Python virtual environment that contains the Activate.ps1 script,
and prefixes the current prompt with the specified string (surrounded in
parentheses) while the virtual environment is active.
.Notes
On Windows, it may be required to enable this Activate.ps1 script by setting the
execution policy for the user. You can do this by issuing the following PowerShell
command:
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
For more information on Execution Policies:
https://go.microsoft.com/fwlink/?LinkID=135170
#>
Param(
[Parameter(Mandatory = $false)]
[String]
$VenvDir,
[Parameter(Mandatory = $false)]
[String]
$Prompt
)
<# Function declarations --------------------------------------------------- #>
<#
.Synopsis
Remove all shell session elements added by the Activate script, including the
addition of the virtual environment's Python executable from the beginning of
the PATH variable.
.Parameter NonDestructive
If present, do not remove this function from the global namespace for the
session.
#>
function global:deactivate ([switch]$NonDestructive) {
# Revert to original values
# The prior prompt:
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
}
# The prior PYTHONHOME:
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
}
# The prior PATH:
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
Remove-Item -Path Env:_OLD_VIRTUAL_PATH
}
# Just remove the VIRTUAL_ENV altogether:
if (Test-Path -Path Env:VIRTUAL_ENV) {
Remove-Item -Path env:VIRTUAL_ENV
}
# Just remove VIRTUAL_ENV_PROMPT altogether.
if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
Remove-Item -Path env:VIRTUAL_ENV_PROMPT
}
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
}
# Leave deactivate function in the global namespace if requested:
if (-not $NonDestructive) {
Remove-Item -Path function:deactivate
}
}
<#
.Description
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
given folder, and returns them in a map.
For each line in the pyvenv.cfg file, if that line can be parsed into exactly
two strings separated by `=` (with any amount of whitespace surrounding the =)
then it is considered a `key = value` line. The left hand string is the key,
the right hand is the value.
If the value starts with a `'` or a `"` then the first and last character is
stripped from the value before being captured.
.Parameter ConfigDir
Path to the directory that contains the `pyvenv.cfg` file.
#>
function Get-PyVenvConfig(
[String]
$ConfigDir
) {
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
# An empty map will be returned if no config file is found.
$pyvenvConfig = @{ }
if ($pyvenvConfigPath) {
Write-Verbose "File exists, parse `key = value` lines"
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
$pyvenvConfigContent | ForEach-Object {
$keyval = $PSItem -split "\s*=\s*", 2
if ($keyval[0] -and $keyval[1]) {
$val = $keyval[1]
# Remove extraneous quotations around a string value.
if ("'""".Contains($val.Substring(0, 1))) {
$val = $val.Substring(1, $val.Length - 2)
}
$pyvenvConfig[$keyval[0]] = $val
Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
}
}
}
return $pyvenvConfig
}
<# Begin Activate script --------------------------------------------------- #>
# Determine the containing directory of this script
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
$VenvExecDir = Get-Item -Path $VenvExecPath
Write-Verbose "Activation script is located in path: '$VenvExecPath'"
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
# Set values required in priority: CmdLine, ConfigFile, Default
# First, get the location of the virtual environment, it might not be
# VenvExecDir if specified on the command line.
if ($VenvDir) {
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
}
else {
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
Write-Verbose "VenvDir=$VenvDir"
}
# Next, read the `pyvenv.cfg` file to determine any required value such
# as `prompt`.
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
# Next, set the prompt from the command line, or the config file, or
# just use the name of the virtual environment folder.
if ($Prompt) {
Write-Verbose "Prompt specified as argument, using '$Prompt'"
}
else {
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
$Prompt = $pyvenvCfg['prompt'];
}
else {
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
$Prompt = Split-Path -Path $venvDir -Leaf
}
}
Write-Verbose "Prompt = '$Prompt'"
Write-Verbose "VenvDir='$VenvDir'"
# Deactivate any currently active virtual environment, but leave the
# deactivate function in place.
deactivate -nondestructive
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
# that there is an activated venv.
$env:VIRTUAL_ENV = $VenvDir
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
Write-Verbose "Setting prompt to '$Prompt'"
# Set the prompt to include the env name
# Make sure _OLD_VIRTUAL_PROMPT is global
function global:_OLD_VIRTUAL_PROMPT { "" }
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
function global:prompt {
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
_OLD_VIRTUAL_PROMPT
}
$env:VIRTUAL_ENV_PROMPT = $Prompt
}
# Clear PYTHONHOME
if (Test-Path -Path Env:PYTHONHOME) {
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
Remove-Item -Path Env:PYTHONHOME
}
# Add the venv to the PATH
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"
+70
View File
@@ -0,0 +1,70 @@
# This file must be used with "source bin/activate" *from bash*
# You cannot run it directly
deactivate () {
# reset old environment variables
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
PATH="${_OLD_VIRTUAL_PATH:-}"
export PATH
unset _OLD_VIRTUAL_PATH
fi
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
export PYTHONHOME
unset _OLD_VIRTUAL_PYTHONHOME
fi
# Call hash to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
hash -r 2> /dev/null
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
PS1="${_OLD_VIRTUAL_PS1:-}"
export PS1
unset _OLD_VIRTUAL_PS1
fi
unset VIRTUAL_ENV
unset VIRTUAL_ENV_PROMPT
if [ ! "${1:-}" = "nondestructive" ] ; then
# Self destruct!
unset -f deactivate
fi
}
# unset irrelevant variables
deactivate nondestructive
# on Windows, a path can contain colons and backslashes and has to be converted:
if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then
# transform D:\path\to\venv to /d/path/to/venv on MSYS
# and to /cygdrive/d/path/to/venv on Cygwin
export VIRTUAL_ENV=$(cygpath /home/ariska/git/BackOneUI/.venv)
else
# use the path as-is
export VIRTUAL_ENV=/home/ariska/git/BackOneUI/.venv
fi
_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/"bin":$PATH"
export PATH
# unset PYTHONHOME if set
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
# could use `if (set -u; : $PYTHONHOME) ;` in bash
if [ -n "${PYTHONHOME:-}" ] ; then
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
unset PYTHONHOME
fi
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
_OLD_VIRTUAL_PS1="${PS1:-}"
PS1='(.venv) '"${PS1:-}"
export PS1
VIRTUAL_ENV_PROMPT='(.venv) '
export VIRTUAL_ENV_PROMPT
fi
# Call hash to forget past commands. Without forgetting
# past commands the $PATH changes we made may not be respected
hash -r 2> /dev/null
+27
View File
@@ -0,0 +1,27 @@
# This file must be used with "source bin/activate.csh" *from csh*.
# You cannot run it directly.
# Created by Davide Di Blasi <davidedb@gmail.com>.
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate'
# Unset irrelevant variables.
deactivate nondestructive
setenv VIRTUAL_ENV /home/ariska/git/BackOneUI/.venv
set _OLD_VIRTUAL_PATH="$PATH"
setenv PATH "$VIRTUAL_ENV/"bin":$PATH"
set _OLD_VIRTUAL_PROMPT="$prompt"
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
set prompt = '(.venv) '"$prompt"
setenv VIRTUAL_ENV_PROMPT '(.venv) '
endif
alias pydoc python -m pydoc
rehash
+69
View File
@@ -0,0 +1,69 @@
# This file must be used with "source <venv>/bin/activate.fish" *from fish*
# (https://fishshell.com/). You cannot run it directly.
function deactivate -d "Exit virtual environment and return to normal shell environment"
# reset old environment variables
if test -n "$_OLD_VIRTUAL_PATH"
set -gx PATH $_OLD_VIRTUAL_PATH
set -e _OLD_VIRTUAL_PATH
end
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
set -e _OLD_VIRTUAL_PYTHONHOME
end
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
set -e _OLD_FISH_PROMPT_OVERRIDE
# prevents error when using nested fish instances (Issue #93858)
if functions -q _old_fish_prompt
functions -e fish_prompt
functions -c _old_fish_prompt fish_prompt
functions -e _old_fish_prompt
end
end
set -e VIRTUAL_ENV
set -e VIRTUAL_ENV_PROMPT
if test "$argv[1]" != "nondestructive"
# Self-destruct!
functions -e deactivate
end
end
# Unset irrelevant variables.
deactivate nondestructive
set -gx VIRTUAL_ENV /home/ariska/git/BackOneUI/.venv
set -gx _OLD_VIRTUAL_PATH $PATH
set -gx PATH "$VIRTUAL_ENV/"bin $PATH
# Unset PYTHONHOME if set.
if set -q PYTHONHOME
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
set -e PYTHONHOME
end
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
# fish uses a function instead of an env var to generate the prompt.
# Save the current fish_prompt function as the function _old_fish_prompt.
functions -c fish_prompt _old_fish_prompt
# With the original prompt function renamed, we can override with our own.
function fish_prompt
# Save the return status of the last command.
set -l old_status $status
# Output the venv prompt; color taken from the blue of the Python logo.
printf "%s%s%s" (set_color 4B8BBE) '(.venv) ' (set_color normal)
# Restore the return status of the previous command.
echo "exit $old_status" | .
# Output the original/"old" prompt.
_old_fish_prompt
end
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
set -gx VIRTUAL_ENV_PROMPT '(.venv) '
end
+8
View File
@@ -0,0 +1,8 @@
#!/home/ariska/git/BackOneUI/.venv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from mesonbuild.mesonmain import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
BIN
View File
Binary file not shown.
Executable
+8
View File
@@ -0,0 +1,8 @@
#!/home/ariska/git/BackOneUI/.venv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
Executable
+8
View File
@@ -0,0 +1,8 @@
#!/home/ariska/git/BackOneUI/.venv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
+8
View File
@@ -0,0 +1,8 @@
#!/home/ariska/git/BackOneUI/.venv/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from pip._internal.cli.main import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
sys.exit(main())
+1
View File
@@ -0,0 +1 @@
python3
+1
View File
@@ -0,0 +1 @@
/usr/bin/python3
+1
View File
@@ -0,0 +1 @@
python3
@@ -0,0 +1 @@
pip
@@ -0,0 +1,40 @@
Metadata-Version: 2.4
Name: meson
Version: 1.11.1
Summary: A high performance build system
Home-page: https://mesonbuild.com
Author: Jussi Pakkanen
Author-email: jpakkane@gmail.com
License: Apache License, Version 2.0
Project-URL: Source, https://github.com/mesonbuild/meson
Keywords: meson,mesonbuild,build system,cmake
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Natural Language :: English
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: BSD
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Build Tools
Requires-Python: >=3.7
License-File: COPYING
Provides-Extra: ninja
Requires-Dist: ninja>=1.8.2; extra == "ninja"
Provides-Extra: progress
Requires-Dist: tqdm; extra == "progress"
Provides-Extra: typing
Requires-Dist: mypy; extra == "typing"
Requires-Dist: typing_extensions; python_version < "3.8" and extra == "typing"
Dynamic: license-file
Meson is a cross-platform build system designed to be both as fast and as user friendly as possible. It supports many languages and compilers, including GCC, Clang, PGI, Intel, and Visual Studio. Its build definitions are written in a simple non-Turing complete DSL.
@@ -0,0 +1,500 @@
../../../bin/meson,sha256=Q-wzMFtzVIAby6usWHknC6WkvOBVinHvRWHkGU-467o,247
../../../share/man/man1/meson.1,sha256=fDTIIeSxa4FUbZA5lZXFsDZuZ212PDkMX65ZM5UinD4,13212
../../../share/polkit-1/actions/com.mesonbuild.install.policy,sha256=Jjwp4WkbT8jtHe57xrJeVPI3e-8mVx7P9HiXQ6RbETc,896
meson-1.11.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
meson-1.11.1.dist-info/METADATA,sha256=j80RkCezi5ZCwtNRHyE8Od_1rmP53K-29NYDBnQmRvE,1830
meson-1.11.1.dist-info/RECORD,,
meson-1.11.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
meson-1.11.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
meson-1.11.1.dist-info/entry_points.txt,sha256=hZ7QUh6nHe31AnI6xlEZmSe6k4KWKZ7FBS54WyDeAY0,52
meson-1.11.1.dist-info/licenses/COPYING,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
meson-1.11.1.dist-info/top_level.txt,sha256=cqZA9dM-WXuPam10-bt2FhnrCrMHPME60jKEhhcuObA,11
mesonbuild/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
mesonbuild/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/__pycache__/_pathlib.cpython-312.pyc,,
mesonbuild/__pycache__/_typing.cpython-312.pyc,,
mesonbuild/__pycache__/arglist.cpython-312.pyc,,
mesonbuild/__pycache__/build.cpython-312.pyc,,
mesonbuild/__pycache__/cmdline.cpython-312.pyc,,
mesonbuild/__pycache__/coredata.cpython-312.pyc,,
mesonbuild/__pycache__/depfile.cpython-312.pyc,,
mesonbuild/__pycache__/envconfig.cpython-312.pyc,,
mesonbuild/__pycache__/environment.cpython-312.pyc,,
mesonbuild/__pycache__/machinefile.cpython-312.pyc,,
mesonbuild/__pycache__/mcompile.cpython-312.pyc,,
mesonbuild/__pycache__/mconf.cpython-312.pyc,,
mesonbuild/__pycache__/mdevenv.cpython-312.pyc,,
mesonbuild/__pycache__/mdist.cpython-312.pyc,,
mesonbuild/__pycache__/mesondata.cpython-312.pyc,,
mesonbuild/__pycache__/mesonlib.cpython-312.pyc,,
mesonbuild/__pycache__/mesonmain.cpython-312.pyc,,
mesonbuild/__pycache__/mformat.cpython-312.pyc,,
mesonbuild/__pycache__/minit.cpython-312.pyc,,
mesonbuild/__pycache__/minstall.cpython-312.pyc,,
mesonbuild/__pycache__/mintro.cpython-312.pyc,,
mesonbuild/__pycache__/mlog.cpython-312.pyc,,
mesonbuild/__pycache__/mparser.cpython-312.pyc,,
mesonbuild/__pycache__/msetup.cpython-312.pyc,,
mesonbuild/__pycache__/msubprojects.cpython-312.pyc,,
mesonbuild/__pycache__/mtest.cpython-312.pyc,,
mesonbuild/__pycache__/munstable_coredata.cpython-312.pyc,,
mesonbuild/__pycache__/optinterpreter.cpython-312.pyc,,
mesonbuild/__pycache__/options.cpython-312.pyc,,
mesonbuild/__pycache__/programs.cpython-312.pyc,,
mesonbuild/__pycache__/rewriter.cpython-312.pyc,,
mesonbuild/__pycache__/tooldetect.cpython-312.pyc,,
mesonbuild/_pathlib.py,sha256=_3jd_4v6wwFvxlPJksvNFluaPoiQqTr4UZNuBJmiXDk,1914
mesonbuild/_typing.py,sha256=58U-_dR30rTRSQ54-6OavunBh7bilqgx5TcpfZarA8s,1860
mesonbuild/arglist.py,sha256=dciJ31h41pbjD9KrEhy_cPcM3vc3c-L5u7p2YenVKr0,13475
mesonbuild/ast/__init__.py,sha256=dnM7EBhwUUzygvK-un05wtKlmHvqO7iAGinb6SR3TR8,707
mesonbuild/ast/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/ast/__pycache__/interpreter.cpython-312.pyc,,
mesonbuild/ast/__pycache__/introspection.cpython-312.pyc,,
mesonbuild/ast/__pycache__/postprocess.cpython-312.pyc,,
mesonbuild/ast/__pycache__/printer.cpython-312.pyc,,
mesonbuild/ast/__pycache__/visitor.cpython-312.pyc,,
mesonbuild/ast/interpreter.py,sha256=B6otExV_iasNwlRsrBuvJM2qmH0ph4qqpnYHe5GoY8Y,35722
mesonbuild/ast/introspection.py,sha256=-OrTvZSdOeesaZGo_nffoyyRpSbvNu8_81v_xwTYOOs,17987
mesonbuild/ast/postprocess.py,sha256=mlkCMpbzSCFC7ssrAh7ijR6DIzj3b90_2jnRqU050a8,3733
mesonbuild/ast/printer.py,sha256=T45cHH-xH-X6yQZd8xqpCn8BmYQGiKeNK5nH5dhelHk,17573
mesonbuild/ast/visitor.py,sha256=ct6Ra1vqOvEALh_Aac3fri0pGWz19oUxRa3_PZuY4lQ,10964
mesonbuild/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
mesonbuild/backend/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/backend/__pycache__/backends.cpython-312.pyc,,
mesonbuild/backend/__pycache__/ninjabackend.cpython-312.pyc,,
mesonbuild/backend/__pycache__/nonebackend.cpython-312.pyc,,
mesonbuild/backend/__pycache__/vs2010backend.cpython-312.pyc,,
mesonbuild/backend/__pycache__/vs2012backend.cpython-312.pyc,,
mesonbuild/backend/__pycache__/vs2013backend.cpython-312.pyc,,
mesonbuild/backend/__pycache__/vs2015backend.cpython-312.pyc,,
mesonbuild/backend/__pycache__/vs2017backend.cpython-312.pyc,,
mesonbuild/backend/__pycache__/vs2019backend.cpython-312.pyc,,
mesonbuild/backend/__pycache__/vs2022backend.cpython-312.pyc,,
mesonbuild/backend/__pycache__/vs2026backend.cpython-312.pyc,,
mesonbuild/backend/__pycache__/xcodebackend.cpython-312.pyc,,
mesonbuild/backend/backends.py,sha256=ZzxbfuFR3oncEhiGyumTtbs-56Tr4CZRWGkhKvTc0oA,101569
mesonbuild/backend/ninjabackend.py,sha256=iM7pbNNFT-0IZjK4J56tkI0P5XXDscgPdYrzQhs4QNY,210005
mesonbuild/backend/nonebackend.py,sha256=mk5rwaWO6qfFI6RQoi4MLMRytRIoM1JF5sSSsp9P7xI,983
mesonbuild/backend/vs2010backend.py,sha256=aqxGh4XMBYClyyGy7ko-x04x4js1bGLY1iX0pg8x9-k,126621
mesonbuild/backend/vs2012backend.py,sha256=cHRGdkCxzRlPqaPeA--pEt3lW4bq8KjwzUabMzG_1jU,1259
mesonbuild/backend/vs2013backend.py,sha256=a2HjzQ4uD19kkhGrc_Jl-0BlDndACPGFUywRaTwxIbc,1258
mesonbuild/backend/vs2015backend.py,sha256=rZv7VXQtMOZxiGL_TwX8YuoYjSotSHvr0G1CmsdQcDM,1225
mesonbuild/backend/vs2017backend.py,sha256=NmaR0p8SPkEL-68uwTYtxCnT_gw05-PVo15itEbNWMQ,2440
mesonbuild/backend/vs2019backend.py,sha256=UhNJwp0e6gg3M65lghw03mqF--CFSWgeemGNc9NI7Z8,2188
mesonbuild/backend/vs2022backend.py,sha256=qi8dXN4nL1UkM78DrcjFonI-4rSeetuS3oKZEvxx0-4,2231
mesonbuild/backend/vs2026backend.py,sha256=gVY-Xr6-r2O2iod6icWwme3WjWrNUEWzvX1AOsJKvp0,2226
mesonbuild/backend/xcodebackend.py,sha256=GizYQrtGCGJgGj4U0a6GyuLVCSjx-36R07DF-XZtI9E,99433
mesonbuild/build.py,sha256=mPD6X2Uh64Glg-Rh49Gthh0TSEI99P9K3nicZURUGjo,154115
mesonbuild/cargo/__init__.py,sha256=EtCIjQorryWo-Fk11qIDBFfobeXfSpXFVjItmDHQOno,220
mesonbuild/cargo/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/cargo/__pycache__/builder.cpython-312.pyc,,
mesonbuild/cargo/__pycache__/cfg.cpython-312.pyc,,
mesonbuild/cargo/__pycache__/interpreter.cpython-312.pyc,,
mesonbuild/cargo/__pycache__/manifest.cpython-312.pyc,,
mesonbuild/cargo/__pycache__/raw.cpython-312.pyc,,
mesonbuild/cargo/__pycache__/toml.cpython-312.pyc,,
mesonbuild/cargo/__pycache__/version.cpython-312.pyc,,
mesonbuild/cargo/builder.py,sha256=PubQVcbPLOO2xYie4ShZ9c4wrY-kXkq-7O1Hlvo8-cU,9174
mesonbuild/cargo/cfg.py,sha256=r-gpXCKLTKNNwlOB6oZbQsdpXsVAT_pABmUInPC2s40,5348
mesonbuild/cargo/interpreter.py,sha256=Cu1_xBSyRMrC_wEiMAY-3Jefn5MFg_bcx2HDhDGv4a8,42495
mesonbuild/cargo/manifest.py,sha256=BY1t0B6VPCAoyNQ-l93rzedZiQxQHJTsSpiDELfdhNk,25817
mesonbuild/cargo/raw.py,sha256=2PCyZudrf7e5IBEOwD82dpO94XbUuR4POHJAl2s366Q,5257
mesonbuild/cargo/toml.py,sha256=WAXFVBeKxn9fhjCN-ZH1AgbqIszw7b7xWual7XgMcJA,2011
mesonbuild/cargo/version.py,sha256=Pys7AIliEJGguPAla4745sp7nyG9bxbusiRCLtcagGU,4646
mesonbuild/cmake/__init__.py,sha256=YhnI0T7qN9tvVs9Fc0PTdlgzE-FExuC-7lUIEAAzLEw,874
mesonbuild/cmake/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/cmake/__pycache__/common.cpython-312.pyc,,
mesonbuild/cmake/__pycache__/executor.cpython-312.pyc,,
mesonbuild/cmake/__pycache__/fileapi.cpython-312.pyc,,
mesonbuild/cmake/__pycache__/generator.cpython-312.pyc,,
mesonbuild/cmake/__pycache__/interpreter.cpython-312.pyc,,
mesonbuild/cmake/__pycache__/toolchain.cpython-312.pyc,,
mesonbuild/cmake/__pycache__/traceparser.cpython-312.pyc,,
mesonbuild/cmake/__pycache__/tracetargets.cpython-312.pyc,,
mesonbuild/cmake/common.py,sha256=VkE23KuDbZe0pWjbuNpOPaloPd4Gxgdch1j6deH1D-8,13258
mesonbuild/cmake/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
mesonbuild/cmake/data/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/cmake/data/preload.cmake,sha256=zo8wFZqrJbksJsWKIZpCfUeDi_oHOUdSIdbImTtJRuU,2065
mesonbuild/cmake/executor.py,sha256=khoySlASYLRMfL4wVS1eK3On2EyPqbECGQfmcX0kN5Q,10748
mesonbuild/cmake/fileapi.py,sha256=1hRJizYHJQ99dQ2yy-nwsbI3gcTcefw9t9FPuaLKCiQ,12931
mesonbuild/cmake/generator.py,sha256=t-k-3KXCoBgj9V3aHFHeRyUyX6TLBCHmx9M_feojeBY,6171
mesonbuild/cmake/interpreter.py,sha256=I26iu3i0nh4l-TtmI9A2z1HIiqSNYB3smH1tXnfza1s,60570
mesonbuild/cmake/toolchain.py,sha256=gbykJcNjEzALs94D6ShBMtm9kRj772fIor-XkbHORIg,10847
mesonbuild/cmake/traceparser.py,sha256=HQWsJ6SNjIGDQ-l9J-ye55DCa19PUtKfjSu_NTUMUUE,33378
mesonbuild/cmake/tracetargets.py,sha256=kWZOGJD78nunWjfxyHyznB82fpNdK2nBkQcVY3zQuWI,7129
mesonbuild/cmdline.py,sha256=mixm9kEDBMCVQRWxY9u9Fu1FbD6h1zi27I9CwqNiU7Y,9869
mesonbuild/compilers/__init__.py,sha256=3_IwwEOif4lsOCwj5EIedEs8i6YZwGej5S5o9iz0Vgo,1957
mesonbuild/compilers/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/asm.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/c.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/c_function_attributes.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/compilers.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/cpp.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/cs.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/cuda.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/cython.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/d.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/detect.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/fortran.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/java.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/objc.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/objcpp.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/rust.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/swift.cpython-312.pyc,,
mesonbuild/compilers/__pycache__/vala.cpython-312.pyc,,
mesonbuild/compilers/asm.py,sha256=5swv661zI9J5w9xkI-PWAnci9r5pd2PDAG-pKgzgZFg,12372
mesonbuild/compilers/c.py,sha256=SejEyguK1D9oFggMWqA8znQK2spaEFcZcx7d1kx-Fdk,33329
mesonbuild/compilers/c_function_attributes.py,sha256=SiaBhP7azAZInniLG-nlujclPocfms7AAr0CiUincYY,5884
mesonbuild/compilers/compilers.py,sha256=amd0zQdR9ss5MJSfMXfJLtS6bSFmPdVSrvw-X-3TvYo,69963
mesonbuild/compilers/cpp.py,sha256=khBPk1GRunHRjnmBRNlG6zac7fJMZpOhlUBhMymfkqg,49285
mesonbuild/compilers/cs.py,sha256=gCOhevfODBM1vAbGj6IPn8l49y9PKcOXAiTKztoaArc,4072
mesonbuild/compilers/cuda.py,sha256=mQmYQmRIin4uRB301zXW02nNLi60uu9AZX-Lqh-dfyg,41416
mesonbuild/compilers/cython.py,sha256=uY-SIMD2v57QwjjDvG_JRl30i0gtmni-owdy7SfZqck,5056
mesonbuild/compilers/d.py,sha256=yE06X-lbiYtlPuWU_1c-d5M6W_Nz0kpRbigr5Y5I204,33035
mesonbuild/compilers/detect.py,sha256=0VJ1vYkOPdag4mbSqRkJTMWBeEkD4yiYjcOh9WjLjbc,74212
mesonbuild/compilers/fortran.py,sha256=A-a07jw-pDiZh65wPuHECbjCZ6fSDYyEe_8PLZDYDW0,29867
mesonbuild/compilers/java.py,sha256=Q7te-ydkjTbBt4lt2TMTLkaIcVkwB0xba9n4bGRvqY8,3982
mesonbuild/compilers/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
mesonbuild/compilers/mixins/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/apple.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/arm.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/ccrx.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/clang.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/clike.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/compcert.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/elbrus.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/emscripten.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/gnu.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/intel.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/islinker.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/metrowerks.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/microchip.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/pgi.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/tasking.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/ti.cpython-312.pyc,,
mesonbuild/compilers/mixins/__pycache__/visualstudio.cpython-312.pyc,,
mesonbuild/compilers/mixins/apple.py,sha256=W0Wm5JlagIqb49GPHx9QWr7XLD96F0Fxi9d-RgClMFQ,3497
mesonbuild/compilers/mixins/arm.py,sha256=Gyj2w_TtVIVWhhM8ve_-l2wZqJ1NebAZawbMXEMHoNE,6157
mesonbuild/compilers/mixins/ccrx.py,sha256=349A3WEyx5NiFOrLBTUV3ZmsU_d-8Ujf0hn64jl3HtI,3477
mesonbuild/compilers/mixins/clang.py,sha256=4gNj8uRRi5y07lmfmnJLyVm6fvHB281xo42KD85wDWA,13271
mesonbuild/compilers/mixins/clike.py,sha256=C1Xyp8W3yU1aO729P-fA2N3SCCyOcLzMkcjstx5fL8M,62339
mesonbuild/compilers/mixins/compcert.py,sha256=UkJI3HDncLydEdEXdJNYpiOmZMgI8_eJUtSWi88n1cs,3538
mesonbuild/compilers/mixins/elbrus.py,sha256=3L8--JNslnXpP6adU9BDOKixztHjBcjO5uFqehjMR0k,4147
mesonbuild/compilers/mixins/emscripten.py,sha256=ew-WvbfDWV_CrhxosNT7dDoMiqE0gHby7BZKtVhU_lc,3743
mesonbuild/compilers/mixins/gnu.py,sha256=LWoZ5glFh0-GT9LeADmXlYm1mRd5lsv-46IXGkBnAcE,24265
mesonbuild/compilers/mixins/intel.py,sha256=SIx79NJuQ6t0xQlxco1nUMV6fRu3UKI7kKpXY2re9Do,5799
mesonbuild/compilers/mixins/islinker.py,sha256=mRKDraCPH-dTI5UuYaq7pVJBkcDeQ0yafxxDtlHO3_g,4269
mesonbuild/compilers/mixins/metrowerks.py,sha256=wOKr11tUODtBXhrEQET1O5pMd75WjR_GuXYR332lMtQ,8821
mesonbuild/compilers/mixins/microchip.py,sha256=Sci8a0zbyTfuVdtGu1bZkBMW56thOH5m0fQs41DCDJg,6099
mesonbuild/compilers/mixins/pgi.py,sha256=4fLeURsXP-1LK3FfQGzRr3iOsM0Bw0mgDUGwqrLJBMM,2993
mesonbuild/compilers/mixins/tasking.py,sha256=8LmnvkZC6qo30PLC66-UJG7WxcMn2IubQnLLvbe6j6c,4401
mesonbuild/compilers/mixins/ti.py,sha256=4hxoH_mxMKNMIEZnLEar-nUdwgoS5930uIiTGcHAEqM,4224
mesonbuild/compilers/mixins/visualstudio.py,sha256=OxIOawET1mboOE7XaaBnhHC_2MesqkFEePvqcFqsVQM,20736
mesonbuild/compilers/objc.py,sha256=NkxiBWBgVcG0dTqT1IVUGLSwoa0Qyy4Bgs2f3D7Zv8U,5396
mesonbuild/compilers/objcpp.py,sha256=q8mSEsRauzdUlLwkGGfF-SjCyUjfv1NP9iJ8KRdEZ_U,5214
mesonbuild/compilers/rust.py,sha256=SkMrZhXBiXvc5TYTFbLd6VOdlwTRKBJ6a5rPqRHkbDA,24895
mesonbuild/compilers/swift.py,sha256=xdVP43qCJ6ad8K-T61Ok_uCDItZvQ_Dd_W5j9OEQJeA,7489
mesonbuild/compilers/vala.py,sha256=RbU5u9uuW94D1o-H-dIw2t5XoMO9QeikFi7d_MaOiRw,10341
mesonbuild/coredata.py,sha256=aLeunMMwWNgPsdaldZ4fylKNBtiEa3fWb56jOqxWlsk,21045
mesonbuild/dependencies/__init__.py,sha256=-cbFRzzJk0RifPqZ1pyXJ1b_LuqIj-h76Egg-a7uRaA,8316
mesonbuild/dependencies/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/base.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/boost.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/cmake.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/coarrays.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/configtool.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/cuda.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/detect.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/dev.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/dub.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/factory.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/framework.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/hdf5.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/misc.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/mpi.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/pkgconfig.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/platform.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/python.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/qt.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/scalapack.cpython-312.pyc,,
mesonbuild/dependencies/__pycache__/ui.cpython-312.pyc,,
mesonbuild/dependencies/base.py,sha256=FFcqpmCLFT7m57t2QLrR2H4I0j_ith5t1VDt-1DyZRE,29904
mesonbuild/dependencies/boost.py,sha256=QFm8dxUMo6NKK9rXneGoqy7qpOfXnxfo8aTUdUkWzdo,40752
mesonbuild/dependencies/cmake.py,sha256=VOQXep77bXosGVg7Wi5M4Ikf3HBYYrBaCtvbIEfXJdk,29635
mesonbuild/dependencies/coarrays.py,sha256=MBVvLyGyV8qrNI9gteeWNau1ardpUNSwKaU1KEbuTR8,3292
mesonbuild/dependencies/configtool.py,sha256=GwUVYoHpq96Se-N2_7fXu767rBgrvQSctfjioQE1Ff8,7452
mesonbuild/dependencies/cuda.py,sha256=2-qPrARL_nzOuUwhqd34IFPihkBbxCSjlSJXiMZSaR8,15612
mesonbuild/dependencies/data/CMakeLists.txt,sha256=llW_00s2-DvsktnH9ga-hR4lQcK_IgbREpHJOaXKeUA,3266
mesonbuild/dependencies/data/CMakeListsLLVM.txt,sha256=0xdZ_r5Y1qRpn_kFu8bbzuaWr7qOHA2Q-fy0dsmo3ZI,6175
mesonbuild/dependencies/data/CMakePathInfo.txt,sha256=dHhSGufAWcN5EJCQhDDYJDBz54MlTXaT6jVdb1vHjX8,1164
mesonbuild/dependencies/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
mesonbuild/dependencies/data/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/dependencies/detect.py,sha256=Tt51NQyIPt0O-L3Y3yNTSejdvjJHXPUrkUK8d-K0Nng,9220
mesonbuild/dependencies/dev.py,sha256=SHZHEXSh_bKU9K8H3RtB500cmERJ-tzJLTp2VU-wdD0,34606
mesonbuild/dependencies/dub.py,sha256=O9TCArzoSxgeSi6AUofKv_fKUCp5bAoLMKvt6CTCU4Q,22631
mesonbuild/dependencies/factory.py,sha256=s-atDzT_sqmaw910G3tvqQVGUNHUb4qL6JelDQYFlnY,7171
mesonbuild/dependencies/framework.py,sha256=DJVr5ipjPw5US57oM_0moTA7Zqdoc6fKk69RASYTfps,5262
mesonbuild/dependencies/hdf5.py,sha256=sigrFP8r6TTdyxqNuMxRq5YV-Z3ISwrYeSHb1S0VwDY,6808
mesonbuild/dependencies/misc.py,sha256=wM-XSzrERN4Hu7Gl-eONW9LpS83qXtNb8pPZkOli1OU,27864
mesonbuild/dependencies/mpi.py,sha256=FcaeF9dA21iwgmHmqbMsU7AqQMxKIDTDK6sUiJmaW2c,11573
mesonbuild/dependencies/pkgconfig.py,sha256=surY177mxnCLPyUq_wTZ6vNDN1sRb9WB8ry-uAjt2Dg,29011
mesonbuild/dependencies/platform.py,sha256=MRSs4etHkiUfPJgQKYYpMSmfzMnJ0xUY6Z6hZ8qkRtQ,1801
mesonbuild/dependencies/python.py,sha256=SV4NaEKeieicbx335vt28FIxjcLILmog__XTqoYteqk,26701
mesonbuild/dependencies/qt.py,sha256=JFBQfZjTwCt6Kq9keP66x1kfI5oHXtf7C1548XQbowA,19694
mesonbuild/dependencies/scalapack.py,sha256=5S_38zs7T1L_RYMcMnXMRbkruGLXsk8GQSdAO-umk30,5543
mesonbuild/dependencies/ui.py,sha256=Iwgt2Nn3c7wD3Lsor2Z6q7uNCyaIBLp0U2KIz-QjtAE,12842
mesonbuild/depfile.py,sha256=TrTvJhMqqCdyiNZR68dYpQ7qhmywp5dz1zzRWN-uyQo,2382
mesonbuild/envconfig.py,sha256=ZGtJVUfACbd2vo86mn3ik3fdCuoio0ILcsl7zLda3Bo,27423
mesonbuild/environment.py,sha256=Gcio3Kdxs5c5qaTBM5zkRqolASuO29-uU1fAAUgOwsM,29327
mesonbuild/interpreter/__init__.py,sha256=TmW-AGMpDqwjSsMixDX-VPNG4994YfZBgc5YVitUziI,1123
mesonbuild/interpreter/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/interpreter/__pycache__/compiler.cpython-312.pyc,,
mesonbuild/interpreter/__pycache__/dependencyfallbacks.cpython-312.pyc,,
mesonbuild/interpreter/__pycache__/interpreter.cpython-312.pyc,,
mesonbuild/interpreter/__pycache__/interpreterobjects.cpython-312.pyc,,
mesonbuild/interpreter/__pycache__/kwargs.cpython-312.pyc,,
mesonbuild/interpreter/__pycache__/mesonmain.cpython-312.pyc,,
mesonbuild/interpreter/__pycache__/type_checking.cpython-312.pyc,,
mesonbuild/interpreter/compiler.py,sha256=pizF7JWf2y-AD91m79Xe9KFPtLxnZ8umgIbs3NES2wc,44068
mesonbuild/interpreter/dependencyfallbacks.py,sha256=0Wl5KBMAvNphuHNq2d3fVjQcNZYSm9Qpn56832gTNNQ,19385
mesonbuild/interpreter/interpreter.py,sha256=2bN0iO7232uFMkBMsQoV4GQLLsddtzFje83-h7MYa94,192743
mesonbuild/interpreter/interpreterobjects.py,sha256=53aSoDPrmwsNYD2Bqbk5ghQ_Be35m37sKBWlx6P6T2s,53026
mesonbuild/interpreter/kwargs.py,sha256=1iPAU1x40Tk7PcOHq06EXWRN0HA9XHrUNJUMLtNrw-k,14837
mesonbuild/interpreter/mesonmain.py,sha256=8NvenPz1VX8vYOzr0pIBnRkVnwhEfpUyKUhfwgrpQfk,23368
mesonbuild/interpreter/primitives/__init__.py,sha256=S8zTgPCTyzJjZuGplHXM9X7LoYSyS6ItLuOubl6UJL0,743
mesonbuild/interpreter/primitives/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/interpreter/primitives/__pycache__/array.cpython-312.pyc,,
mesonbuild/interpreter/primitives/__pycache__/boolean.cpython-312.pyc,,
mesonbuild/interpreter/primitives/__pycache__/dict.cpython-312.pyc,,
mesonbuild/interpreter/primitives/__pycache__/integer.cpython-312.pyc,,
mesonbuild/interpreter/primitives/__pycache__/range.cpython-312.pyc,,
mesonbuild/interpreter/primitives/__pycache__/string.cpython-312.pyc,,
mesonbuild/interpreter/primitives/array.py,sha256=FCF2MzoBkrlRI3pxdVyo4NPP6UfUGG_tO_sZlH_wPvw,4588
mesonbuild/interpreter/primitives/boolean.py,sha256=htKXXJHoFYgIicyrcTFAgp3JhqxsYht0y8EOczlR8K8,1620
mesonbuild/interpreter/primitives/dict.py,sha256=vdMj5RsuZfxf0v9t16uP6QGckzdX90laN0X3KtwdhmQ,2848
mesonbuild/interpreter/primitives/integer.py,sha256=hnX_NReTfjdy9w5c5CLxpzG8Pj8jc0DWAijhokHK7X8,3036
mesonbuild/interpreter/primitives/range.py,sha256=X9g96ONxJ3hljew6KTZ5fa6wsIwJlHQW1yyLNp6q570,1048
mesonbuild/interpreter/primitives/string.py,sha256=6DMqhHcCci5FVkwRpbbbd1IvY_ZFmfJdJhLavhxPNNU,10017
mesonbuild/interpreter/type_checking.py,sha256=EGFy4NWP9eUrFKDqRG3RJBFvf53btAbDhfHboJiIEHw,41358
mesonbuild/interpreterbase/__init__.py,sha256=zfSDaP-NHKuLJPR5gU6hsORFd7Da04yLXPVNH3FPbC8,2468
mesonbuild/interpreterbase/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/interpreterbase/__pycache__/_unholder.cpython-312.pyc,,
mesonbuild/interpreterbase/__pycache__/baseobjects.cpython-312.pyc,,
mesonbuild/interpreterbase/__pycache__/decorators.cpython-312.pyc,,
mesonbuild/interpreterbase/__pycache__/disabler.cpython-312.pyc,,
mesonbuild/interpreterbase/__pycache__/exceptions.cpython-312.pyc,,
mesonbuild/interpreterbase/__pycache__/helpers.cpython-312.pyc,,
mesonbuild/interpreterbase/__pycache__/interpreterbase.cpython-312.pyc,,
mesonbuild/interpreterbase/__pycache__/operator.cpython-312.pyc,,
mesonbuild/interpreterbase/_unholder.py,sha256=nYh2o3LY-qsG6M2jvKscNaDRbV9X9ZCzfa4wwaEFXmw,1065
mesonbuild/interpreterbase/baseobjects.py,sha256=ksjTDd2Ya-BkvC4DfDF4i-uZ3vXq1NoKgHCTn1mQxmA,10574
mesonbuild/interpreterbase/decorators.py,sha256=VFUUHXh8CWwNvGn5q0UirBC44o2CV9NxJbg0O6lNLqo,40970
mesonbuild/interpreterbase/disabler.py,sha256=RfHkBKFgt56jsytpXminZBDhV0UubzRofrrShNu2_rk,980
mesonbuild/interpreterbase/exceptions.py,sha256=owX9NcEK4AEaOk5pb8AzlRKU-zYVZ4XWBB6PWyELkqM,430
mesonbuild/interpreterbase/helpers.py,sha256=-77use0JBqqyn0pgM7YnKv0w2uMmfkFknZIhgvDs4go,2724
mesonbuild/interpreterbase/interpreterbase.py,sha256=RVijAi53y8HZoSxW80mEc7jzb0--J2b7Nmc1A_VLHQg,33854
mesonbuild/interpreterbase/operator.py,sha256=KficNKFn6f4VydkRuLF0dlIAvdcGIOJ5FlWFi2q9Lg8,774
mesonbuild/linkers/__init__.py,sha256=lngm1vB4CoFumlOyJlLhTEZLD4EPYIwYBKzCcMadWEQ,367
mesonbuild/linkers/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/linkers/__pycache__/base.cpython-312.pyc,,
mesonbuild/linkers/__pycache__/detect.cpython-312.pyc,,
mesonbuild/linkers/__pycache__/linkers.cpython-312.pyc,,
mesonbuild/linkers/base.py,sha256=wcQNSVlf1UAkbs3jbfAiBoXS9il7jhL4zfe_i596Trg,993
mesonbuild/linkers/detect.py,sha256=XTDDfIlURD4lWlpDaIS9-xe59cPU1tlXScEhjAQuDtI,12167
mesonbuild/linkers/linkers.py,sha256=07Y60RiaGwYhgrUponktByKXSH1jKBeS8OP591R_gW0,68178
mesonbuild/machinefile.py,sha256=khsQMN3xYM47w_goEy3GmW5GC8Pg354zPlrU9avXOTY,4759
mesonbuild/mcompile.py,sha256=-2u_goWlmsxFvkpwrfrgLE8d_0H69K1z9-LyEMexEd4,14202
mesonbuild/mconf.py,sha256=5D26zckmme4r-i7OQpN-T4x_AGaxNrf49-6ZlHgYqdk,18649
mesonbuild/mdevenv.py,sha256=sB0dIFRr5gRPhaBoEdvqyOI1Owhsfm7T6jWkVrHxF0M,13225
mesonbuild/mdist.py,sha256=m9eW6L1LxYxHbEFJ7xbyxZ6az0StgUoe4yJORMTjNqk,18744
mesonbuild/mesondata.py,sha256=bJzRV3yn14bMkrUyT3DM1SeevpC_epwTYiY8C1uB5pI,1513
mesonbuild/mesonlib.py,sha256=bhz-HS1eQ8dKZa2ghXI10dLZMeydTzB431jleEwlzNs,315
mesonbuild/mesonmain.py,sha256=b2hmzJdg4q2VFszbPzpCs3M9w85xjnjpFe0libFPlbQ,14721
mesonbuild/mformat.py,sha256=kEit2rWqHaUiGtNLLdcbYE46oFOYRC2VZx38idT9C_w,43977
mesonbuild/minit.py,sha256=_zmY1niH7ZkLxXw5M4Io5h_nXDn1QjVGitQAlKdvlow,8307
mesonbuild/minstall.py,sha256=vKCO-YIBzAtVfZhWUS4eyq-UNLmutm6B-xDzbBhIGYE,40027
mesonbuild/mintro.py,sha256=tRkqkzxhUMP7dur59A5xEt9kB6IpEehUOOHiviHjYaU,30085
mesonbuild/mlog.py,sha256=wq_SnO4uTdVPgQjqmj6l9WLw2TAuXHBgPjiGGCJuUz4,21356
mesonbuild/modules/__init__.py,sha256=LlmLx8FsmmHuX4hqN1p2-QVL5h4Zv7oZOjsi0aSG3w8,12182
mesonbuild/modules/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/modules/__pycache__/_qt.cpython-312.pyc,,
mesonbuild/modules/__pycache__/cmake.cpython-312.pyc,,
mesonbuild/modules/__pycache__/codegen.cpython-312.pyc,,
mesonbuild/modules/__pycache__/cuda.cpython-312.pyc,,
mesonbuild/modules/__pycache__/dlang.cpython-312.pyc,,
mesonbuild/modules/__pycache__/external_project.cpython-312.pyc,,
mesonbuild/modules/__pycache__/fs.cpython-312.pyc,,
mesonbuild/modules/__pycache__/gnome.cpython-312.pyc,,
mesonbuild/modules/__pycache__/hotdoc.cpython-312.pyc,,
mesonbuild/modules/__pycache__/i18n.cpython-312.pyc,,
mesonbuild/modules/__pycache__/icestorm.cpython-312.pyc,,
mesonbuild/modules/__pycache__/java.cpython-312.pyc,,
mesonbuild/modules/__pycache__/keyval.cpython-312.pyc,,
mesonbuild/modules/__pycache__/modtest.cpython-312.pyc,,
mesonbuild/modules/__pycache__/pkgconfig.cpython-312.pyc,,
mesonbuild/modules/__pycache__/python.cpython-312.pyc,,
mesonbuild/modules/__pycache__/python3.cpython-312.pyc,,
mesonbuild/modules/__pycache__/qt4.cpython-312.pyc,,
mesonbuild/modules/__pycache__/qt5.cpython-312.pyc,,
mesonbuild/modules/__pycache__/qt6.cpython-312.pyc,,
mesonbuild/modules/__pycache__/rust.cpython-312.pyc,,
mesonbuild/modules/__pycache__/simd.cpython-312.pyc,,
mesonbuild/modules/__pycache__/snippets.cpython-312.pyc,,
mesonbuild/modules/__pycache__/sourceset.cpython-312.pyc,,
mesonbuild/modules/__pycache__/wayland.cpython-312.pyc,,
mesonbuild/modules/__pycache__/windows.cpython-312.pyc,,
mesonbuild/modules/_qt.py,sha256=lzMpOSHPAyTJIrlVv73KZ6mpeGBXw_dBwDDDXrMCwZY,56870
mesonbuild/modules/cmake.py,sha256=yTvvpirvvLrO7uXSkI2ce6JsoVncwJKWFvDg-A3o3CA,19322
mesonbuild/modules/codegen.py,sha256=vIA8M9MIKW6MhODujE5pKQPsbQYGmJS7-Zzpc6mdBWk,18019
mesonbuild/modules/cuda.py,sha256=_zA2WlT6AdoqUfaFes6_kS1dNEe66i6XAynPne6moMI,20846
mesonbuild/modules/dlang.py,sha256=f0OwaPE1ThTYEKgyFBOu88F1J-Oij01YGPBsgE0wEKY,5679
mesonbuild/modules/external_project.py,sha256=5dnlTvbD1cqlzgGmwp2r4wwvhgeKlbkdMLweNShhRIc,15242
mesonbuild/modules/fs.py,sha256=82665U8DzJMfdfme8bEDWEfSvpgMnuTnRip07xKD5dQ,14929
mesonbuild/modules/gnome.py,sha256=OrC6LGDCaw4YUPwrDO9sagQuJJYHrLmWnWcvUOpeJGk,108879
mesonbuild/modules/hotdoc.py,sha256=jGKlqZ5We59Yu8VEojyo5Xw9uF2JXDK_5S2E1rrf_bw,19964
mesonbuild/modules/i18n.py,sha256=RLFajgKaoVXPzgXeiq2nJXazeeI7WWROM9ITG7xM3_A,23203
mesonbuild/modules/icestorm.py,sha256=_yZxJdPREi4FlUS9aoFYUUfR_wfJiCx1mVUjz4cwSkE,4056
mesonbuild/modules/java.py,sha256=VdFO6HdW4tlrzMl8q_6pzuqpwLLMtxerezURCLUcc3M,4526
mesonbuild/modules/keyval.py,sha256=CWk9tfXLJuFV0msJrJp50xcMomCHDn4Q_5Eupr8S_G0,2106
mesonbuild/modules/modtest.py,sha256=P9zPX0xS2NblOgJwIKOUmRIo8ZXil1-8xakU_rzSgD0,908
mesonbuild/modules/pkgconfig.py,sha256=ElKOi1XCHQ4bsqac7EdfPLh4ag56vh-PDFQh5F1T2xw,42957
mesonbuild/modules/python.py,sha256=mXr3cBH0um3SxTG6noWly4p-D7Si4KIGBGxdTpG8hfM,27493
mesonbuild/modules/python3.py,sha256=9EAVlxk_Swcgz-ssErJ8mb6qnfP6pY3IrD1TKWUEB44,3397
mesonbuild/modules/qt4.py,sha256=DJbhjDrWO1TFzjZ4yzrljIt8EClvIUKqvOA-2UhLPi4,514
mesonbuild/modules/qt5.py,sha256=0JNlgM87o6EKgGQcWTJgOmYRm_lVdKXy9ulwhCyrQds,514
mesonbuild/modules/qt6.py,sha256=pPSNmCClS3evpO9RW6NJBgJLi1ZOsVqocyBvlJmqT3k,523
mesonbuild/modules/rust.py,sha256=XrdVxxln7n3CKGRc-ZM3lfh8i2QDMRT8rcNLzOMHQVA,46647
mesonbuild/modules/simd.py,sha256=AwcKKR4_jOq6EHq-sxAPtypz1WH1ZK52TS7RYxENzsw,3865
mesonbuild/modules/snippets.py,sha256=EHS0k1Uoqy0EaHWG8xJ1ZEAN4p7YOAn5iGBUAZ3VmVg,4222
mesonbuild/modules/sourceset.py,sha256=Gn9OG4A0HtkBEPp5WLvxLzAMmZiVEhkedpq9nTKQ_sA,11839
mesonbuild/modules/wayland.py,sha256=Te-8SZ15yomDiP1qqiI6FkYppTQBd5rIhyQPr_kCDNk,5602
mesonbuild/modules/windows.py,sha256=BmerzfCtTRjJKCvzXiXG2_m4MraACQEpAs-niOWE7oQ,10239
mesonbuild/mparser.py,sha256=gFxTaWT8I3vIrxMNHBdqWVUmD0PxE3rTlWL04Pub-fY,41389
mesonbuild/msetup.py,sha256=fywHPxpRkOe2g8Ro-DBhA1qrIZ6G6zEjG8qz9y6exXs,21597
mesonbuild/msubprojects.py,sha256=djYuccoH7JKYg-IBcMgVG4F3km1vANuSLuk9AZeh7b8,33787
mesonbuild/mtest.py,sha256=lMI-zrWxwbyaq6pTKz0s-zIZFMJb3bToNyOk_BwsxZ0,95562
mesonbuild/munstable_coredata.py,sha256=670z6XFudK8BdtjYnOsEJJGBS6eBHH8p0VBQmqX8igc,4267
mesonbuild/optinterpreter.py,sha256=t4fnoioX26BYYpnDzAeT8ZQ1e54jjc_JWauzKUeu5nM,11824
mesonbuild/options.py,sha256=F4JkoTco9SlzT1QalPyrHr9FNMUbMkosJexv6NDF1Dw,62223
mesonbuild/programs.py,sha256=zijnWn3H3lLLAlnJX1T_-vhbeHHUDcKFb00A65DZvGg,19255
mesonbuild/rewriter.py,sha256=Kiv6svd4X0l3c3q1DgnmAKjmwinE8f3uHyqRnmNV5FI,51601
mesonbuild/scripts/__init__.py,sha256=N73MaQv1t8syoOAt7FIb7ngAHbeuFZ1GAjm9uvdp9gw,303
mesonbuild/scripts/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/clangformat.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/clangtidy.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/cleantrees.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/clippy.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/cmake_run_ctgt.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/copy.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/coverage.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/delwithsuffix.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/depaccumulate.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/depfixer.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/depscan.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/dirchanger.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/env2mfile.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/externalproject.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/gettext.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/gtkdochelper.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/hotdochelper.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/itstool.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/meson_exe.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/msgfmthelper.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/pickle_env.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/pycompile.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/python_info.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/rc.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/regen_checker.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/reprotest.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/run_tool.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/rustdoc.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/scanbuild.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/symbolextractor.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/tags.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/test_loaded_modules.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/uninstall.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/vcstagger.cpython-312.pyc,,
mesonbuild/scripts/__pycache__/yasm.cpython-312.pyc,,
mesonbuild/scripts/clangformat.py,sha256=eXGEhLbDBrMPVSgbbaXLJ3PJX2rPGMwlGPJUhns4ZZQ,2150
mesonbuild/scripts/clangtidy.py,sha256=vb6GWAYuk7H5pw6LMChAEg_jfvcFMTr4RqQKkyUW6Bs,2499
mesonbuild/scripts/cleantrees.py,sha256=4jLRxLYQJTGiHAFvpCaH1OqX2DXSEDuxdGzcZqSLevA,1048
mesonbuild/scripts/clippy.py,sha256=GCZggmU_haBUDc0ph4TIpD_YBq4rjS9qesqjPa-yKmw,3024
mesonbuild/scripts/cmake_run_ctgt.py,sha256=NUIQE3n08E5yOTDuXrX0Dr2iXaDP-1FgJthM1bb47Dc,3264
mesonbuild/scripts/cmd_or_ps.ps1,sha256=ox4tg7aMciBZKiIxTuDm25vypj58zvt_OMhHgjGeD3I,510
mesonbuild/scripts/copy.py,sha256=qhVTVswAf4z5m8bpXNYhqU-W4_xvkRhgGkKfMtOGSvU,420
mesonbuild/scripts/coverage.py,sha256=TOB3DKjmGFfZDA0I0fkzmRdlfEVE8JHPefqr7F4FMg4,10819
mesonbuild/scripts/delwithsuffix.py,sha256=WJ94xxkvWRG5AS4k_BZ_18OiY4Bn2_XN2TGmX6TjA1o,664
mesonbuild/scripts/depaccumulate.py,sha256=_paPjNXGTAyqf36tsIqTC81m0KwbyED_NEsm0ag1RTU,4463
mesonbuild/scripts/depfixer.py,sha256=_ZnNKOMp3uzMTf713EbmGMDw1LhvSnMtMl-knxhIJMs,22859
mesonbuild/scripts/depscan.py,sha256=TN-bbkUvgr_ctLPMBBpUNheBo81YwQdPb09efU0JyH4,8574
mesonbuild/scripts/dirchanger.py,sha256=5TOoTlZYggxt4lPcUxcLlJaovNdQtl5lS4WJW2bPFvI,473
mesonbuild/scripts/env2mfile.py,sha256=db0e2TrNpH0rZfzhtSIup-9Z0Sm8F9m6Wv9nqrbgJjQ,21886
mesonbuild/scripts/externalproject.py,sha256=61bM8A7fMRF3WtbrkYQcuh4qgp5eIgmVepN4uTS5a3Q,3846
mesonbuild/scripts/gettext.py,sha256=pb_z0AalADv-7apTBVA_U--gw81fYESbYQccqJctAf4,3453
mesonbuild/scripts/gtkdochelper.py,sha256=Kn0XwjBaPlJ1YVzryqYNSQSzXT79vIKeb45Cl-oRjF0,11131
mesonbuild/scripts/hotdochelper.py,sha256=-JE2-tOBM9lKB3p7PheVr6z5gShWglQc5hYxZg2TGbk,1111
mesonbuild/scripts/itstool.py,sha256=nHuiNoLH0m9GAc90eUa1N5H_uzetr45zI-wJ4TRrAi4,2614
mesonbuild/scripts/meson_exe.py,sha256=QVaD69JCGTSo1FN1BcmPq0EvowFRODhNFfqrj1_a3uE,4159
mesonbuild/scripts/msgfmthelper.py,sha256=DDOAf7ivASuzhxcgzSA6vGtgobOfBj_3O785j3OnMJc,937
mesonbuild/scripts/pickle_env.py,sha256=XoVQpXuOzKGgTBSuG0KKNBKxiz4lS04AwLeySivsSZo,168
mesonbuild/scripts/pycompile.py,sha256=luoDgLqyncSpqFbsBC5fRSTrm8oJlZaAGvWOl1_trqc,1813
mesonbuild/scripts/python_info.py,sha256=ZFVxubbIxnh2Zzn_l-nWhKVw-F18ftTFDUK4-6oWwMc,4401
mesonbuild/scripts/rc.py,sha256=HDjIz_OADKmpH8WEUXQkURd83Rh2yXh4BeOLWvDGtcc,1192
mesonbuild/scripts/regen_checker.py,sha256=5J7qYcFp2eTtRPl7hE6vElClTyFcQCCjZf_O9BnwcSE,2158
mesonbuild/scripts/reprotest.py,sha256=GRU3xjk5O0wFqUYllbLn4HbwFLT0ewsCKVHrtSNI8jQ,4216
mesonbuild/scripts/run_tool.py,sha256=MIQtW667BM_V6wCAsGIjFrbrPnclsZkgkdTrHSf4-tE,6037
mesonbuild/scripts/rustdoc.py,sha256=kjSdpXWw1aZA654q-AH_Qcn-U8u7DZEhbNZG5t_d1CI,4627
mesonbuild/scripts/scanbuild.py,sha256=zAOR45n2CcOYrces4FU6y75pAXsYZKQrLe76dozCUaI,2118
mesonbuild/scripts/symbolextractor.py,sha256=1l1s0RQ2ALTE_Q2ptKW895KjMIuOzfkfqO_RZtS1b-o,14034
mesonbuild/scripts/tags.py,sha256=URXadlB93PzVJ-xdLF7jaaw176pWQQqS2hn33ONzOuA,1239
mesonbuild/scripts/test_loaded_modules.py,sha256=KaXFQibBh278z4qEvTVq3mfbEqwcHag_ctk4sbolGlw,343
mesonbuild/scripts/uninstall.py,sha256=rNjYK4DXlmNas9-yqJUr_U1PIq5KN24IqXMXaeYI0k8,1171
mesonbuild/scripts/vcstagger.py,sha256=-B5LkoiKW7mmh3cTLZ1pNMxmbnQKFsXU-eVt2QvDgFo,1265
mesonbuild/scripts/yasm.py,sha256=xHoAy2WfYvqBGMtecWpw9bO5UwsP4FHQbdG-Eml-DTg,604
mesonbuild/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
mesonbuild/templates/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/templates/__pycache__/cpptemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/cstemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/ctemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/cudatemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/dlangtemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/fortrantemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/javatemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/mesontemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/objcpptemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/objctemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/rusttemplates.cpython-312.pyc,,
mesonbuild/templates/__pycache__/samplefactory.cpython-312.pyc,,
mesonbuild/templates/__pycache__/sampleimpl.cpython-312.pyc,,
mesonbuild/templates/__pycache__/valatemplates.cpython-312.pyc,,
mesonbuild/templates/cpptemplates.py,sha256=xOKYDD3mXlHxX33DQreaXFr0S2vC5kfh7_YTG-VLAFQ,3805
mesonbuild/templates/cstemplates.py,sha256=JPAIH2eW3sC21okcxMpGCDJjzrmyBeeac2aJgsSOA8c,2544
mesonbuild/templates/ctemplates.py,sha256=Ac_XFWcWqbY3SUuGgYL1ygNOhM-yH9yKTXgdPhB-Wgo,3629
mesonbuild/templates/cudatemplates.py,sha256=U6rASA4CiPkwogBMtTYs9oVUGsoU3xWir-_x3OVgfHE,3669
mesonbuild/templates/dlangtemplates.py,sha256=BBu1VDfT-0GowuRT39uCnvGEmSnLoG5LsbH6qm4D9tw,3035
mesonbuild/templates/fortrantemplates.py,sha256=_3BS3wcN5mYrP2afhSb6AfigwpjoDTmljl1aEJbrTck,2819
mesonbuild/templates/javatemplates.py,sha256=KLt2Sqi-2Wz2hbS8BKNx2wNsXKq69UXrnEnzB_gCy1k,2637
mesonbuild/templates/mesontemplates.py,sha256=URb2UHke7jtIXS1S2swMuItssrjic5qFPvcNynlyH9g,482
mesonbuild/templates/objcpptemplates.py,sha256=DIUuWBwTo7HSpBOYRrwsQ3tOLDnJs0Lyv9MoPdJ1bjk,3747
mesonbuild/templates/objctemplates.py,sha256=hoMnu9kZMd3ceGQB9kI6EWEuzVySltI4x_Czm4JejNM,3665
mesonbuild/templates/rusttemplates.py,sha256=Kx2vwcAq0ffFC3YwTMoaibnDvT0IuTewJf-2mCOrc54,2424
mesonbuild/templates/samplefactory.py,sha256=umn1c1Aw7Nw5NpbbXsnUd1LDw2O_Yiy1m1Sbsb4E6ZM,1443
mesonbuild/templates/sampleimpl.py,sha256=OrM0GVBIuOZgCGnqZYv30D0q54NVeip-Lx0R0JjnGsk,8824
mesonbuild/templates/valatemplates.py,sha256=Brq6Z0GrgTjC9KGr0MQ1ArpVNP5NHTg5QVz7Di0XdnU,2279
mesonbuild/tooldetect.py,sha256=FA61m3epYL0dYozAiTuqT7YDwqZumP7XxY5d9nazmv8,9005
mesonbuild/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
mesonbuild/utils/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/utils/__pycache__/core.cpython-312.pyc,,
mesonbuild/utils/__pycache__/platform.cpython-312.pyc,,
mesonbuild/utils/__pycache__/universal.cpython-312.pyc,,
mesonbuild/utils/__pycache__/vsenv.cpython-312.pyc,,
mesonbuild/utils/core.py,sha256=Uh_sBQWpeE_dNSAB5fGjQ20UUXfxcITvFnirfT3_NlU,6928
mesonbuild/utils/platform.py,sha256=XbDh2wZQWypnpgKnhYfAoRVEa_jC80N430DkuuMee0Y,4603
mesonbuild/utils/universal.py,sha256=KFh-Qv5NtnDukzSs7-ZQNvfER9Q0WyCjj2Yop327vaI,92023
mesonbuild/utils/vsenv.py,sha256=cw06iaGuvDY_VUfmZRfq_3ZABLH0sHkH8ltN_XfUBD0,4075
mesonbuild/wrap/__init__.py,sha256=_aUt8AgJr5YK1rdKFxLxqRrR1WtQKWDaCdIPCRAKmgY,2070
mesonbuild/wrap/__pycache__/__init__.cpython-312.pyc,,
mesonbuild/wrap/__pycache__/wrap.cpython-312.pyc,,
mesonbuild/wrap/__pycache__/wraptool.cpython-312.pyc,,
mesonbuild/wrap/wrap.py,sha256=nYBbkE0wcwverKBcyMtGEUcgTo2QWGbL3yqtKwKbU18,45478
mesonbuild/wrap/wraptool.py,sha256=VqlL5Tw6-TCZfJS1fzvZTkHu7rvA5Ig_Hw2x5BS1bns,9310
Whitespace-only changes.
@@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: setuptools (80.9.0)
Root-Is-Purelib: true
Tag: py3-none-any
@@ -0,0 +1,2 @@
[console_scripts]
meson = mesonbuild.mesonmain:main
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -0,0 +1 @@
mesonbuild
Whitespace-only changes.
@@ -0,0 +1,63 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2021 The Meson development team
'''
This module soly exists to work around a pathlib.resolve bug on
certain Windows systems:
https://github.com/mesonbuild/meson/issues/7295
https://bugs.python.org/issue31842
It should **never** be used directly. Instead, it is automatically
used when `import pathlib` is used. This is achieved by messing with
`sys.modules['pathlib']` in mesonmain.
Additionally, the sole purpose of this module is to work around a
python bug. This only bugfixes to pathlib functions and classes are
allowed here. Finally, this file should be removed once all upstream
python bugs are fixed and it is OK to tell our users to "just upgrade
python".
'''
from __future__ import annotations
import pathlib
import os
import platform
__all__ = [
'PurePath',
'PurePosixPath',
'PureWindowsPath',
'Path',
]
PurePath = pathlib.PurePath
PurePosixPath = pathlib.PurePosixPath
PureWindowsPath = pathlib.PureWindowsPath
# Only patch on platforms where the bug occurs
if platform.system().lower() in {'windows'}:
# Can not directly inherit from pathlib.Path because the __new__
# operator of pathlib.Path() returns a {Posix,Windows}Path object.
class Path(type(pathlib.Path())):
def resolve(self, strict: bool = False) -> 'Path':
'''
Work around a resolve bug on certain Windows systems:
https://github.com/mesonbuild/meson/issues/7295
https://bugs.python.org/issue31842
'''
try:
return super().resolve(strict=strict)
except OSError:
return Path(os.path.normpath(self))
else:
Path = pathlib.Path
PosixPath = pathlib.PosixPath
WindowsPath = pathlib.WindowsPath
__all__ += [
'PosixPath',
'WindowsPath',
]
@@ -0,0 +1,69 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2020 The Meson development team
# Copyright © 2020-2024 Intel Corporation
"""Meson specific typing helpers.
Holds typing helper classes, such as the ImmutableProtocol classes
"""
__all__ = [
'Protocol',
'ImmutableListProtocol'
]
import typing
# We can change this to typing when we require python 3.8
from typing_extensions import Protocol
T = typing.TypeVar('T')
class StringProtocol(Protocol):
def __str__(self) -> str: ...
class SizedStringProtocol(Protocol, StringProtocol, typing.Sized):
pass
class ImmutableListProtocol(Protocol[T]):
"""A protocol used in cases where a list is returned, but should not be
mutated.
This provides all of the methods of a Sequence, as well as copy(). copy()
returns a list, which allows mutation as it's a copy and that's (hopefully)
safe.
One particular case this is important is for cached values, since python is
a pass-by-reference language.
"""
def __iter__(self) -> typing.Iterator[T]: ...
@typing.overload
def __getitem__(self, index: int) -> T: ...
@typing.overload
def __getitem__(self, index: slice) -> typing.List[T]: ...
def __contains__(self, item: T) -> bool: ...
def __reversed__(self) -> typing.Iterator[T]: ...
def __len__(self) -> int: ...
def __add__(self, other: typing.List[T]) -> typing.List[T]: ...
def __eq__(self, other: typing.Any) -> bool: ...
def __ne__(self, other: typing.Any) -> bool: ...
def __le__(self, other: typing.Any) -> bool: ...
def __lt__(self, other: typing.Any) -> bool: ...
def __gt__(self, other: typing.Any) -> bool: ...
def __ge__(self, other: typing.Any) -> bool: ...
def count(self, item: T) -> int: ...
def index(self, item: T) -> int: ...
def copy(self) -> typing.List[T]: ...
@@ -0,0 +1,340 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2012-2020 The Meson development team
# Copyright © 2020-2023 Intel Corporation
from __future__ import annotations
from functools import lru_cache
import collections
import enum
import os
import re
import typing as T
if T.TYPE_CHECKING:
from .linkers.linkers import StaticLinker
from .compilers import Compiler
# execinfo is a compiler lib on BSD
UNIXY_COMPILER_INTERNAL_LIBS = ['m', 'c', 'pthread', 'dl', 'rt', 'execinfo']
class Dedup(enum.Enum):
"""What kind of deduplication can be done to compiler args.
OVERRIDDEN - Whether an argument can be 'overridden' by a later argument.
For example, -DFOO defines FOO and -UFOO undefines FOO. In this case,
we can safely remove the previous occurrence and add a new one. The
same is true for include paths and library paths with -I and -L.
UNIQUE - Arguments that once specified cannot be undone, such as `-c` or
`-pipe`. New instances of these can be completely skipped.
NO_DEDUP - When it matters where or how many times on the command-line
a particular argument is present. This can matter for symbol
resolution in static or shared libraries, so we cannot de-dup or
reorder them.
"""
NO_DEDUP = 0
UNIQUE = 1
OVERRIDDEN = 2
class CompilerArgs(T.MutableSequence[str]):
'''
List-like class that manages a list of compiler arguments. Should be used
while constructing compiler arguments from various sources. Can be
operated with ordinary lists, so this does not need to be used
everywhere.
All arguments must be inserted and stored in GCC-style (-lfoo, -Idir, etc)
and can converted to the native type of each compiler by using the
.to_native() method to which you must pass an instance of the compiler or
the compiler class.
New arguments added to this class (either with .append(), .extend(), or +=)
are added in a way that ensures that they override previous arguments.
For example:
>>> a = ['-Lfoo', '-lbar']
>>> a += ['-Lpho', '-lbaz']
>>> print(a)
['-Lpho', '-Lfoo', '-lbar', '-lbaz']
Arguments will also be de-duped if they can be de-duped safely.
Note that because of all this, this class is not commutative and does not
preserve the order of arguments if it is safe to not. For example:
>>> ['-Ifoo', '-Ibar'] + ['-Ifez', '-Ibaz', '-Werror']
['-Ifez', '-Ibaz', '-Ifoo', '-Ibar', '-Werror']
>>> ['-Ifez', '-Ibaz', '-Werror'] + ['-Ifoo', '-Ibar']
['-Ifoo', '-Ibar', '-Ifez', '-Ibaz', '-Werror']
'''
# Arg prefixes that override by prepending instead of appending
prepend_prefixes: T.Tuple[str, ...] = ()
# Arg prefixes and standalone args that must be de-duped by returning 2
dedup2_prefixes: T.Tuple[str, ...] = ()
dedup2_suffixes: T.Tuple[str, ...] = ()
dedup2_args: T.Tuple[str, ...] = ()
# Arg prefixes and standalone args that must be de-duped by returning 1
#
# NOTE: not thorough. A list of potential corner cases can be found in
# https://github.com/mesonbuild/meson/pull/4593#pullrequestreview-182016038
dedup1_prefixes: T.Tuple[str, ...] = ()
dedup1_suffixes = ('.lib', '.dll', '.so', '.dylib', '.a')
# Match a .so of the form path/to/libfoo.so.0.1.0
# Only UNIX shared libraries require this. Others have a fixed extension.
dedup1_regex = re.compile(r'([\/\\]|\A)lib.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$')
dedup1_args: T.Tuple[str, ...] = ()
# In generate_link() we add external libs without de-dup, but we must
# *always* de-dup these because they're special arguments to the linker
# TODO: these should probably move too
always_dedup_args = tuple('-l' + lib for lib in UNIXY_COMPILER_INTERNAL_LIBS)
def __init__(self, compiler: T.Union['Compiler', 'StaticLinker'],
iterable: T.Optional[T.Iterable[str]] = None):
self.compiler = compiler
if isinstance(iterable, CompilerArgs):
iterable.flush_pre_post()
# list(iter(x)) is over two times slower than list(x), so
# pass the underlying list to list() directly, instead of an iterator
iterable = iterable._container
self._container: T.List[str] = list(iterable) if iterable is not None else []
self.pre: T.Deque[str] = collections.deque()
self.post: T.List[str] = []
self.needs_override_check: bool = False
# Flush the saved pre and post list into the _container list
#
# This correctly deduplicates the entries after _can_dedup definition
# Note: This function is designed to work without delete operations, as deletions are worsening the performance a lot.
def flush_pre_post(self) -> None:
if not self.needs_override_check:
if self.pre:
self._container[0:0] = self.pre
self.pre.clear()
if self.post:
self._container.extend(self.post)
self.post.clear()
return
new: T.List[str] = []
pre_flush_set: T.Set[str] = set()
post_flush: T.Deque[str] = collections.deque()
post_flush_set: T.Set[str] = set()
#The two lists are here walked from the front to the back, in order to not need removals for deduplication
for a in self.pre:
dedup = self._can_dedup(a)
if a not in pre_flush_set:
new.append(a)
if dedup is Dedup.OVERRIDDEN:
pre_flush_set.add(a)
for a in reversed(self.post):
dedup = self._can_dedup(a)
if a not in post_flush_set:
post_flush.appendleft(a)
if dedup is Dedup.OVERRIDDEN:
post_flush_set.add(a)
#pre and post will overwrite every element that is in the container
#only copy over args that are in _container but not in the post flush or pre flush set
for a in self._container:
if a not in post_flush_set and a not in pre_flush_set:
new.append(a)
new.extend(post_flush)
self._container = new
self.pre.clear()
self.post.clear()
self.needs_override_check = False
def __iter__(self) -> T.Iterator[str]:
# see also __init__, where this method is essentially inlined
self.flush_pre_post()
return iter(self._container)
@T.overload # noqa: F811
def __getitem__(self, index: int) -> str: # noqa: F811
pass
@T.overload # noqa: F811
def __getitem__(self, index: slice) -> T.MutableSequence[str]: # noqa: F811
pass
def __getitem__(self, index: T.Union[int, slice]) -> T.Union[str, T.MutableSequence[str]]: # noqa: F811
self.flush_pre_post()
return self._container[index]
@T.overload # noqa: F811
def __setitem__(self, index: int, value: str) -> None: # noqa: F811
pass
@T.overload # noqa: F811
def __setitem__(self, index: slice, value: T.Iterable[str]) -> None: # noqa: F811
pass
def __setitem__(self, index: T.Union[int, slice], value: T.Union[str, T.Iterable[str]]) -> None: # noqa: F811
self.flush_pre_post()
self._container[index] = value # type: ignore # TODO: fix 'Invalid index type' and 'Incompatible types in assignment' errors
def __delitem__(self, index: T.Union[int, slice]) -> None:
self.flush_pre_post()
del self._container[index]
def __len__(self) -> int:
return len(self._container) + len(self.pre) + len(self.post)
def insert(self, index: int, value: str) -> None:
self.flush_pre_post()
self._container.insert(index, value)
def copy(self) -> 'CompilerArgs':
self.flush_pre_post()
return type(self)(self.compiler, self._container.copy())
@classmethod
@lru_cache(maxsize=None)
def _can_dedup(cls, arg: str) -> Dedup:
"""Returns whether the argument can be safely de-duped.
In addition to these, we handle library arguments specially.
With GNU ld, we surround library arguments with -Wl,--start/end-group
to recursively search for symbols in the libraries. This is not needed
with other linkers.
"""
# Argument prefixes that are actually not used as a prefix must never
# be deduplicated because they are defined by what comes _after_ them.
# Thus deduping this:
# -D FOO -D BAR
# would yield either
# -D FOO BAR
# or
# FOO -D BAR
# both of which are invalid.
if arg in cls.dedup1_prefixes or arg in cls.dedup2_prefixes:
return Dedup.NO_DEDUP
if arg in cls.dedup2_args or \
arg.startswith(cls.dedup2_prefixes) or \
arg.endswith(cls.dedup2_suffixes):
return Dedup.OVERRIDDEN
if arg in cls.dedup1_args or \
arg.startswith(cls.dedup1_prefixes) or \
arg.endswith(cls.dedup1_suffixes) or \
re.search(cls.dedup1_regex, arg):
return Dedup.UNIQUE
return Dedup.NO_DEDUP
@classmethod
@lru_cache(maxsize=None)
def _should_prepend(cls, arg: str) -> bool:
return arg.startswith(cls.prepend_prefixes)
def to_native(self, copy: bool = False) -> T.List[str]:
# Check if we need to add --start/end-group for circular dependencies
# between static libraries, and for recursively searching for symbols
# needed by static libraries that are provided by object files or
# shared libraries.
self.flush_pre_post()
if copy:
new = self.copy()
else:
new = self
return self.compiler.unix_args_to_native(new._container)
def append_direct(self, arg: str) -> None:
'''
Append the specified argument without any reordering or de-dup except
for absolute paths to libraries, etc, which can always be de-duped
safely.
'''
self.flush_pre_post()
if os.path.isabs(arg):
self.append(arg)
else:
self._container.append(arg)
def extend_direct(self, iterable: T.Iterable[str]) -> None:
'''
Extend using the elements in the specified iterable without any
reordering or de-dup except for absolute paths where the order of
include search directories is not relevant
'''
self.flush_pre_post()
for elem in iterable:
self.append_direct(elem)
def extend_preserving_lflags(self, iterable: T.Iterable[str]) -> None:
normal_flags = []
lflags = []
for i in iterable:
if i not in self.always_dedup_args and (i.startswith('-l') or i.startswith('-L')):
lflags.append(i)
else:
normal_flags.append(i)
self.extend(normal_flags)
self.extend_direct(lflags)
def __add__(self, args: T.Iterable[str]) -> 'CompilerArgs':
self.flush_pre_post()
new = self.copy()
new += args
return new
def __iadd__(self, args: T.Iterable[str]) -> 'CompilerArgs':
'''
Add two CompilerArgs while taking into account overriding of arguments
and while preserving the order of arguments as much as possible
'''
tmp_pre: T.Deque[str] = collections.deque()
if not isinstance(args, collections.abc.Iterable):
raise TypeError(f'can only concatenate Iterable[str] (not "{args}") to CompilerArgs')
for arg in args:
# If the argument can be de-duped, do it either by removing the
# previous occurrence of it and adding a new one, or not adding the
# new occurrence.
dedup = self._can_dedup(arg)
if dedup is Dedup.UNIQUE:
# Argument already exists and adding a new instance is useless
if arg in self._container or arg in self.pre or arg in self.post:
continue
elif dedup is Dedup.OVERRIDDEN:
self.needs_override_check = True
if self._should_prepend(arg):
tmp_pre.appendleft(arg)
else:
self.post.append(arg)
self.pre.extendleft(tmp_pre)
#pre and post is going to be merged later before a iter call
return self
def __radd__(self, args: T.Iterable[str]) -> 'CompilerArgs':
self.flush_pre_post()
new = type(self)(self.compiler, args)
new += self
return new
def __eq__(self, other: object) -> T.Union[bool]:
self.flush_pre_post()
# Only allow equality checks against other CompilerArgs and lists instances
if isinstance(other, CompilerArgs):
return self.compiler == other.compiler and self._container == other._container
elif isinstance(other, list):
return self._container == other
return NotImplemented
def append(self, arg: str) -> None:
self += [arg]
def extend(self, args: T.Iterable[str]) -> None:
self += args
def __repr__(self) -> str:
self.flush_pre_post()
return f'CompilerArgs({self.compiler!r}, {self._container!r})'
@@ -0,0 +1,23 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2019 The Meson development team
# This class contains the basic functionality needed to run any interpreter
# or an interpreter-based tool.
__all__ = [
'AstConditionLevel',
'AstInterpreter',
'AstIDGenerator',
'AstIndentationGenerator',
'AstJSONPrinter',
'AstVisitor',
'AstPrinter',
'IntrospectionInterpreter',
'BUILD_TARGET_FUNCTIONS',
]
from .interpreter import AstInterpreter
from .introspection import IntrospectionInterpreter, BUILD_TARGET_FUNCTIONS
from .visitor import AstVisitor
from .postprocess import AstConditionLevel, AstIDGenerator, AstIndentationGenerator
from .printer import AstPrinter, AstJSONPrinter
@@ -0,0 +1,780 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2016 The Meson development team
# This class contains the basic functionality needed to run any interpreter
# or an interpreter-based tool.
from __future__ import annotations
import os
import sys
import typing as T
from collections import defaultdict
from dataclasses import dataclass
import itertools
from pathlib import Path
from .. import mparser, mesonlib, mlog
from .. import environment
from ..interpreterbase import (
MesonInterpreterObject,
InterpreterBase,
InvalidArguments,
BreakRequest,
ContinueRequest,
Disabler,
default_resolve_key,
is_disabled,
UnknownValue,
UndefinedVariable,
InterpreterObject,
)
from ..interpreterbase.helpers import flatten
from ..interpreter import (
StringHolder,
BooleanHolder,
IntegerHolder,
ArrayHolder,
DictHolder,
)
from ..mparser import (
ArgumentNode,
ArithmeticNode,
ArrayNode,
AssignmentNode,
BaseNode,
EmptyNode,
IdNode,
MethodNode,
NotNode,
PlusAssignmentNode,
TernaryNode,
SymbolNode,
Token,
FunctionNode,
)
if T.TYPE_CHECKING:
from .visitor import AstVisitor
from ..interpreter import Interpreter
from ..interpreterbase import SubProject, TYPE_var, TYPE_nvar
from ..mparser import (
AndNode,
ComparisonNode,
ForeachClauseNode,
IfClauseNode,
IndexNode,
OrNode,
TestCaseClauseNode,
UMinusNode,
)
_T = T.TypeVar('_T')
_V = T.TypeVar('_V')
def _symbol(val: str) -> SymbolNode:
return SymbolNode(Token('', '', 0, 0, 0, (0, 0), val))
# `IntrospectionFile` is to the `IntrospectionInterpreter` what `File` is to the normal `Interpreter`.
@dataclass
class IntrospectionFile:
subdir: str
rel: str
def to_abs_path(self, root_dir: Path) -> Path:
return (root_dir / self.subdir / self.rel).resolve()
def __hash__(self) -> int:
return hash((self.__class__.__name__, self.subdir, self.rel))
# `IntrospectionDependency` is to the `IntrospectionInterpreter` what `Dependency` is to the normal `Interpreter`.
@dataclass
class IntrospectionDependency(MesonInterpreterObject):
name: T.Union[str, UnknownValue]
required: T.Union[bool, UnknownValue]
version: T.Union[T.List[str], UnknownValue]
has_fallback: bool
conditional: bool
node: FunctionNode
# `IntrospectionBuildTarget` is to the `IntrospectionInterpreter` what `BuildTarget` is to the normal `Interpreter`.
@dataclass
class IntrospectionBuildTarget(MesonInterpreterObject):
name: str
machine: str
id: str
typename: str
defined_in: str
subdir: str
build_by_default: T.Union[bool, UnknownValue]
installed: T.Union[bool, UnknownValue]
outputs: T.List[str]
source_nodes: T.List[BaseNode]
extra_files: BaseNode
kwargs: T.Dict[str, TYPE_var]
node: FunctionNode
def is_ignored_edge(src: T.Union[BaseNode, UnknownValue]) -> bool:
return (isinstance(src, FunctionNode) and src.func_name.value not in {'files', 'get_variable'}) or isinstance(src, MethodNode)
class DataflowDAG:
src_to_tgts: T.DefaultDict[T.Union[BaseNode, UnknownValue], T.Set[T.Union[BaseNode, UnknownValue]]]
tgt_to_srcs: T.DefaultDict[T.Union[BaseNode, UnknownValue], T.Set[T.Union[BaseNode, UnknownValue]]]
def __init__(self) -> None:
self.src_to_tgts = defaultdict(set)
self.tgt_to_srcs = defaultdict(set)
def add_edge(self, source: T.Union[BaseNode, UnknownValue], target: T.Union[BaseNode, UnknownValue]) -> None:
self.src_to_tgts[source].add(target)
self.tgt_to_srcs[target].add(source)
# Returns all nodes in the DAG that are reachable from a node in `srcs`.
# In other words, A node `a` is part of the returned set exactly if data
# from `srcs` flows into `a`, directly or indirectly.
# Certain edges are ignored.
def reachable(self, srcs: T.Set[T.Union[BaseNode, UnknownValue]], reverse: bool) -> T.Set[T.Union[BaseNode, UnknownValue]]:
reachable = srcs.copy()
active = srcs.copy()
while active:
new: T.Set[T.Union[BaseNode, UnknownValue]] = set()
if reverse:
for tgt in active:
new.update(src for src in self.tgt_to_srcs[tgt] if not is_ignored_edge(src))
else:
for src in active:
if is_ignored_edge(src):
continue
new.update(tgt for tgt in self.src_to_tgts[src])
reachable.update(new)
active = new
return reachable
# Returns all paths from src to target.
# Certain edges are ignored.
def find_all_paths(self, src: T.Union[BaseNode, UnknownValue], target: T.Union[BaseNode, UnknownValue]) -> T.List[T.List[T.Union[BaseNode, UnknownValue]]]:
queue = [(src, [src])]
paths = []
while queue:
cur, path = queue.pop()
if cur == target:
paths.append(path)
if is_ignored_edge(cur):
continue
queue.extend((tgt, path + [tgt]) for tgt in self.src_to_tgts[cur])
return paths
class AstInterpreter(InterpreterBase):
def __init__(self, source_root: str, subdir: str, subproject: SubProject, subproject_dir: str, env: environment.Environment, visitors: T.Optional[T.List[AstVisitor]] = None):
super().__init__(source_root, subdir, subproject, subproject_dir, env)
self.visitors = visitors if visitors is not None else []
self.nesting: T.List[int] = []
self.cur_assignments: T.DefaultDict[str, T.List[T.Tuple[T.List[int], T.Union[BaseNode, UnknownValue]]]] = defaultdict(list)
self.all_assignment_nodes: T.DefaultDict[str, T.List[AssignmentNode]] = defaultdict(list)
# dataflow_dag is an acyclic directed graph that contains an edge
# from one instance of `BaseNode` to another instance of `BaseNode` if
# data flows directly from one to the other. Example: If meson.build
# contains this:
# var = 'foo' + '123'
# executable(var, 'src.c')
# var = 'bar'
# dataflow_dag will contain an edge from the IdNode corresponding to
# 'var' in line 2 to the ArithmeticNode corresponding to 'foo' + '123'.
# This graph is crucial for e.g. node_to_runtime_value because we have
# to know that 'var' in line2 is 'foo123' and not 'bar'.
self.dataflow_dag = DataflowDAG()
self.funcvals: T.Dict[BaseNode, T.Any] = {}
self.tainted = False
self.predefined_vars = {
'meson': UnknownValue(),
'host_machine': UnknownValue(),
'build_machine': UnknownValue(),
'target_machine': UnknownValue()
}
self.funcs.update({'project': self.func_do_nothing,
'test': self.func_do_nothing,
'benchmark': self.func_do_nothing,
'install_headers': self.func_do_nothing,
'install_man': self.func_do_nothing,
'install_data': self.func_do_nothing,
'install_subdir': self.func_do_nothing,
'install_symlink': self.func_do_nothing,
'install_emptydir': self.func_do_nothing,
'configuration_data': self.func_do_nothing,
'configure_file': self.func_do_nothing,
'find_program': self.func_do_nothing,
'include_directories': self.func_do_nothing,
'add_global_arguments': self.func_do_nothing,
'add_global_link_arguments': self.func_do_nothing,
'add_project_arguments': self.func_do_nothing,
'add_project_dependencies': self.func_do_nothing,
'add_project_link_arguments': self.func_do_nothing,
'message': self.func_do_nothing,
'generator': self.func_do_nothing,
'error': self.func_do_nothing,
'run_command': self.func_do_nothing,
'assert': self.func_do_nothing,
'subproject': self.func_do_nothing,
'dependency': self.func_do_nothing,
'get_option': self.func_do_nothing,
'join_paths': self.func_do_nothing,
'environment': self.func_do_nothing,
'import': self.func_do_nothing,
'vcs_tag': self.func_do_nothing,
'add_languages': self.func_do_nothing,
'declare_dependency': self.func_do_nothing,
'files': self.func_files,
'executable': self.func_do_nothing,
'static_library': self.func_do_nothing,
'shared_library': self.func_do_nothing,
'library': self.func_do_nothing,
'build_target': self.func_do_nothing,
'custom_target': self.func_do_nothing,
'run_target': self.func_do_nothing,
'subdir': self.func_subdir,
'set_variable': self.func_set_variable,
'get_variable': self.func_get_variable,
'unset_variable': self.func_unset_variable,
'is_disabler': self.func_do_nothing,
'is_variable': self.func_do_nothing,
'disabler': self.func_do_nothing,
'jar': self.func_do_nothing,
'warning': self.func_do_nothing,
'shared_module': self.func_do_nothing,
'option': self.func_do_nothing,
'both_libraries': self.func_do_nothing,
'add_test_setup': self.func_do_nothing,
'subdir_done': self.func_do_nothing,
'alias_target': self.func_do_nothing,
'summary': self.func_do_nothing,
'range': self.func_do_nothing,
'structured_sources': self.func_do_nothing,
'debug': self.func_do_nothing,
})
def _unholder_args(self, args: T.Any, kwargs: T.Any) -> T.Tuple[T.Any, T.Any]:
return args, kwargs
def _holderify(self, res: T.Any) -> T.Any:
return res
def func_do_nothing(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> UnknownValue:
return UnknownValue()
def load_root_meson_file(self) -> None:
super().load_root_meson_file()
for i in self.visitors:
self.ast.accept(i)
def func_subdir(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> None:
args = self.flatten_args(args)
if len(args) != 1 or not isinstance(args[0], str):
sys.stderr.write(f'Unable to evaluate subdir({args}) in AstInterpreter --> Skipping\n')
return
subdir, is_new = self._resolve_subdir(self.source_root, args[0])
if not is_new:
sys.stderr.write('Trying to enter {} which has already been visited --> Skipping\n'.format(args[0]))
return
if not self._evaluate_subdir(self.source_root, subdir, self.visitors):
buildfilename = os.path.join(subdir, environment.build_filename)
sys.stderr.write(f'Unable to find build file {buildfilename} --> Skipping\n')
def inner_method_call(self, obj: BaseNode, method_name: str, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Any:
for arg in itertools.chain(args, kwargs.values()):
if isinstance(arg, UnknownValue):
return UnknownValue()
if isinstance(obj, str):
result = StringHolder(obj, T.cast('Interpreter', self)).method_call(method_name, args, kwargs)
elif isinstance(obj, bool):
result = BooleanHolder(obj, T.cast('Interpreter', self)).method_call(method_name, args, kwargs)
elif isinstance(obj, int):
result = IntegerHolder(obj, T.cast('Interpreter', self)).method_call(method_name, args, kwargs)
elif isinstance(obj, list):
result = ArrayHolder(obj, T.cast('Interpreter', self)).method_call(method_name, args, kwargs)
elif isinstance(obj, dict):
result = DictHolder(obj, T.cast('Interpreter', self)).method_call(method_name, args, kwargs)
else:
return UnknownValue()
return result
def method_call(self, node: mparser.MethodNode) -> None:
invocable = node.source_object
self.evaluate_statement(invocable)
obj = self.node_to_runtime_value(invocable)
method_name = node.name.value
(args, kwargs) = self.reduce_arguments(node.args)
if is_disabled(args, kwargs):
res = Disabler()
else:
res = self.inner_method_call(obj, method_name, args, kwargs)
self.funcvals[node] = res
def evaluate_fstring(self, node: mparser.StringNode) -> None:
pass
def evaluate_arraystatement(self, cur: mparser.ArrayNode) -> None:
for arg in cur.args.arguments:
self.evaluate_statement(arg)
def evaluate_arithmeticstatement(self, cur: ArithmeticNode) -> None:
self.evaluate_statement(cur.left)
self.evaluate_statement(cur.right)
def evaluate_uminusstatement(self, cur: UMinusNode) -> None:
self.evaluate_statement(cur.value)
def evaluate_ternary(self, node: TernaryNode) -> None:
assert isinstance(node, TernaryNode)
self.evaluate_statement(node.condition)
self.evaluate_statement(node.trueblock)
self.evaluate_statement(node.falseblock)
def evaluate_dictstatement(self, node: mparser.DictNode) -> None:
for k, v in node.args.kwargs.items():
self.evaluate_statement(k)
self.evaluate_statement(v)
def evaluate_indexing(self, node: IndexNode) -> None:
self.evaluate_statement(node.iobject)
self.evaluate_statement(node.index)
def reduce_arguments(
self,
args: mparser.ArgumentNode,
key_resolver: T.Callable[[mparser.BaseNode], str] = default_resolve_key,
duplicate_key_error: T.Optional[str] = None,
) -> T.Tuple[T.List[T.Any], T.Any]:
for arg in args.arguments:
self.evaluate_statement(arg)
for value in args.kwargs.values():
self.evaluate_statement(value)
if isinstance(args, ArgumentNode):
kwargs = {}
for key, val in args.kwargs.items():
kwargs[key_resolver(key)] = val
if args.incorrect_order():
raise InvalidArguments('All keyword arguments must be after positional arguments.')
return self.flatten_args(args.arguments), kwargs
else:
return self.flatten_args(args), {}
def evaluate_comparison(self, node: ComparisonNode) -> None:
self.evaluate_statement(node.left)
self.evaluate_statement(node.right)
def evaluate_andstatement(self, cur: AndNode) -> None:
self.evaluate_statement(cur.left)
self.evaluate_statement(cur.right)
def evaluate_orstatement(self, cur: OrNode) -> None:
self.evaluate_statement(cur.left)
self.evaluate_statement(cur.right)
def evaluate_notstatement(self, cur: NotNode) -> None:
self.evaluate_statement(cur.value)
def find_potential_writes(self, node: BaseNode) -> T.Set[str]:
if isinstance(node, mparser.ForeachClauseNode):
return {el.value for el in node.varnames} | self.find_potential_writes(node.block)
elif isinstance(node, mparser.CodeBlockNode):
ret = set()
for line in node.lines:
ret.update(self.find_potential_writes(line))
return ret
elif isinstance(node, (AssignmentNode, PlusAssignmentNode)):
return set([node.var_name.value]) | self.find_potential_writes(node.value)
elif isinstance(node, IdNode):
return set()
elif isinstance(node, ArrayNode):
ret = set()
for arg in node.args.arguments:
ret.update(self.find_potential_writes(arg))
return ret
elif isinstance(node, mparser.DictNode):
ret = set()
for k, v in node.args.kwargs.items():
ret.update(self.find_potential_writes(k))
ret.update(self.find_potential_writes(v))
return ret
elif isinstance(node, FunctionNode):
ret = set()
for arg in node.args.arguments:
ret.update(self.find_potential_writes(arg))
for arg in node.args.kwargs.values():
ret.update(self.find_potential_writes(arg))
return ret
elif isinstance(node, MethodNode):
ret = self.find_potential_writes(node.source_object)
for arg in node.args.arguments:
ret.update(self.find_potential_writes(arg))
for arg in node.args.kwargs.values():
ret.update(self.find_potential_writes(arg))
return ret
elif isinstance(node, ArithmeticNode):
return self.find_potential_writes(node.left) | self.find_potential_writes(node.right)
elif isinstance(node, (mparser.NumberNode, mparser.StringNode, mparser.BreakNode, mparser.BooleanNode, mparser.ContinueNode)):
return set()
elif isinstance(node, mparser.IfClauseNode):
if isinstance(node.elseblock, EmptyNode):
ret = set()
else:
ret = self.find_potential_writes(node.elseblock.block)
for i in node.ifs:
ret.update(self.find_potential_writes(i))
return ret
elif isinstance(node, mparser.IndexNode):
return self.find_potential_writes(node.iobject) | self.find_potential_writes(node.index)
elif isinstance(node, mparser.IfNode):
return self.find_potential_writes(node.condition) | self.find_potential_writes(node.block)
elif isinstance(node, (mparser.ComparisonNode, mparser.OrNode, mparser.AndNode)):
return self.find_potential_writes(node.left) | self.find_potential_writes(node.right)
elif isinstance(node, mparser.NotNode):
return self.find_potential_writes(node.value)
elif isinstance(node, mparser.TernaryNode):
return self.find_potential_writes(node.condition) | self.find_potential_writes(node.trueblock) | self.find_potential_writes(node.falseblock)
elif isinstance(node, mparser.UMinusNode):
return self.find_potential_writes(node.value)
elif isinstance(node, mparser.ParenthesizedNode):
return self.find_potential_writes(node.inner)
raise mesonlib.MesonBugException('Unhandled node type')
def evaluate_foreach(self, node: ForeachClauseNode) -> None:
asses = self.find_potential_writes(node)
for ass in asses:
self.cur_assignments[ass].append((self.nesting.copy(), UnknownValue()))
try:
self.evaluate_codeblock(node.block)
except ContinueRequest:
pass
except BreakRequest:
pass
for ass in asses:
self.cur_assignments[ass].append((self.nesting.copy(), UnknownValue())) # In case the foreach loops 0 times.
def evaluate_if(self, node: IfClauseNode) -> None:
self.nesting.append(0)
for i in node.ifs:
self.evaluate_codeblock(i.block)
self.nesting[-1] += 1
if not isinstance(node.elseblock, EmptyNode):
self.evaluate_codeblock(node.elseblock.block)
self.nesting.pop()
for var_name in self.cur_assignments:
potential_values = []
oldval = self.get_cur_value_if_defined(var_name)
if not isinstance(oldval, UndefinedVariable):
potential_values.append(oldval)
for nesting, value in self.cur_assignments[var_name]:
if len(nesting) > len(self.nesting):
potential_values.append(value)
self.cur_assignments[var_name] = [(nesting, v) for (nesting, v) in self.cur_assignments[var_name] if len(nesting) <= len(self.nesting)]
if len(potential_values) > 1 or (len(potential_values) > 0 and isinstance(oldval, UndefinedVariable)):
uv = UnknownValue()
for pv in potential_values:
self.dataflow_dag.add_edge(pv, uv)
self.cur_assignments[var_name].append((self.nesting.copy(), uv))
def func_files(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Any:
ret: T.List[T.Union[IntrospectionFile, UnknownValue]] = []
for arg in args:
if isinstance(arg, str):
ret.append(IntrospectionFile(self.subdir, arg))
elif isinstance(arg, UnknownValue):
ret.append(UnknownValue())
else:
raise TypeError
return ret
def get_cur_value_if_defined(self, var_name: str) -> T.Union[BaseNode, UnknownValue, UndefinedVariable]:
if var_name in self.predefined_vars:
return self.predefined_vars[var_name]
ret: T.Union[BaseNode, UnknownValue, UndefinedVariable] = UndefinedVariable()
for nesting, value in reversed(self.cur_assignments[var_name]):
if len(self.nesting) >= len(nesting) and self.nesting[:len(nesting)] == nesting:
ret = value
break
if isinstance(ret, UndefinedVariable) and self.tainted:
return UnknownValue()
return ret
def get_cur_value(self, var_name: str) -> T.Union[BaseNode, UnknownValue]:
ret = self.get_cur_value_if_defined(var_name)
if isinstance(ret, UndefinedVariable):
path = mlog.get_relative_path(Path(self.current_node.filename), Path(os.getcwd()))
mlog.warning(f"{path}:{self.current_node.lineno}:{self.current_node.colno} will always crash if executed, since a variable named `{var_name}` is not defined")
# We could add more advanced analysis of code referencing undefined
# variables, but it is probably not worth the effort and the
# complexity. So we do the simplest thing, returning an
# UnknownValue.
return UnknownValue()
return ret
# The function `node_to_runtime_value` takes a node of the ast as an
# argument and tries to return the same thing that would be passed to e.g.
# `func_message` if you put `message(node)` in your `meson.build` file and
# run `meson setup`. If this is not possible, `UnknownValue()` is returned.
# There are 3 Reasons why this is sometimes impossible:
# 1. Because the meson rewriter is imperfect and has not implemented everything yet
# 2. Because the value is different on different machines, example:
# ```meson
# node = somedep.found()
# message(node)
# ```
# will print `true` on some machines and `false` on others, so
# `node_to_runtime_value` does not know whether to return `true` or
# `false` and will return `UnknownValue()`.
# 3. Here:
# ```meson
# foreach x : [1, 2]
# node = x
# message(node)
# endforeach
# ```
# `node_to_runtime_value` does not know whether to return `1` or `2` and
# will return `UnknownValue()`.
#
# If you have something like
# ```
# node = [123, somedep.found()]
# ```
# `node_to_runtime_value` will return `[123, UnknownValue()]`.
def node_to_runtime_value(self, node: T.Union[UnknownValue, BaseNode, TYPE_var]) -> T.Any:
if isinstance(node, (mparser.StringNode, mparser.BooleanNode, mparser.NumberNode)):
return node.value
elif isinstance(node, mparser.StringNode):
if node.is_fstring:
return UnknownValue()
else:
return node.value
elif isinstance(node, list):
return [self.node_to_runtime_value(x) for x in node]
elif isinstance(node, ArrayNode):
return [self.node_to_runtime_value(x) for x in node.args.arguments]
elif isinstance(node, mparser.DictNode):
return {self.node_to_runtime_value(k): self.node_to_runtime_value(v) for k, v in node.args.kwargs.items()}
elif isinstance(node, IdNode):
assert len(self.dataflow_dag.tgt_to_srcs[node]) == 1
val = next(iter(self.dataflow_dag.tgt_to_srcs[node]))
return self.node_to_runtime_value(val)
elif isinstance(node, (MethodNode, FunctionNode)):
funcval = self.funcvals[node]
if isinstance(funcval, (dict, str)):
return funcval
else:
return self.node_to_runtime_value(funcval)
elif isinstance(node, ArithmeticNode):
left = self.node_to_runtime_value(node.left)
right = self.node_to_runtime_value(node.right)
if isinstance(left, list) and isinstance(right, UnknownValue):
return left + [right]
if isinstance(right, list) and isinstance(left, UnknownValue):
return [left] + right
if isinstance(left, UnknownValue) or isinstance(right, UnknownValue):
return UnknownValue()
if node.operation == '+':
if isinstance(left, dict) and isinstance(right, dict):
ret = left.copy()
for k, v in right.items():
ret[k] = v
return ret
if isinstance(left, list):
if not isinstance(right, list):
right = [right]
return left + right
return left + right
elif node.operation == '-':
return left - right
elif node.operation == '*':
return left * right
elif node.operation == '/':
if isinstance(left, int) and isinstance(right, int):
return left // right
elif isinstance(left, str) and isinstance(right, str):
return os.path.join(left, right).replace('\\', '/')
elif node.operation == '%':
if isinstance(left, int) and isinstance(right, int):
return left % right
elif isinstance(node, (UnknownValue, IntrospectionBuildTarget, IntrospectionFile, IntrospectionDependency, str, bool, int)):
return node
elif isinstance(node, mparser.IndexNode):
iobject = self.node_to_runtime_value(node.iobject)
index = self.node_to_runtime_value(node.index)
if isinstance(iobject, UnknownValue) or isinstance(index, UnknownValue):
return UnknownValue()
return iobject[index]
elif isinstance(node, mparser.ComparisonNode):
left = self.node_to_runtime_value(node.left)
right = self.node_to_runtime_value(node.right)
if isinstance(left, UnknownValue) or isinstance(right, UnknownValue):
return UnknownValue()
if node.ctype == '==':
return left == right
elif node.ctype == '!=':
return left != right
elif node.ctype == 'in':
return left in right
elif node.ctype == 'not in':
return left not in right
elif isinstance(node, mparser.TernaryNode):
cond = self.node_to_runtime_value(node.condition)
if isinstance(cond, UnknownValue):
return UnknownValue()
if cond is True:
return self.node_to_runtime_value(node.trueblock)
if cond is False:
return self.node_to_runtime_value(node.falseblock)
elif isinstance(node, mparser.OrNode):
left = self.node_to_runtime_value(node.left)
right = self.node_to_runtime_value(node.right)
if isinstance(left, UnknownValue) or isinstance(right, UnknownValue):
return UnknownValue()
return left or right
elif isinstance(node, mparser.AndNode):
left = self.node_to_runtime_value(node.left)
right = self.node_to_runtime_value(node.right)
if isinstance(left, UnknownValue) or isinstance(right, UnknownValue):
return UnknownValue()
return left and right
elif isinstance(node, mparser.UMinusNode):
val = self.node_to_runtime_value(node.value)
if isinstance(val, UnknownValue):
return val
if isinstance(val, (int, float)):
return -val
elif isinstance(node, mparser.NotNode):
val = self.node_to_runtime_value(node.value)
if isinstance(val, UnknownValue):
return val
if isinstance(val, bool):
return not val
elif isinstance(node, mparser.ParenthesizedNode):
return self.node_to_runtime_value(node.inner)
raise mesonlib.MesonBugException('Unhandled node type')
def assignment(self, node: AssignmentNode) -> None:
assert isinstance(node, AssignmentNode)
self.evaluate_statement(node.value)
self.cur_assignments[node.var_name.value].append((self.nesting.copy(), node.value))
self.all_assignment_nodes[node.var_name.value].append(node)
def evaluate_plusassign(self, node: PlusAssignmentNode) -> None:
assert isinstance(node, PlusAssignmentNode)
self.evaluate_statement(node.value)
lhs = self.get_cur_value(node.var_name.value)
newval: T.Union[UnknownValue, ArithmeticNode]
if isinstance(lhs, UnknownValue):
newval = UnknownValue()
else:
newval = mparser.ArithmeticNode(operation='+', left=lhs, operator=_symbol('+'), right=node.value)
self.cur_assignments[node.var_name.value].append((self.nesting.copy(), newval))
self.all_assignment_nodes[node.var_name.value].append(node)
self.dataflow_dag.add_edge(lhs, newval)
self.dataflow_dag.add_edge(node.value, newval)
def func_set_variable(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> None:
assert isinstance(node, FunctionNode)
if bool(node.args.kwargs):
raise InvalidArguments('set_variable accepts no keyword arguments')
if len(node.args.arguments) != 2:
raise InvalidArguments('set_variable requires exactly two positional arguments')
var_name = args[0]
value = node.args.arguments[1]
if isinstance(var_name, UnknownValue):
self.evaluate_statement(value)
self.tainted = True
return
assert isinstance(var_name, str)
equiv = AssignmentNode(var_name=IdNode(Token('', '', 0, 0, 0, (0, 0), var_name)), value=value, operator=_symbol('='))
equiv.ast_id = str(id(equiv))
self.evaluate_statement(equiv)
def func_get_variable(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Any:
assert isinstance(node, FunctionNode)
var_name = args[0]
if isinstance(var_name, UnknownValue):
val: T.Union[UnknownValue, BaseNode] = UnknownValue()
else:
assert isinstance(var_name, str)
val = self.get_cur_value(var_name)
self.dataflow_dag.add_edge(val, node)
return val
def func_unset_variable(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> None:
assert isinstance(node, FunctionNode)
if bool(node.args.kwargs):
raise InvalidArguments('unset_variable accepts no keyword arguments')
if len(node.args.arguments) != 1:
raise InvalidArguments('unset_variable requires exactly one positional arguments')
var_name = args[0]
assert isinstance(var_name, str)
self.cur_assignments[var_name].append((self.nesting.copy(), node))
def nodes_to_pretty_filelist(self, root_path: Path, subdir: str, nodes: T.List[BaseNode]) -> T.List[T.Union[str, UnknownValue]]:
def src_to_abs(src: T.Union[str, IntrospectionFile, UnknownValue]) -> T.Union[str, UnknownValue]:
if isinstance(src, str):
return os.path.normpath(os.path.join(root_path, subdir, src))
elif isinstance(src, IntrospectionFile):
return str(src.to_abs_path(root_path))
elif isinstance(src, UnknownValue):
return src
else:
raise TypeError
rtvals: T.List[T.Any] = flatten([self.node_to_runtime_value(sn) for sn in nodes])
return [src_to_abs(x) for x in rtvals]
def flatten_args(self, args_raw: T.Union[TYPE_nvar, T.Sequence[TYPE_nvar]], include_unknown_args: bool = False) -> T.List[TYPE_var]:
# Make sure we are always dealing with lists
if isinstance(args_raw, list):
args = args_raw
else:
args = [args_raw]
# BaseNode resolves to Any. :/
flattened_args: T.List[T.Union[TYPE_var, T.Any]] = []
# Resolve the contents of args
for i in args:
if isinstance(i, BaseNode):
resolved = self.node_to_runtime_value(i)
if resolved is not None:
if not isinstance(resolved, list):
resolved = [resolved]
flattened_args += resolved
elif isinstance(i, (str, bool, int, float, UnknownValue, IntrospectionFile)) or include_unknown_args:
flattened_args += [i]
else:
raise NotImplementedError
return flattened_args
def evaluate_testcase(self, node: TestCaseClauseNode) -> Disabler | None:
return Disabler(subproject=self.subproject)
def evaluate_statement(self, cur: mparser.BaseNode) -> T.Optional[InterpreterObject]:
if hasattr(cur, 'args'):
for arg in cur.args.arguments:
self.dataflow_dag.add_edge(arg, cur)
for k, v in cur.args.kwargs.items():
self.dataflow_dag.add_edge(v, cur)
for attr in ['source_object', 'left', 'right', 'items', 'iobject', 'index', 'condition']:
if hasattr(cur, attr):
assert isinstance(getattr(cur, attr), mparser.BaseNode)
self.dataflow_dag.add_edge(getattr(cur, attr), cur)
if isinstance(cur, mparser.IdNode):
self.dataflow_dag.add_edge(self.get_cur_value(cur.value), cur)
return None
else:
return super().evaluate_statement(cur)
def function_call(self, node: mparser.FunctionNode) -> T.Any:
ret = super().function_call(node)
if ret is not None:
self.funcvals[node] = ret
return ret
@@ -0,0 +1,373 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2018 The Meson development team
# Copyright © 2024-2025 Intel Corporation
# This class contains the basic functionality needed to run any interpreter
# or an interpreter-based tool
from __future__ import annotations
import os
import typing as T
from .. import compilers, environment, mesonlib, options
from ..build import Executable, Jar, SharedLibrary, SharedModule, StaticLibrary
from ..compilers import detect_compiler_for
from ..interpreterbase import InvalidArguments, SubProject, UnknownValue
from ..mesonlib import MachineChoice
from ..options import OptionKey
from ..mparser import BaseNode, ArrayNode, ElementaryNode, IdNode, FunctionNode, StringNode
from .interpreter import AstInterpreter, IntrospectionBuildTarget, IntrospectionDependency
if T.TYPE_CHECKING:
from ..build import BuildTarget, BuildTargetKeywordArguments
from ..compilers.compilers import Language
from ..interpreterbase import TYPE_var
from .visitor import AstVisitor
# TODO: it would be nice to not have to duplicate this
BUILD_TARGET_FUNCTIONS = [
'executable', 'jar', 'library', 'shared_library', 'shared_module',
'static_library', 'both_libraries'
]
class IntrospectionHelper:
# mimic an argparse namespace
def __init__(self, cross_file: T.Optional[str]):
self.cross_file = [cross_file] if cross_file is not None else []
self.native_file: T.List[str] = []
self.cmd_line_options: T.Dict[OptionKey, str] = {}
self.builtin_keys: T.Set[OptionKey] = set()
self.d_keys: T.Set[OptionKey] = set()
self.projectoptions: T.List[str] = []
def __eq__(self, other: object) -> bool:
return NotImplemented
class IntrospectionInterpreter(AstInterpreter):
# If you run `meson setup ...` the `Interpreter`-class walks over the AST.
# If you run `meson rewrite ...` and `meson introspect meson.build ...`,
# the `AstInterpreter`-class walks over the AST.
# Works without a build directory.
# Most of the code is stolen from interpreter.Interpreter .
def __init__(self,
source_root: str,
subdir: str,
backend: str,
visitors: T.Optional[T.List[AstVisitor]] = None,
cross_file: T.Optional[str] = None,
subproject: SubProject = SubProject(''),
subproject_dir: str = 'subprojects',
env: T.Optional[environment.Environment] = None):
options = IntrospectionHelper(cross_file)
env_ = env or environment.Environment(source_root, None, options)
super().__init__(source_root, subdir, subproject, subproject_dir, env_, visitors=visitors)
self.cross_file = cross_file
self.backend = backend
self.project_data: T.Dict[str, T.Any] = {}
self.targets: T.List[IntrospectionBuildTarget] = []
self.dependencies: T.List[IntrospectionDependency] = []
self.project_node: FunctionNode = None
self.funcs.update({
'add_languages': self.func_add_languages,
'dependency': self.func_dependency,
'executable': self.func_executable,
'jar': self.func_jar,
'library': self.func_library,
'project': self.func_project,
'shared_library': self.func_shared_lib,
'shared_module': self.func_shared_module,
'static_library': self.func_static_lib,
'both_libraries': self.func_both_lib,
})
def func_project(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> None:
if self.project_node:
raise InvalidArguments('Second call to project()')
assert isinstance(node, FunctionNode)
self.project_node = node
if len(args) < 1:
raise InvalidArguments('Not enough arguments to project(). Needs at least the project name.')
def _str_list(node: T.Any) -> T.Optional[T.List[str]]:
if isinstance(node, ArrayNode):
r = []
for v in node.args.arguments:
if not isinstance(v, StringNode):
return None
r.append(v.value)
return r
if isinstance(node, StringNode):
return [node.value]
return None
proj_name = args[0]
proj_vers = kwargs.get('version', 'undefined')
if isinstance(proj_vers, ElementaryNode):
proj_vers = proj_vers.value
if not isinstance(proj_vers, str):
proj_vers = 'undefined'
proj_langs = self.flatten_args(args[1:])
# Match the value returned by ``meson.project_license()`` when
# no ``license`` argument is specified in the ``project()`` call.
proj_license = _str_list(kwargs.get('license', None)) or ['unknown']
proj_license_files = _str_list(kwargs.get('license_files', None)) or []
self.project_data = {'descriptive_name': proj_name, 'version': proj_vers, 'license': proj_license, 'license_files': proj_license_files}
self._load_option_file()
if not self.is_subproject() and 'subproject_dir' in kwargs:
spdirname = kwargs['subproject_dir']
if isinstance(spdirname, StringNode):
assert isinstance(spdirname.value, str)
self.subproject_dir = spdirname.value
if not self.is_subproject():
self.project_data['subprojects'] = []
subprojects_dir = os.path.join(self.source_root, self.subproject_dir)
if os.path.isdir(subprojects_dir):
for i in os.listdir(subprojects_dir):
if os.path.isdir(os.path.join(subprojects_dir, i)):
self.do_subproject(SubProject(i))
self.environment.init_backend_options(self.backend)
self._add_languages(proj_langs, True, MachineChoice.HOST)
self._add_languages(proj_langs, True, MachineChoice.BUILD)
def do_subproject(self, dirname: SubProject) -> None:
subdir = os.path.join(self.environment.source_dir, self.subproject_dir, dirname)
try:
subi = IntrospectionInterpreter(self.source_root, subdir, self.backend, cross_file=self.cross_file, subproject=dirname, subproject_dir=self.subproject_dir, env=self.environment, visitors=self.visitors)
subi.analyze()
subi.project_data['name'] = dirname
self.project_data['subprojects'] += [subi.project_data]
except (mesonlib.MesonException, RuntimeError):
pass
def func_add_languages(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> UnknownValue:
kwargs = self.flatten_kwargs(kwargs)
required = kwargs.get('required', True)
assert isinstance(required, (bool, options.UserFeatureOption, UnknownValue)), 'for mypy'
if isinstance(required, options.UserFeatureOption):
required = required.is_enabled()
if 'native' in kwargs:
native = kwargs.get('native', False)
self._add_languages(args, required, MachineChoice.BUILD if native else MachineChoice.HOST)
else:
for for_machine in [MachineChoice.BUILD, MachineChoice.HOST]:
self._add_languages(args, required, for_machine)
return UnknownValue()
def _add_languages(self, raw_langs: T.List[TYPE_var], required: T.Union[bool, UnknownValue], for_machine: MachineChoice) -> None:
langs: T.List[Language] = []
for l in self.flatten_args(raw_langs):
# we need to call .lower() here because `project('foo', 'CpP')` is valid.
if isinstance(l, str):
langs.append(T.cast('Language', l.lower()))
elif isinstance(l, StringNode):
langs.append(T.cast('Language', l.value.lower()))
for lang in sorted(langs, key=compilers.sort_clink):
if lang not in self.coredata.compilers[for_machine]:
try:
comp = detect_compiler_for(self.environment, lang, for_machine, True, self.subproject)
except mesonlib.MesonException:
# All code paths are evaluated regardless of conditionals,
# so always ignore compiler detection failures.
continue
if comp:
self.coredata.process_compiler_options(lang, comp, self.subproject)
def func_dependency(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Optional[IntrospectionDependency]:
assert isinstance(node, FunctionNode)
args = self.flatten_args(args)
kwargs = self.flatten_kwargs(kwargs)
if not args:
return None
name = args[0]
assert isinstance(name, (str, UnknownValue))
has_fallback = 'fallback' in kwargs
required = kwargs.get('required', True)
version = kwargs.get('version', [])
if not isinstance(version, list):
version = [version]
if any(isinstance(el, UnknownValue) for el in version):
version = UnknownValue()
else:
assert all(isinstance(el, str) for el in version)
version = T.cast(T.List[str], version)
assert isinstance(required, (bool, UnknownValue))
newdep = IntrospectionDependency(
name=name,
required=required,
version=version,
has_fallback=has_fallback,
conditional=node.condition_level > 0,
node=node)
self.dependencies += [newdep]
return newdep
def build_target(self, node: BaseNode, args: T.List[TYPE_var], kwargs_raw: T.Dict[str, TYPE_var], targetclass: T.Type[BuildTarget]) -> T.Union[IntrospectionBuildTarget, UnknownValue]:
assert isinstance(node, FunctionNode)
args = self.flatten_args(args)
if not args or not isinstance(args[0], str):
return UnknownValue()
name = args[0]
srcqueue: T.List[BaseNode] = [node]
extra_queue = []
# Process the sources BEFORE flattening the kwargs, to preserve the original nodes
if 'sources' in kwargs_raw:
srcqueue += mesonlib.listify(kwargs_raw['sources'])
if 'extra_files' in kwargs_raw:
extra_queue += mesonlib.listify(kwargs_raw['extra_files'])
kwargs = self.flatten_kwargs(kwargs_raw, True)
oldlen = len(node.args.arguments)
source_nodes = node.args.arguments[1:]
for k, v in node.args.kwargs.items():
assert isinstance(k, IdNode)
if k.value == 'sources':
source_nodes.append(v)
assert oldlen == len(node.args.arguments)
extraf_nodes = None
for k, v in node.args.kwargs.items():
assert isinstance(k, IdNode)
if k.value == 'extra_files':
assert extraf_nodes is None
extraf_nodes = v
# Make sure nothing can crash when creating the build class
_kwargs_reduced = {k: v for k, v in kwargs.items() if k in targetclass.known_kwargs and k in {'install', 'build_by_default', 'build_always', 'name_prefix'}}
_kwargs_reduced = {k: v.value if isinstance(v, ElementaryNode) else v for k, v in _kwargs_reduced.items()}
_kwargs_reduced = {k: v for k, v in _kwargs_reduced.items() if not isinstance(v, (BaseNode, UnknownValue))}
kwargs_reduced = T.cast('BuildTargetKeywordArguments', _kwargs_reduced)
for_machine = MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST
objects: T.List[T.Any] = []
empty_sources: T.List[T.Any] = []
# Passing the unresolved sources list causes errors
kwargs_reduced['_allow_no_sources'] = True
target = targetclass(name, self.subdir, self.subproject, for_machine, empty_sources, None, objects,
self.environment, self.coredata.compilers[for_machine], kwargs_reduced)
target.process_compilers_late()
build_by_default: T.Union[UnknownValue, bool] = target.build_by_default
if 'build_by_default' in kwargs and isinstance(kwargs['build_by_default'], UnknownValue):
build_by_default = kwargs['build_by_default']
install: T.Union[UnknownValue, bool] = target.should_install()
if 'install' in kwargs and isinstance(kwargs['install'], UnknownValue):
install = kwargs['install']
new_target = IntrospectionBuildTarget(
name=target.get_basename(),
machine=target.for_machine.get_lower_case_name(),
id=target.get_id(),
typename=target.get_typename(),
defined_in=os.path.normpath(os.path.join(self.source_root, self.subdir, environment.build_filename)),
subdir=self.subdir,
build_by_default=build_by_default,
installed=install,
outputs=target.get_outputs(),
source_nodes=source_nodes,
extra_files=extraf_nodes,
kwargs=kwargs,
node=node)
self.targets += [new_target]
return new_target
def build_library(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]:
default_library = self.coredata.optstore.get_value_for(OptionKey('default_library', subproject=self.subproject))
if default_library == 'shared':
return self.build_target(node, args, kwargs, SharedLibrary)
elif default_library == 'static':
return self.build_target(node, args, kwargs, StaticLibrary)
elif default_library == 'both':
return self.build_target(node, args, kwargs, SharedLibrary)
return None
def func_executable(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]:
return self.build_target(node, args, kwargs, Executable)
def func_static_lib(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]:
return self.build_target(node, args, kwargs, StaticLibrary)
def func_shared_lib(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]:
return self.build_target(node, args, kwargs, SharedLibrary)
def func_both_lib(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]:
return self.build_target(node, args, kwargs, SharedLibrary)
def func_shared_module(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]:
return self.build_target(node, args, kwargs, SharedModule)
def func_library(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]:
return self.build_library(node, args, kwargs)
def func_jar(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]:
return self.build_target(node, args, kwargs, Jar)
def func_build_target(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]:
if 'target_type' not in kwargs:
return None
target_type = kwargs.pop('target_type')
if isinstance(target_type, ElementaryNode):
target_type = target_type.value
if target_type == 'executable':
return self.build_target(node, args, kwargs, Executable)
elif target_type == 'shared_library':
return self.build_target(node, args, kwargs, SharedLibrary)
elif target_type == 'static_library':
return self.build_target(node, args, kwargs, StaticLibrary)
elif target_type == 'both_libraries':
return self.build_target(node, args, kwargs, SharedLibrary)
elif target_type == 'library':
return self.build_library(node, args, kwargs)
elif target_type == 'jar':
return self.build_target(node, args, kwargs, Jar)
return None
def is_subproject(self) -> bool:
return self.subproject != ''
def analyze(self) -> None:
self.load_root_meson_file()
self.sanity_check_ast()
self.parse_project()
self.run()
def extract_subproject_dir(self) -> T.Optional[str]:
'''Fast path to extract subproject_dir kwarg.
This is faster than self.parse_project() which also initialize options
and also calls parse_project() on every subproject.
'''
if not self.ast.lines:
return None
project = self.ast.lines[0]
# first line is always project()
if not isinstance(project, FunctionNode):
return None
for kw, val in project.args.kwargs.items():
assert isinstance(kw, IdNode), 'for mypy'
if kw.value == 'subproject_dir':
# mypy does not understand "and isinstance"
if isinstance(val, StringNode):
return val.value
return None
def flatten_kwargs(self, kwargs: T.Dict[str, TYPE_var], include_unknown_args: bool = False) -> T.Dict[str, TYPE_var]:
flattened_kwargs = {}
for key, val in kwargs.items():
if isinstance(val, BaseNode):
resolved = self.node_to_runtime_value(val)
if resolved is not None:
flattened_kwargs[key] = resolved
elif isinstance(val, (str, bool, int, float)) or include_unknown_args:
flattened_kwargs[key] = val
return flattened_kwargs
@@ -0,0 +1,118 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2019 The Meson development team
# This class contains the basic functionality needed to run any interpreter
# or an interpreter-based tool
from __future__ import annotations
from .visitor import AstVisitor, FullAstVisitor
import typing as T
if T.TYPE_CHECKING:
from .. import mparser
class AstIndentationGenerator(AstVisitor):
def __init__(self) -> None:
self.level = 0
def visit_default_func(self, node: mparser.BaseNode) -> None:
# Store the current level in the node
node.level = self.level
def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
self.visit_default_func(node)
self.level += 1
node.args.accept(self)
self.level -= 1
def visit_DictNode(self, node: mparser.DictNode) -> None:
self.visit_default_func(node)
self.level += 1
node.args.accept(self)
self.level -= 1
def visit_MethodNode(self, node: mparser.MethodNode) -> None:
self.visit_default_func(node)
node.source_object.accept(self)
self.level += 1
node.args.accept(self)
self.level -= 1
def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
self.visit_default_func(node)
self.level += 1
node.args.accept(self)
self.level -= 1
def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
self.visit_default_func(node)
self.level += 1
node.items.accept(self)
node.block.accept(self)
self.level -= 1
def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
self.visit_default_func(node)
for i in node.ifs:
i.accept(self)
if node.elseblock:
self.level += 1
node.elseblock.accept(self)
self.level -= 1
def visit_IfNode(self, node: mparser.IfNode) -> None:
self.visit_default_func(node)
self.level += 1
node.condition.accept(self)
node.block.accept(self)
self.level -= 1
class AstIDGenerator(AstVisitor):
def __init__(self) -> None:
self.counter: T.Dict[str, int] = {}
def visit_default_func(self, node: mparser.BaseNode) -> None:
name = type(node).__name__
if name not in self.counter:
self.counter[name] = 0
node.ast_id = name + '#' + str(self.counter[name])
self.counter[name] += 1
class AstConditionLevel(FullAstVisitor):
def __init__(self) -> None:
self.condition_level = 0
def enter_node(self, node: mparser.BaseNode) -> None:
node.condition_level = self.condition_level
def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
self.enter_node(node)
node.foreach_.accept(self)
for varname in node.varnames:
varname.accept(self)
for comma in node.commas:
comma.accept(self)
node.colon.accept(self)
node.items.accept(self)
self.condition_level += 1
node.block.accept(self)
self.condition_level -= 1
node.endforeach.accept(self)
self.exit_node(node)
def visit_IfNode(self, node: mparser.IfNode) -> None:
self.enter_node(node)
node.if_.accept(self)
node.condition.accept(self)
self.condition_level += 1
node.block.accept(self)
self.condition_level -= 1
self.exit_node(node)
def visit_ElseNode(self, node: mparser.ElseNode) -> None:
self.enter_node(node)
node.else_.accept(self)
self.condition_level += 1
node.block.accept(self)
self.condition_level -= 1
self.exit_node(node)
@@ -0,0 +1,470 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2019 The Meson development team
# This class contains the basic functionality needed to run any interpreter
# or an interpreter-based tool
from __future__ import annotations
from .. import mparser
from .visitor import AstVisitor, FullAstVisitor
from ..mesonlib import MesonBugException
import re
import typing as T
# Also known as "order of operations" or "binding power".
# This is the counterpart to Parser.e1, Parser.e2, Parser.e3, Parser.e4, Parser.e5, Parser.e6, Parser.e7, Parser.e8, Parser.e9, Parser.e10
def precedence_level(node: mparser.BaseNode) -> int:
if isinstance(node, (mparser.PlusAssignmentNode, mparser.AssignmentNode, mparser.TernaryNode)):
return 1
elif isinstance(node, mparser.OrNode):
return 2
elif isinstance(node, mparser.AndNode):
return 3
elif isinstance(node, mparser.ComparisonNode):
return 4
elif isinstance(node, mparser.ArithmeticNode):
if node.operation in {'+', '-'}:
return 5
elif node.operation in {'%', '*', '/'}:
return 6
elif isinstance(node, (mparser.NotNode, mparser.UMinusNode)):
return 7
elif isinstance(node, (mparser.FunctionNode, mparser.IndexNode, mparser.MethodNode)):
return 8
elif isinstance(node, (mparser.ArrayNode, mparser.DictNode)):
return 9
elif isinstance(node, (mparser.BooleanNode, mparser.IdNode, mparser.NumberNode, mparser.StringNode, mparser.EmptyNode)):
return 10
elif isinstance(node, mparser.ParenthesizedNode):
# Parenthesize have the highest binding power, but since the AstPrinter
# ignores ParanthesizedNode, the binding power of the inner node is
# relevant.
return precedence_level(node.inner)
raise MesonBugException('Unhandled node type')
class AstPrinter(AstVisitor):
escape_trans: T.Dict[int, str] = str.maketrans({'\\': '\\\\', "'": "\'"})
def __init__(self, indent: int = 2, arg_newline_cutoff: int = 5, update_ast_line_nos: bool = False):
self.result = ''
self.indent = indent
self.arg_newline_cutoff = arg_newline_cutoff
self.ci = ''
self.is_newline = True
self.last_level = 0
self.curr_line = 1 if update_ast_line_nos else None
def post_process(self) -> None:
self.result = re.sub(r'\s+\n', '\n', self.result)
def append(self, data: str, node: mparser.BaseNode) -> None:
self.last_level = node.level
if self.is_newline:
self.result += ' ' * (node.level * self.indent)
self.result += data
self.is_newline = False
def append_padded(self, data: str, node: mparser.BaseNode) -> None:
if self.result and self.result[-1] not in [' ', '\n']:
data = ' ' + data
self.append(data + ' ', node)
def newline(self) -> None:
self.result += '\n'
self.is_newline = True
if self.curr_line is not None:
self.curr_line += 1
def visit_BooleanNode(self, node: mparser.BooleanNode) -> None:
self.append('true' if node.value else 'false', node)
node.lineno = self.curr_line or node.lineno
def visit_IdNode(self, node: mparser.IdNode) -> None:
assert isinstance(node.value, str)
self.append(node.value, node)
node.lineno = self.curr_line or node.lineno
def visit_NumberNode(self, node: mparser.NumberNode) -> None:
self.append(str(node.value), node)
node.lineno = self.curr_line or node.lineno
def escape(self, val: str) -> str:
return val.translate(self.escape_trans)
def visit_StringNode(self, node: mparser.StringNode) -> None:
assert isinstance(node.value, str)
if node.is_fstring:
self.append('f', node)
if node.is_multiline:
self.append("'''" + node.value + "'''", node)
else:
self.append("'" + self.escape(node.value) + "'", node)
node.lineno = self.curr_line or node.lineno
def visit_ContinueNode(self, node: mparser.ContinueNode) -> None:
self.append('continue', node)
node.lineno = self.curr_line or node.lineno
def visit_BreakNode(self, node: mparser.BreakNode) -> None:
self.append('break', node)
node.lineno = self.curr_line or node.lineno
def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
node.lineno = self.curr_line or node.lineno
self.append('[', node)
node.args.accept(self)
self.append(']', node)
def visit_DictNode(self, node: mparser.DictNode) -> None:
node.lineno = self.curr_line or node.lineno
self.append('{', node)
node.args.accept(self)
self.append('}', node)
def visit_OrNode(self, node: mparser.OrNode) -> None:
node.left.accept(self)
self.append_padded('or', node)
node.lineno = self.curr_line or node.lineno
node.right.accept(self)
def visit_AndNode(self, node: mparser.AndNode) -> None:
node.left.accept(self)
self.append_padded('and', node)
node.lineno = self.curr_line or node.lineno
node.right.accept(self)
def visit_ComparisonNode(self, node: mparser.ComparisonNode) -> None:
node.left.accept(self)
self.append_padded(node.ctype, node)
node.lineno = self.curr_line or node.lineno
node.right.accept(self)
def maybe_parentheses(self, outer: mparser.BaseNode, inner: mparser.BaseNode, parens: bool) -> None:
if parens:
self.append('(', inner)
inner.accept(self)
if parens:
self.append(')', inner)
def visit_ArithmeticNode(self, node: mparser.ArithmeticNode) -> None:
prec = precedence_level(node)
prec_left = precedence_level(node.left)
prec_right = precedence_level(node.right)
self.maybe_parentheses(node, node.left, prec > prec_left)
self.append_padded(node.operator.value, node)
node.lineno = self.curr_line or node.lineno
self.maybe_parentheses(node, node.right, prec > prec_right or (prec == prec_right and node.operation in {'sub', 'div', 'mod'}))
def visit_NotNode(self, node: mparser.NotNode) -> None:
node.lineno = self.curr_line or node.lineno
self.append_padded('not', node)
node.value.accept(self)
def visit_CodeBlockNode(self, node: mparser.CodeBlockNode) -> None:
node.lineno = self.curr_line or node.lineno
for i in node.lines:
i.accept(self)
self.newline()
def visit_IndexNode(self, node: mparser.IndexNode) -> None:
node.iobject.accept(self)
node.lineno = self.curr_line or node.lineno
self.append('[', node)
node.index.accept(self)
self.append(']', node)
def visit_MethodNode(self, node: mparser.MethodNode) -> None:
node.lineno = self.curr_line or node.lineno
node.source_object.accept(self)
self.append('.' + node.name.value + '(', node)
node.args.accept(self)
self.append(')', node)
def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
node.lineno = self.curr_line or node.lineno
self.append(node.func_name.value + '(', node)
node.args.accept(self)
self.append(')', node)
def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None:
node.lineno = self.curr_line or node.lineno
self.append(node.var_name.value + ' = ', node)
node.value.accept(self)
def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None:
node.lineno = self.curr_line or node.lineno
self.append(node.var_name.value + ' += ', node)
node.value.accept(self)
def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
node.lineno = self.curr_line or node.lineno
self.append_padded('foreach', node)
self.append_padded(', '.join(varname.value for varname in node.varnames), node)
self.append_padded(':', node)
node.items.accept(self)
self.newline()
node.block.accept(self)
self.append('endforeach', node)
def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
node.lineno = self.curr_line or node.lineno
prefix = ''
for i in node.ifs:
self.append_padded(prefix + 'if', node)
prefix = 'el'
i.accept(self)
if not isinstance(node.elseblock, mparser.EmptyNode):
self.append('else', node)
self.newline()
node.elseblock.accept(self)
self.append('endif', node)
def visit_UMinusNode(self, node: mparser.UMinusNode) -> None:
node.lineno = self.curr_line or node.lineno
self.append_padded('-', node)
node.value.accept(self)
def visit_IfNode(self, node: mparser.IfNode) -> None:
node.lineno = self.curr_line or node.lineno
node.condition.accept(self)
self.newline()
node.block.accept(self)
def visit_TernaryNode(self, node: mparser.TernaryNode) -> None:
node.lineno = self.curr_line or node.lineno
node.condition.accept(self)
self.append_padded('?', node)
node.trueblock.accept(self)
self.append_padded(':', node)
node.falseblock.accept(self)
def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:
node.lineno = self.curr_line or node.lineno
break_args = (len(node.arguments) + len(node.kwargs)) > self.arg_newline_cutoff
for i in node.arguments + list(node.kwargs.values()):
if not isinstance(i, (mparser.ElementaryNode, mparser.IndexNode)):
break_args = True
if break_args:
self.newline()
for i in node.arguments:
i.accept(self)
self.append(', ', node)
if break_args:
self.newline()
for key, val in node.kwargs.items():
key.accept(self)
self.append_padded(':', node)
val.accept(self)
self.append(', ', node)
if break_args:
self.newline()
if break_args:
self.result = re.sub(r', \n$', '\n', self.result)
else:
self.result = re.sub(r', $', '', self.result)
class RawPrinter(FullAstVisitor):
def __init__(self) -> None:
self.result = ''
def visit_default_func(self, node: mparser.BaseNode) -> None:
self.enter_node(node)
assert hasattr(node, 'value')
self.result += node.value
self.exit_node(node)
def visit_EmptyNode(self, node: mparser.EmptyNode) -> None:
self.enter_node(node)
self.exit_node(node)
def visit_BooleanNode(self, node: mparser.BooleanNode) -> None:
self.enter_node(node)
self.result += 'true' if node.value else 'false'
self.exit_node(node)
def visit_NumberNode(self, node: mparser.NumberNode) -> None:
self.enter_node(node)
self.result += node.raw_value
self.exit_node(node)
def visit_StringNode(self, node: mparser.StringNode) -> None:
self.enter_node(node)
if node.is_fstring:
self.result += 'f'
if node.is_multiline:
self.result += f"'''{node.value}'''"
else:
self.result += f"'{node.raw_value}'"
self.exit_node(node)
def visit_ContinueNode(self, node: mparser.ContinueNode) -> None:
self.enter_node(node)
self.result += 'continue'
self.exit_node(node)
def visit_BreakNode(self, node: mparser.BreakNode) -> None:
self.enter_node(node)
self.result += 'break'
self.exit_node(node)
class AstJSONPrinter(AstVisitor):
def __init__(self) -> None:
self.result: T.Dict[str, T.Any] = {}
self.current = self.result
def _accept(self, key: str, node: mparser.BaseNode) -> None:
old = self.current
data: T.Dict[str, T.Any] = {}
self.current = data
node.accept(self)
self.current = old
self.current[key] = data
def _accept_list(self, key: str, nodes: T.Sequence[mparser.BaseNode]) -> None:
old = self.current
datalist: T.List[T.Dict[str, T.Any]] = []
for i in nodes:
self.current = {}
i.accept(self)
datalist += [self.current]
self.current = old
self.current[key] = datalist
def _raw_accept(self, node: mparser.BaseNode, data: T.Dict[str, T.Any]) -> None:
old = self.current
self.current = data
node.accept(self)
self.current = old
def setbase(self, node: mparser.BaseNode) -> None:
self.current['node'] = type(node).__name__
self.current['lineno'] = node.lineno
self.current['colno'] = node.colno
self.current['end_lineno'] = node.end_lineno
self.current['end_colno'] = node.end_colno
def visit_default_func(self, node: mparser.BaseNode) -> None:
self.setbase(node)
def gen_ElementaryNode(self, node: mparser.ElementaryNode) -> None:
self.current['value'] = node.value
self.setbase(node)
def visit_BooleanNode(self, node: mparser.BooleanNode) -> None:
self.gen_ElementaryNode(node)
def visit_IdNode(self, node: mparser.IdNode) -> None:
self.gen_ElementaryNode(node)
def visit_NumberNode(self, node: mparser.NumberNode) -> None:
self.gen_ElementaryNode(node)
def visit_StringNode(self, node: mparser.StringNode) -> None:
self.gen_ElementaryNode(node)
def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
self._accept('args', node.args)
self.setbase(node)
def visit_DictNode(self, node: mparser.DictNode) -> None:
self._accept('args', node.args)
self.setbase(node)
def visit_OrNode(self, node: mparser.OrNode) -> None:
self._accept('left', node.left)
self._accept('right', node.right)
self.setbase(node)
def visit_AndNode(self, node: mparser.AndNode) -> None:
self._accept('left', node.left)
self._accept('right', node.right)
self.setbase(node)
def visit_ComparisonNode(self, node: mparser.ComparisonNode) -> None:
self._accept('left', node.left)
self._accept('right', node.right)
self.current['ctype'] = node.ctype
self.setbase(node)
def visit_ArithmeticNode(self, node: mparser.ArithmeticNode) -> None:
self._accept('left', node.left)
self._accept('right', node.right)
self.current['op'] = node.operator.value
self.setbase(node)
def visit_NotNode(self, node: mparser.NotNode) -> None:
self._accept('right', node.value)
self.setbase(node)
def visit_CodeBlockNode(self, node: mparser.CodeBlockNode) -> None:
self._accept_list('lines', node.lines)
self.setbase(node)
def visit_IndexNode(self, node: mparser.IndexNode) -> None:
self._accept('object', node.iobject)
self._accept('index', node.index)
self.setbase(node)
def visit_MethodNode(self, node: mparser.MethodNode) -> None:
self._accept('object', node.source_object)
self._accept('args', node.args)
self.current['name'] = node.name.value
self.setbase(node)
def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
self._accept('args', node.args)
self.current['name'] = node.func_name.value
self.setbase(node)
def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None:
self._accept('value', node.value)
self.current['var_name'] = node.var_name.value
self.setbase(node)
def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None:
self._accept('value', node.value)
self.current['var_name'] = node.var_name.value
self.setbase(node)
def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
self._accept('items', node.items)
self._accept('block', node.block)
self.current['varnames'] = [varname.value for varname in node.varnames]
self.setbase(node)
def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
self._accept_list('ifs', node.ifs)
self._accept('else', node.elseblock)
self.setbase(node)
def visit_UMinusNode(self, node: mparser.UMinusNode) -> None:
self._accept('right', node.value)
self.setbase(node)
def visit_IfNode(self, node: mparser.IfNode) -> None:
self._accept('condition', node.condition)
self._accept('block', node.block)
self.setbase(node)
def visit_TernaryNode(self, node: mparser.TernaryNode) -> None:
self._accept('condition', node.condition)
self._accept('true', node.trueblock)
self._accept('false', node.falseblock)
self.setbase(node)
def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:
self._accept_list('positional', node.arguments)
kwargs_list: T.List[T.Dict[str, T.Dict[str, T.Any]]] = []
for key, val in node.kwargs.items():
key_res: T.Dict[str, T.Any] = {}
val_res: T.Dict[str, T.Any] = {}
self._raw_accept(key, key_res)
self._raw_accept(val, val_res)
kwargs_list += [{'key': key_res, 'val': val_res}]
self.current['kwargs'] = kwargs_list
self.setbase(node)
@@ -0,0 +1,331 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2019 The Meson development team
# This class contains the basic functionality needed to run any interpreter
# or an interpreter-based tool
from __future__ import annotations
import typing as T
from itertools import zip_longest
if T.TYPE_CHECKING:
from .. import mparser
class AstVisitor:
def __init__(self) -> None:
pass
def visit_default_func(self, node: mparser.BaseNode) -> None:
pass
def visit_BooleanNode(self, node: mparser.BooleanNode) -> None:
self.visit_default_func(node)
def visit_IdNode(self, node: mparser.IdNode) -> None:
self.visit_default_func(node)
def visit_NumberNode(self, node: mparser.NumberNode) -> None:
self.visit_default_func(node)
def visit_StringNode(self, node: mparser.StringNode) -> None:
self.visit_default_func(node)
def visit_ContinueNode(self, node: mparser.ContinueNode) -> None:
self.visit_default_func(node)
def visit_BreakNode(self, node: mparser.BreakNode) -> None:
self.visit_default_func(node)
def visit_SymbolNode(self, node: mparser.SymbolNode) -> None:
self.visit_default_func(node)
def visit_WhitespaceNode(self, node: mparser.WhitespaceNode) -> None:
self.visit_default_func(node)
def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
self.visit_default_func(node)
node.args.accept(self)
def visit_DictNode(self, node: mparser.DictNode) -> None:
self.visit_default_func(node)
node.args.accept(self)
def visit_EmptyNode(self, node: mparser.EmptyNode) -> None:
self.visit_default_func(node)
def visit_OrNode(self, node: mparser.OrNode) -> None:
self.visit_default_func(node)
node.left.accept(self)
node.right.accept(self)
def visit_AndNode(self, node: mparser.AndNode) -> None:
self.visit_default_func(node)
node.left.accept(self)
node.right.accept(self)
def visit_ComparisonNode(self, node: mparser.ComparisonNode) -> None:
self.visit_default_func(node)
node.left.accept(self)
node.right.accept(self)
def visit_ArithmeticNode(self, node: mparser.ArithmeticNode) -> None:
self.visit_default_func(node)
node.left.accept(self)
node.right.accept(self)
def visit_NotNode(self, node: mparser.NotNode) -> None:
self.visit_default_func(node)
node.value.accept(self)
def visit_CodeBlockNode(self, node: mparser.CodeBlockNode) -> None:
self.visit_default_func(node)
for i in node.lines:
i.accept(self)
def visit_IndexNode(self, node: mparser.IndexNode) -> None:
self.visit_default_func(node)
node.iobject.accept(self)
node.index.accept(self)
def visit_MethodNode(self, node: mparser.MethodNode) -> None:
self.visit_default_func(node)
node.source_object.accept(self)
node.name.accept(self)
node.args.accept(self)
def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
self.visit_default_func(node)
node.func_name.accept(self)
node.args.accept(self)
def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None:
self.visit_default_func(node)
node.var_name.accept(self)
node.value.accept(self)
def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None:
self.visit_default_func(node)
node.var_name.accept(self)
node.value.accept(self)
def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
self.visit_default_func(node)
for varname in node.varnames:
varname.accept(self)
node.items.accept(self)
node.block.accept(self)
def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
self.visit_default_func(node)
for i in node.ifs:
i.accept(self)
node.elseblock.accept(self)
def visit_UMinusNode(self, node: mparser.UMinusNode) -> None:
self.visit_default_func(node)
node.value.accept(self)
def visit_IfNode(self, node: mparser.IfNode) -> None:
self.visit_default_func(node)
node.condition.accept(self)
node.block.accept(self)
def visit_ElseNode(self, node: mparser.ElseNode) -> None:
self.visit_default_func(node)
node.block.accept(self)
def visit_TernaryNode(self, node: mparser.TernaryNode) -> None:
self.visit_default_func(node)
node.condition.accept(self)
node.trueblock.accept(self)
node.falseblock.accept(self)
def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:
self.visit_default_func(node)
for i in node.arguments:
i.accept(self)
for key, val in node.kwargs.items():
key.accept(self)
val.accept(self)
def visit_ParenthesizedNode(self, node: mparser.ParenthesizedNode) -> None:
self.visit_default_func(node)
node.inner.accept(self)
class FullAstVisitor(AstVisitor):
"""Visit all nodes, including Symbol and Whitespaces"""
def enter_node(self, node: mparser.BaseNode) -> None:
pass
def exit_node(self, node: mparser.BaseNode) -> None:
if node.whitespaces:
node.whitespaces.accept(self)
def visit_default_func(self, node: mparser.BaseNode) -> None:
self.enter_node(node)
self.exit_node(node)
def visit_UnaryOperatorNode(self, node: mparser.UnaryOperatorNode) -> None:
self.enter_node(node)
node.operator.accept(self)
node.value.accept(self)
self.exit_node(node)
def visit_BinaryOperatorNode(self, node: mparser.BinaryOperatorNode) -> None:
self.enter_node(node)
node.left.accept(self)
node.operator.accept(self)
node.right.accept(self)
self.exit_node(node)
def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
self.enter_node(node)
node.lbracket.accept(self)
node.args.accept(self)
node.rbracket.accept(self)
self.exit_node(node)
def visit_DictNode(self, node: mparser.DictNode) -> None:
self.enter_node(node)
node.lcurl.accept(self)
node.args.accept(self)
node.rcurl.accept(self)
self.exit_node(node)
def visit_OrNode(self, node: mparser.OrNode) -> None:
self.visit_BinaryOperatorNode(node)
def visit_AndNode(self, node: mparser.AndNode) -> None:
self.visit_BinaryOperatorNode(node)
def visit_ComparisonNode(self, node: mparser.ComparisonNode) -> None:
self.visit_BinaryOperatorNode(node)
def visit_ArithmeticNode(self, node: mparser.ArithmeticNode) -> None:
self.visit_BinaryOperatorNode(node)
def visit_NotNode(self, node: mparser.NotNode) -> None:
self.visit_UnaryOperatorNode(node)
def visit_CodeBlockNode(self, node: mparser.CodeBlockNode) -> None:
self.enter_node(node)
if node.pre_whitespaces:
node.pre_whitespaces.accept(self)
for i in node.lines:
i.accept(self)
self.exit_node(node)
def visit_IndexNode(self, node: mparser.IndexNode) -> None:
self.enter_node(node)
node.iobject.accept(self)
node.lbracket.accept(self)
node.index.accept(self)
node.rbracket.accept(self)
self.exit_node(node)
def visit_MethodNode(self, node: mparser.MethodNode) -> None:
self.enter_node(node)
node.source_object.accept(self)
node.dot.accept(self)
node.name.accept(self)
node.lpar.accept(self)
node.args.accept(self)
node.rpar.accept(self)
self.exit_node(node)
def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
self.enter_node(node)
node.func_name.accept(self)
node.lpar.accept(self)
node.args.accept(self)
node.rpar.accept(self)
self.exit_node(node)
def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None:
self.enter_node(node)
node.var_name.accept(self)
node.operator.accept(self)
node.value.accept(self)
self.exit_node(node)
def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None:
self.visit_AssignmentNode(node)
def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
self.enter_node(node)
node.foreach_.accept(self)
for varname, comma in zip_longest(node.varnames, node.commas):
varname.accept(self)
if comma is not None:
comma.accept(self)
node.colon.accept(self)
node.items.accept(self)
node.block.accept(self)
node.endforeach.accept(self)
self.exit_node(node)
def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
self.enter_node(node)
for i in node.ifs:
i.accept(self)
node.elseblock.accept(self)
node.endif.accept(self)
self.exit_node(node)
def visit_UMinusNode(self, node: mparser.UMinusNode) -> None:
self.visit_UnaryOperatorNode(node)
def visit_IfNode(self, node: mparser.IfNode) -> None:
self.enter_node(node)
node.if_.accept(self)
node.condition.accept(self)
node.block.accept(self)
self.exit_node(node)
def visit_ElseNode(self, node: mparser.ElseNode) -> None:
self.enter_node(node)
node.else_.accept(self)
node.block.accept(self)
self.exit_node(node)
def visit_TernaryNode(self, node: mparser.TernaryNode) -> None:
self.enter_node(node)
node.condition.accept(self)
node.questionmark.accept(self)
node.trueblock.accept(self)
node.colon.accept(self)
node.falseblock.accept(self)
self.exit_node(node)
def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:
self.enter_node(node)
commas_iter = iter(node.commas)
for arg in node.arguments:
arg.accept(self)
try:
comma = next(commas_iter)
comma.accept(self)
except StopIteration:
pass
assert len(node.colons) == len(node.kwargs)
for (key, val), colon in zip(node.kwargs.items(), node.colons):
key.accept(self)
colon.accept(self)
val.accept(self)
try:
comma = next(commas_iter)
comma.accept(self)
except StopIteration:
pass
self.exit_node(node)
def visit_ParenthesizedNode(self, node: mparser.ParenthesizedNode) -> None:
self.enter_node(node)
node.lpar.accept(self)
node.inner.accept(self)
node.rpar.accept(self)
self.exit_node(node)
Whitespace-only changes.
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,27 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2022 The Meson development team
from __future__ import annotations
import typing as T
from .backends import Backend
from .. import mlog
from ..mesonlib import MesonBugException
class NoneBackend(Backend):
name = 'none'
def generate(self, capture: bool = False, vslite_ctx: T.Optional[T.Dict] = None) -> None:
# Check for (currently) unexpected capture arg use cases -
if capture:
raise MesonBugException('We do not expect the none backend to generate with \'capture = True\'')
if vslite_ctx:
raise MesonBugException('We do not expect the none backend to be given a valid \'vslite_ctx\'')
if self.build.get_targets():
raise MesonBugException('None backend cannot generate target rules, but should have failed earlier.')
mlog.log('Generating simple install-only backend')
self.serialize_tests()
self.create_install_data_files()
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,36 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2014-2016 The Meson development team
from __future__ import annotations
import typing as T
from .vs2010backend import Vs2010Backend
from ..mesonlib import MesonException
if T.TYPE_CHECKING:
from ..build import Build
class Vs2012Backend(Vs2010Backend):
name = 'vs2012'
def __init__(self, build: T.Optional[Build]):
super().__init__(build)
self.vs_version = '2012'
self.sln_file_version = '12.00'
self.sln_version_comment = '2012'
def detect_toolset(self) -> None:
if self.environment is not None:
# TODO: we assume host == build
comps = self.environment.coredata.compilers.host
if comps and all(c.id == 'intel-cl' for c in comps.values()):
c = list(comps.values())[0]
if c.version.startswith('19'):
self.platform_toolset = 'Intel C++ Compiler 19.0'
else:
# We don't have support for versions older than 2019 right now.
raise MesonException('There is currently no support for ICL before 19, patches welcome.')
if self.platform_toolset is None:
self.platform_toolset = 'v110'
@@ -0,0 +1,35 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2014-2016 The Meson development team
from __future__ import annotations
from .vs2010backend import Vs2010Backend
from ..mesonlib import MesonException
import typing as T
if T.TYPE_CHECKING:
from ..build import Build
class Vs2013Backend(Vs2010Backend):
name = 'vs2013'
def __init__(self, build: T.Optional[Build]):
super().__init__(build)
self.vs_version = '2013'
self.sln_file_version = '12.00'
self.sln_version_comment = '2013'
def detect_toolset(self) -> None:
if self.environment is not None:
# TODO: we assume host == build
comps = self.environment.coredata.compilers.host
if comps and all(c.id == 'intel-cl' for c in comps.values()):
c = list(comps.values())[0]
if c.version.startswith('19'):
self.platform_toolset = 'Intel C++ Compiler 19.0'
else:
# We don't have support for versions older than 2019 right now.
raise MesonException('There is currently no support for ICL before 19, patches welcome.')
if self.platform_toolset is None:
self.platform_toolset = 'v120'
@@ -0,0 +1,35 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2014-2016 The Meson development team
from __future__ import annotations
import typing as T
from .vs2010backend import Vs2010Backend
from ..mesonlib import MesonException
if T.TYPE_CHECKING:
from ..build import Build
class Vs2015Backend(Vs2010Backend):
name = 'vs2015'
def __init__(self, build: T.Optional[Build]):
self.vs_version = '2015'
self.sln_file_version = '12.00'
self.sln_version_comment = '14'
def detect_toolset(self) -> None:
if self.environment is not None:
# TODO: we assume host == build
comps = self.environment.coredata.compilers.host
if comps and all(c.id == 'intel-cl' for c in comps.values()):
c = list(comps.values())[0]
if c.version.startswith('19'):
self.platform_toolset = 'Intel C++ Compiler 19.0'
else:
# We don't have support for versions older than 2019 right now.
raise MesonException('There is currently no support for ICL before 19, patches welcome.')
if self.platform_toolset is None:
self.platform_toolset = 'v140'
@@ -0,0 +1,60 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2014-2016 The Meson development team
from __future__ import annotations
import os
import typing as T
import xml.etree.ElementTree as ET
from .vs2010backend import Vs2010Backend
from ..mesonlib import MesonException
if T.TYPE_CHECKING:
from ..build import Build
class Vs2017Backend(Vs2010Backend):
name = 'vs2017'
def __init__(self, build: T.Optional[Build]):
super().__init__(build)
self.vs_version = '2017'
self.sln_file_version = '12.00'
self.sln_version_comment = '15'
def detect_toolset(self) -> None:
# We assume that host == build
if self.environment is not None:
comps = self.environment.coredata.compilers.host
if comps:
if comps and all(c.id == 'clang-cl' for c in comps.values()):
self.platform_toolset = 'llvm'
elif comps and all(c.id == 'intel-cl' for c in comps.values()):
c = list(comps.values())[0]
if c.version.startswith('19'):
self.platform_toolset = 'Intel C++ Compiler 19.0'
else:
# We don't have support for versions older than 2019 right now.
raise MesonException('There is currently no support for ICL before 19, patches welcome.')
if self.platform_toolset is None:
self.platform_toolset = 'v141'
# WindowsSDKVersion should be set by command prompt.
sdk_version = os.environ.get('WindowsSDKVersion', None)
if sdk_version:
self.windows_target_platform_version = sdk_version.rstrip('\\')
def generate_debug_information(self, link):
# valid values for vs2017 is 'false', 'true', 'DebugFastLink', 'DebugFull'
ET.SubElement(link, 'GenerateDebugInformation').text = 'DebugFull'
def generate_lang_standard_info(self, file_args, clconf):
if 'cpp' in file_args:
optargs = [x for x in file_args['cpp'] if x.startswith('/std:c++')]
if optargs:
ET.SubElement(clconf, 'LanguageStandard').text = optargs[0].replace("/std:c++", "stdcpp")
if 'c' in file_args:
optargs = [x for x in file_args['c'] if x.startswith('/std:c')]
if optargs:
ET.SubElement(clconf, 'LanguageStandard_C').text = optargs[0].replace("/std:c", "stdc")
@@ -0,0 +1,55 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2014-2019 The Meson development team
from __future__ import annotations
import os
import typing as T
import xml.etree.ElementTree as ET
from .vs2010backend import Vs2010Backend
if T.TYPE_CHECKING:
from ..build import Build
class Vs2019Backend(Vs2010Backend):
name = 'vs2019'
def __init__(self, build: T.Optional[Build]):
super().__init__(build)
self.sln_file_version = '12.00'
self.sln_version_comment = 'Version 16'
def detect_toolset(self) -> None:
if self.environment is not None:
comps = self.environment.coredata.compilers.host
if comps and all(c.id == 'clang-cl' for c in comps.values()):
self.platform_toolset = 'ClangCL'
elif comps and all(c.id == 'intel-cl' for c in comps.values()):
c = list(comps.values())[0]
if c.version.startswith('19'):
self.platform_toolset = 'Intel C++ Compiler 19.0'
# We don't have support for versions older than 2019 right now.
if not self.platform_toolset:
self.platform_toolset = 'v142'
self.vs_version = '2019'
# WindowsSDKVersion should be set by command prompt.
sdk_version = os.environ.get('WindowsSDKVersion', None)
if sdk_version:
self.windows_target_platform_version = sdk_version.rstrip('\\')
def generate_debug_information(self, link):
# valid values for vs2019 is 'false', 'true', 'DebugFastLink', 'DebugFull'
ET.SubElement(link, 'GenerateDebugInformation').text = 'DebugFull'
def generate_lang_standard_info(self, file_args, clconf):
if 'cpp' in file_args:
optargs = [x for x in file_args['cpp'] if x.startswith('/std:c++')]
if optargs:
ET.SubElement(clconf, 'LanguageStandard').text = optargs[0].replace("/std:c++", "stdcpp")
if 'c' in file_args:
optargs = [x for x in file_args['c'] if x.startswith('/std:c')]
if optargs:
ET.SubElement(clconf, 'LanguageStandard_C').text = optargs[0].replace("/std:c", "stdc")
@@ -0,0 +1,55 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2014-2021 The Meson development team
from __future__ import annotations
import os
import typing as T
import xml.etree.ElementTree as ET
from .vs2010backend import Vs2010Backend
if T.TYPE_CHECKING:
from ..build import Build
class Vs2022Backend(Vs2010Backend):
name = 'vs2022'
def __init__(self, build: T.Optional[Build], gen_lite: bool = False):
super().__init__(build, gen_lite=gen_lite)
self.sln_file_version = '12.00'
self.sln_version_comment = 'Version 17'
def detect_toolset(self) -> None:
if self.environment is not None:
comps = self.environment.coredata.compilers.host
if comps and all(c.id == 'clang-cl' for c in comps.values()):
self.platform_toolset = 'ClangCL'
elif comps and all(c.id == 'intel-cl' for c in comps.values()):
c = list(comps.values())[0]
if c.version.startswith('19'):
self.platform_toolset = 'Intel C++ Compiler 19.0'
# We don't have support for versions older than 2022 right now.
if not self.platform_toolset:
self.platform_toolset = 'v143'
self.vs_version = '2022'
# WindowsSDKVersion should be set by command prompt.
sdk_version = os.environ.get('WindowsSDKVersion', None)
if sdk_version:
self.windows_target_platform_version = sdk_version.rstrip('\\')
def generate_debug_information(self, link):
# valid values for vs2022 is 'false', 'true', 'DebugFastLink', 'DebugFull'
ET.SubElement(link, 'GenerateDebugInformation').text = 'DebugFull'
def generate_lang_standard_info(self, file_args, clconf):
if 'cpp' in file_args:
optargs = [x for x in file_args['cpp'] if x.startswith('/std:c++')]
if optargs:
ET.SubElement(clconf, 'LanguageStandard').text = optargs[0].replace("/std:c++", "stdcpp")
if 'c' in file_args:
optargs = [x for x in file_args['c'] if x.startswith('/std:c')]
if optargs:
ET.SubElement(clconf, 'LanguageStandard_C').text = optargs[0].replace("/std:c", "stdc")
@@ -0,0 +1,55 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2025 The Meson development team
from __future__ import annotations
import os
import typing as T
import xml.etree.ElementTree as ET
from .vs2010backend import Vs2010Backend
if T.TYPE_CHECKING:
from ..build import Build
class Vs2026Backend(Vs2010Backend):
name = 'vs2026'
def __init__(self, build: T.Optional[Build], gen_lite: bool = False):
super().__init__(build, gen_lite=gen_lite)
self.sln_file_version = '12.00'
self.sln_version_comment = 'Version 18'
def detect_toolset(self) -> None:
if self.environment is not None:
comps = self.environment.coredata.compilers.host
if comps and all(c.id == 'clang-cl' for c in comps.values()):
self.platform_toolset = 'ClangCL'
elif comps and all(c.id == 'intel-cl' for c in comps.values()):
c = list(comps.values())[0]
if c.version.startswith('19'):
self.platform_toolset = 'Intel C++ Compiler 19.0'
# We don't have support for versions older than 2022 right now.
if not self.platform_toolset:
self.platform_toolset = 'v145'
self.vs_version = '2026'
# WindowsSDKVersion should be set by command prompt.
sdk_version = os.environ.get('WindowsSDKVersion', None)
if sdk_version:
self.windows_target_platform_version = sdk_version.rstrip('\\')
def generate_debug_information(self, link):
# valid values for vs2026 is 'false', 'true', 'DebugFastLink', 'DebugFull'
ET.SubElement(link, 'GenerateDebugInformation').text = 'DebugFull'
def generate_lang_standard_info(self, file_args, clconf):
if 'cpp' in file_args:
optargs = [x for x in file_args['cpp'] if x.startswith('/std:c++')]
if optargs:
ET.SubElement(clconf, 'LanguageStandard').text = optargs[0].replace("/std:c++", "stdcpp")
if 'c' in file_args:
optargs = [x for x in file_args['c'] if x.startswith('/std:c')]
if optargs:
ET.SubElement(clconf, 'LanguageStandard_C').text = optargs[0].replace("/std:c", "stdc")
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,9 @@
__all__ = [
'Interpreter',
'PackageState',
'TomlImplementationMissing',
'WorkspaceState',
]
from .interpreter import Interpreter, PackageState, WorkspaceState
from .toml import TomlImplementationMissing
Loaded 100 of 1573 files, more files were not shown because too many files have changed in this diff. Show more