diff options
24 files changed, 130 insertions, 66 deletions
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 4495040..3b72631 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -96,7 +96,7 @@ jobs: find /opt/homebrew/Cellar/python* -name EXTERNALLY-MANAGED -print0 | xargs -0 rm -vf # use python3 from homebrew because it is a valid framework, unlike the actions one: # https://github.com/actions/setup-python/issues/58 - - run: brew install pkg-config ninja llvm qt@5 boost ldc hdf5 openmpi lapack scalapack sdl2 boost-python3 gtk-doc zstd ncurses objfw + - run: brew install pkg-config ninja llvm qt@5 boost ldc hdf5 openmpi lapack scalapack sdl2 boost-python3 gtk-doc zstd ncurses objfw libomp - run: | python3 -m pip install --upgrade setuptools python3 -m pip install --upgrade pip diff --git a/docs/markdown/Users.md b/docs/markdown/Users.md index 19c4ea6..70060ab 100644 --- a/docs/markdown/Users.md +++ b/docs/markdown/Users.md @@ -168,7 +168,7 @@ format files - [ThorVG](https://www.thorvg.org/), vector-based scenes and animations library - [Tilix](https://github.com/gnunn1/tilix), a tiling terminal emulator for Linux using GTK+ 3 - [Tizonia](https://github.com/tizonia/tizonia-openmax-il), a command-line cloud music player for Linux with support for Spotify, Google Play Music, YouTube, SoundCloud, TuneIn, Plex servers and Chromecast devices - - [Fossil Logic Standard](https://github.com/fossil-lib), a collection frameworks in C/C++, Objective-C and Objective-C++. + - [Fossil Logic](https://github.com/fossillogic), Fossil Logic is a cutting-edge software development company specializing in C/C++, Python, programming, Android development using Kotlin, and SQL solutions. - [UFJF-MLTK](https://github.com/mateus558/UFJF-Machine-Learning-Toolkit), A C++ cross-platform framework for machine learning algorithms development and testing - [Vala Language Server](https://github.com/benwaffle/vala-language-server), code intelligence engine for the Vala and Genie programming languages - [Valum](https://github.com/valum-framework/valum), a micro web framework written in Vala diff --git a/man/meson.1 b/man/meson.1 index 10a5eb9..182ac17 100644 --- a/man/meson.1 +++ b/man/meson.1 @@ -1,4 +1,4 @@ -.TH MESON "1" "March 2024" "meson 1.4.0" "User Commands" +.TH MESON "1" "June 2024" "meson 1.5.0" "User Commands" .SH NAME meson - a high productivity build system .SH DESCRIPTION diff --git a/mesonbuild/_typing.py b/mesonbuild/_typing.py index 05ff2b3..8336c46 100644 --- a/mesonbuild/_typing.py +++ b/mesonbuild/_typing.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2020 The Meson development team -# Copyright © 2020-2023 Intel Corporation +# Copyright © 2020-2024 Intel Corporation """Meson specific typing helpers. diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 8fda3a5..cbc1bea 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -10,6 +10,7 @@ from .. import options from .. import mlog from ..mesonlib import MesonException, version_compare from .c_function_attributes import C_FUNC_ATTRIBUTES +from .mixins.apple import AppleCompilerMixin from .mixins.clike import CLikeCompiler from .mixins.ccrx import CcrxCompiler from .mixins.xc16 import Xc16Compiler @@ -187,7 +188,7 @@ class ArmLtdClangCCompiler(ClangCCompiler): id = 'armltdclang' -class AppleClangCCompiler(ClangCCompiler): +class AppleClangCCompiler(AppleCompilerMixin, ClangCCompiler): """Handle the differences between Apple Clang and Vanilla Clang. diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index c03f1fd..08a596c 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2012-2022 The Meson development team -# Copyright © 2023 Intel Corporation +# Copyright © 2023-2024 Intel Corporation from __future__ import annotations @@ -936,11 +936,11 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): def thread_link_flags(self, env: 'Environment') -> T.List[str]: return self.linker.thread_flags(env) - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: raise EnvironmentException('Language %s does not support OpenMP flags.' % self.get_display_language()) - def openmp_link_flags(self) -> T.List[str]: - return self.openmp_flags() + def openmp_link_flags(self, env: Environment) -> T.List[str]: + return self.openmp_flags(env) def language_stdlib_only_link_flags(self, env: 'Environment') -> T.List[str]: return [] diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 9467a35..5e8947b 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -19,6 +19,7 @@ from .compilers import ( CompileCheckMode, ) from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES +from .mixins.apple import AppleCompilerMixin from .mixins.clike import CLikeCompiler from .mixins.ccrx import CcrxCompiler from .mixins.ti import TICompiler @@ -337,7 +338,7 @@ class ArmLtdClangCPPCompiler(ClangCPPCompiler): id = 'armltdclang' -class AppleClangCPPCompiler(ClangCPPCompiler): +class AppleClangCPPCompiler(AppleCompilerMixin, ClangCPPCompiler): _CPP23_VERSION = '>=13.0.0' # TODO: We don't know which XCode version will include LLVM 17 yet, so diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index ad266e9..3e33238 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -256,7 +256,7 @@ class SunFortranCompiler(FortranCompiler): def get_module_outdir_args(self, path: str) -> T.List[str]: return ['-moddir=' + path] - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: return ['-xopenmp'] @@ -381,7 +381,7 @@ class PathScaleFortranCompiler(FortranCompiler): '3': default_warn_args, 'everything': default_warn_args} - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: return ['-mp'] @@ -482,7 +482,7 @@ class Open64FortranCompiler(FortranCompiler): '3': default_warn_args, 'everything': default_warn_args} - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: return ['-mp'] @@ -525,5 +525,5 @@ class NAGFortranCompiler(FortranCompiler): def get_std_exe_link_args(self) -> T.List[str]: return self.get_always_args() - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: return ['-openmp'] diff --git a/mesonbuild/compilers/mixins/apple.py b/mesonbuild/compilers/mixins/apple.py new file mode 100644 index 0000000..98c4bfa --- /dev/null +++ b/mesonbuild/compilers/mixins/apple.py @@ -0,0 +1,57 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright © 2024 Intel Corporation + +"""Provides mixins for Apple compilers.""" + +from __future__ import annotations +import typing as T + +from ...mesonlib import MesonException + +if T.TYPE_CHECKING: + from ..._typing import ImmutableListProtocol + from ...environment import Environment + from ..compilers import Compiler +else: + # This is a bit clever, for mypy we pretend that these mixins descend from + # Compiler, so we get all of the methods and attributes defined for us, but + # for runtime we make them descend from object (which all classes normally + # do). This gives up DRYer type checking, with no runtime impact + Compiler = object + + +class AppleCompilerMixin(Compiler): + + """Handle differences between Vanilla Clang and the Clang shipped with XCode.""" + + __BASE_OMP_FLAGS: ImmutableListProtocol[str] = ['-Xpreprocessor', '-fopenmp'] + + def openmp_flags(self, env: Environment) -> T.List[str]: + """Flags required to compile with OpenMP on Apple. + + The Apple Clang Compiler doesn't have builtin support for OpenMP, it + must be provided separately. As such, we need to add the -Xpreprocessor + argument so that an external OpenMP can be found. + + :return: A list of arguments + """ + m = env.machines[self.for_machine] + assert m is not None, 'for mypy' + if m.cpu_family.startswith('x86'): + root = '/usr/local' + else: + root = '/opt/homebrew' + return self.__BASE_OMP_FLAGS + [f'-I{root}/opt/libomp/include'] + + def openmp_link_flags(self, env: Environment) -> T.List[str]: + m = env.machines[self.for_machine] + assert m is not None, 'for mypy' + if m.cpu_family.startswith('x86'): + root = '/usr/local' + else: + root = '/opt/homebrew' + + link = self.find_library('omp', env, [f'{root}/opt/libomp/lib']) + if not link: + raise MesonException("Couldn't find libomp") + return self.__BASE_OMP_FLAGS + link diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py index e9e83f2..a799e06 100644 --- a/mesonbuild/compilers/mixins/clang.py +++ b/mesonbuild/compilers/mixins/clang.py @@ -123,7 +123,7 @@ class ClangCompiler(GnuLikeCompiler): return super().has_function(funcname, prefix, env, extra_args=extra_args, dependencies=dependencies) - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: if mesonlib.version_compare(self.version, '>=3.8.0'): return ['-fopenmp'] elif mesonlib.version_compare(self.version, '>=3.7.0'): diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py index 10df3de..71cf722 100644 --- a/mesonbuild/compilers/mixins/elbrus.py +++ b/mesonbuild/compilers/mixins/elbrus.py @@ -1,5 +1,5 @@ # SPDX-License-Identifier: Apache-2.0 -# Copyright © 2023 Intel Corporation +# Copyright © 2023-2024 Intel Corporation from __future__ import annotations @@ -89,5 +89,5 @@ class ElbrusCompiler(GnuLikeCompiler): args.append('-std=' + std) return args - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: return ['-fopenmp'] diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py index 587b0cc..4a9eb88 100644 --- a/mesonbuild/compilers/mixins/gnu.py +++ b/mesonbuild/compilers/mixins/gnu.py @@ -402,7 +402,7 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta): return gnulike_default_include_dirs(tuple(self.get_exelist(ccache=False)), self.language).copy() @abc.abstractmethod - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: pass def gnu_symbol_visibility_args(self, vistype: str) -> T.List[str]: @@ -585,7 +585,7 @@ class GnuCompiler(GnuLikeCompiler): def get_pch_suffix(self) -> str: return 'gch' - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: return ['-fopenmp'] def has_arguments(self, args: T.List[str], env: 'Environment', code: str, diff --git a/mesonbuild/compilers/mixins/intel.py b/mesonbuild/compilers/mixins/intel.py index d38a42e..902cc74 100644 --- a/mesonbuild/compilers/mixins/intel.py +++ b/mesonbuild/compilers/mixins/intel.py @@ -19,6 +19,9 @@ from ..compilers import CompileCheckMode from .gnu import GnuLikeCompiler from .visualstudio import VisualStudioLikeCompiler +if T.TYPE_CHECKING: + from ...environment import Environment + # XXX: avoid circular dependencies # TODO: this belongs in a posix compiler class # NOTE: the default Intel optimization is -O2, unlike GNU which defaults to -O0. @@ -78,7 +81,7 @@ class IntelGnuLikeCompiler(GnuLikeCompiler): def get_pch_name(self, name: str) -> str: return os.path.basename(name) + '.' + self.get_pch_suffix() - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: if mesonlib.version_compare(self.version, '>=15.0.0'): return ['-qopenmp'] else: @@ -154,7 +157,7 @@ class IntelVisualStudioLikeCompiler(VisualStudioLikeCompiler): version = int(v1 + v2) return self._calculate_toolset_version(version) - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: return ['/Qopenmp'] def get_debug_args(self, is_debug: bool) -> T.List[str]: diff --git a/mesonbuild/compilers/mixins/pgi.py b/mesonbuild/compilers/mixins/pgi.py index 0d8245a..71ad81f 100644 --- a/mesonbuild/compilers/mixins/pgi.py +++ b/mesonbuild/compilers/mixins/pgi.py @@ -51,7 +51,7 @@ class PGICompiler(Compiler): return ['-fPIC'] return [] - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: return ['-mp'] def get_optimization_args(self, optimization_level: str) -> T.List[str]: diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py index 4e2ce09..907ea07 100644 --- a/mesonbuild/compilers/mixins/visualstudio.py +++ b/mesonbuild/compilers/mixins/visualstudio.py @@ -204,10 +204,10 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): objname = os.path.splitext(source)[0] + '.obj' return objname, ['/Yc' + header, '/Fp' + pchname, '/Fo' + objname] - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: return ['/openmp'] - def openmp_link_flags(self) -> T.List[str]: + def openmp_link_flags(self, env: Environment) -> T.List[str]: return [] # FIXME, no idea what these should be. @@ -483,3 +483,10 @@ class ClangClCompiler(VisualStudioLikeCompiler): return converted else: return dep.get_compile_args() + + def openmp_link_flags(self, env: Environment) -> T.List[str]: + # see https://github.com/mesonbuild/meson/issues/5298 + libs = self.find_library('libomp', env, []) + if libs is None: + raise mesonlib.MesonBugException('Could not find libomp') + return super().openmp_link_flags(env) + libs diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 36191d9..7fb3bca 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -72,7 +72,7 @@ if T.TYPE_CHECKING: # # Pip requires that RCs are named like this: '0.1.0.rc1' # But the corresponding Git tag needs to be '0.1.0rc1' -version = '1.4.99' +version = '1.5.0.rc1' # The next stable version when we are in dev. This is used to allow projects to # require meson version >=1.2.0 when using 1.1.99. FeatureNew won't warn when diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 72c7cf0..4011c60 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -95,50 +95,47 @@ class OpenMPDependency(SystemDependency): # No macro defined for OpenMP, but OpenMP 3.1 is supported. self.version = '3.1' self.is_found = True - self.compile_args = self.link_args = self.clib_compiler.openmp_flags() + self.compile_args = self.link_args = self.clib_compiler.openmp_flags(environment) return if self.clib_compiler.get_id() == 'pgi': # through at least PGI 19.4, there is no macro defined for OpenMP, but OpenMP 3.1 is supported. self.version = '3.1' self.is_found = True - self.compile_args = self.link_args = self.clib_compiler.openmp_flags() + self.compile_args = self.link_args = self.clib_compiler.openmp_flags(environment) + return + + # Set these now so they're available for the following compiler checks + try: + self.compile_args.extend(self.clib_compiler.openmp_flags(environment)) + self.link_args.extend(self.clib_compiler.openmp_link_flags(environment)) + except mesonlib.MesonException as e: + mlog.warning('OpenMP support not available because:', str(e), fatal=False) return try: openmp_date = self.clib_compiler.get_define( - '_OPENMP', '', self.env, self.clib_compiler.openmp_flags(), [self], disable_cache=True)[0] + '_OPENMP', '', self.env, [], [self], disable_cache=True)[0] except mesonlib.EnvironmentException as e: mlog.debug('OpenMP support not available in the compiler') mlog.debug(e) - openmp_date = None - - if openmp_date: - try: - self.version = self.VERSIONS[openmp_date] - except KeyError: - mlog.debug(f'Could not find an OpenMP version matching {openmp_date}') - if openmp_date == '_OPENMP': - mlog.debug('This can be caused by flags such as gcc\'s `-fdirectives-only`, which affect preprocessor behavior.') - return + return - if self.clib_compiler.get_id() == 'clang-cl': - # this is necessary for clang-cl, see https://github.com/mesonbuild/meson/issues/5298 - clangcl_openmp_link_args = self.clib_compiler.find_library("libomp", self.env, []) - if not clangcl_openmp_link_args: - mlog.log(mlog.yellow('WARNING:'), 'OpenMP found but libomp for clang-cl missing.') - return - self.link_args.extend(clangcl_openmp_link_args) - - # Flang has omp_lib.h - header_names = ('omp.h', 'omp_lib.h') - for name in header_names: - if self.clib_compiler.has_header(name, '', self.env, dependencies=[self], disable_cache=True)[0]: - self.is_found = True - self.compile_args.extend(self.clib_compiler.openmp_flags()) - self.link_args.extend(self.clib_compiler.openmp_link_flags()) - break - if not self.is_found: - mlog.log(mlog.yellow('WARNING:'), 'OpenMP found but omp.h missing.') + try: + self.version = self.VERSIONS[openmp_date] + except KeyError: + mlog.debug(f'Could not find an OpenMP version matching {openmp_date}') + if openmp_date == '_OPENMP': + mlog.debug('This can be caused by flags such as gcc\'s `-fdirectives-only`, which affect preprocessor behavior.') + return + + # Flang has omp_lib.h + header_names = ('omp.h', 'omp_lib.h') + for name in header_names: + if self.clib_compiler.has_header(name, '', self.env, dependencies=[self], disable_cache=True)[0]: + self.is_found = True + break + else: + mlog.warning('OpenMP found but omp.h missing.', fatal=False) packages['openmp'] = OpenMPDependency diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index 7507f5a..f5e8080 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -62,7 +62,7 @@ class StaticLinker: def thread_link_flags(self, env: 'Environment') -> T.List[str]: return [] - def openmp_flags(self) -> T.List[str]: + def openmp_flags(self, env: Environment) -> T.List[str]: return [] def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: diff --git a/mesonbuild/mformat.py b/mesonbuild/mformat.py index e20e458..42f562e 100644 --- a/mesonbuild/mformat.py +++ b/mesonbuild/mformat.py @@ -744,7 +744,7 @@ class ComputeLineLengths(FullAstVisitor): self.exit_node(node) def split_if_needed(self, node: mparser.ArgumentNode) -> None: - if not node.is_multiline and self.length > self.config.max_line_length: + if len(node) and not node.is_multiline and self.length > self.config.max_line_length: arg = self.argument_stack[self.level] if len(self.argument_stack) > self.level else node if not arg.is_multiline: arg.is_multiline = True diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py index ec08ccf..50d7203 100644 --- a/mesonbuild/mparser.py +++ b/mesonbuild/mparser.py @@ -377,7 +377,7 @@ class ArgumentNode(BaseNode): return self.order_error def __len__(self) -> int: - return self.num_args() # Fixme + return self.num_args() + self.num_kwargs() @dataclass(unsafe_hash=True) class ArrayNode(BaseNode): diff --git a/mesonbuild/scripts/depfixer.py b/mesonbuild/scripts/depfixer.py index 71599f7..f0166bd 100644 --- a/mesonbuild/scripts/depfixer.py +++ b/mesonbuild/scripts/depfixer.py @@ -406,7 +406,7 @@ def fix_darwin(fname: str, rpath_dirs_to_remove: T.Set[bytes], new_rpath: str, f return new_rpaths: OrderedSet[str] = OrderedSet() if new_rpath: - new_rpaths.update(new_rpath) + new_rpaths.update(new_rpath.split(':')) # filter out build-only rpath entries, like in # fix_rpathtype_entry remove_rpaths = [x.decode('utf8') for x in rpath_dirs_to_remove] diff --git a/test cases/common/184 openmp/meson.build b/test cases/common/184 openmp/meson.build index 4cbe806..ab09b2c 100644 --- a/test cases/common/184 openmp/meson.build +++ b/test cases/common/184 openmp/meson.build @@ -16,9 +16,6 @@ endif if cc.get_id() == 'clang' and host_machine.system() == 'windows' error('MESON_SKIP_TEST Windows clang does not support OpenMP.') endif -if host_machine.system() == 'darwin' - error('MESON_SKIP_TEST macOS does not support OpenMP.') -endif openmp = dependency('openmp') env = environment() diff --git a/test cases/format/1 default/gh13242.meson b/test cases/format/1 default/gh13242.meson index b9122ec..67f7dd1 100644 --- a/test cases/format/1 default/gh13242.meson +++ b/test cases/format/1 default/gh13242.meson @@ -10,9 +10,7 @@ test( ) test( - should_fail: (settings.get('x', false) and not settings['y'] and dep.version( - - ).version_compare( + should_fail: (settings.get('x', false) and not settings['y'] and dep.version().version_compare( '>=1.2.3', )), ) diff --git a/test cases/format/1 default/meson.build b/test cases/format/1 default/meson.build index 35e5b96..83ae19a 100644 --- a/test cases/format/1 default/meson.build +++ b/test cases/format/1 default/meson.build @@ -10,6 +10,9 @@ meson_files = { 'gh13242': files('gh13242.meson'), } +# Ensure empty function are formatted correctly on long lines +a = '@0@@1@@2@@3@@4@'.format('one', 'two', 'three', 'four', 'five').strip().strip() + foreach name, f : meson_files test(name, meson_cmd, args: ['format', '--check-only', f]) endforeach |