aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/FAQ.md34
-rw-r--r--mesonbuild/build.py4
-rw-r--r--mesonbuild/compilers/cpp.py1
-rw-r--r--mesonbuild/coredata.py2
-rw-r--r--mesonbuild/dependencies/base.py5
-rw-r--r--mesonbuild/dependencies/platform.py13
-rw-r--r--mesonbuild/envconfig.py4
-rw-r--r--mesonbuild/environment.py15
-rw-r--r--mesonbuild/interpreter.py1
-rw-r--r--mesonbuild/mesonlib.py10
-rw-r--r--mesonbuild/mintro.py2
-rw-r--r--mesonbuild/mtest.py2
-rwxr-xr-xrun_unittests.py32
-rw-r--r--test cases/objc/2 nsstring/meson.build3
-rw-r--r--test cases/unit/4 suite selection/meson.build4
-rw-r--r--test cases/unit/4 suite selection/subprojects/subprjfail/meson.build4
-rw-r--r--test cases/unit/4 suite selection/subprojects/subprjsucc/meson.build4
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 : [])