diff options
-rw-r--r-- | docs/markdown/FAQ.md | 34 | ||||
-rw-r--r-- | mesonbuild/build.py | 4 | ||||
-rw-r--r-- | mesonbuild/compilers/cpp.py | 1 | ||||
-rw-r--r-- | mesonbuild/coredata.py | 2 | ||||
-rw-r--r-- | mesonbuild/dependencies/base.py | 5 | ||||
-rw-r--r-- | mesonbuild/dependencies/platform.py | 13 | ||||
-rw-r--r-- | mesonbuild/envconfig.py | 4 | ||||
-rw-r--r-- | mesonbuild/environment.py | 15 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 1 | ||||
-rw-r--r-- | mesonbuild/mesonlib.py | 10 | ||||
-rw-r--r-- | mesonbuild/mintro.py | 2 | ||||
-rw-r--r-- | mesonbuild/mtest.py | 2 | ||||
-rwxr-xr-x | run_unittests.py | 32 | ||||
-rw-r--r-- | test cases/objc/2 nsstring/meson.build | 3 | ||||
-rw-r--r-- | test cases/unit/4 suite selection/meson.build | 4 | ||||
-rw-r--r-- | test cases/unit/4 suite selection/subprojects/subprjfail/meson.build | 4 | ||||
-rw-r--r-- | test cases/unit/4 suite selection/subprojects/subprjsucc/meson.build | 4 |
17 files changed, 99 insertions, 41 deletions
diff --git a/docs/markdown/FAQ.md b/docs/markdown/FAQ.md index ff93216..0208c1a 100644 --- a/docs/markdown/FAQ.md +++ b/docs/markdown/FAQ.md @@ -331,3 +331,37 @@ that could fullfill these requirements: Out of these we have chosen Python because it is the best fit for our needs. + +## I have proprietary compiler toolchain X that does not work with Meson, how can I make it work? + +Meson needs to know several details about each compiler in order to +compile code with it. These include things such as which compiler +flags to use for each option and how to detect the compiler from its +output. This information can not be input via a configuration file, +instead it requires changes to Meson's source code that need to be +submitted to Meson master repository. In theory you can run your own +forked version with custom patches, but that's not good use of your +time. Please submit the code upstream so everyone can use the +toolchain. + +The steps for adding a new compiler for an existing language are +roughly the following. For simplicity we're going to assume a C +compiler. + +- Create a new class with a proper name in + `mesonbuild/compilers/c.py`. Look at the methods that other + compilers for the same language have and duplicate what they do. + +- If the compiler can only be used for cross compilation, make sure to + flag it as such (see existing compiler classes for examples). + +- Add detection logic to `mesonbuild/environment.py`, look for a + method called `detect_c_compiler`. + +- Run the test suite and fix issues until the tests pass. + +- Submit a pull request, add the result of the test suite to your MR + (linking an existing page is fine). + +- If the compiler is freely available, consider adding it to the CI + system. diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 190ef15..1fad9e0 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -28,7 +28,7 @@ from .mesonlib import ( get_filenames_templates_dict, substitute_values, for_windows, for_darwin, for_cygwin, for_android, has_path_sep ) -from .compilers import is_object, clink_langs, sort_clink, lang_suffixes, get_macos_dylib_install_name +from .compilers import Compiler, is_object, clink_langs, sort_clink, lang_suffixes, get_macos_dylib_install_name from .interpreterbase import FeatureNew pch_kwargs = set(['c_pch', 'cpp_pch']) @@ -450,7 +450,7 @@ class BuildTarget(Target): self.is_unity = unity_opt == 'on' or (unity_opt == 'subprojects' and subproject != '') self.environment = environment self.sources = [] - self.compilers = OrderedDict() + self.compilers = OrderedDict() # type: OrderedDict[str, Compiler] self.objects = [] self.external_deps = [] self.include_dirs = [] diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 7c2253d..2b2c4a0 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -23,7 +23,6 @@ from .c import CCompiler, VisualStudioCCompiler, ClangClCCompiler, IntelClCCompi from .compilers import ( gnu_winlibs, msvc_winlibs, - CompilerType, ClangCompiler, GnuCompiler, ElbrusCompiler, diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 9281019..b836086 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -20,7 +20,7 @@ from pathlib import PurePath from collections import OrderedDict from .mesonlib import ( MesonException, MachineChoice, PerMachine, - default_libdir, default_libexecdir, default_prefix, stringlistify + default_libdir, default_libexecdir, default_prefix ) from .wrap import WrapMode import ast diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index 6063fd3..1a60a16 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -14,7 +14,6 @@ # This file contains the detection logic for external dependencies. # Custom logic for several other packages are in separate files. -from typing import Dict, Any import copy import functools import os @@ -26,7 +25,7 @@ import textwrap import platform import itertools import ctypes -from typing import List, Tuple +from typing import Any, Dict, List, Tuple from enum import Enum from pathlib import Path, PurePath @@ -2302,7 +2301,7 @@ class ExtraFrameworkDependency(ExternalDependency): return 'framework' -def get_dep_identifier(name, kwargs, want_cross): +def get_dep_identifier(name, kwargs, want_cross: bool) -> Tuple: identifier = (name, want_cross) for key, value in kwargs.items(): # 'version' is irrelevant for caching; the caller must check version matches diff --git a/mesonbuild/dependencies/platform.py b/mesonbuild/dependencies/platform.py index 9863fb1..e913ed4 100644 --- a/mesonbuild/dependencies/platform.py +++ b/mesonbuild/dependencies/platform.py @@ -16,7 +16,7 @@ # platform-specific (generally speaking). from .base import ExternalDependency, DependencyException - +from ..mesonlib import MesonException class AppleFrameworks(ExternalDependency): def __init__(self, env, kwargs): @@ -31,7 +31,16 @@ class AppleFrameworks(ExternalDependency): raise DependencyException('No C-like compilers are available, cannot find the framework') self.is_found = True for f in self.frameworks: - args = self.clib_compiler.find_framework(f, env, []) + try: + args = self.clib_compiler.find_framework(f, env, []) + except MesonException as e: + if 'non-clang' in str(e): + self.is_found = False + self.link_args = [] + self.compile_args = [] + return + raise + if args is not None: # No compile args are needed for system frameworks self.link_args += args diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index f4c371f..977d930 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -255,7 +255,7 @@ class MachineInfo: def libdir_layout_is_win(self) -> bool: return self.is_windows() or self.is_cygwin() -class PerMachineDefaultable(PerMachine[_T]): +class PerMachineDefaultable(PerMachine[typing.Optional[_T]]): """Extends `PerMachine` with the ability to default from `None`s. """ def __init__(self) -> None: @@ -285,7 +285,7 @@ class PerMachineDefaultable(PerMachine[_T]): if self.host == self.build: self.host = None -class MachineInfos(PerMachineDefaultable[typing.Optional[MachineInfo]]): +class MachineInfos(PerMachineDefaultable[MachineInfo]): def matches_build_machine(self, machine: MachineChoice) -> bool: return self.build == self[machine] diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index bf2cce9..462672e 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os, platform, re, sys, shlex, shutil, subprocess +import os, platform, re, sys, shlex, shutil, subprocess, typing from . import coredata from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker, CcrxLinker @@ -28,6 +28,7 @@ from .envconfig import ( ) from . import compilers from .compilers import ( + Compiler, CompilerType, is_assembly, is_header, @@ -83,6 +84,8 @@ from .compilers import ( build_filename = 'meson.build' +CompilersDict = typing.Dict[str, Compiler] + def detect_gcovr(min_version='3.3', new_rootdir_version='4.2', log=False): gcovr_exe = 'gcovr' try: @@ -150,7 +153,7 @@ def detect_native_windows_arch(): raise EnvironmentException('Unable to detect native OS architecture') return arch -def detect_windows_arch(compilers): +def detect_windows_arch(compilers: CompilersDict) -> str: """ Detecting the 'native' architecture of Windows is not a trivial task. We cannot trust that the architecture that Python is built for is the 'native' @@ -190,7 +193,7 @@ def detect_windows_arch(compilers): return 'x86' return os_arch -def any_compiler_has_define(compilers, define): +def any_compiler_has_define(compilers: CompilersDict, define): for c in compilers.values(): try: if c.has_builtin_define(define): @@ -200,7 +203,7 @@ def any_compiler_has_define(compilers, define): pass return False -def detect_cpu_family(compilers): +def detect_cpu_family(compilers: CompilersDict) -> str: """ Python is inconsistent in its platform module. It returns different values for the same cpu. @@ -262,7 +265,7 @@ def detect_cpu_family(compilers): return trial -def detect_cpu(compilers): +def detect_cpu(compilers: CompilersDict): if mesonlib.is_windows(): trial = detect_windows_arch(compilers) else: @@ -295,7 +298,7 @@ def detect_msys2_arch(): return os.environ['MSYSTEM_CARCH'] return None -def detect_machine_info(compilers = None) -> MachineInfo: +def detect_machine_info(compilers: typing.Optional[CompilersDict] = None) -> MachineInfo: """Detect the machine we're running on If compilers are not provided, we cannot know as much. None out those diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 8ca7758..a3505a4 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -2996,6 +2996,7 @@ external dependencies (including libraries) must go to "dependencies".''') self._handle_featurenew_dependencies(name) kwargs['required'] = required and not has_fallback dep = dependencies.find_external_dependency(name, self.environment, kwargs) + kwargs['required'] = required # Only store found-deps in the cache # Never add fallback deps to self.coredata.deps since we diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 7219946..1e776e4 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -323,22 +323,20 @@ class MachineChoice(OrderedEnum): HOST = 1 TARGET = 2 -_T = typing.TypeVar('_T') - class PerMachine(typing.Generic[_T]): - def __init__(self, build: typing.Optional[_T], host: typing.Optional[_T], target: typing.Optional[_T]): + def __init__(self, build: _T, host: _T, target: _T): self.build = build self.host = host self.target = target - def __getitem__(self, machine: MachineChoice) -> typing.Optional[_T]: + def __getitem__(self, machine: MachineChoice) -> _T: return { MachineChoice.BUILD: self.build, MachineChoice.HOST: self.host, MachineChoice.TARGET: self.target }[machine] - def __setitem__(self, machine: MachineChoice, val: typing.Optional[_T]) -> None: + def __setitem__(self, machine: MachineChoice, val: _T) -> None: key = { MachineChoice.BUILD: 'build', MachineChoice.HOST: 'host', @@ -968,7 +966,7 @@ def Popen_safe(args, write=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, return p, o, e def Popen_safe_legacy(args, write=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs): - p = subprocess.Popen(args, universal_newlines=False, + p = subprocess.Popen(args, universal_newlines=False, close_fds=False, stdout=stdout, stderr=stderr, **kwargs) if write is not None: write = write.encode('utf-8') diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index a4a6978..c47fffd 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -27,7 +27,7 @@ from . import mlog from .backend import backends from .mparser import FunctionNode, ArrayNode, ArgumentNode, StringNode from typing import List, Optional -import sys, os +import os import pathlib def get_meson_info_file(info_dir: str): diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index 17af4df..8df8f48 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -873,7 +873,7 @@ Timeout: %4d return wrap def get_pretty_suite(self, test): - if len(self.suites) > 1: + if len(self.suites) > 1 and test.suite: rv = TestHarness.split_suite_string(test.suite[0])[0] s = "+".join(TestHarness.split_suite_string(s)[1] for s in test.suite) if len(s): diff --git a/run_unittests.py b/run_unittests.py index 2457a50..110782b 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -1813,48 +1813,48 @@ class AllPlatformTests(BasePlatformTests): self.init(testdir) self.build() - self.assertFailedTestCount(3, self.mtest_command) + self.assertFailedTestCount(4, self.mtest_command) self.assertFailedTestCount(0, self.mtest_command + ['--suite', ':success']) self.assertFailedTestCount(3, self.mtest_command + ['--suite', ':fail']) - self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', ':success']) - self.assertFailedTestCount(0, self.mtest_command + ['--no-suite', ':fail']) + self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', ':success']) + self.assertFailedTestCount(1, self.mtest_command + ['--no-suite', ':fail']) self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'mainprj']) self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'subprjsucc']) self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'subprjfail']) self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'subprjmix']) - self.assertFailedTestCount(2, self.mtest_command + ['--no-suite', 'mainprj']) - self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjsucc']) - self.assertFailedTestCount(2, self.mtest_command + ['--no-suite', 'subprjfail']) - self.assertFailedTestCount(2, self.mtest_command + ['--no-suite', 'subprjmix']) + self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'mainprj']) + self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'subprjsucc']) + self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjfail']) + self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjmix']) self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'mainprj:fail']) self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'mainprj:success']) - self.assertFailedTestCount(2, self.mtest_command + ['--no-suite', 'mainprj:fail']) - self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'mainprj:success']) + self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'mainprj:fail']) + self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'mainprj:success']) self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'subprjfail:fail']) self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'subprjfail:success']) - self.assertFailedTestCount(2, self.mtest_command + ['--no-suite', 'subprjfail:fail']) - self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjfail:success']) + self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjfail:fail']) + self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'subprjfail:success']) self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'subprjsucc:fail']) self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'subprjsucc:success']) - self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjsucc:fail']) - self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjsucc:success']) + self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'subprjsucc:fail']) + self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'subprjsucc:success']) self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'subprjmix:fail']) self.assertFailedTestCount(0, self.mtest_command + ['--suite', 'subprjmix:success']) - self.assertFailedTestCount(2, self.mtest_command + ['--no-suite', 'subprjmix:fail']) - self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjmix:success']) + self.assertFailedTestCount(3, self.mtest_command + ['--no-suite', 'subprjmix:fail']) + self.assertFailedTestCount(4, self.mtest_command + ['--no-suite', 'subprjmix:success']) self.assertFailedTestCount(2, self.mtest_command + ['--suite', 'subprjfail', '--suite', 'subprjmix:fail']) self.assertFailedTestCount(3, self.mtest_command + ['--suite', 'subprjfail', '--suite', 'subprjmix', '--suite', 'mainprj']) self.assertFailedTestCount(2, self.mtest_command + ['--suite', 'subprjfail', '--suite', 'subprjmix', '--suite', 'mainprj', '--no-suite', 'subprjmix:fail']) self.assertFailedTestCount(1, self.mtest_command + ['--suite', 'subprjfail', '--suite', 'subprjmix', '--suite', 'mainprj', '--no-suite', 'subprjmix:fail', 'mainprj-failing_test']) - self.assertFailedTestCount(1, self.mtest_command + ['--no-suite', 'subprjfail:fail', '--no-suite', 'subprjmix:fail']) + self.assertFailedTestCount(2, self.mtest_command + ['--no-suite', 'subprjfail:fail', '--no-suite', 'subprjmix:fail']) def test_build_by_default(self): testdir = os.path.join(self.common_test_dir, '134 build by default') diff --git a/test cases/objc/2 nsstring/meson.build b/test cases/objc/2 nsstring/meson.build index 7f2483f..94d2cf1 100644 --- a/test cases/objc/2 nsstring/meson.build +++ b/test cases/objc/2 nsstring/meson.build @@ -15,3 +15,6 @@ else endif exe = executable('stringprog', 'stringprog.m', dependencies : dep) test('stringtest', exe) + +# Ensure that a non-required dep that is not found does not cause an error +dependency('appleframeworks', modules: 'nonexisting', required: false) diff --git a/test cases/unit/4 suite selection/meson.build b/test cases/unit/4 suite selection/meson.build index d3d4e1a..ea6db92 100644 --- a/test cases/unit/4 suite selection/meson.build +++ b/test cases/unit/4 suite selection/meson.build @@ -11,3 +11,7 @@ test('mainprj-failing_test', test('mainprj-successful_test', executable('successful_test', 'successful_test.c'), suite : 'success') + +test('mainprj-successful_test_no_suite', + executable('no_suite_test', 'successful_test.c'), + suite : []) diff --git a/test cases/unit/4 suite selection/subprojects/subprjfail/meson.build b/test cases/unit/4 suite selection/subprojects/subprjfail/meson.build index d95f271..e6270a8 100644 --- a/test cases/unit/4 suite selection/subprojects/subprjfail/meson.build +++ b/test cases/unit/4 suite selection/subprojects/subprjfail/meson.build @@ -3,3 +3,7 @@ project('subprjfail', 'c') test('subprjfail-failing_test', executable('failing_test', 'failing_test.c'), suite : 'fail') + +test('subprjfail-failing_test_no_suite', + executable('failing_test_no_suite', 'failing_test.c'), + suite : []) diff --git a/test cases/unit/4 suite selection/subprojects/subprjsucc/meson.build b/test cases/unit/4 suite selection/subprojects/subprjsucc/meson.build index 8dafd65..b5ffaa4 100644 --- a/test cases/unit/4 suite selection/subprojects/subprjsucc/meson.build +++ b/test cases/unit/4 suite selection/subprojects/subprjsucc/meson.build @@ -3,3 +3,7 @@ project('subprjsucc', 'c') test('subprjsucc-successful_test', executable('successful_test', 'successful_test.c'), suite : 'success') + +test('subprjsucc-successful_test_no_suite', + executable('successful_test_no_suite', 'successful_test.c'), + suite : []) |