diff options
Diffstat (limited to 'mesonbuild/backend')
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 87f9b38..463e999 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 @@ -1826,7 +1826,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 @@ -1849,11 +1850,23 @@ 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) + 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: @@ -1879,9 +1892,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): |