Skip to content

Commit 99b848f

Browse files
committed
dependencies/cmake: correctly handle spaces in variable names
1 parent 2e2c3c9 commit 99b848f

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

mesonbuild/dependencies/base.py

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,13 +1546,27 @@ def _var_to_bool(self, var):
15461546
return True
15471547
return False
15481548

1549-
def _cmake_set(self, tline: CMakeTraceLine):
1549+
def _cmake_set(self, tline: CMakeTraceLine) -> None:
1550+
"""Handler for the CMake set() function in all variaties.
1551+
1552+
comes in three flavors:
1553+
set(<var> <value> [PARENT_SCOPE])
1554+
set(<var> <value> CACHE <type> <docstring> [FORCE])
1555+
set(ENV{<var>} <value>)
1556+
1557+
We don't support the ENV variant, and any uses of it will be ignored
1558+
silently. the other two variates are supported, with some caveats:
1559+
- we don't properly handle scoping, so calls to set() inside a
1560+
function without PARENT_SCOPE set could incorrectly shadow the
1561+
outer scope.
1562+
- We don't honor the type of CACHE arguments
1563+
"""
15501564
# DOC: https://cmake.org/cmake/help/latest/command/set.html
15511565

15521566
# 1st remove PARENT_SCOPE and CACHE from args
15531567
args = []
15541568
for i in tline.args:
1555-
if i == 'PARENT_SCOPE' or len(i) == 0:
1569+
if not i or i == 'PARENT_SCOPE':
15561570
continue
15571571

15581572
# Discard everything after the CACHE keyword
@@ -1564,13 +1578,19 @@ def _cmake_set(self, tline: CMakeTraceLine):
15641578
if len(args) < 1:
15651579
raise self._gen_exception('CMake: set() requires at least one argument\n{}'.format(tline))
15661580

1567-
if len(args) == 1:
1581+
# Now that we've removed extra arguments all that should be left is the
1582+
# variable identifier and the value, join the value back together to
1583+
# ensure spaces in the value are correctly handled. This assumes that
1584+
# variable names don't have spaces. Please don't do that...
1585+
identifier = args.pop(0)
1586+
value = ' '.join(args)
1587+
1588+
if not value:
15681589
# Same as unset
1569-
if args[0] in self.vars:
1570-
del self.vars[args[0]]
1590+
if identifier in self.vars:
1591+
del self.vars[identifier]
15711592
else:
1572-
values = list(itertools.chain(*map(lambda x: x.split(';'), args[1:])))
1573-
self.vars[args[0]] = values
1593+
self.vars[identifier] = value.split(';')
15741594

15751595
def _cmake_unset(self, tline: CMakeTraceLine):
15761596
# DOC: https://cmake.org/cmake/help/latest/command/unset.html

test cases/unit/61 cmake parser/meson.build

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ dep = dependency('mesontest')
44

55
# Test a bunch of variations of the set() command
66
assert(dep.get_variable(cmake : 'VAR_WITHOUT_SPACES') == 'NoSpaces', 'set() without spaces incorrect')
7-
#assert(dep.get_variable(cmake : 'VAR_WITH_SPACES') == 'With Spaces', 'set() with spaces incorrect')
7+
assert(dep.get_variable(cmake : 'VAR_WITH_SPACES') == 'With Spaces', 'set() with spaces incorrect')
88

99
assert(dep.get_variable(cmake : 'VAR_WITHOUT_SPACES_PS') == 'NoSpaces', 'set(PARENT_SCOPE) without spaces incorrect')
10-
#assert(dep.get_variable(cmake : 'VAR_WITH_SPACES_PS') == 'With Spaces', 'set(PARENT_SCOPE) with spaces incorrect')
10+
assert(dep.get_variable(cmake : 'VAR_WITH_SPACES_PS') == 'With Spaces', 'set(PARENT_SCOPE) with spaces incorrect')
1111

1212
assert(dep.get_variable(cmake : 'VAR_THAT_IS_UNSET', default_value : 'sentinal') == 'sentinal', 'set() to unset is incorrect')
1313
assert(dep.get_variable(cmake : 'CACHED_STRING_NS') == 'foo', 'set(CACHED) without spaces is incorrect')
14-
#assert(dep.get_variable(cmake : 'CACHED_STRING_WS') == 'foo bar', 'set(CACHED STRING) with spaces is incorrect')
14+
assert(dep.get_variable(cmake : 'CACHED_STRING_WS') == 'foo bar', 'set(CACHED STRING) with spaces is incorrect')
1515
assert(dep.get_variable(cmake : 'CACHED_STRING_ARRAY_NS') == ['foo', 'bar'], 'set(CACHED STRING) without spaces is incorrect')
16-
#assert(dep.get_variable(cmake : 'CACHED_STRING_ARRAY_WS') == ['foo', 'foo bar', 'bar'], 'set(CACHED STRING[]) with spaces is incorrect')
16+
assert(dep.get_variable(cmake : 'CACHED_STRING_ARRAY_WS') == ['foo', 'foo bar', 'bar'], 'set(CACHED STRING[]) with spaces is incorrect')
1717

1818
# We don't suppor this, so it should be unset.
1919
assert(dep.get_variable(cmake : 'ENV{var}', default_value : 'sentinal') == 'sentinal', 'set(ENV) should be ignored')

0 commit comments

Comments
 (0)