Skip to content

Commit bc09189

Browse files
committed
ninja: Fix multiline arguments
When using a custom_target() and an argument contains a newline, the command gets wrapped and written into a pickle file. However, when it's a compiler argument, the ninja backend was raising an error.
1 parent d819ed3 commit bc09189

File tree

5 files changed

+34
-9
lines changed

5 files changed

+34
-9
lines changed

mesonbuild/backend/ninjabackend.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,14 @@ def gcc_rsp_quote(s: str) -> str:
100100
# from, etc.), so it must not be shell quoted.
101101
raw_names = {'DEPFILE_UNQUOTED', 'DESC', 'pool', 'description', 'targetdep', 'dyndep'}
102102

103-
NINJA_QUOTE_BUILD_PAT = re.compile(r"[$ :\n]")
104-
NINJA_QUOTE_VAR_PAT = re.compile(r"[$ \n]")
103+
NINJA_QUOTE_BUILD_PAT = re.compile(r"[$ :]")
104+
NINJA_QUOTE_VAR_PAT = re.compile(r"[$ ]")
105+
NINJA_QUOTE_NEWLINE = re.compile(r"\n")
105106

106107
def ninja_quote(text: str, is_build_line: bool = False) -> str:
108+
if not is_build_line:
109+
text = NINJA_QUOTE_VAR_PAT.sub(r'$\g<0>', text)
110+
return NINJA_QUOTE_NEWLINE.sub(r'\\n', text)
107111
if '\n' in text:
108112
errmsg = f'''Ninja does not support newlines in rules. The content was:
109113
@@ -112,11 +116,7 @@ def ninja_quote(text: str, is_build_line: bool = False) -> str:
112116
Please report this error with a test case to the Meson bug tracker.'''
113117
raise MesonException(errmsg)
114118

115-
quote_re = NINJA_QUOTE_BUILD_PAT if is_build_line else NINJA_QUOTE_VAR_PAT
116-
if ' ' in text or '$' in text or (is_build_line and ':' in text):
117-
return quote_re.sub(r'$\g<0>', text)
118-
119-
return text
119+
return NINJA_QUOTE_BUILD_PAT.sub(r'$\g<0>', text)
120120

121121

122122
@dataclass

mesonbuild/cargo/interpreter.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,7 @@ def _pkg_common_env(self, pkg: PackageState, subdir: str) -> T.Dict[str, str]:
611611
'CARGO_PKG_VERSION_PRE': version_arr[3],
612612
'CARGO_PKG_AUTHORS': ','.join(pkg.manifest.package.authors),
613613
'CARGO_PKG_NAME': pkg.manifest.package.name,
614-
# FIXME: description can contain newlines which breaks ninja.
615-
#'CARGO_PKG_DESCRIPTION': pkg.manifest.package.description or '',
614+
'CARGO_PKG_DESCRIPTION': pkg.manifest.package.description or '',
616615
'CARGO_PKG_HOMEPAGE': pkg.manifest.package.homepage or '',
617616
'CARGO_PKG_REPOSITORY': pkg.manifest.package.repository or '',
618617
'CARGO_PKG_LICENSE': pkg.manifest.package.license or '',

test cases/common/27 multiline string/meson.build

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,13 @@ int main(void) {
3535
}'''
3636

3737
assert(cc.compiles(prog), 'multiline test compile failed')
38+
39+
# Test we can pass multiline strings as compiler arguments
40+
helloworld = '''
41+
Hello
42+
World
43+
'''
44+
exe = executable('multiline', 'multiline.c',
45+
c_args: ['-DHELLO_WORLD_STRING="' + helloworld + '"']
46+
)
47+
test('multiline run', files('test_multiline.py'), args: [exe])
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include <stdio.h>
2+
int main(int argc, char **argv) {
3+
printf("%s", HELLO_WORLD_STRING);
4+
return 0;
5+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#! /usr/bin/env python3
2+
3+
import sys
4+
import subprocess
5+
6+
output = subprocess.check_output(sys.argv[1:], universal_newlines=True, encoding='utf-8')
7+
8+
assert output == '''
9+
Hello
10+
World
11+
'''

0 commit comments

Comments
 (0)