Fortran: handle self-referential files

pull/4988/head
Michael Hirsch, Ph.D 6 years ago committed by Jussi Pakkanen
parent 76e385391f
commit 32a344b949
  1. 28
      mesonbuild/backend/ninjabackend.py
  2. 2
      test cases/fortran/4 self dependency/meson.build
  3. 6
      test cases/fortran/4 self dependency/src/selfdep_mod.f90
  4. 8
      test cases/fortran/7 generated/prog.f90

@ -19,7 +19,7 @@ import pickle
import subprocess import subprocess
from collections import OrderedDict from collections import OrderedDict
import itertools import itertools
from pathlib import PurePath from pathlib import PurePath, Path
from functools import lru_cache from functools import lru_cache
from . import backends from . import backends
@ -1851,9 +1851,11 @@ rule FORTRAN_DEP_HACK%s
mod_files = [] mod_files = []
usere = re.compile(r"\s*use,?\s*(?:non_intrinsic)?\s*(?:::)?\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) 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()] 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: for line in f:
usematch = usere.match(line) usematch = usere.match(line)
if usematch is not None: if usematch is not None:
@ -1876,10 +1878,14 @@ rule FORTRAN_DEP_HACK%s
# Check if a source uses a module it exports itself. # Check if a source uses a module it exports itself.
# Potential bug if multiple targets have a file with # Potential bug if multiple targets have a file with
# the same name. # the same name.
if mod_source_file.fname == os.path.basename(src): try:
continue if (srcdir / mod_source_file.fname).samefile(src):
continue
except FileNotFoundError:
pass
mod_name = compiler.module_name_to_filename(usename) 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: else:
submodmatch = submodre.match(line) submodmatch = submodre.match(line)
if submodmatch is not None: if submodmatch is not None:
@ -1890,10 +1896,14 @@ rule FORTRAN_DEP_HACK%s
for parent in parents: for parent in parents:
if parent not in tdeps: if parent not in tdeps:
raise MesonException("submodule {} relies on parent module {} that was not found.".format(submodmatch.group(2).lower(), parent)) 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_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 return mod_files

@ -2,3 +2,5 @@ project('selfdep', 'fortran')
e = executable('selfdep', 'selfdep.f90') e = executable('selfdep', 'selfdep.f90')
test('selfdep', e) test('selfdep', e)
library('selfmod', 'src/selfdep_mod.f90')

@ -0,0 +1,6 @@
module a
end module a
module b
use a
end module b

@ -1,9 +1,7 @@
program prog program prog
use mod2 use mod2
implicit none implicit none
if (modval1 + modval2 /= 3) then if (modval1 + modval2 /= 3) stop 1
stop 1
end if
end program prog end program prog

Loading…
Cancel
Save