aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Dlang-module.md4
-rw-r--r--mesonbuild/backend/ninjabackend.py23
-rw-r--r--mesonbuild/build.py7
-rw-r--r--mesonbuild/compilers/clike.py30
-rw-r--r--mesonbuild/compilers/fortran.py20
-rw-r--r--mesonbuild/environment.py4
-rw-r--r--mesonbuild/interpreter.py13
-rw-r--r--mesonbuild/modules/cmake.py5
-rw-r--r--mesonbuild/modules/windows.py2
-rwxr-xr-xrun_unittests.py19
-rw-r--r--test cases/fortran/1 basic/meson.build5
11 files changed, 85 insertions, 47 deletions
diff --git a/docs/markdown/Dlang-module.md b/docs/markdown/Dlang-module.md
index ca9a381..677359d 100644
--- a/docs/markdown/Dlang-module.md
+++ b/docs/markdown/Dlang-module.md
@@ -7,7 +7,7 @@ This module provides tools related to the D programming language.
To use this module, just do: **`dlang = import('dlang')`**.
You can, of course, replace the name `dlang` with anything else.
-The module only exposes one fucntion, `generate_dub_file`, used to
+The module only exposes one function, `generate_dub_file`, used to
automatically generate Dub configuration files.
### generate_dub_file()
@@ -40,4 +40,4 @@ initial one. The module will only update the values specified in
`generate_dub_file()`.
Although not required, you will need to have a `description` and
-`license` if you want to publish the package in the [D package registry](https://code.dlang.org/). \ No newline at end of file
+`license` if you want to publish the package in the [D package registry](https://code.dlang.org/).
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 69682d4..b897180 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -219,7 +219,7 @@ class NinjaBackend(backends.Backend):
def detect_vs_dep_prefix(self, tempfilename):
'''VS writes its dependency in a locale dependent format.
Detect the search prefix to use.'''
- for compiler in self.build.compilers.values():
+ for compiler in self.environment.coredata.compilers.values():
# Have to detect the dependency format
# IFort on windows is MSVC like, but doesn't have /showincludes
@@ -314,9 +314,9 @@ int dummy;
# http://clang.llvm.org/docs/JSONCompilationDatabase.html
def generate_compdb(self):
- pch_compilers = ['%s_PCH' % i for i in self.build.compilers]
- native_compilers = ['%s_COMPILER' % i for i in self.build.compilers]
- cross_compilers = ['%s_CROSS_COMPILER' % i for i in self.build.cross_compilers]
+ pch_compilers = ['%s_PCH' % i for i in self.environment.coredata.compilers]
+ native_compilers = ['%s_COMPILER' % i for i in self.environment.coredata.compilers]
+ cross_compilers = ['%s_CROSS_COMPILER' % i for i in self.environment.coredata.cross_compilers]
ninja_compdb = [self.ninja_command, '-t', 'compdb'] + pch_compilers + native_compilers + cross_compilers
builddir = self.environment.get_build_dir()
try:
@@ -1492,7 +1492,7 @@ int dummy;
def generate_static_link_rules(self, is_cross):
num_pools = self.environment.coredata.backend_options['backend_max_links'].value
- if 'java' in self.build.compilers:
+ if 'java' in self.environment.coredata.compilers:
if not is_cross:
self.generate_java_link()
if is_cross:
@@ -1532,11 +1532,8 @@ int dummy;
def generate_dynamic_link_rules(self):
num_pools = self.environment.coredata.backend_options['backend_max_links'].value
- ctypes = [(self.build.compilers, False)]
- if self.environment.is_cross_build():
- ctypes.append((self.build.cross_compilers, True))
- else:
- ctypes.append((self.build.cross_compilers, True))
+ ctypes = [(self.environment.coredata.compilers, False),
+ (self.environment.coredata.cross_compilers, True)]
for (complist, is_cross) in ctypes:
for langname, compiler in complist.items():
if langname == 'java' \
@@ -1718,13 +1715,13 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
depfile=depfile))
def generate_compile_rules(self):
- for langname, compiler in self.build.compilers.items():
+ for langname, compiler in self.environment.coredata.compilers.items():
if compiler.get_id() == 'clang':
self.generate_llvm_ir_compile_rule(compiler, False)
self.generate_compile_rule_for(langname, compiler, False)
self.generate_pch_rule_for(langname, compiler, False)
if self.environment.is_cross_build():
- cclist = self.build.cross_compilers
+ cclist = self.environment.coredata.cross_compilers
for langname, compiler in cclist.items():
if compiler.get_id() == 'clang':
self.generate_llvm_ir_compile_rule(compiler, True)
@@ -1822,7 +1819,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
Find all module and submodule made available in a Fortran code file.
"""
compiler = None
- for lang, c in self.build.compilers.items():
+ for lang, c in self.environment.coredata.compilers.items():
if lang == 'fortran':
compiler = c
break
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 093ab8f..d51e2e3 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -114,9 +114,6 @@ class Build:
self.environment = environment
self.projects = {}
self.targets = OrderedDict()
- # Coredata holds the state. This is just here for convenience.
- self.compilers = environment.coredata.compilers
- self.cross_compilers = environment.coredata.cross_compilers
self.global_args = {}
self.projects_args = {}
self.global_link_args = {}
@@ -149,10 +146,6 @@ class Build:
def copy(self):
other = Build(self.environment)
for k, v in self.__dict__.items():
- if k in ['compilers', 'cross_compilers']:
- # These alias coredata's fields of the same name, and must not
- # become copies.
- continue
if isinstance(v, (list, dict, set, OrderedDict)):
other.__dict__[k] = v.copy()
else:
diff --git a/mesonbuild/compilers/clike.py b/mesonbuild/compilers/clike.py
index 3d29b75..3665f1f 100644
--- a/mesonbuild/compilers/clike.py
+++ b/mesonbuild/compilers/clike.py
@@ -170,10 +170,22 @@ class CLikeCompiler:
stdo = p.stdo
return stdo
- @staticmethod
- def _split_fetch_real_dirs(pathstr, sep=':'):
- paths = []
- for p in pathstr.split(sep):
+ def _split_fetch_real_dirs(self, pathstr):
+ # We need to use the path separator used by the compiler for printing
+ # lists of paths ("gcc --print-search-dirs"). By default
+ # we assume it uses the platform native separator.
+ pathsep = os.pathsep
+
+ # clang uses ':' instead of ';' on Windows https://reviews.llvm.org/D61121
+ # so we need to repair things like 'C:\foo:C:\bar'
+ if pathsep == ';':
+ pathstr = re.sub(r':([^/\\])', r';\1', pathstr)
+
+ # pathlib treats empty paths as '.', so filter those out
+ paths = [p for p in pathstr.split(pathsep) if p]
+
+ result = []
+ for p in paths:
# GCC returns paths like this:
# /usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/lib
# It would make sense to normalize them to get rid of the .. parts
@@ -185,15 +197,15 @@ class CLikeCompiler:
pobj = Path(p)
unresolved = pobj.as_posix()
if pobj.exists():
- if unresolved not in paths:
- paths.append(unresolved)
+ if unresolved not in result:
+ result.append(unresolved)
try:
resolved = Path(p).resolve().as_posix()
- if resolved not in paths:
- paths.append(resolved)
+ if resolved not in result:
+ result.append(resolved)
except FileNotFoundError:
pass
- return tuple(paths)
+ return tuple(result)
def get_compiler_dirs(self, env, name):
'''
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 06e01d0..5de1de4 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -31,6 +31,7 @@ from .compilers import (
IntelVisualStudioLikeCompiler,
)
from .clike import CLikeCompiler
+from .. import mlog
from mesonbuild.mesonlib import (
EnvironmentException, MachineChoice, is_osx, LibType
@@ -145,6 +146,25 @@ class FortranCompiler(CLikeCompiler, Compiler):
end program main'''
return self.find_library_impl(libname, env, extra_dirs, code, libtype)
+ def has_multi_arguments(self, args, env):
+ for arg in args[:]:
+ # some compilers, e.g. GCC, don't warn for unsupported warning-disable
+ # flags, so when we are testing a flag like "-Wno-forgotten-towel", also
+ # check the equivalent enable flag too "-Wforgotten-towel"
+ if arg.startswith('-Wno-'):
+ args.append('-W' + arg[5:])
+ 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. has_link_argument or '
+ 'other similar method can be used instead.'
+ .format(arg))
+ code = 'program main\ncall exit(0)\nend program main'
+ return self.has_arguments(args, env, code, mode='compile')
+
class GnuFortranCompiler(GnuCompiler, FortranCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None, **kwargs):
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 48ae189..6b536a4 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -411,8 +411,8 @@ class Environment:
# target machine.)
machines = PerThreeMachineDefaultable()
- # Similar to coredata.compilers and build.compilers, but lower level in
- # that there is no meta data, only names/paths.
+ # Similar to coredata.compilers, but lower level in that there is no
+ # meta data, only names/paths.
binaries = PerMachineDefaultable()
# Misc other properties about each machine.
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 9efe5cd..678560f 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1633,7 +1633,7 @@ class CompilerHolder(InterpreterObject):
ModuleState = namedtuple('ModuleState', [
'build_to_src', 'subproject', 'subdir', 'current_lineno', 'environment',
- 'project_name', 'project_version', 'backend', 'compilers', 'targets',
+ 'project_name', 'project_version', 'backend', 'targets',
'data', 'headers', 'man', 'global_args', 'project_args', 'build_machine',
'host_machine', 'target_machine', 'current_node'])
@@ -1668,7 +1668,6 @@ class ModuleHolder(InterpreterObject, ObjectHolder):
# The backend object is under-used right now, but we will need it:
# https://github.com/mesonbuild/meson/issues/1419
backend=self.interpreter.backend,
- compilers=self.interpreter.build.compilers,
targets=self.interpreter.build.targets,
data=self.interpreter.build.data,
headers=self.interpreter.build.get_headers(),
@@ -1825,9 +1824,9 @@ class MesonMain(InterpreterObject):
if not isinstance(native, bool):
raise InterpreterException('Type of "native" must be a boolean.')
if native:
- clist = self.build.compilers
+ clist = self.interpreter.coredata.compilers
else:
- clist = self.build.cross_compilers
+ clist = self.interpreter.coredata.cross_compilers
if cname in clist:
return CompilerHolder(clist[cname], self.build.environment, self.interpreter.subproject)
raise InterpreterException('Tried to access compiler for unspecified language "%s".' % cname)
@@ -2209,7 +2208,7 @@ class Interpreter(InterpreterBase):
def check_cross_stdlibs(self):
if self.build.environment.is_cross_build():
props = self.build.environment.properties.host
- for l in self.build.cross_compilers.keys():
+ for l in self.coredata.cross_compilers.keys():
try:
di = mesonlib.stringlistify(props.get_stdlib(l))
if len(di) != 2:
@@ -3861,7 +3860,7 @@ different subdirectory.
self.print_extra_warnings()
def print_extra_warnings(self):
- for c in self.build.compilers.values():
+ for c in self.coredata.compilers.values():
if c.get_id() == 'clang':
self.check_clang_asan_lundef()
break
@@ -4078,7 +4077,7 @@ This will become a hard error in the future.''', location=self.current_node)
def get_used_languages(self, target):
result = {}
for i in target.sources:
- for lang, c in self.build.compilers.items():
+ for lang, c in self.coredata.compilers.items():
if c.can_compile(i):
result[lang] = True
break
diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py
index 6af4adb..d72ceca 100644
--- a/mesonbuild/modules/cmake.py
+++ b/mesonbuild/modules/cmake.py
@@ -52,7 +52,8 @@ class CmakeModule(ExtensionModule):
super().__init__(interpreter)
self.snippets.add('configure_package_config_file')
- def detect_voidp_size(self, compilers, env):
+ def detect_voidp_size(self, env):
+ compilers = env.coredata.compilers
compiler = compilers.get('c', None)
if not compiler:
compiler = compilers.get('cpp', None)
@@ -115,7 +116,7 @@ class CmakeModule(ExtensionModule):
conf = {
'CVF_VERSION': (version, ''),
- 'CMAKE_SIZEOF_VOID_P': (str(self.detect_voidp_size(state.compilers, state.environment)), '')
+ 'CMAKE_SIZEOF_VOID_P': (str(self.detect_voidp_size(state.environment)), '')
}
mesonlib.do_conf_file(template_file, version_file, conf, 'meson')
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index e2fd9a8..3b4eb15 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -50,7 +50,7 @@ class WindowsModule(ExtensionModule):
rescomp = ExternalProgram.from_bin_list(state.environment.binaries.host, 'windres')
if not rescomp or not rescomp.found():
- comp = self.detect_compiler(state.compilers)
+ comp = self.detect_compiler(state.environment.coredata.compilers)
if comp.id in {'msvc', 'clang-cl', 'intel-cl'}:
rescomp = ExternalProgram('rc', silent=True)
else:
diff --git a/run_unittests.py b/run_unittests.py
index 7242a5f..d64e60e 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1587,6 +1587,14 @@ class AllPlatformTests(BasePlatformTests):
self.assertEqual(value, expected[args][name])
self.wipe()
+ def test_clike_get_library_dirs(self):
+ env = get_fake_env()
+ cc = env.detect_c_compiler(False)
+ for d in cc.get_library_dirs(env):
+ self.assertTrue(os.path.exists(d))
+ self.assertTrue(os.path.isdir(d))
+ self.assertTrue(os.path.isabs(d))
+
def test_static_library_overwrite(self):
'''
Tests that static libraries are never appended to, always overwritten.
@@ -2743,9 +2751,14 @@ int main(int argc, char **argv) {
f.write(cross_content)
name = os.path.basename(f.name)
- with mock.patch('mesonbuild.coredata.os.path.expanduser', lambda x: x.replace('~', d)):
- self.init(testdir, ['--cross-file=' + name], inprocess=True)
- self.wipe()
+ # If XDG_DATA_HOME is set in the environment running the
+ # tests this test will fail, os mock the environment, pop
+ # it, then test
+ with mock.patch.dict(os.environ):
+ os.environ.pop('XDG_DATA_HOME', None)
+ with mock.patch('mesonbuild.coredata.os.path.expanduser', lambda x: x.replace('~', d)):
+ self.init(testdir, ['--cross-file=' + name], inprocess=True)
+ self.wipe()
def test_compiler_run_command(self):
'''
diff --git a/test cases/fortran/1 basic/meson.build b/test cases/fortran/1 basic/meson.build
index 959ad35..52e2d6f 100644
--- a/test cases/fortran/1 basic/meson.build
+++ b/test cases/fortran/1 basic/meson.build
@@ -5,6 +5,9 @@ if fc.get_id() == 'gcc'
add_global_arguments('-fbounds-check', language : 'fortran')
endif
+args = fc.first_supported_argument(['-ffree-form', '-free', '/free'])
+assert(args != [], 'No arguments found?')
+
e = executable('simple', 'simple.f90',
- fortran_args : '-ffree-form')
+ fortran_args : args)
test('Simple Fortran', e)