Compare commits

...

5 Commits

Author SHA1 Message Date
Daniel Mensinger e1fd830070 cmake: Log warnings in CMakeLists.txt 4 years ago
Binh Nguyen f6758f2434 Prevent install_name_tool to run on EXE when cross compile on OSX 4 years ago
Luca Bacci ad20067ed2 Raise an exception if we cannot detect the MSVC compiler target architecture 4 years ago
fchin 4e460f04f3 Fixed issue that the key's value type wasn't checked correctly. 4 years ago
franczc adb4e071e6 Adding dictionary entry using string variable as key. 4 years ago
  1. 17
      docs/markdown/snippets/add_dictionary_variable_key.md
  2. 43
      mesonbuild/cmake/interpreter.py
  3. 6
      mesonbuild/environment.py
  4. 13
      mesonbuild/interpreterbase.py
  5. 21
      mesonbuild/mparser.py
  6. 4
      mesonbuild/scripts/depfixer.py
  7. 12
      test cases/common/228 add dict variable key/meson.build
  8. 9
      test cases/failing/97 add dict non string key/meson.build
  9. 9
      test cases/failing/98 add dict duplicate keys/meson.build

@ -0,0 +1,17 @@
## Adding dictionary entry using string variable as key
New dictionary entry can now be added using string variable as key,
in addition to using string literal as key.
```meson
dict = {}
# A variable to be used as a key
key = 'myKey'
# Add new entry using the variable
dict += {key : 'myValue'}
# Test that the stored value is correct
assert(dict[key] == 'myValue', 'Incorrect value retrieved from dictionary')
```

