From d8b9b12adbd2fa04f40ea2823929acc41f0a8003 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 14 Jul 2016 17:49:40 +0530 Subject: [PATCH] Ninja now supports backslash in command args, so we can too At the same time, this also adds a bunch of tests that document and keep track of how we expect quoting to pass through via Ninja to the compiler. We need at least Ninja 1.6.0 for this. This fixes https://github.com/mesonbuild/meson/issues/489 --- mesonbuild/build.py | 24 ---------------- .../asm output/meson.build | 2 ++ .../comparer-end-notstring.c | 20 +++++++++++++ .../115 spaces backslash/comparer-end.c | 16 +++++++++++ .../common/115 spaces backslash/comparer.c | 16 +++++++++++ .../115 spaces backslash/include/comparer.h | 4 +++ .../common/115 spaces backslash/meson.build | 28 +++++++++++++++++++ test cases/failing/24 backslash/comparer.c | 10 ------- test cases/failing/24 backslash/meson.build | 3 -- 9 files changed, 86 insertions(+), 37 deletions(-) create mode 100644 test cases/common/115 spaces backslash/asm output/meson.build create mode 100644 test cases/common/115 spaces backslash/comparer-end-notstring.c create mode 100644 test cases/common/115 spaces backslash/comparer-end.c create mode 100644 test cases/common/115 spaces backslash/comparer.c create mode 100644 test cases/common/115 spaces backslash/include/comparer.h create mode 100644 test cases/common/115 spaces backslash/meson.build delete mode 100644 test cases/failing/24 backslash/comparer.c delete mode 100644 test cases/failing/24 backslash/meson.build diff --git a/mesonbuild/build.py b/mesonbuild/build.py index b610bb8d9..6a4f37596 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -50,28 +50,6 @@ known_shlib_kwargs.update({'version' : True, 'name_suffix' : True, 'vs_module_defs' : True}) -backslash_explanation = \ -'''Compiler arguments have a backslash "\\" character. This is unfortunately not -permitted. The reason for this is that backslash is a shell quoting character -that behaves differently across different systems. Because of this is it not -possible to make it work reliably across all the platforms Meson needs to -support. - -There are several different ways of working around this issue. Most of the time -you are using this to provide a -D define to your compiler. Try instead to -create a config.h file and put all of your definitions in it using -configure_file(). - -Another approach is to move the backslashes into the source and have the other -bits in the def. So you would have an arg -DPLAIN_TEXT="foo" and then in your -C sources something like this: - -const char *fulltext = "\\\\" PLAIN_TEXT; - -We are fully aware that these are not really usable or pleasant ways to do -this but it's the best we can do given the way shell quoting works. -''' - def sources_are_suffix(sources, suffix): for source in sources: if source.endswith('.' + suffix): @@ -606,8 +584,6 @@ class BuildTarget(): for a in args: if not isinstance(a, (str, File)): raise InvalidArguments('A non-string passed to compiler args.') - if isinstance(a, str) and '\\' in a: - raise InvalidArguments(backslash_explanation) if language in self.extra_args: self.extra_args[language] += args else: diff --git a/test cases/common/115 spaces backslash/asm output/meson.build b/test cases/common/115 spaces backslash/asm output/meson.build new file mode 100644 index 000000000..b5f13f5ca --- /dev/null +++ b/test cases/common/115 spaces backslash/asm output/meson.build @@ -0,0 +1,2 @@ +configure_file(output : 'blank.txt', configuration : configuration_data()) + diff --git a/test cases/common/115 spaces backslash/comparer-end-notstring.c b/test cases/common/115 spaces backslash/comparer-end-notstring.c new file mode 100644 index 000000000..65bf8bc55 --- /dev/null +++ b/test cases/common/115 spaces backslash/comparer-end-notstring.c @@ -0,0 +1,20 @@ +#include "comparer.h" + +#ifndef COMPARER_INCLUDED +#error "comparer.h not included" +#endif + +/* This converts foo\\\\bar\\\\ to "foo\\bar\\" (string literal) */ +#define Q(x) #x +#define QUOTE(x) Q(x) + +#define COMPARE_WITH "foo\\bar\\" /* This is the literal `foo\bar\` */ + +int main(int argc, char **argv) { + if(strcmp(QUOTE(DEF_WITH_BACKSLASH), COMPARE_WITH)) { + printf("Arg string is quoted incorrectly: %s instead of %s\n", + QUOTE(DEF_WITH_BACKSLASH), COMPARE_WITH); + return 1; + } + return 0; +} diff --git a/test cases/common/115 spaces backslash/comparer-end.c b/test cases/common/115 spaces backslash/comparer-end.c new file mode 100644 index 000000000..fef25a545 --- /dev/null +++ b/test cases/common/115 spaces backslash/comparer-end.c @@ -0,0 +1,16 @@ +#include "comparer.h" + +#ifndef COMPARER_INCLUDED +#error "comparer.h not included" +#endif + +#define COMPARE_WITH "foo\\bar\\" /* This is `foo\bar\` */ + +int main (int argc, char **argv) { + if (strcmp (DEF_WITH_BACKSLASH, COMPARE_WITH)) { + printf ("Arg string is quoted incorrectly: %s vs %s\n", + DEF_WITH_BACKSLASH, COMPARE_WITH); + return 1; + } + return 0; +} diff --git a/test cases/common/115 spaces backslash/comparer.c b/test cases/common/115 spaces backslash/comparer.c new file mode 100644 index 000000000..937cb47f0 --- /dev/null +++ b/test cases/common/115 spaces backslash/comparer.c @@ -0,0 +1,16 @@ +#include "comparer.h" + +#ifndef COMPARER_INCLUDED +#error "comparer.h not included" +#endif + +#define COMPARE_WITH "foo\\bar" /* This is the literal `foo\bar` */ + +int main (int argc, char **argv) { + if (strcmp (DEF_WITH_BACKSLASH, COMPARE_WITH)) { + printf ("Arg string is quoted incorrectly: %s instead of %s\n", + DEF_WITH_BACKSLASH, COMPARE_WITH); + return 1; + } + return 0; +} diff --git a/test cases/common/115 spaces backslash/include/comparer.h b/test cases/common/115 spaces backslash/include/comparer.h new file mode 100644 index 000000000..624d96c92 --- /dev/null +++ b/test cases/common/115 spaces backslash/include/comparer.h @@ -0,0 +1,4 @@ +#include +#include + +#define COMPARER_INCLUDED diff --git a/test cases/common/115 spaces backslash/meson.build b/test cases/common/115 spaces backslash/meson.build new file mode 100644 index 000000000..bf614e8fc --- /dev/null +++ b/test cases/common/115 spaces backslash/meson.build @@ -0,0 +1,28 @@ +project('comparer', 'c') + +# Added manually as a c_arg to test handling of include paths with backslashes +# and spaces. This is especially useful on Windows in vcxproj files since it +# stores include directories in a separate element that has its own +# context-specific escaping/quoting. +include_dir = meson.current_source_dir() + '/include' +default_c_args = ['-I' + include_dir] + +if meson.get_compiler('c').get_id() == 'msvc' + default_c_args += ['/Faasm output\\'] + # Hack to create the 'asm output' directory in the builddir + subdir('asm output') +endif + +# Path can contain \. Here we're sending `"foo\bar"`. +test('backslash quoting', + executable('comparer', 'comparer.c', + c_args : default_c_args + ['-DDEF_WITH_BACKSLASH="foo\\bar"'])) +# Path can end in \ without any special quoting. Here we send `"foo\bar\"`. +test('backslash end quoting', + executable('comparer-end', 'comparer-end.c', + c_args : default_c_args + ['-DDEF_WITH_BACKSLASH="foo\\bar\\"'])) +# Path can (really) end in \ if we're not passing a string literal without any +# special quoting. Here we're sending `foo\bar\`. +test('backslash end quoting when not a string literal', + executable('comparer-end-notstring', 'comparer-end-notstring.c', + c_args : default_c_args + ['-DDEF_WITH_BACKSLASH=foo\\bar\\'])) diff --git a/test cases/failing/24 backslash/comparer.c b/test cases/failing/24 backslash/comparer.c deleted file mode 100644 index f562f5e37..000000000 --- a/test cases/failing/24 backslash/comparer.c +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - -int main(int argc, char **argv) { - if(strcmp(DEF_WITH_BACKSLASH, "foo\\bar")) { - printf("Arg string is quoted incorrectly: %s\n", DEF_WITH_BACKSLASH); - return 1; - } - return 0; -} diff --git a/test cases/failing/24 backslash/meson.build b/test cases/failing/24 backslash/meson.build deleted file mode 100644 index dba891eea..000000000 --- a/test cases/failing/24 backslash/meson.build +++ /dev/null @@ -1,3 +0,0 @@ -project('comparer', 'c') - -test('backslash quoting', executable('comparer', 'comparer.c', c_args : '-DDEF_WITH_BACKSLASH="foo\\bar"'))