From 54697b41303c900bd44f962d174cda799d177a9e Mon Sep 17 00:00:00 2001 From: Philipp Geier Date: Sat, 24 Dec 2016 17:19:58 +0100 Subject: [PATCH 01/16] ICC 17.0.0 working for Linux and Ninja Backend. Added IntelCompiler, IntelCCompiler and IntelCCompiler. environments.py has been changed to detect icc and icpc. ninjabackend changed for proper pch generation. ICC 17.0.0 does not support C++13 (that's why default arguments tests fails). Test 25 object extraction fails due to some unescaped whitespaces. Some test with vala fail because of successful build, although they should fail, as warning do not exit with failure. --- mesonbuild/backend/ninjabackend.py | 5 + mesonbuild/compilers.py | 141 ++++++++++++++++++++++++++++- mesonbuild/environment.py | 8 ++ 3 files changed, 152 insertions(+), 2 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 349168176..60383afa6 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1837,6 +1837,8 @@ rule FORTRAN_DEP_HACK pchlist = [] if len(pchlist) == 0: pch_dep = [] + elif compiler.id == 'intel': + pch_dep = [] else: arr = [] i = os.path.join(self.get_target_private_dir(target), compiler.get_pch_name(pchlist[0])) @@ -1956,6 +1958,9 @@ rule FORTRAN_DEP_HACK src = os.path.join(self.build_to_src, target.get_source_subdir(), pch[-1]) (commands, dep, dst, objs) = self.generate_msvc_pch_command(target, compiler, pch) extradep = os.path.join(self.build_to_src, target.get_source_subdir(), pch[0]) + elif compiler.id == 'intel': + # Intel generates on target generation + continue else: src = os.path.join(self.build_to_src, target.get_source_subdir(), pch[0]) (commands, dep, dst, objs) = self.generate_gcc_pch_command(target, compiler, pch[0]) diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 0481ab2e9..9e4e62277 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -1923,7 +1923,7 @@ class VisualStudioCCompiler(CCompiler): def gen_pch_args(self, header, source, pchname): objname = os.path.splitext(pchname)[0] + '.obj' - return (objname, ['/Yc' + header, '/Fp' + pchname, '/Fo' + objname ]) + return (objname, ['/Yc' + header, '/Fp' + pchname, '/Fo' + objname]) def gen_import_library_args(self, implibname): "The name of the outputted import library" @@ -2064,6 +2064,10 @@ CLANG_OSX = 1 CLANG_WIN = 2 # Possibly clang-cl? +ICC_STANDARD = 0 +ICC_OSX = 1 +ICC_WIN = 2 + def get_gcc_soname_args(gcc_type, prefix, shlib_name, suffix, path, soversion, is_shared_module): if soversion is None: sostr = '' @@ -2223,6 +2227,7 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler): # too strict without this and always fails. return self.get_no_optimization_args() + ['-fpermissive'] + class GnuObjCCompiler(GnuCompiler, ObjCCompiler): def __init__(self, exelist, version, is_cross, exe_wrapper=None, defines=None): @@ -2283,7 +2288,7 @@ class ClangCompiler(): # Workaround for Clang bug http://llvm.org/bugs/show_bug.cgi?id=15136 # This flag is internal to Clang (or at least not documented on the man page) # so it might change semantics at any time. - return ['-include-pch', os.path.join (pch_dir, self.get_pch_name (header))] + return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))] def get_soname_args(self, prefix, shlib_name, suffix, path, soversion, is_shared_module): if self.clang_type == CLANG_STANDARD: @@ -2378,6 +2383,137 @@ class ClangObjCPPCompiler(ClangCompiler, GnuObjCPPCompiler): ClangCompiler.__init__(self, cltype) self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage'] + +# Only tested on linux for ICC 17.0.0 +# * object extraction does not compile (don't know) (25 object extraction fails) +# * ICC 17.0.0 does not support c++03 and g++03 (94 default options fails) +class IntelCompiler: + def __init__(self, icc_type): + self.id = 'intel' + self.icc_type = icc_type + self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage', + 'b_colorout', 'b_ndebug', 'b_staticpic', 'b_lundef', 'b_asneeded'] + # Assembly + self.can_compile_suffixes.add('s') + + def get_pic_args(self): + return ['-fPIC'] + + def get_buildtype_args(self, buildtype): + return gnulike_buildtype_args[buildtype] + + def get_buildtype_linker_args(self, buildtype): + return gnulike_buildtype_linker_args[buildtype] + + def get_pch_suffix(self): + return 'pchi' + + def get_pch_use_args(self, pch_dir, header): + return ['-pch', '-pch_dir', os.path.join(pch_dir), '-include', header] + + def get_pch_name(self, header_name): + return os.path.split(header_name)[-1] + '.' + self.get_pch_suffix() + + # Not required, but possible if backend should create pch files. However Intel does it automatically + # def gen_pch_args(self, header, source, pchname): + # return ['-pch_create', os.path.join(pchname, self.get_pch_name(header)), '-include', header, source]) + + def split_shlib_to_parts(self, fname): + return (os.path.split(fname)[0], fname) + + def get_soname_args(self, prefix, shlib_name, suffix, path, soversion, is_shared_module): + if self.icc_type == ICC_STANDARD: + gcc_type = GCC_STANDARD + elif self.icc_type == ICC_OSX: + gcc_type = GCC_OSX + elif self.icc_type == ICC_WIN: + gcc_type = GCC_MINGW + else: + raise MesonException('Unreachable code when converting icc type to gcc type.') + return get_gcc_soname_args(gcc_type, prefix, shlib_name, suffix, path, soversion, is_shared_module) + + def get_std_shared_lib_link_args(self): + # Don't know how icc works on OSX + # if self.icc_type == ICC_OSX: + # return ['-bundle'] + return ['-shared'] + + +class IntelCCompiler(IntelCompiler, CCompiler): + def __init__(self, exelist, version, icc_type, is_cross, exe_wrapper=None): + CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper) + IntelCompiler.__init__(self, icc_type) + self.warn_args = {'1': ['-Wall', '-w3', '-diag-disable:remark', '-Wpch-messages'], + '2': ['-Wall', '-w3', '-diag-disable:remark', '-Wextra-tokens', '-Wpch-messages'], + '3': ['-Wall', '-w3', '-diag-disable:remark', '-Wpedantic', '-Wextra', '-Wpch-messages']} + + def get_options(self): + opts = {'c_std': coredata.UserComboOption('c_std', 'C language standard to use', + ['none', 'c89', 'c99', + 'gnu89', 'gnu99'], + 'none')} + return opts + + def get_option_compile_args(self, options): + args = [] + std = options['c_std'] + if std.value != 'none': + args.append('-std=' + std.value) + return args + + def get_std_shared_lib_link_args(self): + return ['-shared'] + + def has_multi_arguments(self, args, env): + return super(IntelCCompiler, self).has_multi_arguments(args + ['-diag-error', '10006'], env) + + +class IntelCPPCompiler(IntelCompiler, CPPCompiler): + def __init__(self, exelist, version, icc_type, is_cross, exe_wrap): + CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) + IntelCompiler.__init__(self, icc_type) + self.warn_args = {'1': ['-Wall', '-w3', '-diag-disable:remark', '-Wpch-messages', '-Wnon-virtual-dtor'], + '2': ['-Wall', '-w3', '-diag-disable:remark', '-Wextra', '-Wpch-messages', '-Wnon-virtual-dtor'], + '3': ['-Wall', '-w3', '-diag-disable:remark', '-Wpedantic', '-Wextra', '-Wpch-messages', '-Wnon-virtual-dtor']} + + def get_options(self): + if mesonlib.version_compare(self.version, '>=17.0.0'): + opts = {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use', + ['none', 'c++11', 'c++0x', 'c++14', + 'gnu++98', 'gnu++11', 'gnu++0x', 'gnu++14'], + 'none'), + 'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl', + 'STL debug mode', + False)} + else: + opts = {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use', + ['none', 'c++03', 'c++11', 'c++0x', + 'gnu++98', 'gnu++03', 'gnu++11', 'gnu++0x'], + 'none'), + 'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl', + 'STL debug mode', + False)} + return opts + + def get_option_compile_args(self, options): + args = [] + std = options['cpp_std'] + if std.value != 'none': + args.append('-std=' + std.value) + if options['cpp_debugstl'].value: + args.append('-D_GLIBCXX_DEBUG=1') + return args + + def get_option_link_args(self, options): + return [] + + def get_compiler_check_args(self): + return self.get_no_optimization_args() + + def has_multi_arguments(self, args, env): + return super(IntelCPPCompiler, self).has_multi_arguments(args + ['-diag-error', '10006'], env) + + class FortranCompiler(Compiler): def __init__(self, exelist, version, is_cross, exe_wrapper=None): self.language = 'fortran' @@ -2634,6 +2770,7 @@ class NAGFortranCompiler(FortranCompiler): class VisualStudioLinker(): always_args = ['/NOLOGO'] + def __init__(self, exelist): self.exelist = exelist diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 2e5387dd8..48f5865c8 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -396,6 +396,10 @@ class Environment(): # everything else to stdout. Why? Lord only knows. version = search_version(err) return VisualStudioCCompiler([compiler], version, is_cross, exe_wrap) + if '(ICC)' in out: + # TODO: add microsoft add check OSX + inteltype = ICC_STANDARD + return IntelCCompiler(ccache + [compiler], version, inteltype, is_cross, exe_wrap) errmsg = 'Unknown compiler(s): "' + ', '.join(compilers) + '"' if popen_exceptions: errmsg += '\nThe follow exceptions were encountered:' @@ -525,6 +529,10 @@ class Environment(): if 'Microsoft' in out or 'Microsoft' in err: version = search_version(err) return VisualStudioCPPCompiler([compiler], version, is_cross, exe_wrap) + if '(ICC)' in out: + # TODO: add microsoft add check OSX + inteltype = ICC_STANDARD + return IntelCPPCompiler(ccache + [compiler], version, inteltype, is_cross, exe_wrap) errmsg = 'Unknown compiler(s): "' + ', '.join(compilers) + '"' if popen_exceptions: errmsg += '\nThe follow exceptions were encountered:' From c8bb7f2217fdc336cab6fc4b29d561ce17518c4d Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 05:40:47 +0530 Subject: [PATCH 02/16] unit tests: Be more specific in checking for commands '-w' in c_command will check for it as a substring, which will also match '-wd', etc. So match it with quotes. This won't give us false positives, but might give us false negatives in case the argument is not quoted, but that's better behaviour for a test. The alternative is to split the string command, but the command does not necessarily obey shell quoting rules, so we cannot reliably use shlex.split(). --- run_unittests.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/run_unittests.py b/run_unittests.py index 73268003e..3e8d32b01 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -221,15 +221,15 @@ class LinuxlikeTests(unittest.TestCase): self.assertIsNotNone(vala_command) self.assertIsNotNone(c_command) # -w suppresses all warnings, should be there in Vala but not in C - self.assertTrue('-w' in vala_command) - self.assertFalse('-w' in c_command) + self.assertTrue("'-w'" in vala_command) + self.assertFalse("'-w'" in c_command) # -Wall enables all warnings, should be there in C but not in Vala - self.assertFalse('-Wall' in vala_command) - self.assertTrue('-Wall' in c_command) + self.assertFalse("'-Wall'" in vala_command) + self.assertTrue("'-Wall'" in c_command) # -Werror converts warnings to errors, should always be there since it's # injected by an unrelated piece of code and the project has werror=true - self.assertTrue('-Werror' in vala_command) - self.assertTrue('-Werror' in c_command) + self.assertTrue("'-Werror'" in vala_command) + self.assertTrue("'-Werror'" in c_command) def test_static_compile_order(self): ''' From 78325f884db614b6f8369574173149b9ce0b07e4 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 05:42:47 +0530 Subject: [PATCH 03/16] tests/failing build/1: Fix test with ICC Explicitly warn with the `#warning` macro to ensure that ICC emits a warning since ICC does not emit a warning for unused variables. Also makes the test more reliable with other compilers. --- test cases/failing build/1 vala c werror/unused-var.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test cases/failing build/1 vala c werror/unused-var.c b/test cases/failing build/1 vala c werror/unused-var.c index e11d64c8c..6b85078c9 100644 --- a/test cases/failing build/1 vala c werror/unused-var.c +++ b/test cases/failing build/1 vala c werror/unused-var.c @@ -1,3 +1,5 @@ +#warning "something" + int somelib(void) { From 84931e1f780d621616dff1c2bd51ae8ba6c0deb3 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 05:49:03 +0530 Subject: [PATCH 04/16] test/7 gnome: Fix on ICC and suppress a warning Ignore warning 2282 about GCC pragmas since they are emitted in system headers and are extremely spammy. They are emitted because ICC pretends to be GCC via C macros but doesn't implement some pragmas. https://bugzilla.gnome.org/show_bug.cgi?id=776562 Also, append to LD_LIBRARY_PATH because ICC uses that for some internal libraries such as libintlc.so. --- .../frameworks/11 gir subproject/gir/meson.build | 8 +++++--- test cases/frameworks/7 gnome/gir/meson.build | 7 ++++--- test cases/frameworks/7 gnome/meson.build | 10 +++++++++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/test cases/frameworks/11 gir subproject/gir/meson.build b/test cases/frameworks/11 gir subproject/gir/meson.build index e92c64163..48e0a47a0 100644 --- a/test cases/frameworks/11 gir subproject/gir/meson.build +++ b/test cases/frameworks/11 gir subproject/gir/meson.build @@ -28,8 +28,10 @@ gnome.generate_gir( message('TEST: ' + girsubproject.outdir()) +envdata = environment() +envdata.append('GI_TYPELIB_PATH', girsubproject.outdir(), 'subprojects/mesongir', separator : ':') +envdata.append('LD_LIBRARY_PATH', girsubproject.outdir(), 'subprojects/mesongir') + test('gobject introspection/subproject/c', girexe) test('gobject introspection/subproject/py', find_program('prog.py'), - env : ['GI_TYPELIB_PATH=' + girsubproject.outdir() + ':subprojects/mesongir', - 'LD_LIBRARY_PATH=' + girsubproject.outdir() + ':subprojects/mesongir', - ]) + env : envdata) diff --git a/test cases/frameworks/7 gnome/gir/meson.build b/test cases/frameworks/7 gnome/gir/meson.build index beddc8183..f3a453433 100644 --- a/test cases/frameworks/7 gnome/gir/meson.build +++ b/test cases/frameworks/7 gnome/gir/meson.build @@ -33,7 +33,8 @@ gnome.generate_gir( test('gobject introspection/c', girexe) gir_paths = ':'.join([girlib.outdir(), dep1lib.outdir(), dep2lib.outdir()]) +envdata = environment() +envdata.append('GI_TYPELIB_PATH', gir_paths, separator : ':') +envdata.append('LD_LIBRARY_PATH', gir_paths) test('gobject introspection/py', find_program('prog.py'), - env : ['GI_TYPELIB_PATH=' + gir_paths, - 'LD_LIBRARY_PATH=' + gir_paths, - ]) + env : envdata) diff --git a/test cases/frameworks/7 gnome/meson.build b/test cases/frameworks/7 gnome/meson.build index a771e71b7..c75c0490f 100644 --- a/test cases/frameworks/7 gnome/meson.build +++ b/test cases/frameworks/7 gnome/meson.build @@ -1,5 +1,14 @@ project('gobject-introspection', 'c') +cc = meson.get_compiler('c') + +add_global_arguments('-DMESON_TEST', language : 'c') +if cc.get_id() == 'intel' + # Ignore invalid GCC pragma warnings from glib + # https://bugzilla.gnome.org/show_bug.cgi?id=776562 + add_global_arguments('-wd2282', language : 'c') +endif + gnome = import('gnome') gio = dependency('gio-2.0') giounix = dependency('gio-unix-2.0') @@ -7,7 +16,6 @@ glib = dependency('glib-2.0') gobj = dependency('gobject-2.0') gir = dependency('gobject-introspection-1.0') gmod = dependency('gmodule-2.0') -add_global_arguments('-DMESON_TEST', language : 'c') subdir('resources-data') subdir('resources') From f024114c29da07eb847b447e095e1a1259736115 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 08:44:38 +0530 Subject: [PATCH 05/16] tests/common/25: Remove spaces in exe name ICC doesn't escape spaces in file paths while writing out the dependency file, so don't use spaces to avoid a spurious failure. --- test cases/common/25 object extraction/meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test cases/common/25 object extraction/meson.build b/test cases/common/25 object extraction/meson.build index c76b0db70..d99ec8444 100644 --- a/test cases/common/25 object extraction/meson.build +++ b/test cases/common/25 object extraction/meson.build @@ -9,8 +9,8 @@ else obj1 = lib1.extract_objects('src/lib.c') obj2 = lib2.extract_objects(['lib.c']) - e1 = executable('main 1', 'main.c', objects : obj1) - e2 = executable('main 2', 'main.c', objects : obj2) + e1 = executable('main1', 'main.c', objects : obj1) + e2 = executable('main2', 'main.c', objects : obj2) test('extraction test 1', e1) test('extraction test 2', e2) From 2f5943d34dd6203c8984c60573d890c3b49b5de4 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 08:54:20 +0530 Subject: [PATCH 06/16] Add a new test for depfile generation with spaces This checks that dependency generation is correct even when the sources and outputs have spaces in them. --- .../common/132 dependency file generation/main .c | 3 +++ .../132 dependency file generation/meson.build | 12 ++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 test cases/common/132 dependency file generation/main .c create mode 100644 test cases/common/132 dependency file generation/meson.build diff --git a/test cases/common/132 dependency file generation/main .c b/test cases/common/132 dependency file generation/main .c new file mode 100644 index 000000000..0fb4389f7 --- /dev/null +++ b/test cases/common/132 dependency file generation/main .c @@ -0,0 +1,3 @@ +int main(int argc, char *argv[]) { + return 0; +} diff --git a/test cases/common/132 dependency file generation/meson.build b/test cases/common/132 dependency file generation/meson.build new file mode 100644 index 000000000..dcfdcd9f3 --- /dev/null +++ b/test cases/common/132 dependency file generation/meson.build @@ -0,0 +1,12 @@ +project('dep file gen', 'c') + +cc_id = meson.get_compiler('c').get_id() +if cc_id == 'intel' + # ICC does not escape spaces in paths in the dependency file, so Ninja + # (correctly) thinks that the rule has multiple outputs and errors out: + # 'depfile has multiple output paths' + error('MESON_SKIP_TEST: Skipping test with Intel compiler because it generates broken dependency files') +endif + +e = executable('main file', 'main .c') +test('test it', e) From 28e491c706cc1943d8ce2fde9ad4b43d54fce3a4 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 10:36:36 +0530 Subject: [PATCH 07/16] Skip a few tests properly --- test cases/d/3 shared library/meson.build | 15 ++++++--------- test cases/d/3 shared library/no-installed-files | 0 2 files changed, 6 insertions(+), 9 deletions(-) delete mode 100644 test cases/d/3 shared library/no-installed-files diff --git a/test cases/d/3 shared library/meson.build b/test cases/d/3 shared library/meson.build index 5dae66bfc..1f45109d7 100644 --- a/test cases/d/3 shared library/meson.build +++ b/test cases/d/3 shared library/meson.build @@ -1,12 +1,9 @@ project('D Shared Library', 'd') -if meson.get_compiler('d').get_id() != 'gcc' - - ldyn = shared_library('stuff', 'libstuff.d', install : true) - ed = executable('app_d', 'app.d', link_with : ldyn, install : true) - test('linktest_dyn', ed) - -else - message('GDC can not build shared libraries. Test skipped.') - install_data('no-installed-files', install_dir : '') +if meson.get_compiler('d').get_id() == 'gcc' + error('MESON_SKIP_TEST: GDC can not build shared libraries') endif + +ldyn = shared_library('stuff', 'libstuff.d', install : true) +ed = executable('app_d', 'app.d', link_with : ldyn, install : true) +test('linktest_dyn', ed) diff --git a/test cases/d/3 shared library/no-installed-files b/test cases/d/3 shared library/no-installed-files deleted file mode 100644 index e69de29bb..000000000 From e36183aab43ce92509a7f8d3a20c46c5e4c85714 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 10:40:24 +0530 Subject: [PATCH 08/16] tests: Use the new test skipping facility everywhere --- test cases/d/4 library versions/meson.build | 33 +++++++++---------- .../d/4 library versions/no-installed-files | 0 .../7 mingw dll versioning/meson.build | 20 +++++------ .../7 mingw dll versioning/no-installed-files | 0 .../windows/8 msvc dll versioning/meson.build | 20 +++++------ .../8 msvc dll versioning/no-installed-files | 0 6 files changed, 35 insertions(+), 38 deletions(-) delete mode 100644 test cases/d/4 library versions/no-installed-files delete mode 100644 test cases/windows/7 mingw dll versioning/no-installed-files delete mode 100644 test cases/windows/8 msvc dll versioning/no-installed-files diff --git a/test cases/d/4 library versions/meson.build b/test cases/d/4 library versions/meson.build index 26cc38a5a..f680651c9 100644 --- a/test cases/d/4 library versions/meson.build +++ b/test cases/d/4 library versions/meson.build @@ -1,25 +1,22 @@ project('D library versions', 'd') if meson.get_compiler('d').get_id() == 'gcc' - message('GDC can not build shared libraries. Test skipped.') - install_data('no-installed-files', install_dir : '') -else - - shared_library('some', 'lib.d', - version : '1.2.3', - soversion : '0', - install : true) + error('MESON_SKIP_TEST: GDC can not build shared libraries') +endif - shared_library('noversion', 'lib.d', - install : true) +shared_library('some', 'lib.d', + version : '1.2.3', + soversion : '0', + install : true) - shared_library('onlyversion', 'lib.d', - version : '1.4.5', - install : true) +shared_library('noversion', 'lib.d', + install : true) - shared_library('onlysoversion', 'lib.d', - # Also test that int soversion is acceptable - soversion : 5, - install : true) +shared_library('onlyversion', 'lib.d', + version : '1.4.5', + install : true) -endif +shared_library('onlysoversion', 'lib.d', + # Also test that int soversion is acceptable + soversion : 5, + install : true) diff --git a/test cases/d/4 library versions/no-installed-files b/test cases/d/4 library versions/no-installed-files deleted file mode 100644 index e69de29bb..000000000 diff --git a/test cases/windows/7 mingw dll versioning/meson.build b/test cases/windows/7 mingw dll versioning/meson.build index 23a33435b..2f6035eca 100644 --- a/test cases/windows/7 mingw dll versioning/meson.build +++ b/test cases/windows/7 mingw dll versioning/meson.build @@ -2,16 +2,16 @@ project('mingw dll versioning', 'c') cc = meson.get_compiler('c') +if cc.get_id() == 'msvc' + error('MESON_SKIP_TEST: test is only for MinGW') +endif + # Test that MinGW/GCC creates correctly-named dll files and dll.a files, # and also installs them in the right place -if cc.get_id() != 'msvc' - shared_library('some', 'lib.c', - version : '1.2.3', - soversion : '0', - install : true) +shared_library('some', 'lib.c', + version : '1.2.3', + soversion : '0', + install : true) - shared_library('noversion', 'lib.c', - install : true) -else - install_data('no-installed-files', install_dir : '') -endif +shared_library('noversion', 'lib.c', + install : true) diff --git a/test cases/windows/7 mingw dll versioning/no-installed-files b/test cases/windows/7 mingw dll versioning/no-installed-files deleted file mode 100644 index e69de29bb..000000000 diff --git a/test cases/windows/8 msvc dll versioning/meson.build b/test cases/windows/8 msvc dll versioning/meson.build index 0c361735b..d6aecb60a 100644 --- a/test cases/windows/8 msvc dll versioning/meson.build +++ b/test cases/windows/8 msvc dll versioning/meson.build @@ -2,15 +2,15 @@ project('msvc dll versioning', 'c') cc = meson.get_compiler('c') +if cc.get_id() != 'msvc' + error('MESON_SKIP_TEST: test is only for msvc') +endif + # Test that MSVC creates foo-0.dll and bar.dll -if cc.get_id() == 'msvc' - shared_library('some', 'lib.c', - version : '1.2.3', - soversion : '0', - install : true) +shared_library('some', 'lib.c', + version : '1.2.3', + soversion : '0', + install : true) - shared_library('noversion', 'lib.c', - install : true) -else - install_data('no-installed-files', install_dir : '') -endif +shared_library('noversion', 'lib.c', + install : true) diff --git a/test cases/windows/8 msvc dll versioning/no-installed-files b/test cases/windows/8 msvc dll versioning/no-installed-files deleted file mode 100644 index e69de29bb..000000000 From 731aca216e2e840e114b5ab934e78bd3f8a59e5f Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 12:52:39 +0530 Subject: [PATCH 09/16] icc: Fix C/C++ std options and add a unit test for them Compiler versions 15.0 and later actually ignore invalid values for the -std= option unless `-diag-error 10159` is passed, so we need to put that in the unit test. I have tested this with versions 14.0.3, 15.0.6, 16.0.4, and 17.0.1. Would be great if someone could test with 13.x.y --- mesonbuild/compilers.py | 37 +++++++------- run_unittests.py | 67 +++++++++++++++++++++++-- test cases/common/1 trivial/meson.build | 5 ++ test cases/common/2 cpp/meson.build | 6 +++ 4 files changed, 95 insertions(+), 20 deletions(-) diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 9e4e62277..bde829aaf 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -2448,9 +2448,12 @@ class IntelCCompiler(IntelCompiler, CCompiler): '3': ['-Wall', '-w3', '-diag-disable:remark', '-Wpedantic', '-Wextra', '-Wpch-messages']} def get_options(self): + c_stds = ['c89', 'c99'] + g_stds = ['gnu89', 'gnu99'] + if mesonlib.version_compare(self.version, '>=16.0.0'): + c_stds += ['c11'] opts = {'c_std': coredata.UserComboOption('c_std', 'C language standard to use', - ['none', 'c89', 'c99', - 'gnu89', 'gnu99'], + ['none'] + c_stds + g_stds, 'none')} return opts @@ -2469,6 +2472,7 @@ class IntelCCompiler(IntelCompiler, CCompiler): class IntelCPPCompiler(IntelCompiler, CPPCompiler): + def __init__(self, exelist, version, icc_type, is_cross, exe_wrap): CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) IntelCompiler.__init__(self, icc_type) @@ -2477,22 +2481,21 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler): '3': ['-Wall', '-w3', '-diag-disable:remark', '-Wpedantic', '-Wextra', '-Wpch-messages', '-Wnon-virtual-dtor']} def get_options(self): + c_stds = [] + g_stds = ['gnu++98'] + if mesonlib.version_compare(self.version, '>=15.0.0'): + c_stds += ['c++11', 'c++14'] + g_stds += ['gnu++11'] + if mesonlib.version_compare(self.version, '>=16.0.0'): + c_stds += ['c++17'] if mesonlib.version_compare(self.version, '>=17.0.0'): - opts = {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use', - ['none', 'c++11', 'c++0x', 'c++14', - 'gnu++98', 'gnu++11', 'gnu++0x', 'gnu++14'], - 'none'), - 'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl', - 'STL debug mode', - False)} - else: - opts = {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use', - ['none', 'c++03', 'c++11', 'c++0x', - 'gnu++98', 'gnu++03', 'gnu++11', 'gnu++0x'], - 'none'), - 'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl', - 'STL debug mode', - False)} + g_stds += ['gnu++14'] + opts = {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use', + ['none'] + c_stds + g_stds, + 'none'), + 'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl', + 'STL debug mode', + False)} return opts def get_option_compile_args(self, options): diff --git a/run_unittests.py b/run_unittests.py index 3e8d32b01..c7a809555 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -19,7 +19,7 @@ import re, json import tempfile from glob import glob import mesonbuild.environment -from mesonbuild.environment import detect_ninja +from mesonbuild.environment import detect_ninja, Environment from mesonbuild.dependencies import PkgConfigDependency def get_soname(fname): @@ -33,6 +33,12 @@ def get_soname(fname): return m.group(1) raise RuntimeError('Could not determine soname:\n\n' + raw_out) +def get_fake_options(): + import argparse + opts = argparse.Namespace() + opts.cross_file = None + return opts + class FakeEnvironment(object): def __init__(self): self.cross_info = None @@ -81,11 +87,13 @@ class LinuxlikeTests(unittest.TestCase): def _run(self, command): self.output += subprocess.check_output(command, env=os.environ.copy()) - def init(self, srcdir): + def init(self, srcdir, extra_args=None): + if extra_args is None: + extra_args = [] args = [srcdir, self.builddir, '--prefix', self.prefix, '--libdir', self.libdir] - self._run(self.meson_command + args) + self._run(self.meson_command + args + extra_args) self.privatedir = os.path.join(self.builddir, 'meson-private') def build(self): @@ -410,6 +418,59 @@ class LinuxlikeTests(unittest.TestCase): self.assertTrue('TEST_ENV is set' in vg_log) self.assertTrue('Memcheck' in vg_log) + def _test_stds_impl(self, testdir, compiler, p): + lang_std = p + '_std' + # Check that all the listed -std=xxx options for this compiler work + # just fine when used + for v in compiler.get_options()[lang_std].choices: + std_opt = '{}={}'.format(lang_std, v) + self.init(testdir, ['-D' + std_opt]) + cmd = self.get_compdb()[0]['command'] + if v != 'none': + cmd_std = "'-std={}'".format(v) + self.assertIn(cmd_std, cmd) + try: + self.build() + except: + print('{} was {!r}'.format(lang_std, v)) + raise + self.wipe() + # Check that an invalid std option in CFLAGS/CPPFLAGS fails + # Needed because by default ICC ignores invalid options + cmd_std = '-std=FAIL' + env_flags = p.upper() + 'FLAGS' + os.environ[env_flags] = cmd_std + self.init(testdir) + cmd = self.get_compdb()[0]['command'] + qcmd_std = "'{}'".format(cmd_std) + self.assertIn(qcmd_std, cmd) + with self.assertRaises(subprocess.CalledProcessError, + msg='{} should have failed'.format(qcmd_std)): + self.build() + + def test_compiler_c_stds(self): + ''' + Test that C stds specified for this compiler can all be used. Can't be + an ordinary test because it requires passing options to meson. + ''' + testdir = os.path.join(self.common_test_dir, '1 trivial') + env = Environment(testdir, self.builddir, self.meson_command, + get_fake_options(), []) + cc = env.detect_c_compiler(False) + self._test_stds_impl(testdir, cc, 'c') + + def test_compiler_cpp_stds(self): + ''' + Test that C++ stds specified for this compiler can all be used. Can't + be an ordinary test because it requires passing options to meson. + ''' + testdir = os.path.join(self.common_test_dir, '2 cpp') + env = Environment(testdir, self.builddir, self.meson_command, + get_fake_options(), []) + cpp = env.detect_cpp_compiler(False) + self._test_stds_impl(testdir, cpp, 'cpp') + + class RewriterTests(unittest.TestCase): def setUp(self): diff --git a/test cases/common/1 trivial/meson.build b/test cases/common/1 trivial/meson.build index 1f7b37564..a93de75da 100644 --- a/test cases/common/1 trivial/meson.build +++ b/test cases/common/1 trivial/meson.build @@ -6,6 +6,11 @@ project('trivial test', #this is a comment sources = 'trivial.c' +if meson.get_compiler('c').get_id() == 'intel' + # Error out if the -std=xxx option is incorrect + add_project_arguments('-diag-error', '10159', language : 'c') +endif + exe = executable('trivialprog', sources : sources) test('runtest', exe) # This is a comment diff --git a/test cases/common/2 cpp/meson.build b/test cases/common/2 cpp/meson.build index 9c6f71a17..639838212 100644 --- a/test cases/common/2 cpp/meson.build +++ b/test cases/common/2 cpp/meson.build @@ -1,3 +1,9 @@ project('c++ test', 'cpp') + +if meson.get_compiler('cpp').get_id() == 'intel' + # Error out if the -std=xxx option is incorrect + add_project_arguments('-diag-error', '10159', language : 'cpp') +endif + exe = executable('trivialprog', 'trivial.cc', extra_files : 'something.txt') test('runtest', exe) From 7f3aeb27e7e2e7f5f69234e78ea912830f7141ab Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 21:13:21 +0530 Subject: [PATCH 10/16] unit tests: Use assertIn() instead of assertTrue() assertIn() will print both the arguments on assertion fail, but assertTrue() will not, so that makes it easier to debug. --- run_unittests.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/run_unittests.py b/run_unittests.py index c7a809555..d1c192f04 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -178,7 +178,7 @@ class LinuxlikeTests(unittest.TestCase): testdir = os.path.join(self.common_test_dir, '3 static') self.init(testdir) compdb = self.get_compdb() - self.assertTrue('-fPIC' in compdb[0]['command']) + self.assertIn('-fPIC', compdb[0]['command']) # This is needed to increase the difference between build.ninja's # timestamp and coredata.dat's timestamp due to a Ninja bug. # https://github.com/ninja-build/ninja/issues/371 @@ -187,7 +187,7 @@ class LinuxlikeTests(unittest.TestCase): # Regenerate build self.build() compdb = self.get_compdb() - self.assertTrue('-fPIC' not in compdb[0]['command']) + self.assertNotIn('-fPIC', compdb[0]['command']) def test_pkgconfig_gen(self): ''' @@ -204,7 +204,7 @@ class LinuxlikeTests(unittest.TestCase): simple_dep = PkgConfigDependency('libfoo', env, kwargs) self.assertTrue(simple_dep.found()) self.assertEqual(simple_dep.get_version(), '1.0') - self.assertTrue('-lfoo' in simple_dep.get_link_args()) + self.assertIn('-lfoo', simple_dep.get_link_args()) def test_vala_c_warnings(self): ''' @@ -229,15 +229,15 @@ class LinuxlikeTests(unittest.TestCase): self.assertIsNotNone(vala_command) self.assertIsNotNone(c_command) # -w suppresses all warnings, should be there in Vala but not in C - self.assertTrue("'-w'" in vala_command) - self.assertFalse("'-w'" in c_command) + self.assertIn("'-w'", vala_command) + self.assertNotIn("'-w'", c_command) # -Wall enables all warnings, should be there in C but not in Vala - self.assertFalse("'-Wall'" in vala_command) - self.assertTrue("'-Wall'" in c_command) + self.assertNotIn("'-Wall'", vala_command) + self.assertIn("'-Wall'", c_command) # -Werror converts warnings to errors, should always be there since it's # injected by an unrelated piece of code and the project has werror=true - self.assertTrue("'-Werror'" in vala_command) - self.assertTrue("'-Werror'" in c_command) + self.assertIn("'-Werror'", vala_command) + self.assertIn("'-Werror'", c_command) def test_static_compile_order(self): ''' From 6b774982feae67d31e22b795bcf918843698072e Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 21:19:33 +0530 Subject: [PATCH 11/16] tests/common/94: Set the default C++ std to C++11 The Intel compiler does not support C++03, but does support C++11, so use that as the lowest-common-denominator for our tests. --- test cases/common/94 default options/meson.build | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test cases/common/94 default options/meson.build b/test cases/common/94 default options/meson.build index a718bcc5a..a9176e0a9 100644 --- a/test cases/common/94 default options/meson.build +++ b/test cases/common/94 default options/meson.build @@ -1,20 +1,20 @@ project('default options', 'cpp', 'c', default_options : [ 'buildtype=debugoptimized', - 'cpp_std=c++03', + 'cpp_std=c++11', 'cpp_eh=none', 'warning_level=3', ]) -cpp = meson.get_compiler('cpp') +cpp_id = meson.get_compiler('cpp').get_id() assert(get_option('buildtype') == 'debugoptimized', 'Build type default value wrong.') -if cpp.get_id() == 'msvc' +if cpp_id == 'msvc' cpp_eh = get_option('cpp_eh') assert(cpp_eh == 'none', 'MSVC eh value is "' + cpp_eh + '" instead of "none"') else cpp_std = get_option('cpp_std') - assert(cpp_std == 'c++03', 'C++ std value is "' + cpp_std + '" instead of c++03.') + assert(cpp_std == 'c++11', 'C++ std value is "' + cpp_std + '" instead of c++11.') endif w_level = get_option('warning_level') From 509bc30cddd9574b8aa544afaa772d8ad72596e0 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 29 Dec 2016 22:01:05 +0530 Subject: [PATCH 12/16] compilers: gnu++03 is not a valid Clang C++ standard It is not (no longer?) supported by Clang: error: invalid value 'gnu++03' in '-std=gnu++03' --- mesonbuild/compilers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index bde829aaf..40c58d6b6 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -2358,7 +2358,7 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler): def get_options(self): return {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use', ['none', 'c++03', 'c++11', 'c++14', 'c++1z', - 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++1z'], + 'gnu++11', 'gnu++14', 'gnu++1z'], 'none')} def get_option_compile_args(self, options): From e31d067fedb3508d933a22fb66491942cbe24003 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 30 Dec 2016 21:54:40 +0530 Subject: [PATCH 13/16] compilers.py: Use a common variable for warn args Makes it totally clear what extra args are added by each warning level. --- mesonbuild/compilers.py | 75 +++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 40c58d6b6..daae2b3c2 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -1683,9 +1683,10 @@ class GnuDCompiler(DCompiler): def __init__(self, exelist, version, is_cross): DCompiler.__init__(self, exelist, version, is_cross) self.id = 'gcc' - self.warn_args = {'1': ['-Wall', '-Wdeprecated'], - '2': ['-Wall', '-Wextra', '-Wdeprecated'], - '3': ['-Wall', '-Wextra', '-Wdeprecated', '-Wpedantic']} + default_warn_args = ['-Wall', '-Wdeprecated'] + self.warn_args = {'1': default_warn_args, + '2': default_warn_args + ['-Wextra'], + '3': default_warn_args + ['-Wextra', '-Wpedantic']} self.base_options = ['b_colorout', 'b_sanitize', 'b_staticpic'] def get_colorout_args(self, colortype): @@ -2152,9 +2153,10 @@ class GnuCCompiler(GnuCompiler, CCompiler): def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None, defines=None): CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper) GnuCompiler.__init__(self, gcc_type, defines) - self.warn_args = {'1': ['-Wall', '-Winvalid-pch'], - '2': ['-Wall', '-Wextra', '-Winvalid-pch'], - '3': ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch']} + default_warn_args = ['-Wall', '-Winvalid-pch'] + self.warn_args = {'1': default_warn_args, + '2': default_warn_args + ['-Wextra'], + '3': default_warn_args + ['-Wextra', '-Wpedantic']} def get_options(self): opts = {'c_std': coredata.UserComboOption('c_std', 'C language standard to use', @@ -2188,9 +2190,10 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler): def __init__(self, exelist, version, gcc_type, is_cross, exe_wrap, defines): CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) GnuCompiler.__init__(self, gcc_type, defines) - self.warn_args = {'1': ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'], - '2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'], - '3': ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']} + default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'] + self.warn_args = {'1': default_warn_args, + '2': default_warn_args + ['-Wextra'], + '3': default_warn_args + ['-Wextra', '-Wpedantic']} def get_options(self): opts = {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use', @@ -2235,9 +2238,10 @@ class GnuObjCCompiler(GnuCompiler, ObjCCompiler): # Not really correct, but GNU objc is only used on non-OSX non-win. File a bug # if this breaks your use case. GnuCompiler.__init__(self, GCC_STANDARD, defines) - self.warn_args = {'1': ['-Wall', '-Winvalid-pch'], - '2': ['-Wall', '-Wextra', '-Winvalid-pch'], - '3': ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch']} + default_warn_args = ['-Wall', '-Winvalid-pch'] + self.warn_args = {'1': default_warn_args, + '2': default_warn_args + ['-Wextra'], + '3': default_warn_args + ['-Wextra', '-Wpedantic']} class GnuObjCPPCompiler(GnuCompiler, ObjCPPCompiler): @@ -2246,9 +2250,10 @@ class GnuObjCPPCompiler(GnuCompiler, ObjCPPCompiler): # Not really correct, but GNU objc is only used on non-OSX non-win. File a bug # if this breaks your use case. GnuCompiler.__init__(self, GCC_STANDARD, defines) - self.warn_args = {'1': ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'], - '2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'], - '3': ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']} + default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'] + self.warn_args = {'1': default_warn_args, + '2': default_warn_args + ['-Wextra'], + '3': default_warn_args + ['-Wextra', '-Wpedantic']} def get_compiler_check_args(self): # -fpermissive allows non-conforming code to compile which is necessary @@ -2326,9 +2331,10 @@ class ClangCCompiler(ClangCompiler, CCompiler): def __init__(self, exelist, version, clang_type, is_cross, exe_wrapper=None): CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper) ClangCompiler.__init__(self, clang_type) - self.warn_args = {'1': ['-Wall', '-Winvalid-pch'], - '2': ['-Wall', '-Wextra', '-Winvalid-pch'], - '3': ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch']} + default_warn_args = ['-Wall', '-Winvalid-pch'] + self.warn_args = {'1': default_warn_args, + '2': default_warn_args + ['-Wextra'], + '3': default_warn_args + ['-Wextra', '-Wpedantic']} def get_options(self): return {'c_std': coredata.UserComboOption('c_std', 'C language standard to use', @@ -2351,9 +2357,10 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler): def __init__(self, exelist, version, cltype, is_cross, exe_wrapper=None): CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper) ClangCompiler.__init__(self, cltype) - self.warn_args = {'1': ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'], - '2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'], - '3': ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']} + default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'] + self.warn_args = {'1': default_warn_args, + '2': default_warn_args + ['-Wextra'], + '3': default_warn_args + ['-Wextra', '-Wpedantic']} def get_options(self): return {'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use', @@ -2384,9 +2391,7 @@ class ClangObjCPPCompiler(ClangCompiler, GnuObjCPPCompiler): self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage'] -# Only tested on linux for ICC 17.0.0 -# * object extraction does not compile (don't know) (25 object extraction fails) -# * ICC 17.0.0 does not support c++03 and g++03 (94 default options fails) +# Tested on linux for ICC 14.0.3, 15.0.6, 16.0.4, 17.0.1 class IntelCompiler: def __init__(self, icc_type): self.id = 'intel' @@ -2414,10 +2419,6 @@ class IntelCompiler: def get_pch_name(self, header_name): return os.path.split(header_name)[-1] + '.' + self.get_pch_suffix() - # Not required, but possible if backend should create pch files. However Intel does it automatically - # def gen_pch_args(self, header, source, pchname): - # return ['-pch_create', os.path.join(pchname, self.get_pch_name(header)), '-include', header, source]) - def split_shlib_to_parts(self, fname): return (os.path.split(fname)[0], fname) @@ -2433,7 +2434,7 @@ class IntelCompiler: return get_gcc_soname_args(gcc_type, prefix, shlib_name, suffix, path, soversion, is_shared_module) def get_std_shared_lib_link_args(self): - # Don't know how icc works on OSX + # FIXME: Don't know how icc works on OSX # if self.icc_type == ICC_OSX: # return ['-bundle'] return ['-shared'] @@ -2443,9 +2444,10 @@ class IntelCCompiler(IntelCompiler, CCompiler): def __init__(self, exelist, version, icc_type, is_cross, exe_wrapper=None): CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper) IntelCompiler.__init__(self, icc_type) - self.warn_args = {'1': ['-Wall', '-w3', '-diag-disable:remark', '-Wpch-messages'], - '2': ['-Wall', '-w3', '-diag-disable:remark', '-Wextra-tokens', '-Wpch-messages'], - '3': ['-Wall', '-w3', '-diag-disable:remark', '-Wpedantic', '-Wextra', '-Wpch-messages']} + default_warn_args = ['-Wall', '-w3', '-diag-disable:remark', '-Wpch-messages'] + self.warn_args = {'1': default_warn_args, + '2': default_warn_args + ['-Wextra'], + '3': default_warn_args + ['-Wextra', '-Wpedantic']} def get_options(self): c_stds = ['c89', 'c99'] @@ -2472,13 +2474,14 @@ class IntelCCompiler(IntelCompiler, CCompiler): class IntelCPPCompiler(IntelCompiler, CPPCompiler): - def __init__(self, exelist, version, icc_type, is_cross, exe_wrap): CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) IntelCompiler.__init__(self, icc_type) - self.warn_args = {'1': ['-Wall', '-w3', '-diag-disable:remark', '-Wpch-messages', '-Wnon-virtual-dtor'], - '2': ['-Wall', '-w3', '-diag-disable:remark', '-Wextra', '-Wpch-messages', '-Wnon-virtual-dtor'], - '3': ['-Wall', '-w3', '-diag-disable:remark', '-Wpedantic', '-Wextra', '-Wpch-messages', '-Wnon-virtual-dtor']} + default_warn_args = ['-Wall', '-w3', '-diag-disable:remark', + '-Wpch-messages', '-Wnon-virtual-dtor'] + self.warn_args = {'1': default_warn_args, + '2': default_warn_args + ['-Wextra'], + '3': default_warn_args + ['-Wextra', '-Wpedantic']} def get_options(self): c_stds = [] From 6e5c87e3803ae49c694d4663616365ab193a45c2 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 30 Dec 2016 22:00:52 +0530 Subject: [PATCH 14/16] icc: Always specify the language to use for PCH usage Without this, ICC sometimes gets confused and thinks that the included header is a C header instead of a C++ header. --- mesonbuild/compilers.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index daae2b3c2..b36f2854c 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -2396,6 +2396,7 @@ class IntelCompiler: def __init__(self, icc_type): self.id = 'intel' self.icc_type = icc_type + self.lang_header = 'none' self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage', 'b_colorout', 'b_ndebug', 'b_staticpic', 'b_lundef', 'b_asneeded'] # Assembly @@ -2414,7 +2415,8 @@ class IntelCompiler: return 'pchi' def get_pch_use_args(self, pch_dir, header): - return ['-pch', '-pch_dir', os.path.join(pch_dir), '-include', header] + return ['-pch', '-pch_dir', os.path.join(pch_dir), '-x', + self.lang_header, '-include', header, '-x', 'none'] def get_pch_name(self, header_name): return os.path.split(header_name)[-1] + '.' + self.get_pch_suffix() @@ -2444,6 +2446,7 @@ class IntelCCompiler(IntelCompiler, CCompiler): def __init__(self, exelist, version, icc_type, is_cross, exe_wrapper=None): CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper) IntelCompiler.__init__(self, icc_type) + self.lang_header = 'c-header' default_warn_args = ['-Wall', '-w3', '-diag-disable:remark', '-Wpch-messages'] self.warn_args = {'1': default_warn_args, '2': default_warn_args + ['-Wextra'], @@ -2477,6 +2480,7 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler): def __init__(self, exelist, version, icc_type, is_cross, exe_wrap): CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap) IntelCompiler.__init__(self, icc_type) + self.lang_header = 'c++-header' default_warn_args = ['-Wall', '-w3', '-diag-disable:remark', '-Wpch-messages', '-Wnon-virtual-dtor'] self.warn_args = {'1': default_warn_args, From 2589009d236442dfbaa7573343329baf5b1c3dd1 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Sat, 31 Dec 2016 00:48:34 +0530 Subject: [PATCH 15/16] ifort: Derive from IntelCompiler base class And fix the list of supported file suffixes, and use .f90 for all fortran tests since ifort, the Intel Fortran compiler ignores files ending with .f95, .f03, and .f08 --- mesonbuild/compilers.py | 16 +++++++++------- test cases/fortran/1 basic/meson.build | 2 +- .../fortran/1 basic/{simple.f95 => simple.f90} | 0 test cases/fortran/2 modules/meson.build | 2 +- .../fortran/2 modules/{prog.f95 => prog.f90} | 0 .../fortran/2 modules/{stuff.f95 => stuff.f90} | 0 .../fortran/5 static/{main.f95 => main.f90} | 0 test cases/fortran/5 static/meson.build | 4 ++-- .../{static_hello.f95 => static_hello.f90} | 0 .../6 dynamic/{dynamic.f95 => dynamic.f90} | 0 .../fortran/6 dynamic/{main.f95 => main.f90} | 0 test cases/fortran/6 dynamic/meson.build | 4 ++-- 12 files changed, 15 insertions(+), 13 deletions(-) rename test cases/fortran/1 basic/{simple.f95 => simple.f90} (100%) rename test cases/fortran/2 modules/{prog.f95 => prog.f90} (100%) rename test cases/fortran/2 modules/{stuff.f95 => stuff.f90} (100%) rename test cases/fortran/5 static/{main.f95 => main.f90} (100%) rename test cases/fortran/5 static/{static_hello.f95 => static_hello.f90} (100%) rename test cases/fortran/6 dynamic/{dynamic.f95 => dynamic.f90} (100%) rename test cases/fortran/6 dynamic/{main.f95 => main.f90} (100%) diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index b36f2854c..8212d012c 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -33,7 +33,9 @@ lib_suffixes = ('a', 'lib', 'dll', 'dylib', 'so') lang_suffixes = { 'c': ('c',), 'cpp': ('cpp', 'cc', 'cxx', 'c++', 'hh', 'hpp', 'ipp', 'hxx'), - 'fortran': ('f', 'f90', 'f95'), + # f90, f95, f03, f08 are for free-form fortran ('f90' recommended) + # f, for, ftn, fpp are for fixed-form fortran ('f' or 'for' recommended) + 'fortran': ('f90', 'f95', 'f03', 'f08', 'f', 'for', 'ftn', 'fpp'), 'd': ('d', 'di'), 'objc': ('m',), 'objcpp': ('mm',), @@ -2704,12 +2706,15 @@ class SunFortranCompiler(FortranCompiler): def get_module_outdir_args(self, path): return ['-moddir=' + path] -class IntelFortranCompiler(FortranCompiler): +class IntelFortranCompiler(IntelCompiler, FortranCompiler): std_warn_args = ['-warn', 'all'] def __init__(self, exelist, version, is_cross, exe_wrapper=None): - self.file_suffixes = ('f', 'f90') - super().__init__(exelist, version, is_cross, exe_wrapper=None) + self.file_suffixes = ('f90', 'f', 'for', 'ftn', 'fpp') + FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper) + # FIXME: Add support for OS X and Windows in detect_fortran_compiler so + # we are sent the type of compiler + IntelCompiler.__init__(self, ICC_STANDARD) self.id = 'intel' def get_module_outdir_args(self, path): @@ -2771,9 +2776,6 @@ class NAGFortranCompiler(FortranCompiler): def get_module_outdir_args(self, path): return ['-mdir', path] - def get_always_args(self): - return [] - def get_warn_args(self, level): return NAGFortranCompiler.std_warn_args diff --git a/test cases/fortran/1 basic/meson.build b/test cases/fortran/1 basic/meson.build index 9c40951f3..833a17776 100644 --- a/test cases/fortran/1 basic/meson.build +++ b/test cases/fortran/1 basic/meson.build @@ -2,6 +2,6 @@ project('simple fortran', 'fortran') add_global_arguments('-fbounds-check', language : 'fortran') -e = executable('simple', 'simple.f95', +e = executable('simple', 'simple.f90', fortran_args : '-ffree-form') test('Simple Fortran', e) diff --git a/test cases/fortran/1 basic/simple.f95 b/test cases/fortran/1 basic/simple.f90 similarity index 100% rename from test cases/fortran/1 basic/simple.f95 rename to test cases/fortran/1 basic/simple.f90 diff --git a/test cases/fortran/2 modules/meson.build b/test cases/fortran/2 modules/meson.build index 0087c26ec..030f25598 100644 --- a/test cases/fortran/2 modules/meson.build +++ b/test cases/fortran/2 modules/meson.build @@ -1,4 +1,4 @@ project('modules', 'fortran') -e = executable('modprog', 'stuff.f95', 'prog.f95') +e = executable('modprog', 'stuff.f90', 'prog.f90') test('moduletest', e) diff --git a/test cases/fortran/2 modules/prog.f95 b/test cases/fortran/2 modules/prog.f90 similarity index 100% rename from test cases/fortran/2 modules/prog.f95 rename to test cases/fortran/2 modules/prog.f90 diff --git a/test cases/fortran/2 modules/stuff.f95 b/test cases/fortran/2 modules/stuff.f90 similarity index 100% rename from test cases/fortran/2 modules/stuff.f95 rename to test cases/fortran/2 modules/stuff.f90 diff --git a/test cases/fortran/5 static/main.f95 b/test cases/fortran/5 static/main.f90 similarity index 100% rename from test cases/fortran/5 static/main.f95 rename to test cases/fortran/5 static/main.f90 diff --git a/test cases/fortran/5 static/meson.build b/test cases/fortran/5 static/meson.build index d6f922b44..bd74a2990 100644 --- a/test cases/fortran/5 static/meson.build +++ b/test cases/fortran/5 static/meson.build @@ -1,5 +1,5 @@ project('try-static-library', 'fortran') -static_hello = static_library('static_hello', 'static_hello.f95') +static_hello = static_library('static_hello', 'static_hello.f90') -executable('test_exe', 'main.f95', link_with : static_hello) +executable('test_exe', 'main.f90', link_with : static_hello) diff --git a/test cases/fortran/5 static/static_hello.f95 b/test cases/fortran/5 static/static_hello.f90 similarity index 100% rename from test cases/fortran/5 static/static_hello.f95 rename to test cases/fortran/5 static/static_hello.f90 diff --git a/test cases/fortran/6 dynamic/dynamic.f95 b/test cases/fortran/6 dynamic/dynamic.f90 similarity index 100% rename from test cases/fortran/6 dynamic/dynamic.f95 rename to test cases/fortran/6 dynamic/dynamic.f90 diff --git a/test cases/fortran/6 dynamic/main.f95 b/test cases/fortran/6 dynamic/main.f90 similarity index 100% rename from test cases/fortran/6 dynamic/main.f95 rename to test cases/fortran/6 dynamic/main.f90 diff --git a/test cases/fortran/6 dynamic/meson.build b/test cases/fortran/6 dynamic/meson.build index 53edaf663..c791dac9f 100644 --- a/test cases/fortran/6 dynamic/meson.build +++ b/test cases/fortran/6 dynamic/meson.build @@ -1,4 +1,4 @@ project('dynamic_fortran', 'fortran') -dynamic = shared_library('dynamic', 'dynamic.f95') -executable('test_exe', 'main.f95', link_with : dynamic) +dynamic = shared_library('dynamic', 'dynamic.f90') +executable('test_exe', 'main.f90', link_with : dynamic) From a99732aaf2e84e2c08e976f05e98e2d7aa96c7d5 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Wed, 4 Jan 2017 00:42:06 +0530 Subject: [PATCH 16/16] Project tests: Also catch ValueError It seems on Windows, deleting in a loop can cause a race where the following error is raised: Traceback (most recent call last): File "run_project_tests.py", line 550, in (passing_tests, failing_tests, skipped_tests) = run_tests(all_tests, 'meson-test-run', options.extra_args) File "run_project_tests.py", line 416, in run_tests result = result.result() File "C:\python34-x64\lib\concurrent\futures\_base.py", line 402, in result return self.__get_result() File "C:\python34-x64\lib\concurrent\futures\_base.py", line 354, in __get_result raise self._exception ValueError: I/O operation on closed file. https://ci.appveyor.com/project/jpakkane/meson/build/1.0.1559/job/vsek754eu000kg3e --- run_project_tests.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/run_project_tests.py b/run_project_tests.py index c26b885e9..18988fb32 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -58,6 +58,11 @@ class AutoDeletedDir(): try: shutil.rmtree(self.dir) return + # Sometimes we get: ValueError: I/O operation on closed file. + except ValueError: + return + # Deleting can raise OSError or PermissionError on Windows + # (most likely because of anti-virus locking the file) except (OSError, PermissionError): if i == retries - 1: mlog.warning('Could not delete temporary directory.')