diff options
-rw-r--r-- | docs/markdown/Dlang-module.md | 4 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 23 | ||||
-rw-r--r-- | mesonbuild/build.py | 7 | ||||
-rw-r--r-- | mesonbuild/compilers/clike.py | 30 | ||||
-rw-r--r-- | mesonbuild/compilers/fortran.py | 20 | ||||
-rw-r--r-- | mesonbuild/environment.py | 4 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 13 | ||||
-rw-r--r-- | mesonbuild/modules/cmake.py | 5 | ||||
-rw-r--r-- | mesonbuild/modules/windows.py | 2 | ||||
-rwxr-xr-x | run_unittests.py | 19 | ||||
-rw-r--r-- | test cases/fortran/1 basic/meson.build | 5 |
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) |