From 32a344b9497ec90d31179cc3a0b385aa2a5f691c Mon Sep 17 00:00:00 2001 From: "Michael Hirsch, Ph.D" Date: Tue, 26 Feb 2019 12:16:50 -0500 Subject: [PATCH] Fortran: handle self-referential files --- mesonbuild/backend/ninjabackend.py | 28 +++++++++++++------ .../fortran/4 self dependency/meson.build | 2 ++ .../4 self dependency/src/selfdep_mod.f90 | 6 ++++ test cases/fortran/7 generated/prog.f90 | 8 ++---- 4 files changed, 30 insertions(+), 14 deletions(-) create mode 100644 test cases/fortran/4 self dependency/src/selfdep_mod.f90 diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 16962a4b1..0a1681fc7 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -19,7 +19,7 @@ import pickle import subprocess from collections import OrderedDict import itertools -from pathlib import PurePath +from pathlib import PurePath, Path from functools import lru_cache from . import backends @@ -1851,9 +1851,11 @@ rule FORTRAN_DEP_HACK%s mod_files = [] 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) + dirname = Path(self.get_target_private_dir(target)) tdeps = self.fortran_deps[target.get_basename()] - with open(src, encoding='ascii', errors='ignore') as f: + src = Path(src) + srcdir = Path(self.source_dir) + with src.open(encoding='ascii', errors='ignore') as f: for line in f: usematch = usere.match(line) if usematch is not None: @@ -1876,10 +1878,14 @@ rule FORTRAN_DEP_HACK%s # Check if a source uses a module it exports itself. # Potential bug if multiple targets have a file with # the same name. - if mod_source_file.fname == os.path.basename(src): - continue + try: + if (srcdir / mod_source_file.fname).samefile(src): + continue + except FileNotFoundError: + pass + mod_name = compiler.module_name_to_filename(usename) - mod_files.append(os.path.join(dirname, mod_name)) + mod_files.append(str(dirname / mod_name)) else: submodmatch = submodre.match(line) if submodmatch is not None: @@ -1890,10 +1896,14 @@ rule FORTRAN_DEP_HACK%s 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 + + try: + if (srcdir / tdeps[parent].fname).samefile(src): + continue + except FileNotFoundError: + pass mod_name = compiler.module_name_to_filename(parent) - mod_files.append(os.path.join(dirname, mod_name)) + mod_files.append(str(dirname / mod_name)) return mod_files diff --git a/test cases/fortran/4 self dependency/meson.build b/test cases/fortran/4 self dependency/meson.build index bc5dab4ed..8eef4eb66 100644 --- a/test cases/fortran/4 self dependency/meson.build +++ b/test cases/fortran/4 self dependency/meson.build @@ -2,3 +2,5 @@ project('selfdep', 'fortran') e = executable('selfdep', 'selfdep.f90') test('selfdep', e) + +library('selfmod', 'src/selfdep_mod.f90') diff --git a/test cases/fortran/4 self dependency/src/selfdep_mod.f90 b/test cases/fortran/4 self dependency/src/selfdep_mod.f90 new file mode 100644 index 000000000..4aa00576a --- /dev/null +++ b/test cases/fortran/4 self dependency/src/selfdep_mod.f90 @@ -0,0 +1,6 @@ +module a +end module a + +module b +use a +end module b diff --git a/test cases/fortran/7 generated/prog.f90 b/test cases/fortran/7 generated/prog.f90 index c476e9c91..8a102c059 100644 --- a/test cases/fortran/7 generated/prog.f90 +++ b/test cases/fortran/7 generated/prog.f90 @@ -1,9 +1,7 @@ program prog - use mod2 - implicit none +use mod2 +implicit none - if (modval1 + modval2 /= 3) then - stop 1 - end if +if (modval1 + modval2 /= 3) stop 1 end program prog