aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Compiler-properties.md2
-rw-r--r--docs/markdown/Reference-tables.md2
-rw-r--r--docs/markdown/Users.md2
-rw-r--r--docs/markdown/snippets/config-tool-cross.md13
-rw-r--r--mesonbuild/backend/backends.py2
-rw-r--r--mesonbuild/backend/ninjabackend.py16
-rw-r--r--mesonbuild/backend/vs2010backend.py2
-rw-r--r--mesonbuild/backend/xcodebackend.py2
-rw-r--r--mesonbuild/build.py16
-rw-r--r--mesonbuild/compilers/c.py19
-rw-r--r--mesonbuild/compilers/compilers.py6
-rw-r--r--mesonbuild/compilers/cpp.py10
-rw-r--r--mesonbuild/compilers/fortran.py2
-rw-r--r--mesonbuild/dependencies/base.py15
-rw-r--r--mesonbuild/environment.py2
-rw-r--r--mesonbuild/interpreter.py10
-rw-r--r--mesonbuild/interpreterbase.py2
-rw-r--r--mesonbuild/mesonlib.py10
-rw-r--r--mesonbuild/mesonmain.py5
-rw-r--r--mesonbuild/mintro.py4
-rw-r--r--mesonbuild/mlog.py7
-rw-r--r--mesonbuild/modules/qt.py4
-rw-r--r--mesonbuild/mparser.py2
-rw-r--r--mesonbuild/mtest.py2
-rw-r--r--mesonbuild/scripts/coverage.py11
-rw-r--r--mesonbuild/scripts/gettext.py2
-rw-r--r--mesonbuild/scripts/meson_install.py16
-rw-r--r--mesonbuild/wrap/wraptool.py4
-rwxr-xr-xrun_project_tests.py52
-rwxr-xr-xrun_unittests.py14
30 files changed, 136 insertions, 120 deletions
diff --git a/docs/markdown/Compiler-properties.md b/docs/markdown/Compiler-properties.md
index 4def628..579417a 100644
--- a/docs/markdown/Compiler-properties.md
+++ b/docs/markdown/Compiler-properties.md
@@ -173,7 +173,7 @@ Does a structure contain a member?
==
Some platforms have different standard structures. Here's how one
-would check if a struct called `mystruct` from header `myheader.h</hh>
+would check if a struct called `mystruct` from header `myheader.h`
contains a member called `some_member`.
```meson
diff --git a/docs/markdown/Reference-tables.md b/docs/markdown/Reference-tables.md
index ee3b8c2..5ee0db1 100644
--- a/docs/markdown/Reference-tables.md
+++ b/docs/markdown/Reference-tables.md
@@ -57,7 +57,7 @@ These are provided by the `.system()` method call.
| windows | Any version of Windows |
| cygwin | The Cygwin environment for Windows |
| haiku | |
-| freebsd | FreeBSD and it's derivatives |
+| freebsd | FreeBSD and its derivatives |
| dragonfly | DragonFly BSD |
| netbsd | |
diff --git a/docs/markdown/Users.md b/docs/markdown/Users.md
index 78ad1b7..0503c22 100644
--- a/docs/markdown/Users.md
+++ b/docs/markdown/Users.md
@@ -37,12 +37,14 @@ If you have a project that uses Meson that you want to add to this list, let us
- [Mesa](https://www.mesa3d.org/), An open source graphics driver project
- [Nautilus](https://git.gnome.org/browse/nautilus/commit/?id=ed5652c89ac0654df2e82b54b00b27d51c825465) the Gnome file manager
- [Orc](http://cgit.freedesktop.org/gstreamer/orc/), the Optimized Inner Loop Runtime Compiler (not the default yet)
+ - [Outlier](https://github.com/kerolasa/outlier), a small Hello World style meson example project
- [Pango](https://git.gnome.org/browse/pango/), an Internationalized text layout and rendering library (not the default yet)
- [Parzip](https://github.com/jpakkane/parzip), a multithreaded reimplementation of Zip
- [Pitivi](http://pitivi.org/), a nonlinear video editor
- [Polari](https://git.gnome.org/browse/polari), an IRC client
- [Sysprof](https://wiki.gnome.org/Apps/Sysprof), a profiling tool
- [systemd](https://github.com/systemd/systemd), the init system
+ - [Taisei Project](https://taisei-project.org/), an open-source Touhou Project clone and fangame
- [Xorg](https://cgit.freedesktop.org/xorg/xserver/) the X.org display server (not the default yet)
- [Valum](https://github.com/valum-framework/valum), a micro web framework written in Vala
- [Wayland and Weston](https://lists.freedesktop.org/archives/wayland-devel/2016-November/031984.html), a next generation display server (not merged yet)
diff --git a/docs/markdown/snippets/config-tool-cross.md b/docs/markdown/snippets/config-tool-cross.md
new file mode 100644
index 0000000..1102481
--- /dev/null
+++ b/docs/markdown/snippets/config-tool-cross.md
@@ -0,0 +1,13 @@
+# Config-Tool based dependencies can be specified in a cross file
+
+Tools like LLVM and pcap use a config tool for dependencies, this is a script
+or binary that is run to get configuration information (cflags, ldflags, etc)
+from.
+
+These binaries may now be specified in the `binaries` section of a cross file.
+
+```dosini
+[binaries]
+cc = ...
+llvm-config = '/usr/bin/llvm-config32'
+```
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 5a5db22..292b027 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -322,7 +322,7 @@ class Backend:
continue
if os.path.splitext(libpath)[1] not in ['.dll', '.lib', '.so']:
continue
- absdir = os.path.split(libpath)[0]
+ absdir = os.path.dirname(libpath)
rel_to_src = absdir[len(self.environment.get_source_dir()) + 1:]
assert(not os.path.isabs(rel_to_src))
paths.append(os.path.join(self.build_to_src, rel_to_src))
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 77c7d50..9318926 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -823,7 +823,7 @@ int dummy;
if subdir is None:
subdir = os.path.join(manroot, 'man' + num)
srcabs = f.absolute_path(self.environment.get_source_dir(), self.environment.get_build_dir())
- dstabs = os.path.join(subdir, os.path.split(f.fname)[1] + '.gz')
+ dstabs = os.path.join(subdir, os.path.basename(f.fname) + '.gz')
i = [srcabs, dstabs]
d.man.append(i)
@@ -836,7 +836,7 @@ int dummy;
subdir = de.install_dir
for f in de.sources:
assert(isinstance(f, mesonlib.File))
- plain_f = os.path.split(f.fname)[1]
+ plain_f = os.path.basename(f.fname)
dstabs = os.path.join(subdir, plain_f)
i = [f.absolute_path(srcdir, builddir), dstabs, de.install_mode]
d.data.append(i)
@@ -1278,7 +1278,7 @@ int dummy;
# Target names really should not have slashes in them, but
# unfortunately we did not check for that and some downstream projects
# now have them. Once slashes are forbidden, remove this bit.
- target_slashname_workaround_dir = os.path.join(os.path.split(target.name)[0],
+ target_slashname_workaround_dir = os.path.join(os.path.dirname(target.name),
self.get_target_dir(target))
else:
target_slashname_workaround_dir = self.get_target_dir(target)
@@ -1401,7 +1401,7 @@ int dummy;
objects = [] # Relative to swift invocation dir
rel_objects = [] # Relative to build.ninja
for i in abssrc + abs_generated:
- base = os.path.split(i)[1]
+ base = os.path.basename(i)
oname = os.path.splitext(base)[0] + '.o'
objects.append(oname)
rel_objects.append(os.path.join(self.get_target_private_dir(target), oname))
@@ -1928,7 +1928,7 @@ rule FORTRAN_DEP_HACK
# Check if a source uses a module it exports itself.
# Potential bug if multiple targets have a file with
# the same name.
- if mod_source_file.fname == os.path.split(src)[1]:
+ if mod_source_file.fname == os.path.basename(src):
continue
mod_name = compiler.module_name_to_filename(
usematch.group(1))
@@ -2271,7 +2271,7 @@ rule FORTRAN_DEP_HACK
commands = []
commands += self.generate_basic_compiler_args(target, compiler)
- just_name = os.path.split(header)[1]
+ just_name = os.path.basename(header)
(objname, pch_args) = compiler.gen_pch_args(just_name, source, dst)
commands += pch_args
commands += self.get_compile_debugfile_args(compiler, target, objname)
@@ -2281,7 +2281,7 @@ rule FORTRAN_DEP_HACK
def generate_gcc_pch_command(self, target, compiler, pch):
commands = self._generate_single_compile(target, compiler)
dst = os.path.join(self.get_target_private_dir(target),
- os.path.split(pch)[-1] + '.' + compiler.get_pch_suffix())
+ os.path.basename(pch) + '.' + compiler.get_pch_suffix())
dep = dst + '.' + compiler.get_depfile_suffix()
return commands, dep, dst, [] # Gcc does not create an object file during pch generation.
@@ -2476,7 +2476,7 @@ rule FORTRAN_DEP_HACK
# unfortunately we did not check for that and some downstream projects
# now have them. Once slashes are forbidden, remove this bit.
target_slashname_workaround_dir = os.path.join(
- os.path.split(target.name)[0],
+ os.path.dirname(target.name),
self.get_target_dir(target))
else:
target_slashname_workaround_dir = self.get_target_dir(target)
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 1722db7..057e7c9 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -1034,7 +1034,7 @@ class Vs2010Backend(backends.Backend):
pch_file = ET.SubElement(inc_cl, 'PrecompiledHeaderFile')
# MSBuild searches for the header relative from the implementation, so we have to use
# just the file name instead of the relative path to the file.
- pch_file.text = os.path.split(header)[1]
+ pch_file.text = os.path.basename(header)
self.add_additional_options(lang, inc_cl, file_args)
self.add_preprocessor_defines(lang, inc_cl, file_defines)
self.add_include_dirs(lang, inc_cl, file_inc_dirs)
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index aca3aea..3ae31e4 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -311,7 +311,7 @@ class XCodeBackend(backends.Backend):
for fname, idval in self.filemap.items():
fullpath = os.path.join(self.environment.get_source_dir(), fname)
xcodetype = self.get_xcodetype(fname)
- name = os.path.split(fname)[-1]
+ name = os.path.basename(fname)
path = fname
self.ofile.write(src_templ % (idval, fullpath, xcodetype, name, path))
target_templ = '%s /* %s */ = { isa = PBXFileReference; explicitFileType = "%s"; path = %s; refType = %d; sourceTree = BUILT_PRODUCTS_DIR; };\n'
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 5eab794..dc19b73 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1065,7 +1065,7 @@ class Generator:
depfile = kwargs['depfile']
if not isinstance(depfile, str):
raise InvalidArguments('Depfile must be a string.')
- if os.path.split(depfile)[1] != depfile:
+ if os.path.basename(depfile) != depfile:
raise InvalidArguments('Depfile must be a plain filename without a subdirectory.')
self.depfile = depfile
if 'capture' in kwargs:
@@ -1075,7 +1075,7 @@ class Generator:
self.capture = capture
def get_base_outnames(self, inname):
- plainname = os.path.split(inname)[1]
+ plainname = os.path.basename(inname)
basename = os.path.splitext(plainname)[0]
bases = [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.outputs]
return bases
@@ -1083,12 +1083,12 @@ class Generator:
def get_dep_outname(self, inname):
if self.depfile is None:
raise InvalidArguments('Tried to get dep name for rule that does not have dependency file defined.')
- plainname = os.path.split(inname)[1]
+ plainname = os.path.basename(inname)
basename = os.path.splitext(plainname)[0]
return self.depfile.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname)
def get_arglist(self, inname):
- plainname = os.path.split(inname)[1]
+ plainname = os.path.basename(inname)
basename = os.path.splitext(plainname)[0]
return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.arglist]
@@ -1130,7 +1130,7 @@ class GeneratedList:
in_abs = infile.absolute_path(state.environment.source_dir, state.environment.build_dir)
assert(os.path.isabs(self.preserve_path_from))
rel = os.path.relpath(in_abs, self.preserve_path_from)
- path_segment = os.path.split(rel)[0]
+ path_segment = os.path.dirname(rel)
for of in outfiles:
result.append(os.path.join(path_segment, of))
return result
@@ -1637,6 +1637,10 @@ class CustomTarget(Target):
for i in self.outputs:
if not(isinstance(i, str)):
raise InvalidArguments('Output argument not a string.')
+ if i == '':
+ raise InvalidArguments('Output must not be empty.')
+ if i.strip() == '':
+ raise InvalidArguments('Output must not consist only of whitespace.')
if '/' in i:
raise InvalidArguments('Output must not contain a path segment.')
if '@INPUT@' in i or '@INPUT0@' in i:
@@ -1659,7 +1663,7 @@ class CustomTarget(Target):
depfile = kwargs['depfile']
if not isinstance(depfile, str):
raise InvalidArguments('Depfile must be a string.')
- if os.path.split(depfile)[1] != depfile:
+ if os.path.basename(depfile) != depfile:
raise InvalidArguments('Depfile must be a plain filename without a subdirectory.')
self.depfile = depfile
self.command = self.flatten_command(kwargs['command'])
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 4c6e3a2..f738615 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -172,10 +172,10 @@ class CCompiler(Compiler):
return ' '.join(self.exelist)
def get_pch_use_args(self, pch_dir, header):
- return ['-include', os.path.split(header)[-1]]
+ return ['-include', os.path.basename(header)]
def get_pch_name(self, header_name):
- return os.path.split(header_name)[-1] + '.' + self.get_pch_suffix()
+ return os.path.basename(header_name) + '.' + self.get_pch_suffix()
def get_linker_search_args(self, dirname):
return ['-L' + dirname]
@@ -804,6 +804,13 @@ class CCompiler(Compiler):
return ['-pthread']
def has_multi_arguments(self, args, env):
+ for arg in args:
+ if arg.startswith('-Wl,'):
+ mlog.warning('''{} looks like a linker argument, but has_argument
+and other similar methods only support checking compiler arguments.
+Using them to check linker arguments are never supported, and results
+are likely to be wrong regardless of the compiler you are using.
+'''.format(arg))
return self.compiles('int i;\n', env, extra_args=args)
@@ -875,7 +882,7 @@ class GnuCCompiler(GnuCompiler, CCompiler):
return ['-shared']
def get_pch_use_args(self, pch_dir, header):
- return ['-fpch-preprocess', '-include', os.path.split(header)[-1]]
+ return ['-fpch-preprocess', '-include', os.path.basename(header)]
class IntelCCompiler(IntelCompiler, CCompiler):
@@ -954,13 +961,13 @@ class VisualStudioCCompiler(CCompiler):
return 'pch'
def get_pch_name(self, header):
- chopped = os.path.split(header)[-1].split('.')[:-1]
+ chopped = os.path.basename(header).split('.')[:-1]
chopped.append(self.get_pch_suffix())
pchname = '.'.join(chopped)
return pchname
def get_pch_use_args(self, pch_dir, header):
- base = os.path.split(header)[-1]
+ base = os.path.basename(header)
pchname = self.get_pch_name(header)
return ['/FI' + base, '/Yu' + base, '/Fp' + os.path.join(pch_dir, pchname)]
@@ -1087,7 +1094,7 @@ class VisualStudioCCompiler(CCompiler):
mlog.debug('Running VS compile:')
mlog.debug('Command line: ', ' '.join(commands))
mlog.debug('Code:\n', code)
- p, stdo, stde = Popen_safe(commands, cwd=os.path.split(srcname)[0])
+ p, stdo, stde = Popen_safe(commands, cwd=os.path.dirname(srcname))
if p.returncode != 0:
return False
return not(warning_text in stde or warning_text in stdo)
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 2602d14..dbaf730 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -1040,7 +1040,7 @@ class GnuCompiler:
return 'gch'
def split_shlib_to_parts(self, fname):
- return os.path.split(fname)[0], fname
+ return os.path.dirname(fname), fname
def get_soname_args(self, prefix, shlib_name, suffix, path, soversion, is_shared_module):
return get_gcc_soname_args(self.gcc_type, prefix, shlib_name, suffix, path, soversion, is_shared_module)
@@ -1188,10 +1188,10 @@ class IntelCompiler:
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()
+ return os.path.basename(header_name) + '.' + self.get_pch_suffix()
def split_shlib_to_parts(self, fname):
- return os.path.split(fname)[0], fname
+ return os.path.dirname(fname), fname
def get_soname_args(self, prefix, shlib_name, suffix, path, soversion, is_shared_module):
if self.icc_type == ICC_STANDARD:
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 5e32ace..c10f38e 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -14,6 +14,7 @@
import os.path
+from .. import mlog
from .. import coredata
from ..mesonlib import version_compare
@@ -129,7 +130,7 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
return []
def get_pch_use_args(self, pch_dir, header):
- return ['-fpch-preprocess', '-include', os.path.split(header)[-1]]
+ return ['-fpch-preprocess', '-include', os.path.basename(header)]
class IntelCPPCompiler(IntelCompiler, CPPCompiler):
@@ -174,6 +175,13 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler):
return []
def has_multi_arguments(self, args, env):
+ for arg in args:
+ if arg.startswith('-Wl,'):
+ mlog.warning('''{} looks like a linker argument, but has_argument
+and other similar methods only support checking compiler arguments.
+Using them to check linker arguments are never supported, and results
+are likely to be wrong regardless of the compiler you are using.
+'''.format(arg))
return super().has_multi_arguments(args + ['-diag-error', '10006'], env)
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 1b42bfa..f9fcc1c 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -91,7 +91,7 @@ end program prog
return gnulike_buildtype_linker_args[buildtype]
def split_shlib_to_parts(self, fname):
- return os.path.split(fname)[0], fname
+ return os.path.dirname(fname), fname
def get_soname_args(self, prefix, shlib_name, suffix, path, soversion, is_shared_module):
return get_gcc_soname_args(self.gcc_type, prefix, shlib_name, suffix, path, soversion, is_shared_module)
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 560e389..f89e631 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -212,6 +212,7 @@ class ConfigToolDependency(ExternalDependency):
def __init__(self, name, environment, language, kwargs):
super().__init__('config-tool', environment, language, kwargs)
self.name = name
+ self.native = kwargs.get('native', False)
self.tools = listify(kwargs.get('tools', self.tools))
req_version = kwargs.get('version', None)
@@ -260,8 +261,20 @@ class ConfigToolDependency(ExternalDependency):
if not isinstance(versions, list) and versions is not None:
versions = listify(versions)
+ if self.env.is_cross_build() and not self.native:
+ cross_file = self.env.cross_info.config['binaries']
+ try:
+ tools = [cross_file[self.tool_name]]
+ except KeyError:
+ mlog.warning('No entry for {0} specified in your cross file. '
+ 'Falling back to searching PATH. This may find a '
+ 'native version of {0}!'.format(self.tool_name))
+ tools = self.tools
+ else:
+ tools = self.tools
+
best_match = (None, None)
- for tool in self.tools:
+ for tool in tools:
try:
p, out = Popen_safe([tool, '--version'])[:2]
except (FileNotFoundError, PermissionError):
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 53bba60..4737dd3 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -594,7 +594,7 @@ class Environment:
return self.scratch_dir
def get_depfixer(self):
- path = os.path.split(__file__)[0]
+ path = os.path.dirname(__file__)
return os.path.join(path, 'depfixer.py')
def detect_objc_compiler(self, want_cross):
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index b5ced9b..9c2fd00 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1583,7 +1583,7 @@ class Interpreter(InterpreterBase):
modname = args[0]
if modname.startswith('unstable-'):
plainname = modname.split('-', 1)[1]
- mlog.warning('Module %s has no backwards or forwards compatibility and might not exist in future releases' % modname, location=node)
+ mlog.warning('Module %s has no backwards or forwards compatibility and might not exist in future releases.' % modname, location=node)
modname = 'unstable_' + plainname
if modname not in self.environment.coredata.modules:
try:
@@ -2739,7 +2739,7 @@ root and issuing %s.
values = mesonlib.get_filenames_templates_dict([ifile_abs], None)
outputs = mesonlib.substitute_values([output], values)
output = outputs[0]
- if os.path.split(output)[0] != '':
+ if os.path.dirname(output) != '':
raise InterpreterException('Output file name must not contain a subdirectory.')
(ofile_path, ofile_fname) = os.path.split(os.path.join(self.subdir, output))
ofile_abs = os.path.join(self.environment.build_dir, ofile_path, ofile_fname)
@@ -2756,7 +2756,7 @@ root and issuing %s.
var_list = ", ".join(map(repr, sorted(missing_variables)))
mlog.warning(
"The variable(s) %s in the input file %s are not "
- "present in the given configuration data" % (
+ "present in the given configuration data." % (
var_list, inputfile), location=node)
else:
mesonlib.dump_conf_header(ofile_abs, conf.held_object)
@@ -2977,7 +2977,7 @@ different subdirectory.
norm = os.path.relpath(norm, self.environment.source_dir)
assert(not os.path.isabs(norm))
(num_sps, sproj_name) = self.evaluate_subproject_info(norm, self.subproject_dir)
- plain_filename = os.path.split(norm)[-1]
+ plain_filename = os.path.basename(norm)
if num_sps == 0:
if self.subproject == '':
return
@@ -3006,6 +3006,8 @@ different subdirectory.
def add_target(self, name, tobj):
if name == '':
raise InterpreterException('Target name must not be empty.')
+ if name.strip() == '':
+ raise InterpreterException('Target name must not consist only of whitespace.')
if name.startswith('meson-'):
raise InvalidArguments("Target names starting with 'meson-' are reserved "
"for Meson's internal use. Please rename.")
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index 9dc6b0f..35ca5c8 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -74,7 +74,7 @@ class permittedKwargs:
loc = None
for k in kwargs:
if k not in self.permitted:
- mlog.warning('''Passed invalid keyword argument "{}"'''.format(k), location=loc)
+ mlog.warning('''Passed invalid keyword argument "{}".'''.format(k), location=loc)
mlog.warning('This will become a hard error in the future.')
return f(s, node_or_state, args, kwargs)
return wrapped
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index 4871bf7..a90cb6e 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -576,7 +576,8 @@ def do_conf_file(src, dst, confdata):
return missing_variables
def dump_conf_header(ofilename, cdata):
- with open(ofilename, 'w', encoding='utf-8') as ofile:
+ ofilename_tmp = ofilename + '~'
+ with open(ofilename_tmp, 'w', encoding='utf-8') as ofile:
ofile.write('''/*
* Autogenerated by the Meson build system.
* Do not edit, your changes will be lost.
@@ -598,6 +599,7 @@ def dump_conf_header(ofilename, cdata):
ofile.write('#define %s %s\n\n' % (k, v))
else:
raise MesonException('Unknown data type in configuration file entry: ' + k)
+ replace_if_different(ofilename, ofilename_tmp)
def replace_if_different(dst, dst_tmp):
# If contents are identical, don't touch the file to prevent
@@ -855,7 +857,7 @@ def get_filenames_templates_dict(inputs, outputs):
values['@INPUT{}@'.format(ii)] = vv
if len(inputs) == 1:
# Just one value, substitute @PLAINNAME@ and @BASENAME@
- values['@PLAINNAME@'] = plain = os.path.split(inputs[0])[1]
+ values['@PLAINNAME@'] = plain = os.path.basename(inputs[0])
values['@BASENAME@'] = os.path.splitext(plain)[0]
if outputs:
# Gather values derived from the outputs, similar to above.
@@ -863,7 +865,7 @@ def get_filenames_templates_dict(inputs, outputs):
for (ii, vv) in enumerate(outputs):
values['@OUTPUT{}@'.format(ii)] = vv
# Outdir should be the same for all outputs
- values['@OUTDIR@'] = os.path.split(outputs[0])[0]
+ values['@OUTDIR@'] = os.path.dirname(outputs[0])
# Many external programs fail on empty arguments.
if values['@OUTDIR@'] == '':
values['@OUTDIR@'] = '.'
@@ -893,7 +895,7 @@ def detect_subprojects(spdir_name, current_dir='', result=None):
if not os.path.exists(spdir):
return result
for trial in glob(os.path.join(spdir, '*')):
- basename = os.path.split(trial)[1]
+ basename = os.path.basename(trial)
if trial == 'packagecache':
continue
append_this = True
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 11a631a..619aa39 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -366,10 +366,11 @@ def run(original_args, mainfile=None):
app.generate()
except Exception as e:
if isinstance(e, MesonException):
+ mlog.log()
if hasattr(e, 'file') and hasattr(e, 'lineno') and hasattr(e, 'colno'):
- mlog.log(mlog.red('\nMeson encountered an error in file %s, line %d, column %d:' % (e.file, e.lineno, e.colno)))
+ mlog.log('%s:%d:%d:' % (e.file, e.lineno, e.colno), mlog.red('ERROR: '), end='')
else:
- mlog.log(mlog.red('\nMeson encountered an error:'))
+ mlog.log(mlog.red('ERROR: '), end='')
# Error message
mlog.log(e)
# Path to log file
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index b23869f..aaaf8fc 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -49,14 +49,14 @@ parser.add_argument('builddir', nargs='?', help='The build directory')
def determine_installed_path(target, installdata):
install_target = None
for i in installdata.targets:
- if os.path.split(i[0])[1] == target.get_filename(): # FIXME, might clash due to subprojects.
+ if os.path.basename(i[0]) == target.get_filename(): # FIXME, might clash due to subprojects.
install_target = i
break
if install_target is None:
raise RuntimeError('Something weird happened. File a bug.')
fname = i[0]
outdir = i[1]
- outname = os.path.join(installdata.prefix, outdir, os.path.split(fname)[-1])
+ outname = os.path.join(installdata.prefix, outdir, os.path.basename(fname))
# Normalize the path by using os.path.sep consistently, etc.
# Does not change the effective path.
return str(pathlib.PurePath(outname))
diff --git a/mesonbuild/mlog.py b/mesonbuild/mlog.py
index aa2ac20..273552d 100644
--- a/mesonbuild/mlog.py
+++ b/mesonbuild/mlog.py
@@ -105,12 +105,15 @@ def log(*args, **kwargs):
def warning(*args, **kwargs):
from . import environment
+ args = (yellow('WARNING:'),) + args
+
if kwargs.get('location'):
location = kwargs['location']
del kwargs['location']
- args += ('in file {}, line {}.'.format(os.path.join(location.subdir, environment.build_filename), location.lineno),)
+ location = '{}:{}:'.format(os.path.join(location.subdir, environment.build_filename), location.lineno)
+ args = (location,) + args
- log(yellow('WARNING:'), *args, **kwargs)
+ log(*args, **kwargs)
# Format a list for logging purposes as a string. It separates
# all but the last item with commas, and the last with 'and'.
diff --git a/mesonbuild/modules/qt.py b/mesonbuild/modules/qt.py
index 595269e..f5ce1ed 100644
--- a/mesonbuild/modules/qt.py
+++ b/mesonbuild/modules/qt.py
@@ -73,7 +73,7 @@ class QtBaseModule:
def parse_qrc(self, state, fname):
abspath = os.path.join(state.environment.source_dir, state.subdir, fname)
- relative_part = os.path.split(fname)[0]
+ relative_part = os.path.dirname(fname)
try:
tree = ET.parse(abspath)
root = tree.getroot()
@@ -116,7 +116,7 @@ class QtBaseModule:
sources.append(res_target)
else:
for rcc_file in rcc_files:
- basename = os.path.split(rcc_file)[1]
+ basename = os.path.basename(rcc_file)
name = 'qt' + str(self.qt_version) + '-' + basename.replace('.', '_')
rcc_kwargs = {'input': rcc_file,
'output': name + '.cpp',
diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py
index eb03393..5df056f 100644
--- a/mesonbuild/mparser.py
+++ b/mesonbuild/mparser.py
@@ -368,7 +368,7 @@ class ArgumentNode:
def set_kwarg(self, name, value):
if name in self.kwargs:
- mlog.warning('Keyword argument "{}" defined multiple times'.format(name), location=self)
+ mlog.warning('Keyword argument "{}" defined multiple times.'.format(name), location=self)
mlog.warning('This will be an error in future Meson releases.')
self.kwargs[name] = value
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index b39f5af..2032e05 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -438,7 +438,7 @@ TIMEOUT: %4d
logfile_base = os.path.join(self.options.wd, 'meson-logs', self.options.logbase)
if self.options.wrapper:
- namebase = os.path.split(self.get_wrapper()[0])[1]
+ namebase = os.path.basename(self.get_wrapper()[0])
elif self.options.setup:
namebase = self.options.setup
diff --git a/mesonbuild/scripts/coverage.py b/mesonbuild/scripts/coverage.py
index 25451d4..d1fad11 100644
--- a/mesonbuild/scripts/coverage.py
+++ b/mesonbuild/scripts/coverage.py
@@ -14,7 +14,7 @@
from mesonbuild import environment
-import sys, os, subprocess
+import sys, os, subprocess, pathlib
def remove_dir_from_trace(lcov_command, covfile, dirname):
tmpfile = covfile + '.tmp'
@@ -68,6 +68,15 @@ def coverage(source_root, build_root, log_dir):
'--show-details',
'--branch-coverage',
covinfo])
+ if gcovr_exe:
+ print('')
+ print('XML coverage report can be found at',
+ pathlib.Path(log_dir, 'coverage.xml').as_uri())
+ print('Text coverage report can be found at',
+ pathlib.Path(log_dir, 'coverage.txt').as_uri())
+ if lcov_exe and genhtml_exe:
+ print('Html coverage report can be found at',
+ pathlib.Path(htmloutdir, 'index.html').as_uri())
return 0
def run(args):
diff --git a/mesonbuild/scripts/gettext.py b/mesonbuild/scripts/gettext.py
index 30ac54c..f308c5a 100644
--- a/mesonbuild/scripts/gettext.py
+++ b/mesonbuild/scripts/gettext.py
@@ -81,7 +81,7 @@ def do_install(src_sub, bld_sub, dest, pkgname, langs):
srcfile = os.path.join(bld_sub, l + '.gmo')
outfile = os.path.join(dest, l, 'LC_MESSAGES',
pkgname + '.mo')
- os.makedirs(os.path.split(outfile)[0], exist_ok=True)
+ os.makedirs(os.path.dirname(outfile), exist_ok=True)
shutil.copyfile(srcfile, outfile)
shutil.copystat(srcfile, outfile)
print('Installing %s to %s' % (srcfile, outfile))
diff --git a/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py
index fe1de1f..2f9f135 100644
--- a/mesonbuild/scripts/meson_install.py
+++ b/mesonbuild/scripts/meson_install.py
@@ -164,10 +164,10 @@ def do_copydir(data, src_prefix, src_dir, dst_dir, exclude):
print('Tried to copy file %s but a directory of that name already exists.' % abs_dst)
if os.path.exists(abs_dst):
os.unlink(abs_dst)
- parent_dir = os.path.split(abs_dst)[0]
+ parent_dir = os.path.dirname(abs_dst)
if not os.path.isdir(parent_dir):
os.mkdir(parent_dir)
- shutil.copystat(os.path.split(abs_src)[0], parent_dir)
+ shutil.copystat(os.path.dirname(abs_src), parent_dir)
shutil.copy2(abs_src, abs_dst, follow_symlinks=False)
append_to_log(abs_dst)
@@ -211,7 +211,7 @@ def install_data(d):
fullfilename = i[0]
outfilename = get_destdir_path(d, i[1])
mode = i[2]
- outdir = os.path.split(outfilename)[0]
+ outdir = os.path.dirname(outfilename)
d.dirmaker.makedirs(outdir, exist_ok=True)
print('Installing %s to %s' % (fullfilename, outdir))
do_copyfile(fullfilename, outfilename)
@@ -221,7 +221,7 @@ def install_man(d):
for m in d.man:
full_source_filename = m[0]
outfilename = get_destdir_path(d, m[1])
- outdir = os.path.split(outfilename)[0]
+ outdir = os.path.dirname(outfilename)
d.dirmaker.makedirs(outdir, exist_ok=True)
print('Installing %s to %s' % (full_source_filename, outdir))
if outfilename.endswith('.gz') and not full_source_filename.endswith('.gz'):
@@ -238,7 +238,7 @@ def install_man(d):
def install_headers(d):
for t in d.headers:
fullfilename = t[0]
- fname = os.path.split(fullfilename)[1]
+ fname = os.path.basename(fullfilename)
outdir = get_destdir_path(d, t[1])
outfilename = os.path.join(outdir, fname)
print('Installing %s to %s' % (fname, outdir))
@@ -304,7 +304,7 @@ def install_targets(d):
for t in d.targets:
fname = check_for_stampfile(t[0])
outdir = get_destdir_path(d, t[1])
- outname = os.path.join(outdir, os.path.split(fname)[-1])
+ outname = os.path.join(outdir, os.path.basename(fname))
aliases = t[2]
should_strip = t[3]
install_rpath = t[4]
@@ -316,7 +316,7 @@ def install_targets(d):
do_copyfile(fname, outname)
if should_strip and d.strip_bin is not None:
if fname.endswith('.jar'):
- print('Not stripping jar target:', os.path.split(fname)[1])
+ print('Not stripping jar target:', os.path.basename(fname))
continue
print('Stripping target {!r}'.format(fname))
ps, stdo, stde = Popen_safe(d.strip_bin + [outname])
@@ -366,7 +366,7 @@ def run(args):
print('Installer script for Meson. Do not run on your own, mmm\'kay?')
print('meson_install.py [install info file]')
datafilename = args[0]
- private_dir = os.path.split(datafilename)[0]
+ private_dir = os.path.dirname(datafilename)
log_dir = os.path.join(private_dir, '../meson-logs')
with open(os.path.join(log_dir, 'install-log.txt'), 'w') as lf:
install_log_file = lf
diff --git a/mesonbuild/wrap/wraptool.py b/mesonbuild/wrap/wraptool.py
index 0bdc417..09a0289 100644
--- a/mesonbuild/wrap/wraptool.py
+++ b/mesonbuild/wrap/wraptool.py
@@ -150,7 +150,7 @@ def do_promotion(from_path, spdir_name):
assert(from_path.endswith('.wrap'))
shutil.copy(from_path, spdir_name)
elif os.path.isdir(from_path):
- sproj_name = os.path.split(from_path)[1]
+ sproj_name = os.path.basename(from_path)
outputdir = os.path.join(spdir_name, sproj_name)
if os.path.exists(outputdir):
sys.exit('Output dir %s already exists. Will not overwrite.' % outputdir)
@@ -178,7 +178,7 @@ def promote(argument):
def status():
print('Subproject status')
for w in glob('subprojects/*.wrap'):
- name = os.path.split(w)[1][:-5]
+ name = os.path.basename(w)[:-5]
try:
(latest_branch, latest_revision) = get_latest_version(name)
except Exception:
diff --git a/run_project_tests.py b/run_project_tests.py
index d191e28..1d17000 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -31,7 +31,7 @@ import argparse
import xml.etree.ElementTree as ET
import time
import multiprocessing
-import concurrent.futures as conc
+from concurrent.futures import ProcessPoolExecutor
import re
from run_unittests import get_fake_options, run_configure
@@ -59,50 +59,6 @@ class TestResult:
self.buildtime = buildtime
self.testtime = testtime
-class DummyFuture(conc.Future):
- '''
- Dummy Future implementation that executes the provided function when you
- ask for the result. Used on platforms where sem_open() is not available:
- MSYS2, OpenBSD, etc: https://bugs.python.org/issue3770
- '''
- def set_function(self, fn, *args, **kwargs):
- self.fn = fn
- self.fn_args = args
- self.fn_kwargs = kwargs
-
- def result(self, **kwargs):
- try:
- result = self.fn(*self.fn_args, **self.fn_kwargs)
- except BaseException as e:
- self.set_exception(e)
- else:
- self.set_result(result)
- return super().result(**kwargs)
-
-
-class DummyExecutor(conc.Executor):
- '''
- Dummy single-thread 'concurrent' executor for use on platforms where
- sem_open is not available: https://bugs.python.org/issue3770
- '''
-
- def __init__(self):
- from threading import Lock
- self._shutdown = False
- self._shutdownLock = Lock()
-
- def submit(self, fn, *args, **kwargs):
- with self._shutdownLock:
- if self._shutdown:
- raise RuntimeError('Cannot schedule new futures after shutdown')
- f = DummyFuture()
- f.set_function(fn, *args, **kwargs)
- return f
-
- def shutdown(self, wait=True):
- with self._shutdownLock:
- self._shutdown = True
-
class AutoDeletedDir:
def __init__(self, d):
@@ -548,11 +504,7 @@ def _run_tests(all_tests, log_name_base, extra_args):
# Remove this once the following issue has been resolved:
# https://github.com/mesonbuild/meson/pull/2082
num_workers *= 2
- try:
- executor = conc.ProcessPoolExecutor(max_workers=num_workers)
- except ImportError:
- print('Platform doesn\'t ProcessPoolExecutor, falling back to single-threaded testing\n')
- executor = DummyExecutor()
+ executor = ProcessPoolExecutor(max_workers=num_workers)
for name, test_cases, skipped in all_tests:
current_suite = ET.SubElement(junit_root, 'testsuite', {'name': name, 'tests': str(len(test_cases))})
diff --git a/run_unittests.py b/run_unittests.py
index 7abbe6c..103847a 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1713,13 +1713,13 @@ int main(int argc, char **argv) {
tdir = os.path.join(self.unit_test_dir, '21 warning location')
out = self.init(tdir)
for expected in [
- r'WARNING: Keyword argument "link_with" defined multiple times in file meson.build, line 4',
- r'WARNING: Keyword argument "link_with" defined multiple times in file sub' + os.path.sep + r'meson.build, line 3',
- r'WARNING: a warning of some sort in file meson.build, line 6',
- r'WARNING: subdir warning in file sub' + os.path.sep + r'meson.build, line 4',
- r'WARNING: Module unstable-simd has no backwards or forwards compatibility and might not exist in future releases in file meson.build, line 7',
- r"WARNING: The variable(s) 'MISSING' in the input file conf.in are not present in the given configuration data in file meson.build, line 10",
- r'WARNING: Passed invalid keyword argument "invalid" in file meson.build, line 1'
+ r'meson.build:4: WARNING: Keyword argument "link_with" defined multiple times.',
+ r'sub' + os.path.sep + r'meson.build:3: WARNING: Keyword argument "link_with" defined multiple times.',
+ r'meson.build:6: WARNING: a warning of some sort',
+ r'sub' + os.path.sep + r'meson.build:4: WARNING: subdir warning',
+ r'meson.build:7: WARNING: Module unstable-simd has no backwards or forwards compatibility and might not exist in future releases.',
+ r"meson.build:10: WARNING: The variable(s) 'MISSING' in the input file conf.in are not present in the given configuration data.",
+ r'meson.build:1: WARNING: Passed invalid keyword argument "invalid".',
]:
self.assertRegex(out, re.escape(expected))