@ -51,6 +51,20 @@ if TYPE_CHECKING:
from ..build import Build
from ..backend.backends import Backend
# Disable all warnings automaticall enabled with --trace and friends
# See https://cmake.org/cmake/help/latest/variable/CMAKE_POLICY_WARNING_CMPNNNN.html
disable_policy_warnings = [
'CMP0025',
'CMP0047',
'CMP0056',
'CMP0060',
'CMP0065',
'CMP0066',
'CMP0067',
'CMP0082',
'CMP0089',
]
backend_generator_map = {
'ninja': 'Ninja',
'xcode': 'Xcode',
@ -503,6 +517,8 @@ class CMakeInterpreter:
generator = backend_generator_map[self.backend_name]
cmake_args = cmake_exe.get_command()
trace_args = ['--trace', '--trace-expand', '--no-warn-unused-cli']
cmcmp_args = ['-DCMAKE_POLICY_WARNING_{}=OFF'.format(x) for x in disable_policy_warnings]
if version_compare(cmake_exe.version(), '>=3.14'):
self.cmake_api = CMakeAPI.FILE
@ -523,7 +539,6 @@ class CMakeInterpreter:
cmake_args += ['-DCMAKE_LINKER={}'.format(comp.get_linker_exelist()[0])]
cmake_args += ['-G', generator]
cmake_args += ['-DCMAKE_INSTALL_PREFIX={}'.format(self.install_prefix)]
cmake_args += ['--trace', '--trace-expand']
cmake_args += extra_cmake_options
# Run CMake
@ -531,11 +546,16 @@ class CMakeInterpreter:
with mlog.nested():
mlog.log('Configuring the build directory with', mlog.bold('CMake'), 'version', mlog.cyan(cmake_exe.version()))
mlog.log(mlog.bold('Running:'), ' '.join(cmake_args))
mlog.log(mlog.bold(' - build directory: '), self.build_dir)
mlog.log(mlog.bold(' - source directory: '), self.src_dir)
mlog.log(mlog.bold(' - trace args: '), ' '.join(trace_args))
mlog.log(mlog.bold(' - disabled policy warnings:'), '[{}]'.format(', '.join(disable_policy_warnings)))
mlog.log()
os.makedirs(self.build_dir, exist_ok=True)
os_env = os.environ.copy()
os_env['LC_ALL'] = 'C'
proc = Popen(cmake_args + [self.src_dir], stdout=PIPE, stderr=PIPE, cwd=self.build_dir, env=os_env)
final_command = cmake_args + trace_args + cmcmp_args + [self.src_dir]
proc = Popen(final_command, stdout=PIPE, stderr=PIPE, cwd=self.build_dir, env=os_env)
def print_stdout():
while True:
@ -548,8 +568,23 @@ class CMakeInterpreter:
t = Thread(target=print_stdout)
t.start()
self.raw_trace = proc.stderr.read()
self.raw_trace = self.raw_trace.decode('utf-8')
# Read stderr line by line and log non trace lines
self.raw_trace = ''
tline_start_reg = re.compile(r'^\s*(.*\.(cmake|txt))\(([0-9]+)\):\s*(\w+)\(.*$')
inside_multiline_trace = False
while True:
line = proc.stderr.readline()
if not line:
break
line = line.decode('utf-8')
if tline_start_reg.match(line):
self.raw_trace += line
inside_multiline_trace = not line.endswith(' )\n')
elif inside_multiline_trace:
self.raw_trace += line
else:
mlog.warning(line.strip('\n'))
proc.stderr.close()
proc.wait()

@ -990,11 +990,13 @@ class Environment:
else:
m = 'Failed to detect MSVC compiler version: stderr was\n{!r}'
raise EnvironmentException(m.format(err))
match = re.search(' for .*(x86|x64|ARM|ARM64)$', lookat.split('\n')[0])
cl_signature = lookat.split('\n')[0]
match = re.search(' for .*(x86|x64|ARM|ARM64)$', cl_signature)
if match:
target = match.group(1)
else:
target = 'x86'
m = 'Failed to detect MSVC compiler target architecture: \'cl /?\' output is\n{}'
raise EnvironmentException(m.format(cl_signature))
linker = MSVCDynamicLinker(for_machine, version=version)
cls = VisualStudioCCompiler if lang == 'c' else VisualStudioCPPCompiler
return cls(

@ -731,7 +731,16 @@ The result of this is undefined and will become a hard error in a future Meson r
elif isinstance(old_variable, dict):
if not isinstance(addition, dict):
raise InvalidArguments('The += operator requires a dict on the right hand side if the variable on the left is a dict')
new_value = {**old_variable, **addition}
new_addition = {}
for (key, value) in addition.items():
if isinstance(key, str):
new_addition[key] = value
elif isinstance(key, mparser.IdNode) and isinstance(self.get_variable(key.value), str):
FeatureNew('Adding dictionary entry using string variable as key', '0.53.0').use(self.subproject)
new_addition[self.get_variable(key.value)] = value
else:
raise InvalidArguments('Dictionary key must be a string or string variable')
new_value = {**old_variable, **new_addition}
# Add other data types here.
else:
raise InvalidArguments('The += operator currently only works with arrays, dicts, strings or ints ')
@ -1021,8 +1030,6 @@ The result of this is undefined and will become a hard error in a future Meson r
reduced_pos = [self.evaluate_statement(arg) for arg in args.arguments]
reduced_kw = {}
for key in args.kwargs.keys():
if not isinstance(key, str):
raise InvalidArguments('Keyword argument name is not a string.')
a = args.kwargs[key]
reduced_kw[key] = self.evaluate_statement(a)
self.argument_depth -= 1

@ -676,14 +676,19 @@ class Parser:
while not isinstance(s, EmptyNode):
potential = self.current
if self.accept('colon'):
if not isinstance(s, StringNode):
raise ParseException('Key must be a string.',
self.getline(), s.lineno, s.colno)
if s.value in a.kwargs:
# + 1 to colno to point to the actual string, not the opening quote
raise ParseException('Duplicate dictionary key: {}'.format(s.value),
self.getline(), s.lineno, s.colno + 1)
a.set_kwarg(s.value, self.statement())
key_value = self.statement()
if isinstance(s, StringNode):
if s.value in a.kwargs:
# + 1 to colno to point to the actual string, not the opening quote
raise ParseException('Duplicate dictionary key: {}'.format(s.value), self.getline(), s.lineno, s.colno + 1)
a.set_kwarg(s.value, key_value)
elif isinstance(s, IdNode) and isinstance(key_value, StringNode):
for key in a.kwargs:
if s.value == key.value:
raise ParseException('Duplicate dictionary variable key: {}'.format(s.value), self.getline(), s.lineno, s.colno)
a.set_kwarg(s, key_value)
else:
raise ParseException('Key must be a string or string variable', self.getline(), s.lineno, s.colno)
potential = self.current
if not self.accept('comma'):
return a

@ -431,8 +431,8 @@ def fix_rpath(fname, new_rpath, final_path, install_name_mappings, verbose=True)
# Static libraries never have rpaths
if fname.endswith('.a'):
return
# DLLs never have rpaths
if fname.endswith('.dll'):
# DLLs and EXE never have rpaths
if fname.endswith('.dll') or fname.endswith('.exe'):
return
try:
if fname.endswith('.jar'):

@ -0,0 +1,12 @@
project('add dictionary entry using string variable as key', meson_version: '>=0.52')
dict = {}
# A variable to be used as a key
key = 'myKey'
# Add new entry using the variable
dict += {key : 'myValue'}
# Test that the stored value is correct
assert(dict[key] == 'myValue', 'Incorrect value retrieved from dictionary')

@ -0,0 +1,9 @@
project('add dictionary entry using non-string key')
dict = {}
# An integer variable to be used as a key
key = 1
# Add new entry using integer variable as key should fail
dict += {key : 'myValue'}

@ -0,0 +1,9 @@
project('add dictionary entries with duplicate keys')
dict = {}
# A variable to be used as a key
key = 'myKey'
# Add two entries with duplicate keys should fail
dict += {key : 'myValue1', key : 'myValue2'}
Loading…
Cancel
Save