aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/snippets/msvc_utf8.md16
-rw-r--r--mesonbuild/compilers/mixins/visualstudio.py13
-rw-r--r--test cases/windows/18 msvc charset/iso-8859-1.c7
-rw-r--r--test cases/windows/18 msvc charset/meson.build15
-rw-r--r--test cases/windows/18 msvc charset/meson_options.txt1
-rw-r--r--test cases/windows/18 msvc charset/utf8.c7
-rw-r--r--unittests/windowstests.py13
7 files changed, 70 insertions, 2 deletions
diff --git a/docs/markdown/snippets/msvc_utf8.md b/docs/markdown/snippets/msvc_utf8.md
new file mode 100644
index 0000000..fb8763d
--- /dev/null
+++ b/docs/markdown/snippets/msvc_utf8.md
@@ -0,0 +1,16 @@
+## MSVC compiler now assumes UTF-8 source code by default
+
+Every project that uses UTF-8 source files had to add manually `/utf-8` C/C++
+compiler argument for MSVC otherwise they wouldn't work on non-English locale.
+Meson now switched the default to UTF-8 to be more consistent with all other
+compilers.
+
+This can be overridden but using `/source-charset`:
+```meson
+if cc.get_id() == 'msvc'
+ add_project_arguments('/source-charset:.XYZ', language: ['c', 'cpp'])
+endif
+```
+
+See Microsoft documentation for details:
+https://docs.microsoft.com/en-us/cpp/build/reference/source-charset-set-source-character-set.
diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py
index eb81764..0360fa7 100644
--- a/mesonbuild/compilers/mixins/visualstudio.py
+++ b/mesonbuild/compilers/mixins/visualstudio.py
@@ -100,7 +100,9 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
# /showIncludes is needed for build dependency tracking in Ninja
# See: https://ninja-build.org/manual.html#_deps
- always_args = ['/nologo', '/showIncludes']
+ # Assume UTF-8 sources by default, but self.unix_args_to_native() removes it
+ # if `/source-charset` is set too.
+ always_args = ['/nologo', '/showIncludes', '/utf-8']
warn_args = {
'0': [],
'1': ['/W2'],
@@ -214,7 +216,7 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
@classmethod
def unix_args_to_native(cls, args: T.List[str]) -> T.List[str]:
- result = []
+ result: T.List[str] = []
for i in args:
# -mms-bitfields is specific to MinGW-GCC
# -pthread is only valid for GCC
@@ -248,6 +250,13 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
# -pthread in link flags is only used on Linux
elif i == '-pthread':
continue
+ # cl.exe does not allow specifying both, so remove /utf-8 that we
+ # added automatically in the case the user overrides it manually.
+ elif i.startswith('/source-charset:') or i.startswith('/execution-charset:'):
+ try:
+ result.remove('/utf-8')
+ except ValueError:
+ pass
result.append(i)
return result
diff --git a/test cases/windows/18 msvc charset/iso-8859-1.c b/test cases/windows/18 msvc charset/iso-8859-1.c
new file mode 100644
index 0000000..66c6a00
--- /dev/null
+++ b/test cases/windows/18 msvc charset/iso-8859-1.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char *argcv[])
+{
+ printf("This is ISO-8859-1 encoded é\n");
+ return 0;
+}
diff --git a/test cases/windows/18 msvc charset/meson.build b/test cases/windows/18 msvc charset/meson.build
new file mode 100644
index 0000000..bb6f667
--- /dev/null
+++ b/test cases/windows/18 msvc charset/meson.build
@@ -0,0 +1,15 @@
+project('charset', 'c')
+
+cc = meson.get_compiler('c')
+
+if cc.get_id() != 'msvc'
+ error('MESON_SKIP_TEST requires MSVC.')
+endif
+
+executable('utf8', 'utf8.c')
+
+if get_option('test-failure')
+ executable('iso-8859-1', 'iso-8859-1.c')
+else
+ executable('iso-8859-1', 'iso-8859-1.c', c_args: '/source-charset:.850')
+endif
diff --git a/test cases/windows/18 msvc charset/meson_options.txt b/test cases/windows/18 msvc charset/meson_options.txt
new file mode 100644
index 0000000..2cfba63
--- /dev/null
+++ b/test cases/windows/18 msvc charset/meson_options.txt
@@ -0,0 +1 @@
+option('test-failure', type: 'boolean', value: false)
diff --git a/test cases/windows/18 msvc charset/utf8.c b/test cases/windows/18 msvc charset/utf8.c
new file mode 100644
index 0000000..d6dc5aa
--- /dev/null
+++ b/test cases/windows/18 msvc charset/utf8.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main(int argc, char *argcv[])
+{
+ printf("This is UTF-8 encoded é\n");
+ return 0;
+}
diff --git a/unittests/windowstests.py b/unittests/windowstests.py
index 9359642..1e5964c 100644
--- a/unittests/windowstests.py
+++ b/unittests/windowstests.py
@@ -360,3 +360,16 @@ class WindowsTests(BasePlatformTests):
self.init(os.path.join(self.unit_test_dir, '86 cpp modules'))
self.build()
+ def test_non_utf8_fails(self):
+ # FIXME: VS backend does not use flags from compiler.get_always_args()
+ # and thus it's missing /utf-8 argument. Was that intentional? This needs
+ # to be revisited.
+ if self.backend is not Backend.ninja:
+ raise SkipTest(f'This test only pass with ninja backend (not {self.backend.name}).')
+ testdir = os.path.join(self.platform_test_dir, '18 msvc charset')
+ env = get_fake_env(testdir, self.builddir, self.prefix)
+ cc = detect_c_compiler(env, MachineChoice.HOST)
+ if cc.get_argument_syntax() != 'msvc':
+ raise SkipTest('Not using MSVC')
+ self.init(testdir, extra_args=['-Dtest-failure=true'])
+ self.assertRaises(subprocess.CalledProcessError, self.build)