aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--azure-pipelines.yml2
-rw-r--r--docs/markdown/Builtin-options.md2
-rw-r--r--docs/markdown/Configuring-a-build-directory.md5
-rw-r--r--docs/markdown/Cuda-module.md2
-rw-r--r--docs/markdown/snippets/configure_default_opts.md6
-rw-r--r--docs/markdown/snippets/fortran_submodule.md12
-rw-r--r--mesonbuild/backend/ninjabackend.py89
-rw-r--r--mesonbuild/backend/vs2010backend.py14
-rw-r--r--mesonbuild/compilers/d.py2
-rw-r--r--mesonbuild/compilers/fortran.py2
-rw-r--r--mesonbuild/dependencies/base.py4
-rw-r--r--mesonbuild/mconf.py59
-rw-r--r--mesonbuild/mintro.py2
-rw-r--r--mesonbuild/mtest.py7
-rw-r--r--test cases/common/13 pch/generated/gen_custom.py5
-rw-r--r--test cases/common/13 pch/generated/gen_generator.py7
-rw-r--r--test cases/common/13 pch/generated/generated_generator.in1
-rw-r--r--test cases/common/13 pch/generated/meson.build16
-rw-r--r--test cases/common/13 pch/generated/pch/prog.h2
-rw-r--r--test cases/common/13 pch/generated/pch/prog_pch.c5
-rw-r--r--test cases/common/13 pch/generated/prog.c6
-rw-r--r--test cases/common/13 pch/meson.build2
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h1
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/meson.build9
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/pch/prog.h1
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c5
-rw-r--r--test cases/common/13 pch/withIncludeDirectories/prog.c10
-rw-r--r--test cases/fortran/12 submodule/a1.f9025
-rw-r--r--test cases/fortran/12 submodule/a2.f9010
-rw-r--r--test cases/fortran/12 submodule/a3.f9010
-rw-r--r--test cases/fortran/12 submodule/child.f9010
-rw-r--r--test cases/fortran/12 submodule/meson.build7
-rw-r--r--test cases/fortran/12 submodule/parent.f9023
33 files changed, 312 insertions, 51 deletions
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 39e41e9..90ebeff 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -136,6 +136,7 @@ jobs:
git ^
mercurial ^
mingw-w64-$(MSYS2_ARCH)-cmake ^
+ mingw-w64-$(MSYS2_ARCH)-ninja ^
mingw-w64-$(MSYS2_ARCH)-pkg-config ^
mingw-w64-$(MSYS2_ARCH)-python2 ^
mingw-w64-$(MSYS2_ARCH)-python3 ^
@@ -144,7 +145,6 @@ jobs:
displayName: Install Dependencies
- script: |
set PATH=%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem
- %MSYS2_ROOT%\usr\bin\bash -lc "wget https://github.com/mesonbuild/cidata/raw/master/ninja.exe; mv ninja.exe /$MSYSTEM/bin"
set PATHEXT=%PATHEXT%;.py
if %compiler%==clang ( set CC=clang && set CXX=clang++ )
%MSYS2_ROOT%\usr\bin\bash -lc "MSYSTEM= python3 run_tests.py --backend=ninja"
diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md
index 288bd79..0d1a16b 100644
--- a/docs/markdown/Builtin-options.md
+++ b/docs/markdown/Builtin-options.md
@@ -42,7 +42,7 @@ Installation options are all relative to the prefix, except:
| werror | false | Treat warnings as errors |
| warning_level {1, 2, 3} | 1 | Set the warning level. From 1 = lowest to 3 = highest |
| layout {mirror,flat} | mirror | Build directory layout. |
-| default-library {shared, static, both} | shared | Default library type. |
+| default_library {shared, static, both} | shared | Default library type. |
| backend {ninja, vs,<br>vs2010, vs2015, vs2017, xcode} | | Backend to use (default: ninja). |
| stdsplit | | Split stdout and stderr in test logs. |
| errorlogs | | Whether to print the logs from failing tests. |
diff --git a/docs/markdown/Configuring-a-build-directory.md b/docs/markdown/Configuring-a-build-directory.md
index 0c7487f..91ad6f7 100644
--- a/docs/markdown/Configuring-a-build-directory.md
+++ b/docs/markdown/Configuring-a-build-directory.md
@@ -111,3 +111,8 @@ you would issue the following command.
Then you would run your build command (usually `ninja`), which would
cause Meson to detect that the build setup has changed and do all the
work required to bring your build tree up to date.
+
+Since 0.50.0, it is also possible to get a list of all build options
+by invoking `meson configure` with the project source directory or
+the path to the root `meson.build`. In this case, meson will print the
+default values of all options similar to the example output from above.
diff --git a/docs/markdown/Cuda-module.md b/docs/markdown/Cuda-module.md
index 6e7be47..caa1756 100644
--- a/docs/markdown/Cuda-module.md
+++ b/docs/markdown/Cuda-module.md
@@ -6,7 +6,7 @@ authors:
has-copyright: false
...
-# Unstable CUDA Module (`unstable-cuda`)
+# Unstable CUDA Module
_Since: 0.50.0_
This module provides helper functionality related to the CUDA Toolkit and
diff --git a/docs/markdown/snippets/configure_default_opts.md b/docs/markdown/snippets/configure_default_opts.md
new file mode 100644
index 0000000..4b88bdf
--- /dev/null
+++ b/docs/markdown/snippets/configure_default_opts.md
@@ -0,0 +1,6 @@
+## meson configure can now print the default options of an unconfigured project
+
+With this release, it is also possible to get a list of all build options
+by invoking `meson configure` with the project source directory or
+the path to the root `meson.build`. In this case, meson will print the
+default values of all options.
diff --git a/docs/markdown/snippets/fortran_submodule.md b/docs/markdown/snippets/fortran_submodule.md
new file mode 100644
index 0000000..9e4b9cc
--- /dev/null
+++ b/docs/markdown/snippets/fortran_submodule.md
@@ -0,0 +1,12 @@
+## Fortran submodule support
+
+Initial support for Fortran ``submodule`` was added, where the submodule is in
+the same or different file than the parent ``module``.
+The submodule hierarchy specified in the source Fortran code `submodule`
+statements are used by Meson to resolve source file dependencies.
+For example:
+
+```fortran
+submodule (ancestor:parent) child
+```
+
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 87f9b38..afef9a9 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -11,7 +11,7 @@
# 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.
-
+from typing import List
import os
import re
import shlex
@@ -29,7 +29,7 @@ from .. import build
from .. import mlog
from .. import dependencies
from .. import compilers
-from ..compilers import CompilerArgs, CCompiler, VisualStudioCCompiler
+from ..compilers import CompilerArgs, CCompiler, VisualStudioCCompiler, FortranCompiler
from ..linkers import ArLinker
from ..mesonlib import File, MachineChoice, MesonException, OrderedSet
from ..mesonlib import get_compiler_for_source, has_path_sep
@@ -428,12 +428,7 @@ int dummy;
# Generate rules for building the remaining source files in this target
outname = self.get_target_filename(target)
obj_list = []
- use_pch = self.environment.coredata.base_options.get('b_pch', False)
is_unity = self.is_unity(target)
- if use_pch and target.has_pch():
- pch_objects = self.generate_pch(target, outfile)
- else:
- pch_objects = []
header_deps = []
unity_src = []
unity_deps = [] # Generated sources that must be built before compiling a Unity target.
@@ -486,6 +481,12 @@ int dummy;
header_deps=header_deps)
obj_list.append(o)
+ use_pch = self.environment.coredata.base_options.get('b_pch', False)
+ if use_pch and target.has_pch():
+ pch_objects = self.generate_pch(target, outfile, header_deps=header_deps)
+ else:
+ pch_objects = []
+
# Generate compilation targets for C sources generated from Vala
# sources. This can be extended to other $LANG->C compilers later if
# necessary. This needs to be separate for at least Vala
@@ -1826,7 +1827,8 @@ rule FORTRAN_DEP_HACK%s
if compiler is None:
self.fortran_deps[target.get_basename()] = {}
return
- modre = re.compile(r"\bmodule\s+(\w+)\s*$", re.IGNORECASE)
+ modre = re.compile(r"\s*\bmodule\b\s+(\w+)\s*$", re.IGNORECASE)
+ submodre = re.compile(r"\s*\bsubmodule\b\s+\((\w+:?\w+)\)\s+(\w+)\s*$", re.IGNORECASE)
module_files = {}
for s in target.get_sources():
# FIXME, does not work for Fortran sources generated by
@@ -1836,9 +1838,8 @@ rule FORTRAN_DEP_HACK%s
continue
filename = s.absolute_path(self.environment.get_source_dir(),
self.environment.get_build_dir())
- # Some Fortran editors save in weird encodings,
- # but all the parts we care about are in ASCII.
- with open(filename, errors='ignore') as f:
+ # Fortran keywords must be ASCII.
+ with open(filename, encoding='ascii', errors='ignore') as f:
for line in f:
modmatch = modre.match(line)
if modmatch is not None:
@@ -1849,18 +1850,32 @@ rule FORTRAN_DEP_HACK%s
'two files %s and %s.' %
(modname, module_files[modname], s))
module_files[modname] = s
+ else:
+ submodmatch = submodre.match(line)
+ if submodmatch is not None:
+ submodname = submodmatch.group(2).lower()
+ if submodname in module_files:
+ raise InvalidArguments(
+ 'Namespace collision: submodule %s defined in '
+ 'two files %s and %s.' %
+ (submodname, module_files[submodname], s))
+ module_files[submodname] = s
+
self.fortran_deps[target.get_basename()] = module_files
- def get_fortran_deps(self, compiler, src, target):
+ def get_fortran_deps(self, compiler: FortranCompiler, src: str, target) -> List[str]:
mod_files = []
- usere = re.compile(r"\s*use\s+(\w+)", re.IGNORECASE)
+ usere = re.compile(r"\s*use,?\s*(?:non_intrinsic)?\s*(?:::)?\s*(\w+)", re.IGNORECASE)
+ submodre = re.compile(r"\s*\bsubmodule\b\s+\((\w+:?\w+)\)\s+(\w+)\s*$", re.IGNORECASE)
dirname = self.get_target_private_dir(target)
tdeps = self.fortran_deps[target.get_basename()]
- with open(src) as f:
+ with open(src, encoding='ascii', errors='ignore') as f:
for line in f:
usematch = usere.match(line)
if usematch is not None:
usename = usematch.group(1).lower()
+ if usename == 'intrinsic': # this keeps the regex simpler
+ continue
if usename not in tdeps:
# The module is not provided by any source file. This
# is due to:
@@ -1879,9 +1894,23 @@ rule FORTRAN_DEP_HACK%s
# the same name.
if mod_source_file.fname == os.path.basename(src):
continue
- mod_name = compiler.module_name_to_filename(
- usematch.group(1))
+ mod_name = compiler.module_name_to_filename(usename)
mod_files.append(os.path.join(dirname, mod_name))
+ else:
+ submodmatch = submodre.match(line)
+ if submodmatch is not None:
+ parents = submodmatch.group(1).lower().split(':')
+ assert len(parents) in (1, 2), (
+ 'submodule ancestry must be specified as'
+ ' ancestor:parent but Meson found {}'.parents)
+ for parent in parents:
+ if parent not in tdeps:
+ raise MesonException("submodule {} relies on parent module {} that was not found.".format(submodmatch.group(2).lower(), parent))
+ if tdeps[parent].fname == os.path.basename(src): # same file
+ continue
+ mod_name = compiler.module_name_to_filename(parent)
+ mod_files.append(os.path.join(dirname, mod_name))
+
return mod_files
def get_cross_stdlib_args(self, target, compiler):
@@ -2181,12 +2210,7 @@ rule FORTRAN_DEP_HACK%s
commands += compiler.get_module_outdir_args(self.get_target_private_dir(target))
element = NinjaBuildElement(self.all_outputs, rel_obj, compiler_name, rel_src)
- for d in header_deps:
- if isinstance(d, File):
- d = d.rel_to_builddir(self.build_to_src)
- elif not self.has_dir_part(d):
- d = os.path.join(self.get_target_private_dir(target), d)
- element.add_dep(d)
+ self.add_header_deps(target, element, header_deps)
for d in extra_deps:
element.add_dep(d)
for d in order_deps:
@@ -2195,7 +2219,14 @@ rule FORTRAN_DEP_HACK%s
elif not self.has_dir_part(d):
d = os.path.join(self.get_target_private_dir(target), d)
element.add_orderdep(d)
- element.add_orderdep(pch_dep)
+ if compiler.id == 'msvc':
+ # MSVC does not show includes coming from the PCH with '/showIncludes',
+ # thus we must add an implicit dependency to the generated PCH.
+ element.add_dep(pch_dep)
+ else:
+ # All other compilers properly handle includes through the PCH, so only an
+ # orderdep is needed to make the initial build without depfile work.
+ element.add_orderdep(pch_dep)
# Convert from GCC-style link argument naming to the naming used by the
# current compiler.
commands = commands.to_native()
@@ -2206,6 +2237,14 @@ rule FORTRAN_DEP_HACK%s
element.write(outfile)
return rel_obj
+ def add_header_deps(self, target, ninja_element, header_deps):
+ for d in header_deps:
+ if isinstance(d, File):
+ d = d.rel_to_builddir(self.build_to_src)
+ elif not self.has_dir_part(d):
+ d = os.path.join(self.get_target_private_dir(target), d)
+ ninja_element.add_dep(d)
+
def has_dir_part(self, fname):
# FIXME FIXME: The usage of this is a terrible and unreliable hack
if isinstance(fname, File):
@@ -2236,6 +2275,7 @@ rule FORTRAN_DEP_HACK%s
just_name = os.path.basename(header)
(objname, pch_args) = compiler.gen_pch_args(just_name, source, dst)
commands += pch_args
+ commands += self._generate_single_compile(target, compiler)
commands += self.get_compile_debugfile_args(compiler, target, objname)
dep = dst + '.' + compiler.get_depfile_suffix()
return commands, dep, dst, [objname]
@@ -2251,7 +2291,7 @@ rule FORTRAN_DEP_HACK%s
dep = dst + '.' + compiler.get_depfile_suffix()
return commands, dep, dst, [] # Gcc does not create an object file during pch generation.
- def generate_pch(self, target, outfile):
+ def generate_pch(self, target, outfile, header_deps=[]):
cstr = ''
pch_objects = []
if target.is_cross:
@@ -2282,6 +2322,7 @@ rule FORTRAN_DEP_HACK%s
elem = NinjaBuildElement(self.all_outputs, dst, rulename, src)
if extradep is not None:
elem.add_dep(extradep)
+ self.add_header_deps(target, elem, header_deps)
elem.add_item('ARGS', commands)
elem.add_item('DEPFILE', dep)
elem.write(outfile)
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 074c3a9..8029d58 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -312,8 +312,6 @@ class Vs2010Backend(backends.Backend):
target_dict, recursive=True)
ofile.write('\tProjectSection(ProjectDependencies) = '
'postProject\n')
- regen_guid = self.environment.coredata.regen_guid
- ofile.write('\t\t{%s} = {%s}\n' % (regen_guid, regen_guid))
for dep in all_deps.keys():
guid = self.environment.coredata.target_guids[dep]
ofile.write('\t\t{%s} = {%s}\n' % (guid, guid))
@@ -520,6 +518,7 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(customstep, 'Command').text = cmd_templ % tuple(cmd)
ET.SubElement(customstep, 'Message').text = 'Running custom command.'
ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
+ self.add_regen_dependency(root)
self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)
def gen_custom_target_vcxproj(self, target, ofname, guid):
@@ -547,6 +546,7 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(customstep, 'Inputs').text = ';'.join([exe_data] + srcs + depend_files)
ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
self.generate_custom_generator_commands(target, root)
+ self.add_regen_dependency(root)
self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)
@classmethod
@@ -1213,9 +1213,7 @@ class Vs2010Backend(backends.Backend):
self.add_generated_objects(inc_objs, gen_objs)
ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
- # Reference the regen target.
- regen_vcxproj = os.path.join(self.environment.get_build_dir(), 'REGEN.vcxproj')
- self.add_project_reference(root, regen_vcxproj, self.environment.coredata.regen_guid)
+ self.add_regen_dependency(root)
self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)
def gen_regenproj(self, project_name, ofname):
@@ -1366,6 +1364,7 @@ if %%errorlevel%% neq 0 goto :VCEnd'''
ET.SubElement(postbuild, 'Command').text =\
cmd_templ % ('" "'.join(test_command))
ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
+ self.add_regen_dependency(root)
self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)
def gen_installproj(self, target_name, ofname):
@@ -1434,8 +1433,13 @@ if %%errorlevel%% neq 0 goto :VCEnd'''
ET.SubElement(postbuild, 'Command').text =\
cmd_templ % ('" "'.join(test_command))
ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.targets')
+ self.add_regen_dependency(root)
self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname)
def generate_debug_information(self, link):
# valid values for vs2015 is 'false', 'true', 'DebugFastLink'
ET.SubElement(link, 'GenerateDebugInformation').text = 'true'
+
+ def add_regen_dependency(self, root):
+ regen_vcxproj = os.path.join(self.environment.get_build_dir(), 'REGEN.vcxproj')
+ self.add_project_reference(root, regen_vcxproj, self.environment.coredata.regen_guid)
diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py
index 1390694..40906c5 100644
--- a/mesonbuild/compilers/d.py
+++ b/mesonbuild/compilers/d.py
@@ -380,7 +380,7 @@ class DCompiler(Compiler):
# translate library link flag
dcargs.append('-L=' + arg)
continue
- elif arg.startswith('-L'):
+ elif arg.startswith('-L/') or arg.startswith('-L./'):
# we need to handle cases where -L is set by e.g. a pkg-config
# setting to select a linker search path. We can however not
# unconditionally prefix '-L' with '-L' because the user might
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index eea1660..8c50736 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -179,7 +179,7 @@ class FortranCompiler(Compiler):
return parameter_list
- def module_name_to_filename(self, module_name):
+ def module_name_to_filename(self, module_name: str) -> str:
return module_name.lower() + '.mod'
def get_std_shared_lib_link_args(self):
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 9da0d7c..8196124 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -1674,9 +1674,9 @@ class DubDependency(ExternalDependency):
return ''
# Ex.: library-debug-linux.posix-x86_64-ldc_2081-EF934983A3319F8F8FF2F0E107A363BA
- build_name = 'library-{}-{}-{}-{}_{}'.format(description['buildType'], '.'.join(description['platform']), '.'.join(description['architecture']), comp, d_ver)
+ build_name = '-{}-{}-{}-{}_{}'.format(description['buildType'], '.'.join(description['platform']), '.'.join(description['architecture']), comp, d_ver)
for entry in os.listdir(module_build_path):
- if entry.startswith(build_name):
+ if build_name in entry:
for file in os.listdir(os.path.join(module_build_path, entry)):
if file == lib_file_name:
if folder_only:
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index a3feebe..18bb37b 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -13,8 +13,7 @@
# limitations under the License.
import os
-from . import (coredata, mesonlib, build)
-from . import mintro
+from . import coredata, environment, mesonlib, build, mintro, mlog
def add_arguments(parser):
coredata.register_builtin_arguments(parser)
@@ -38,11 +37,28 @@ class ConfException(mesonlib.MesonException):
class Conf:
def __init__(self, build_dir):
- self.build_dir = build_dir
- if not os.path.isdir(os.path.join(build_dir, 'meson-private')):
- raise ConfException('Directory %s does not seem to be a Meson build directory.' % build_dir)
- self.build = build.load(self.build_dir)
- self.coredata = coredata.load(self.build_dir)
+ self.build_dir = os.path.abspath(os.path.realpath(build_dir))
+ if 'meson.build' in [os.path.basename(self.build_dir), self.build_dir]:
+ self.build_dir = os.path.dirname(self.build_dir)
+ self.build = None
+
+ if os.path.isdir(os.path.join(self.build_dir, 'meson-private')):
+ self.build = build.load(self.build_dir)
+ self.source_dir = self.build.environment.get_source_dir()
+ self.coredata = coredata.load(self.build_dir)
+ self.default_values_only = False
+ elif os.path.isfile(os.path.join(self.build_dir, environment.build_filename)):
+ # Make sure that log entries in other parts of meson don't interfere with the JSON output
+ mlog.disable()
+ self.source_dir = os.path.abspath(os.path.realpath(self.build_dir))
+ intr = mintro.IntrospectionInterpreter(self.source_dir, '', 'ninja')
+ intr.analyze()
+ # Reenable logging just in case
+ mlog.enable()
+ self.coredata = intr.coredata
+ self.default_values_only = True
+ else:
+ raise ConfException('Directory {} is neither a Meson build directory nor a project source directory.'.format(build_dir))
def clear_cache(self):
self.coredata.deps = {}
@@ -51,18 +67,22 @@ class Conf:
self.coredata.set_options(options)
def save(self):
+ # Do nothing when using introspection
+ if self.default_values_only:
+ return
# Only called if something has changed so overwrite unconditionally.
coredata.save(self.coredata, self.build_dir)
# We don't write the build file because any changes to it
# are erased when Meson is executed the next time, i.e. when
# Ninja is run.
- @staticmethod
- def print_aligned(arr):
+ def print_aligned(self, arr):
if not arr:
return
titles = {'name': 'Option', 'descr': 'Description', 'value': 'Current Value', 'choices': 'Possible Values'}
+ if self.default_values_only:
+ titles['value'] = 'Default Value'
name_col = [titles['name'], '-' * len(titles['name'])]
value_col = [titles['value'], '-' * len(titles['value'])]
@@ -110,9 +130,18 @@ class Conf:
self.print_aligned(arr)
def print_conf(self):
+ def print_default_values_warning():
+ mlog.warning('The source directory instead of the build directory was specified.')
+ mlog.warning('Only the default values for the project are printed, and all command line parameters are ignored.')
+
+ if self.default_values_only:
+ print_default_values_warning()
+ print('')
+
print('Core properties:')
- print(' Source dir', self.build.environment.source_dir)
- print(' Build dir ', self.build.environment.build_dir)
+ print(' Source dir', self.source_dir)
+ if not self.default_values_only:
+ print(' Build dir ', self.build_dir)
dir_option_names = ['bindir',
'datadir',
@@ -144,6 +173,10 @@ class Conf:
self.print_options('Project options', self.coredata.user_options)
self.print_options('Testing options', test_options)
+ # Print the warning twice so that the user shouldn't be able to miss it
+ if self.default_values_only:
+ print('')
+ print_default_values_warning()
def run(options):
coredata.parse_cmd_line_options(options)
@@ -151,6 +184,10 @@ def run(options):
c = None
try:
c = Conf(builddir)
+ if c.default_values_only:
+ c.print_conf()
+ return 0
+
save = False
if len(options.cmd_line_options) > 0:
c.set_options(options.cmd_line_options)
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index 5eecb67..2d01c11 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -321,7 +321,7 @@ def run(options):
if options.builddir is not None:
datadir = os.path.join(options.builddir, datadir)
infodir = os.path.join(options.builddir, infodir)
- if options.builddir.endswith('/meson.build') or options.builddir.endswith('\\meson.build') or options.builddir == 'meson.build':
+ if 'meson.build' in [os.path.basename(options.builddir), options.builddir]:
sourcedir = '.' if options.builddir == 'meson.build' else options.builddir[:-11]
if options.projectinfo:
list_projinfo_from_source(sourcedir, indent)
diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py
index b4bd4f2..6536558 100644
--- a/mesonbuild/mtest.py
+++ b/mesonbuild/mtest.py
@@ -438,6 +438,8 @@ class TestHarness:
current = self.build_data.test_setups[full_name]
if not options.gdb:
options.gdb = current.gdb
+ if options.gdb:
+ options.verbose = True
if options.timeout_multiplier is None:
options.timeout_multiplier = current.timeout_multiplier
# if options.env is None:
@@ -693,18 +695,17 @@ Timeout: %4d
for _ in range(self.options.repeat):
for i, test in enumerate(tests):
visible_name = self.get_pretty_suite(test)
+ single_test = self.get_test_runner(test)
- if not test.is_parallel or self.options.gdb:
+ if not test.is_parallel or single_test.options.gdb:
self.drain_futures(futures)
futures = []
- single_test = self.get_test_runner(test)
res = single_test.run()
self.process_test_result(res)
self.print_stats(numlen, tests, visible_name, res, i)
else:
if not executor:
executor = conc.ThreadPoolExecutor(max_workers=self.options.num_processes)
- single_test = self.get_test_runner(test)
f = executor.submit(single_test.run)
futures.append((f, numlen, tests, visible_name, i))
if self.options.repeat > 1 and self.fail_count:
diff --git a/test cases/common/13 pch/generated/gen_custom.py b/test cases/common/13 pch/generated/gen_custom.py
new file mode 100644
index 0000000..650e03c
--- /dev/null
+++ b/test cases/common/13 pch/generated/gen_custom.py
@@ -0,0 +1,5 @@
+#!/usr/bin/env python3
+import sys
+
+with open(sys.argv[1], 'w') as f:
+ f.write("#define FOO 0")
diff --git a/test cases/common/13 pch/generated/gen_generator.py b/test cases/common/13 pch/generated/gen_generator.py
new file mode 100644
index 0000000..a245e7a
--- /dev/null
+++ b/test cases/common/13 pch/generated/gen_generator.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+import sys
+
+with open(sys.argv[1]) as f:
+ content = f.read()
+with open(sys.argv[2], 'w') as f:
+ f.write(content)
diff --git a/test cases/common/13 pch/generated/generated_generator.in b/test cases/common/13 pch/generated/generated_generator.in
new file mode 100644
index 0000000..1a00ebd
--- /dev/null
+++ b/test cases/common/13 pch/generated/generated_generator.in
@@ -0,0 +1 @@
+#define BAR 0
diff --git a/test cases/common/13 pch/generated/meson.build b/test cases/common/13 pch/generated/meson.build
new file mode 100644
index 0000000..372a00e
--- /dev/null
+++ b/test cases/common/13 pch/generated/meson.build
@@ -0,0 +1,16 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+if cc_id == 'lcc'
+ error('MESON_SKIP_TEST: Elbrus compiler does not support PCH.')
+endif
+
+generated_customTarget = custom_target('makeheader',
+ output: 'generated_customTarget.h',
+ command : [find_program('gen_custom.py'), '@OUTPUT0@'])
+
+generated_generator = generator(find_program('gen_generator.py'),
+ output: '@BASENAME@.h',
+ arguments: ['@INPUT@', '@OUTPUT@'])
+
+exe = executable('prog', 'prog.c', generated_customTarget, generated_generator.process('generated_generator.in'),
+ c_pch: ['pch/prog_pch.c', 'pch/prog.h'])
diff --git a/test cases/common/13 pch/generated/pch/prog.h b/test cases/common/13 pch/generated/pch/prog.h
new file mode 100644
index 0000000..15fec38
--- /dev/null
+++ b/test cases/common/13 pch/generated/pch/prog.h
@@ -0,0 +1,2 @@
+#include "generated_customTarget.h"
+#include "generated_generator.h"
diff --git a/test cases/common/13 pch/generated/pch/prog_pch.c b/test cases/common/13 pch/generated/pch/prog_pch.c
new file mode 100644
index 0000000..4960505
--- /dev/null
+++ b/test cases/common/13 pch/generated/pch/prog_pch.c
@@ -0,0 +1,5 @@
+#if !defined(_MSC_VER)
+#error "This file is only for use with MSVC."
+#endif
+
+#include "prog.h"
diff --git a/test cases/common/13 pch/generated/prog.c b/test cases/common/13 pch/generated/prog.c
new file mode 100644
index 0000000..9b2e2ef
--- /dev/null
+++ b/test cases/common/13 pch/generated/prog.c
@@ -0,0 +1,6 @@
+// No includes here, they need to come from the PCH
+
+int main(int argc, char **argv) {
+ return FOO + BAR;
+}
+
diff --git a/test cases/common/13 pch/meson.build b/test cases/common/13 pch/meson.build
index d39527b..43129c9 100644
--- a/test cases/common/13 pch/meson.build
+++ b/test cases/common/13 pch/meson.build
@@ -2,6 +2,8 @@ project('pch test', 'c', 'cpp')
subdir('c')
subdir('cpp')
+subdir('generated')
+subdir('withIncludeDirectories')
if meson.backend() == 'xcode'
warning('Xcode backend only supports one precompiled header per target. Skipping "mixed" which has various precompiled headers.')
diff --git a/test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h b/test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h
new file mode 100644
index 0000000..53c5fdf
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/include/lib/lib.h
@@ -0,0 +1 @@
+#include <stdio.h>
diff --git a/test cases/common/13 pch/withIncludeDirectories/meson.build b/test cases/common/13 pch/withIncludeDirectories/meson.build
new file mode 100644
index 0000000..2ab2cd8
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/meson.build
@@ -0,0 +1,9 @@
+cc = meson.get_compiler('c')
+cc_id = cc.get_id()
+if cc_id == 'lcc'
+ error('MESON_SKIP_TEST: Elbrus compiler does not support PCH.')
+endif
+
+exe = executable('prog', 'prog.c',
+ include_directories: 'include',
+ c_pch : ['pch/prog_pch.c', 'pch/prog.h'])
diff --git a/test cases/common/13 pch/withIncludeDirectories/pch/prog.h b/test cases/common/13 pch/withIncludeDirectories/pch/prog.h
new file mode 100644
index 0000000..383b2c5
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/pch/prog.h
@@ -0,0 +1 @@
+#include<lib/lib.h>
diff --git a/test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c b/test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c
new file mode 100644
index 0000000..4960505
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/pch/prog_pch.c
@@ -0,0 +1,5 @@
+#if !defined(_MSC_VER)
+#error "This file is only for use with MSVC."
+#endif
+
+#include "prog.h"
diff --git a/test cases/common/13 pch/withIncludeDirectories/prog.c b/test cases/common/13 pch/withIncludeDirectories/prog.c
new file mode 100644
index 0000000..0ce3d0a
--- /dev/null
+++ b/test cases/common/13 pch/withIncludeDirectories/prog.c
@@ -0,0 +1,10 @@
+// No includes here, they need to come from the PCH
+
+void func() {
+ fprintf(stdout, "This is a function that fails if stdio is not #included.\n");
+}
+
+int main(int argc, char **argv) {
+ return 0;
+}
+
diff --git a/test cases/fortran/12 submodule/a1.f90 b/test cases/fortran/12 submodule/a1.f90
new file mode 100644
index 0000000..cb44916
--- /dev/null
+++ b/test cases/fortran/12 submodule/a1.f90
@@ -0,0 +1,25 @@
+module a1
+implicit none
+
+interface
+module elemental real function pi2tau(pi)
+ real, intent(in) :: pi
+end function pi2tau
+
+module real function get_pi()
+end function get_pi
+end interface
+
+end module a1
+
+program hierN
+
+use a1
+
+pi = get_pi()
+
+tau = pi2tau(pi)
+
+print *,'pi=',pi,'tau=',tau
+
+end program
diff --git a/test cases/fortran/12 submodule/a2.f90 b/test cases/fortran/12 submodule/a2.f90
new file mode 100644
index 0000000..b3ce1f0
--- /dev/null
+++ b/test cases/fortran/12 submodule/a2.f90
@@ -0,0 +1,10 @@
+submodule (a1) a2
+
+contains
+
+module procedure pi2tau
+ pi2tau = 2*pi
+end procedure pi2tau
+
+
+end submodule a2
diff --git a/test cases/fortran/12 submodule/a3.f90 b/test cases/fortran/12 submodule/a3.f90
new file mode 100644
index 0000000..d6929b0
--- /dev/null
+++ b/test cases/fortran/12 submodule/a3.f90
@@ -0,0 +1,10 @@
+submodule (a1:a2) a3
+
+contains
+
+module procedure get_pi
+ get_pi = 4.*atan(1.)
+end procedure get_pi
+
+
+end submodule a3
diff --git a/test cases/fortran/12 submodule/child.f90 b/test cases/fortran/12 submodule/child.f90
new file mode 100644
index 0000000..aa5bb5e
--- /dev/null
+++ b/test cases/fortran/12 submodule/child.f90
@@ -0,0 +1,10 @@
+submodule (mother) daughter
+
+contains
+
+module procedure pi2tau
+ pi2tau = 2*pi
+end procedure pi2tau
+
+end submodule daughter
+
diff --git a/test cases/fortran/12 submodule/meson.build b/test cases/fortran/12 submodule/meson.build
new file mode 100644
index 0000000..cd62a30
--- /dev/null
+++ b/test cases/fortran/12 submodule/meson.build
@@ -0,0 +1,7 @@
+project('submodule single level', 'fortran')
+
+hier2 = executable('single', 'parent.f90','child.f90')
+test('single-level hierarchy', hier2)
+
+hierN = executable('multi', 'a1.f90', 'a2.f90', 'a3.f90')
+test('multi-level hierarchy', hierN)
diff --git a/test cases/fortran/12 submodule/parent.f90 b/test cases/fortran/12 submodule/parent.f90
new file mode 100644
index 0000000..05fe431
--- /dev/null
+++ b/test cases/fortran/12 submodule/parent.f90
@@ -0,0 +1,23 @@
+module mother
+real, parameter :: pi = 4.*atan(1.)
+real :: tau
+
+interface
+module elemental real function pi2tau(pi)
+ real, intent(in) :: pi
+end function pi2tau
+end interface
+
+contains
+
+end module mother
+
+
+program hier1
+use mother
+
+tau = pi2tau(pi)
+
+print *,'pi=',pi, 'tau=', tau
+
+end program