aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--azure-pipelines.yml26
-rw-r--r--ci/azure-steps.yml11
-rw-r--r--docs/markdown/Configuring-a-build-directory.md2
-rw-r--r--docs/markdown/Dependencies.md2
-rw-r--r--docs/markdown/Reference-manual.md8
-rw-r--r--docs/markdown/snippets/gpgme-config.md2
-rw-r--r--mesonbuild/backend/ninjabackend.py4
-rw-r--r--mesonbuild/backend/vs2010backend.py6
-rw-r--r--mesonbuild/backend/vs2019backend.py34
-rw-r--r--mesonbuild/build.py12
-rw-r--r--mesonbuild/compilers/c.py3
-rw-r--r--mesonbuild/compilers/compilers.py8
-rw-r--r--mesonbuild/compilers/cpp.py15
-rw-r--r--mesonbuild/coredata.py68
-rw-r--r--mesonbuild/dependencies/misc.py24
-rw-r--r--mesonbuild/environment.py68
-rw-r--r--mesonbuild/interpreter.py22
-rw-r--r--mesonbuild/mesonmain.py10
-rw-r--r--mesonbuild/modules/python.py8
-rwxr-xr-xmsi/createmsi.py24
-rwxr-xr-xrun_project_tests.py27
-rwxr-xr-xrun_tests.py6
-rwxr-xr-xrun_unittests.py53
-rw-r--r--test cases/failing/96 dependency not config-tool/96 unknown config tool/meson.build2
-rw-r--r--test cases/frameworks/27 gpgme/meson.build6
25 files changed, 315 insertions, 136 deletions
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 483f1eb..3d04ffc 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -57,6 +57,29 @@ jobs:
architecture: 'x64'
- template: ci/azure-steps.yml
+- job: vs2019
+ pool:
+ vmImage: windows-2019
+
+ strategy:
+ matrix:
+ vc2019x64ninja:
+ arch: x64
+ compiler: msvc2019
+ backend: ninja
+ vc2019x64vs:
+ arch: x64
+ compiler: msvc2019
+ backend: vs2019
+
+ steps:
+ - task: UsePythonVersion@0
+ inputs:
+ versionSpec: '3.7'
+ addToPath: true
+ architecture: 'x64'
+ - template: ci/azure-steps.yml
+
- job: cygwin
pool:
vmImage: VS2017-Win2016
@@ -73,6 +96,7 @@ jobs:
- script: |
%CYGWIN_ROOT%\cygwinsetup.exe -qnNdO -R "%CYGWIN_ROOT%" -s "%CYGWIN_MIRROR%" -g -P ^
cmake,^
+ gcc-fortran,^
gcc-objc++,^
gcc-objc,^
git,^
@@ -154,7 +178,7 @@ jobs:
set BOOST_ROOT=
set PATH=%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem
set PATHEXT=%PATHEXT%;.py
- if %compiler%==clang ( set CC=clang && set CXX=clang++ )
+ if %compiler%==clang ( set CC=clang && set CXX=clang++ && set OBJC=clang && set OBJCXX=clang++ )
%MSYS2_ROOT%\usr\bin\bash -lc "MSYSTEM= python3 run_tests.py --backend=ninja"
env:
CHERE_INVOKING: yes
diff --git a/ci/azure-steps.yml b/ci/azure-steps.yml
index d0f6d09..abbed65 100644
--- a/ci/azure-steps.yml
+++ b/ci/azure-steps.yml
@@ -5,8 +5,8 @@ steps:
exit 0
}
- # remove MinGW from path, so we don't find gfortran and try to use it
- $env:Path = ($env:Path.Split(';') | Where-Object { $_ -notlike '*mingw*' }) -join ';'
+ # remove Chocolately, MinGW, Strawberry Perl from path, so we don't find gcc/gfortran and try to use it
+ $env:Path = ($env:Path.Split(';') | Where-Object { $_ -notmatch 'mingw|Strawberry|Chocolatey' }) -join ';'
# download and install prerequisites
function DownloadFile([String] $Source, [String] $Destination) {
@@ -99,6 +99,8 @@ steps:
# import visual studio variables
if ($env:compiler -eq 'msvc2015') {
$vcvars = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"
+ } elseif($env:compiler -eq 'msvc2019') {
+ $vcvars = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"
} else {
$vcvars = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat"
}
@@ -154,7 +156,10 @@ steps:
echo ""
echo "=== Start running tests ==="
- python run_tests.py --backend $(backend)
+ # Starting from VS2019 Powershell(?) will fail the test run
+ # if it prints anything to stderr. Python's test runner
+ # does that by default so we need to forward it.
+ cmd /c 'python 2>&1' run_tests.py --backend $(backend)
- task: PublishTestResults@2
inputs:
diff --git a/docs/markdown/Configuring-a-build-directory.md b/docs/markdown/Configuring-a-build-directory.md
index 73585e2..b0fb574 100644
--- a/docs/markdown/Configuring-a-build-directory.md
+++ b/docs/markdown/Configuring-a-build-directory.md
@@ -24,7 +24,7 @@ sample output for a simple project.
Option Current Value Possible Values Description
------ ------------- --------------- -----------
auto_features auto [enabled, disabled, auto] Override value of all 'auto' features
- backend ninja [ninja, vs, vs2010, vs2015, vs2017, xcode] Backend to use
+ backend ninja [ninja, vs, vs2010, vs2015, vs2017, vs2019, xcode] Backend to use
buildtype release [plain, debug, debugoptimized, release, minsize, custom] Build type to use
debug false [true, false] Debug
default_library shared [shared, static, both] Default library type
diff --git a/docs/markdown/Dependencies.md b/docs/markdown/Dependencies.md
index 2789ee0..50dbcf5 100644
--- a/docs/markdown/Dependencies.md
+++ b/docs/markdown/Dependencies.md
@@ -394,7 +394,7 @@ The `language` keyword may used.
*(added 0.51.0)*
-`method` may be `auto` or `config-tool`.
+`method` may be `auto`, `config-tool` or `pkg-config`.
## Python3
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 5825004..056612d 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -1066,8 +1066,9 @@ res2 = foo / bar
```
Builds a library that is either static, shared or both depending on
-the value of `default_library` user option. You should use this
-instead of [`shared_library`](#shared_library),
+the value of `default_library`
+user [option](https://mesonbuild.com/Builtin-options.html).
+You should use this instead of [`shared_library`](#shared_library),
[`static_library`](#static_library) or
[`both_libraries`](#both_libraries) most of the time. This allows you
to toggle your entire project (including subprojects) from shared to
@@ -1552,7 +1553,8 @@ the following methods.
`MESON_SOURCE_ROOT` and `MESON_BUILD_ROOT` set.
- `backend()` *(added 0.37.0)* returns a string representing the
- current backend: `ninja`, `vs2010`, `vs2015`, `vs2017`, or `xcode`.
+ current backend: `ninja`, `vs2010`, `vs2015`, `vs2017`, `vs2019`,
+ or `xcode`.
- `build_root()` returns a string with the absolute path to the build
root directory. Note: this function will return the build root of
diff --git a/docs/markdown/snippets/gpgme-config.md b/docs/markdown/snippets/gpgme-config.md
index 08a7d38..65569fb 100644
--- a/docs/markdown/snippets/gpgme-config.md
+++ b/docs/markdown/snippets/gpgme-config.md
@@ -1,3 +1,3 @@
## gpgme dependency now supports gpgme-config
-Previously, we could only detect GPGME with custom invocations of `gpgme-config`. Now we added support to Meson allowing us to use `dependency('gpgme')` instead.
+Previously, we could only detect GPGME with custom invocations of `gpgme-config` or when the GPGME version was recent enough (>=1.13.0) to install pkg-config files. Now we added support to Meson allowing us to use `dependency('gpgme')` and fall back on `gpgme-config` parsing.
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index a3b9ce8..08b14c8 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1757,7 +1757,7 @@ rule FORTRAN_DEP_HACK%s
exe_arr = self.exe_object_to_cmd_array(exe)
infilelist = genlist.get_inputs()
outfilelist = genlist.get_outputs()
- extra_dependencies = [os.path.join(self.build_to_src, i) for i in genlist.extra_depends]
+ extra_dependencies = self.get_custom_target_depend_files(genlist)
for i in range(len(infilelist)):
curfile = infilelist[i]
if len(generator.outputs) == 1:
@@ -2418,7 +2418,7 @@ rule FORTRAN_DEP_HACK%s
guessed_dependencies = []
# TODO The get_library_naming requirement currently excludes link targets that use d or fortran as their main linker
if hasattr(linker, 'get_library_naming'):
- search_dirs = tuple(search_dirs) + linker.get_library_dirs(self.environment)
+ search_dirs = tuple(search_dirs) + tuple(linker.get_library_dirs(self.environment))
static_patterns = linker.get_library_naming(self.environment, LibType.STATIC, strict=True)
shared_patterns = linker.get_library_naming(self.environment, LibType.SHARED, strict=True)
for libname in libs:
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 2ef8187..d1bf1e5 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -126,6 +126,7 @@ class Vs2010Backend(backends.Backend):
sole_output = ''
curfile = infilelist[i]
infilename = os.path.join(down, curfile.rel_to_builddir(self.build_to_src))
+ deps = self.get_custom_target_depend_files(genlist, True)
base_args = generator.get_arglist(infilename)
outfiles_rel = genlist.get_outputs_for(curfile)
outfiles = [os.path.join(target_private_dir, of) for of in outfiles_rel]
@@ -156,6 +157,8 @@ class Vs2010Backend(backends.Backend):
cbs = ET.SubElement(idgroup, 'CustomBuild', Include=infilename)
ET.SubElement(cbs, 'Command').text = ' '.join(self.quote_arguments(cmd))
ET.SubElement(cbs, 'Outputs').text = ';'.join(outfiles)
+ if deps:
+ ET.SubElement(cbs, 'AdditionalInputs').text = ';'.join(deps)
return generator_output_files, custom_target_output_files, custom_target_include_dirs
def generate(self, interp):
@@ -207,7 +210,7 @@ class Vs2010Backend(backends.Backend):
if 'VCINSTALLDIR' in os.environ:
vs_version = os.environ['VisualStudioVersion'] \
if 'VisualStudioVersion' in os.environ else None
- relative_path = 'Auxiliary\\Build\\' if vs_version == '15.0' else ''
+ relative_path = 'Auxiliary\\Build\\' if vs_version >= '15.0' else ''
script_path = os.environ['VCINSTALLDIR'] + relative_path + 'vcvarsall.bat'
if os.path.exists(script_path):
if has_arch_values:
@@ -507,7 +510,6 @@ class Vs2010Backend(backends.Backend):
def gen_run_target_vcxproj(self, target, ofname, guid):
root = self.create_basic_crap(target, guid)
- action = ET.SubElement(root, 'ItemDefinitionGroup')
cmd_raw = [target.command] + target.args
cmd = python_command + \
[os.path.join(self.environment.get_script_dir(), 'commandrunner.py'),
diff --git a/mesonbuild/backend/vs2019backend.py b/mesonbuild/backend/vs2019backend.py
new file mode 100644
index 0000000..c6e78cb
--- /dev/null
+++ b/mesonbuild/backend/vs2019backend.py
@@ -0,0 +1,34 @@
+# Copyright 2014-2019 The Meson development team
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+
+# http://www.apache.org/licenses/LICENSE-2.0
+
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import xml.etree.ElementTree as ET
+
+from .vs2010backend import Vs2010Backend
+
+
+class Vs2019Backend(Vs2010Backend):
+ def __init__(self, build):
+ super().__init__(build)
+ self.name = 'vs2019'
+ self.platform_toolset = 'v142'
+ self.vs_version = '2019'
+ # WindowsSDKVersion should be set by command prompt.
+ sdk_version = os.environ.get('WindowsSDKVersion', None)
+ if sdk_version:
+ self.windows_target_platform_version = sdk_version.rstrip('\\')
+
+ def generate_debug_information(self, link):
+ # valid values for vs2019 is 'false', 'true', 'DebugFastLink', 'DebugFull'
+ ET.SubElement(link, 'GenerateDebugInformation').text = 'DebugFull'
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index dae94b6..66f08d8 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1365,8 +1365,17 @@ class GeneratedList:
self.outfilelist = []
self.outmap = {}
self.extra_depends = []
+ self.depend_files = []
self.preserve_path_from = preserve_path_from
self.extra_args = extra_args
+ if isinstance(generator.exe, dependencies.ExternalProgram):
+ if not generator.exe.found():
+ raise InvalidArguments('Tried to use not-found external program as generator')
+ path = generator.exe.get_path()
+ if os.path.isabs(path):
+ # Can only add a dependency on an external program which we
+ # know the absolute path of
+ self.depend_files.append(File.from_absolute_file(path))
def add_preserved_path_segment(self, infile, outfiles, state):
result = []
@@ -1962,8 +1971,7 @@ class CustomTarget(Target):
final_cmd.append(c)
elif isinstance(c, dependencies.ExternalProgram):
if not c.found():
- m = 'Tried to use not-found external program {!r} in "command"'
- raise InvalidArguments(m.format(c.name))
+ raise InvalidArguments('Tried to use not-found external program in "command"')
path = c.get_path()
if os.path.isabs(path):
# Can only add a dependency on an external program which we
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 12f7838..da9a5dc 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -1674,6 +1674,9 @@ class VisualStudioCCompiler(CCompiler):
return '14.0' # (Visual Studio 2015)
elif version < 1920:
return '14.1' # (Visual Studio 2017)
+ elif version < 1930:
+ return '14.2' # (Visual Studio 2019)
+ mlog.warning('Could not find toolset for version {!r}'.format(self.version))
return None
def get_default_include_dirs(self):
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index e29ca55..2239aa8 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -914,6 +914,12 @@ class Compiler:
def get_id(self):
return self.id
+ def get_version_string(self):
+ details = [self.id, self.version]
+ if self.full_version:
+ details += ['"%s"' % (self.full_version)]
+ return '(%s)' % (' '.join(details))
+
def get_language(self):
return self.language
@@ -1736,7 +1742,7 @@ class ElbrusCompiler(GnuCompiler):
# FIXME: use _build_wrapper to call this so that linker flags from the env
# get applied
- def get_library_dirs(self, env):
+ def get_library_dirs(self, env, elf_class = None):
os_env = os.environ.copy()
os_env['LC_ALL'] = 'C'
stdo = Popen_safe(self.exelist + ['--print-search-dirs'], env=os_env)[1]
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 67de684..87e6ffc 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -115,8 +115,8 @@ class CPPCompiler(CCompiler):
'gnu++17': 'gnu++1z'
}
- # Currently, remapping is only supported for Clang and GCC
- assert(self.id in frozenset(['clang', 'gcc']))
+ # Currently, remapping is only supported for Clang, Elbrus and GCC
+ assert(self.id in frozenset(['clang', 'lcc', 'gcc']))
if cpp_std not in CPP_FALLBACKS:
# 'c++03' and 'c++98' don't have fallback types
@@ -251,10 +251,13 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler):
# It does not support c++/gnu++ 17 and 1z, but still does support 0x, 1y, and gnu++98.
def get_options(self):
opts = CPPCompiler.get_options(self)
- opts['cpp_std'] = coredata.UserComboOption('cpp_std', 'C++ language standard to use',
- ['none', 'c++98', 'c++03', 'c++0x', 'c++11', 'c++14', 'c++1y',
- 'gnu++98', 'gnu++03', 'gnu++0x', 'gnu++11', 'gnu++14', 'gnu++1y'],
- 'none')
+ opts.update({'cpp_std': coredata.UserComboOption('cpp_std', 'C++ language standard to use',
+ ['none', 'c++98', 'c++03', 'c++0x', 'c++11', 'c++14', 'c++1y',
+ 'gnu++98', 'gnu++03', 'gnu++0x', 'gnu++11', 'gnu++14', 'gnu++1y'],
+ 'none'),
+ 'cpp_debugstl': coredata.UserBooleanOption('cpp_debugstl',
+ 'STL debug mode',
+ False)})
return opts
# Elbrus C++ compiler does not have lchmod, but there is only linker warning, not compiler error.
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 6b86529..51b36f0 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -773,39 +773,41 @@ class BuiltinOption(Generic[_U]):
kwargs['dest'] = 'cross_' + name
parser.add_argument(self.argparse_name_to_arg('cross_' + name), help=h + ' (for host in cross compiles)', **kwargs)
-
-builtin_options = {
- 'buildtype': BuiltinOption(UserComboOption, 'Build type to use', 'debug',
- choices=['plain', 'debug', 'debugoptimized', 'release', 'minsize', 'custom']),
- 'strip': BuiltinOption(UserBooleanOption, 'Strip targets on install', False),
- 'unity': BuiltinOption(UserComboOption, 'Unity build', 'off', choices=['on', 'off', 'subprojects']),
- 'prefix': BuiltinOption(UserStringOption, 'Installation prefix', default_prefix()),
- 'libdir': BuiltinOption(UserStringOption, 'Library directory', default_libdir()),
- 'libexecdir': BuiltinOption(UserStringOption, 'Library executable directory', default_libexecdir()),
- 'bindir': BuiltinOption(UserStringOption, 'Executable directory', 'bin'),
- 'sbindir': BuiltinOption(UserStringOption, 'System executable directory', 'sbin'),
- 'includedir': BuiltinOption(UserStringOption, 'Header file directory', 'include'),
- 'datadir': BuiltinOption(UserStringOption, 'Data file directory', 'share'),
- 'mandir': BuiltinOption(UserStringOption, 'Manual page directory', 'share/man'),
- 'infodir': BuiltinOption(UserStringOption, 'Info page directory', 'share/info'),
- 'localedir': BuiltinOption(UserStringOption, 'Locale data directory', 'share/locale'),
- 'sysconfdir': BuiltinOption(UserStringOption, 'Sysconf data directory', 'etc'),
- 'localstatedir': BuiltinOption(UserStringOption, 'Localstate data directory', 'var'),
- 'sharedstatedir': BuiltinOption(UserStringOption, 'Architecture-independent data directory', 'com'),
- 'werror': BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False),
- 'warning_level': BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3']),
- 'layout': BuiltinOption(UserComboOption, 'Build directory layout', 'mirror', choices=['mirror', 'flat']),
- 'default_library': BuiltinOption(UserComboOption, 'Default library type', 'shared', choices=['shared', 'static', 'both']),
- 'backend': BuiltinOption(UserComboOption, 'Backend to use', 'ninja', choices=backendlist),
- 'stdsplit': BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True),
- 'errorlogs': BuiltinOption(UserBooleanOption, "Whether to print the logs from failing tests", True),
- 'install_umask': BuiltinOption(UserUmaskOption, 'Default umask to apply on permissions of installed files', '022'),
- 'auto_features': BuiltinOption(UserFeatureOption, "Override value of all 'auto' features", 'auto'),
- 'optimization': BuiltinOption(UserComboOption, 'Optimization level', '0', choices=['0', 'g', '1', '2', '3', 's']),
- 'debug': BuiltinOption(UserBooleanOption, 'Debug', True),
- 'wrap_mode': BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback']),
- 'pkg_config_path': BuiltinOption(UserArrayOption, 'List of additional paths for pkg-config to search', [], separate_cross=True),
-}
+# Update `docs/markdown/Builtin-options.md` after changing the options below
+builtin_options = OrderedDict([
+ # Directories
+ ('prefix', BuiltinOption(UserStringOption, 'Installation prefix', default_prefix())),
+ ('bindir', BuiltinOption(UserStringOption, 'Executable directory', 'bin')),
+ ('datadir', BuiltinOption(UserStringOption, 'Data file directory', 'share')),
+ ('includedir', BuiltinOption(UserStringOption, 'Header file directory', 'include')),
+ ('infodir', BuiltinOption(UserStringOption, 'Info page directory', 'share/info')),
+ ('libdir', BuiltinOption(UserStringOption, 'Library directory', default_libdir())),
+ ('libexecdir', BuiltinOption(UserStringOption, 'Library executable directory', default_libexecdir())),
+ ('localedir', BuiltinOption(UserStringOption, 'Locale data directory', 'share/locale')),
+ ('localstatedir', BuiltinOption(UserStringOption, 'Localstate data directory', 'var')),
+ ('mandir', BuiltinOption(UserStringOption, 'Manual page directory', 'share/man')),
+ ('sbindir', BuiltinOption(UserStringOption, 'System executable directory', 'sbin')),
+ ('sharedstatedir', BuiltinOption(UserStringOption, 'Architecture-independent data directory', 'com')),
+ ('sysconfdir', BuiltinOption(UserStringOption, 'Sysconf data directory', 'etc')),
+ # Core options
+ ('auto_features', BuiltinOption(UserFeatureOption, "Override value of all 'auto' features", 'auto')),
+ ('backend', BuiltinOption(UserComboOption, 'Backend to use', 'ninja', choices=backendlist)),
+ ('buildtype', BuiltinOption(UserComboOption, 'Build type to use', 'debug',
+ choices=['plain', 'debug', 'debugoptimized', 'release', 'minsize', 'custom'])),
+ ('debug', BuiltinOption(UserBooleanOption, 'Debug', True)),
+ ('default_library', BuiltinOption(UserComboOption, 'Default library type', 'shared', choices=['shared', 'static', 'both'])),
+ ('errorlogs', BuiltinOption(UserBooleanOption, "Whether to print the logs from failing tests", True)),
+ ('install_umask', BuiltinOption(UserUmaskOption, 'Default umask to apply on permissions of installed files', '022')),
+ ('layout', BuiltinOption(UserComboOption, 'Build directory layout', 'mirror', choices=['mirror', 'flat'])),
+ ('pkg_config_path', BuiltinOption(UserArrayOption, 'List of additional paths for pkg-config to search', [], separate_cross=True)),
+ ('optimization', BuiltinOption(UserComboOption, 'Optimization level', '0', choices=['0', 'g', '1', '2', '3', 's'])),
+ ('stdsplit', BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True)),
+ ('strip', BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),
+ ('unity', BuiltinOption(UserComboOption, 'Unity build', 'off', choices=['on', 'off', 'subprojects'])),
+ ('warning_level', BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3'])),
+ ('werror', BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False)),
+ ('wrap_mode', BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback'])),
+])
# Special prefix-dependent defaults for installation directories that reside in
# a path outside of the prefix in FHS and common usage.
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index 219b3d6..55cb569 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -680,6 +680,9 @@ class GpgmeDependency(ExternalDependency):
methods = cls._process_method_kw(kwargs)
candidates = []
+ if DependencyMethods.PKGCONFIG in methods:
+ candidates.append(functools.partial(PkgConfigDependency, 'gpgme', environment, kwargs))
+
if DependencyMethods.CONFIG_TOOL in methods:
candidates.append(functools.partial(ConfigToolDependency.factory,
'gpgme', environment, None, kwargs, ['gpgme-config'],
@@ -696,7 +699,7 @@ class GpgmeDependency(ExternalDependency):
@staticmethod
def get_methods():
- return [DependencyMethods.CONFIG_TOOL]
+ return [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL]
class ShadercDependency(ExternalDependency):
@@ -732,12 +735,25 @@ class ShadercDependency(ExternalDependency):
methods = cls._process_method_kw(kwargs)
candidates = []
+ if DependencyMethods.PKGCONFIG in methods:
+ # ShaderC packages their shared and static libs together
+ # and provides different pkg-config files for each one. We
+ # smooth over this difference by handling the static
+ # keyword before handing off to the pkg-config handler.
+ shared_libs = ['shaderc']
+ static_libs = ['shaderc_combined', 'shaderc_static']
+
+ if kwargs.get('static', False):
+ c = [functools.partial(PkgConfigDependency, name, environment, kwargs)
+ for name in static_libs + shared_libs]
+ else:
+ c = [functools.partial(PkgConfigDependency, name, environment, kwargs)
+ for name in shared_libs + static_libs]
+ candidates.exend(c)
+
if DependencyMethods.SYSTEM in methods:
candidates.append(functools.partial(ShadercDependency, environment, kwargs))
- if DependencyMethods.PKGCONFIG in methods:
- candidates.append(functools.partial(PkgConfigDependency, 'shaderc', environment, kwargs))
-
return candidates
@staticmethod
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 2241089..f85decd 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -921,6 +921,8 @@ class Environment:
return GnuObjCCompiler(ccache + compiler, version, compiler_type, is_cross, exe_wrap, defines)
if out.startswith('Apple LLVM'):
return ClangObjCCompiler(ccache + compiler, version, CompilerType.CLANG_OSX, is_cross, exe_wrap)
+ if 'windows' in out:
+ return ClangObjCCompiler(ccache + compiler, version, CompilerType.CLANG_MINGW, is_cross, exe_wrap)
if out.startswith(('clang', 'OpenBSD clang')):
return ClangObjCCompiler(ccache + compiler, version, CompilerType.CLANG_STANDARD, is_cross, exe_wrap)
self._handle_exceptions(popen_exceptions, compilers)
@@ -948,6 +950,8 @@ class Environment:
return GnuObjCPPCompiler(ccache + compiler, version, compiler_type, is_cross, exe_wrap, defines)
if out.startswith('Apple LLVM'):
return ClangObjCPPCompiler(ccache + compiler, version, CompilerType.CLANG_OSX, is_cross, exe_wrap)
+ if 'windows' in out:
+ return ClangObjCPPCompiler(ccache + compiler, version, CompilerType.CLANG_MINGW, is_cross, exe_wrap)
if out.startswith(('clang', 'OpenBSD clang')):
return ClangObjCPPCompiler(ccache + compiler, version, CompilerType.CLANG_STANDARD, is_cross, exe_wrap)
self._handle_exceptions(popen_exceptions, compilers)
@@ -1084,65 +1088,43 @@ class Environment:
return compilers.SwiftCompiler(exelist, version)
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
- def compilers_from_language(self, lang: str, need_cross_compiler: bool):
- comp = None
- cross_comp = None
+ def compiler_from_language(self, lang: str, want_cross: bool):
if lang == 'c':
- comp = self.detect_c_compiler(False)
- if need_cross_compiler:
- cross_comp = self.detect_c_compiler(True)
+ comp = self.detect_c_compiler(want_cross)
elif lang == 'cpp':
- comp = self.detect_cpp_compiler(False)
- if need_cross_compiler:
- cross_comp = self.detect_cpp_compiler(True)
+ comp = self.detect_cpp_compiler(want_cross)
elif lang == 'objc':
- comp = self.detect_objc_compiler(False)
- if need_cross_compiler:
- cross_comp = self.detect_objc_compiler(True)
+ comp = self.detect_objc_compiler(want_cross)
elif lang == 'cuda':
- comp = self.detect_cuda_compiler(False)
- if need_cross_compiler:
- cross_comp = self.detect_cuda_compiler(True)
+ comp = self.detect_cuda_compiler(want_cross)
elif lang == 'objcpp':
- comp = self.detect_objcpp_compiler(False)
- if need_cross_compiler:
- cross_comp = self.detect_objcpp_compiler(True)
+ comp = self.detect_objcpp_compiler(want_cross)
elif lang == 'java':
- comp = self.detect_java_compiler()
- if need_cross_compiler:
- cross_comp = comp # Java is platform independent.
+ comp = self.detect_java_compiler() # Java is platform independent.
elif lang == 'cs':
- comp = self.detect_cs_compiler()
- if need_cross_compiler:
- cross_comp = comp # C# is platform independent.
+ comp = self.detect_cs_compiler() # C# is platform independent.
elif lang == 'vala':
- comp = self.detect_vala_compiler()
- if need_cross_compiler:
- cross_comp = comp # Vala compiles to platform-independent C
+ comp = self.detect_vala_compiler() # Vala compiles to platform-independent C
elif lang == 'd':
- comp = self.detect_d_compiler(False)
- if need_cross_compiler:
- cross_comp = self.detect_d_compiler(True)
+ comp = self.detect_d_compiler(want_cross)
elif lang == 'rust':
- comp = self.detect_rust_compiler(False)
- if need_cross_compiler:
- cross_comp = self.detect_rust_compiler(True)
+ comp = self.detect_rust_compiler(want_cross)
elif lang == 'fortran':
- comp = self.detect_fortran_compiler(False)
- if need_cross_compiler:
- cross_comp = self.detect_fortran_compiler(True)
+ comp = self.detect_fortran_compiler(want_cross)
elif lang == 'swift':
- comp = self.detect_swift_compiler()
- if need_cross_compiler:
+ if want_cross:
raise EnvironmentException('Cross compilation with Swift is not working yet.')
- # cross_comp = self.environment.detect_fortran_compiler(True)
+ comp = self.detect_swift_compiler()
else:
- return None, None
-
- return comp, cross_comp
+ comp = None
+ return comp
def detect_compilers(self, lang: str, need_cross_compiler: bool):
- (comp, cross_comp) = self.compilers_from_language(lang, need_cross_compiler)
+ comp = self.compiler_from_language(lang, False)
+ if need_cross_compiler:
+ cross_comp = self.compiler_from_language(lang, True)
+ else:
+ cross_comp = None
if comp is not None:
self.coredata.process_new_compilers(lang, comp, cross_comp, self)
return comp, cross_comp
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 993ebbd..3a3fb81 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2575,6 +2575,12 @@ external dependencies (including libraries) must go to "dependencies".''')
if ':' in proj_name:
raise InvalidArguments("Project name {!r} must not contain ':'".format(proj_name))
+ if 'meson_version' in kwargs:
+ cv = coredata.version
+ pv = kwargs['meson_version']
+ if not mesonlib.version_compare(cv, pv):
+ raise InterpreterException('Meson version is %s but project requires %s' % (cv, pv))
+
if os.path.exists(self.option_file):
oi = optinterpreter.OptionInterpreter(self.subproject)
oi.process(self.option_file)
@@ -2621,11 +2627,8 @@ external dependencies (including libraries) must go to "dependencies".''')
mesonlib.project_meson_versions[self.subproject] = ''
if 'meson_version' in kwargs:
- cv = coredata.version
- pv = kwargs['meson_version']
- mesonlib.project_meson_versions[self.subproject] = pv
- if not mesonlib.version_compare(cv, pv):
- raise InterpreterException('Meson version is %s but project requires %s.' % (cv, pv))
+ mesonlib.project_meson_versions[self.subproject] = kwargs['meson_version']
+
self.build.projects[self.subproject] = proj_name
mlog.log('Project name:', mlog.bold(proj_name))
mlog.log('Project version:', mlog.bold(self.project_version))
@@ -2710,17 +2713,12 @@ external dependencies (including libraries) must go to "dependencies".''')
continue
else:
raise
- if comp.full_version is not None:
- version_string = '(%s %s "%s")' % (comp.id, comp.version, comp.full_version)
- else:
- version_string = '(%s %s)' % (comp.id, comp.version)
mlog.log('Native', comp.get_display_language(), 'compiler:',
- mlog.bold(' '.join(comp.get_exelist())), version_string)
+ mlog.bold(' '.join(comp.get_exelist())), comp.get_version_string())
self.build.ensure_static_linker(comp)
if need_cross_compiler:
- version_string = '(%s %s)' % (cross_comp.id, cross_comp.version)
mlog.log('Cross', cross_comp.get_display_language(), 'compiler:',
- mlog.bold(' '.join(cross_comp.get_exelist())), version_string)
+ mlog.bold(' '.join(cross_comp.get_exelist())), cross_comp.get_version_string())
self.build.ensure_static_cross_linker(cross_comp)
langs = self.coredata.compilers.keys()
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 91a52b1..e7005e9 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -81,14 +81,18 @@ class CommandLineParser:
self.commands[i] = p
def add_runpython_arguments(self, parser):
+ parser.add_argument('-c', action='store_true', dest='eval_arg', default=False)
parser.add_argument('script_file')
parser.add_argument('script_args', nargs=argparse.REMAINDER)
def run_runpython_command(self, options):
import runpy
- sys.argv[1:] = options.script_args
- sys.path.insert(0, os.path.dirname(options.script_file))
- runpy.run_path(options.script_file, run_name='__main__')
+ if options.eval_arg:
+ exec(options.script_file)
+ else:
+ sys.argv[1:] = options.script_args
+ sys.path.insert(0, os.path.dirname(options.script_file))
+ runpy.run_path(options.script_file, run_name='__main__')
return 0
def add_help_arguments(self, parser):
diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py
index bd69244..a0ebe0e 100644
--- a/mesonbuild/modules/python.py
+++ b/mesonbuild/modules/python.py
@@ -42,9 +42,8 @@ mod_kwargs -= set(['name_prefix', 'name_suffix'])
def run_command(python, command):
- _, stdout, _ = mesonlib.Popen_safe(python.get_command() + [
- '-c',
- command])
+ cmd = python.get_command() + ['-c', command]
+ _, stdout, _ = mesonlib.Popen_safe(cmd)
return stdout.strip()
@@ -265,8 +264,7 @@ class PythonDependency(ExternalDependency):
return super().get_pkgconfig_variable(variable_name, kwargs)
-INTROSPECT_COMMAND = '''
-import sysconfig
+INTROSPECT_COMMAND = '''import sysconfig
import json
import sys
diff --git a/msi/createmsi.py b/msi/createmsi.py
index a7a9c3c..4eb5111 100755
--- a/msi/createmsi.py
+++ b/msi/createmsi.py
@@ -84,6 +84,28 @@ class PackageGenerator:
modules = ['mesonbuild.' + modname + '.' + x for x in modules if not x.startswith('_')]
return modules
+ def get_more_modules(self):
+ # Python packagers want to minimal and only copy the things that
+ # they can see that are used. They are blind to many things.
+ return ['distutils.archive_util',
+ 'distutils.cmd',
+ 'distutils.config',
+ 'distutils.core',
+ 'distutils.debug',
+ 'distutils.dep_util',
+ 'distutils.dir_util',
+ 'distutils.dist',
+ 'distutils.errors',
+ 'distutils.extension',
+ 'distutils.fancy_getopt',
+ 'distutils.file_util',
+ 'distutils.spawn',
+ 'distutils.util',
+ 'distutils.version',
+ 'distutils.command.build_ext',
+ 'distutils.command.build',
+ ]
+
def build_dist(self):
for sdir in self.staging_dirs:
if os.path.exists(sdir):
@@ -91,7 +113,7 @@ class PackageGenerator:
main_stage, ninja_stage = self.staging_dirs
modules = self.get_all_modules_from_dir('mesonbuild/modules')
modules += self.get_all_modules_from_dir('mesonbuild/scripts')
- modules += ['distutils.version']
+ modules += self.get_more_modules()
modulestr = ','.join(modules)
python = shutil.which('python')
cxfreeze = os.path.join(os.path.dirname(python), "Scripts", "cxfreeze")
diff --git a/run_project_tests.py b/run_project_tests.py
index fdb5f48..c1d42fc 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -27,6 +27,7 @@ import tempfile
from pathlib import Path, PurePath
from mesonbuild import build
from mesonbuild import environment
+from mesonbuild import compilers
from mesonbuild import mesonlib
from mesonbuild import mlog
from mesonbuild import mtest
@@ -564,8 +565,8 @@ def detect_tests_to_run():
('vala', 'vala', backend is not Backend.ninja or not shutil.which('valac')),
('rust', 'rust', backend is not Backend.ninja or not shutil.which('rustc')),
('d', 'd', backend is not Backend.ninja or not have_d_compiler()),
- ('objective c', 'objc', backend not in (Backend.ninja, Backend.xcode) or mesonlib.is_windows() or not have_objc_compiler()),
- ('objective c++', 'objcpp', backend not in (Backend.ninja, Backend.xcode) or mesonlib.is_windows() or not have_objcpp_compiler()),
+ ('objective c', 'objc', backend not in (Backend.ninja, Backend.xcode) or not have_objc_compiler()),
+ ('objective c++', 'objcpp', backend not in (Backend.ninja, Backend.xcode) or not have_objcpp_compiler()),
('fortran', 'fortran', backend is not Backend.ninja or not shutil.which('gfortran')),
('swift', 'swift', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('swiftc')),
('cuda', 'cuda', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('nvcc')),
@@ -768,11 +769,23 @@ def detect_system_compiler():
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir:
env = environment.Environment(None, build_dir, get_fake_options('/'))
- try:
- comp = env.detect_c_compiler(env.is_cross_build())
- except:
- raise RuntimeError("Could not find C compiler.")
- system_compiler = comp.get_id()
+ print()
+ for lang in sorted(compilers.all_languages):
+ try:
+ comp = env.compiler_from_language(lang, env.is_cross_build())
+ details = '%s %s' % (' '.join(comp.get_exelist()), comp.get_version_string())
+ except:
+ comp = None
+ details = 'not found'
+ print('%-7s: %s' % (lang, details))
+
+ # note C compiler for later use by platform_fix_name()
+ if lang == 'c':
+ if comp:
+ system_compiler = comp.get_id()
+ else:
+ raise RuntimeError("Could not find C compiler.")
+ print()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Run the test suite of Meson.")
diff --git a/run_tests.py b/run_tests.py
index d72546b..fb3bc28 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -292,7 +292,7 @@ def main():
os.environ.pop('platform')
# Run tests
print(mlog.bold('Running unittests.').get_text(mlog.colorize_console))
- print()
+ print(flush=True)
# Can't pass arguments to unit tests, so set the backend to use in the environment
env = os.environ.copy()
env['MESON_UNIT_TEST_BACKEND'] = backend.name
@@ -325,7 +325,7 @@ def main():
else:
cross_test_args = mesonlib.python_command + ['run_cross_test.py']
print(mlog.bold('Running armhf cross tests.').get_text(mlog.colorize_console))
- print()
+ print(flush=True)
cmd = cross_test_args + ['cross/ubuntu-armhf.txt']
if options.failfast:
cmd += ['--failfast']
@@ -334,7 +334,7 @@ def main():
return returncode
print(mlog.bold('Running mingw-w64 64-bit cross tests.')
.get_text(mlog.colorize_console))
- print()
+ print(flush=True)
cmd = cross_test_args + ['cross/linux-mingw-w64-64bit.txt']
if options.failfast:
cmd += ['--failfast']
diff --git a/run_unittests.py b/run_unittests.py
index 156e4b8..faef00f 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -958,6 +958,25 @@ class InternalTests(unittest.TestCase):
self.assertEqual(ver_a.__cmp__(ver_b), result)
self.assertEqual(ver_b.__cmp__(ver_a), -result)
+ def test_msvc_toolset_version(self):
+ '''
+ Ensure that the toolset version returns the correct value for this MSVC
+ '''
+ env = get_fake_env()
+ cc = env.detect_c_compiler(False)
+ if cc.get_argument_syntax() != 'msvc':
+ raise unittest.SkipTest('Test only applies to MSVC-like compilers')
+ toolset_ver = cc.get_toolset_version()
+ self.assertIsNotNone(toolset_ver)
+ # Visual Studio 2015 and older versions do not define VCToolsVersion
+ if int(''.join(cc.version.split('.')[0:2])) < 1910:
+ return
+ self.assertIn('VCToolsVersion', os.environ)
+ vctools_ver = os.environ['VCToolsVersion']
+ self.assertTrue(vctools_ver.startswith(toolset_ver),
+ msg='{!r} does not start with {!r}'.format(vctools_ver, toolset_ver))
+
+
@unittest.skipIf(is_tarball(), 'Skipping because this is a tarball release')
class DataTests(unittest.TestCase):
@@ -2144,6 +2163,20 @@ class AllPlatformTests(BasePlatformTests):
self.utime(os.path.join(testdir, f))
self.assertRebuiltTarget('prog')
+ def test_source_generator_program_cause_rebuild(self):
+ '''
+ Test that changes to generator programs in the source tree cause
+ a rebuild.
+ '''
+ testdir = os.path.join(self.common_test_dir, '95 gen extra')
+ self.init(testdir)
+ self.build()
+ # Immediately rebuilding should not do anything
+ self.assertBuildIsNoop()
+ # Changing mtime of generator should rebuild the executable
+ self.utime(os.path.join(testdir, 'srcgen.py'))
+ self.assertRebuiltTarget('basic')
+
def test_static_library_lto(self):
'''
Test that static libraries can be built with LTO and linked to
@@ -3611,12 +3644,13 @@ class FailureTests(BasePlatformTests):
super().setUp()
self.srcdir = os.path.realpath(tempfile.mkdtemp())
self.mbuild = os.path.join(self.srcdir, 'meson.build')
+ self.moptions = os.path.join(self.srcdir, 'meson_options.txt')
def tearDown(self):
super().tearDown()
windows_proof_rmtree(self.srcdir)
- def assertMesonRaises(self, contents, match, extra_args=None, langs=None, meson_version=None):
+ def assertMesonRaises(self, contents, match, extra_args=None, langs=None, meson_version=None, options=None):
'''
Assert that running meson configure on the specified @contents raises
a error message matching regex @match.
@@ -3631,6 +3665,9 @@ class FailureTests(BasePlatformTests):
for lang in langs:
f.write("add_languages('{}', required : false)\n".format(lang))
f.write(contents)
+ if options is not None:
+ with open(self.moptions, 'w') as f:
+ f.write(options)
# Force tracebacks so we can detect them properly
os.environ['MESON_FORCE_BACKTRACE'] = '1'
with self.assertRaisesRegex(MesonException, match, msg=contents):
@@ -3863,6 +3900,14 @@ class FailureTests(BasePlatformTests):
"sub1.get_variable('naaa')",
"""Subproject "subprojects/not-found-subproject" disabled can't get_variable on it.""")
+ def test_version_checked_before_parsing_options(self):
+ '''
+ https://github.com/mesonbuild/meson/issues/5281
+ '''
+ options = "option('some-option', type: 'foo', value: '')"
+ match = 'Meson version is.*but project requires >=2000'
+ self.assertMesonRaises("", match, meson_version='>=2000', options=options)
+
@unittest.skipUnless(is_windows() or is_cygwin(), "requires Windows (or Windows via Cygwin)")
class WindowsTests(BasePlatformTests):
@@ -5796,7 +5841,11 @@ class NativeFileTests(BasePlatformTests):
@skip_if_env_set('FC')
def test_fortran_compiler(self):
def cb(comp):
- if comp.id == 'gcc':
+ if comp.id == 'lcc':
+ if shutil.which('lfortran'):
+ return 'lfortran', 'lcc'
+ raise unittest.SkipTest('No alternate Fortran implementation.')
+ elif comp.id == 'gcc':
if shutil.which('ifort'):
return 'ifort', 'intel'
elif shutil.which('flang'):
diff --git a/test cases/failing/96 dependency not config-tool/96 unknown config tool/meson.build b/test cases/failing/96 dependency not config-tool/96 unknown config tool/meson.build
new file mode 100644
index 0000000..536976e
--- /dev/null
+++ b/test cases/failing/96 dependency not config-tool/96 unknown config tool/meson.build
@@ -0,0 +1,2 @@
+project('no-such-config-tool')
+dependency('no-such-config-tool', method:'config-tool')
diff --git a/test cases/frameworks/27 gpgme/meson.build b/test cases/frameworks/27 gpgme/meson.build
index 220a4c0..91b1aaa 100644
--- a/test cases/frameworks/27 gpgme/meson.build
+++ b/test cases/frameworks/27 gpgme/meson.build
@@ -19,3 +19,9 @@ dependency('gpgme', method: 'config-tool')
# Check we can apply a version constraint
dependency('gpgme', version: '>=@0@'.format(gpgme_dep.version()), method: 'config-tool')
+
+# If gpgme is new enough, make sure it picks up pkg-config by default:
+
+if gpgme_ver.version_compare('>=1.13.0')
+ assert(gpgme_dep.type_name() == 'pkgconfig', 'dependency found via pkg-config')
+endif