aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2019-03-26 20:18:34 +0200
committerGitHub <noreply@github.com>2019-03-26 20:18:34 +0200
commit6253bbc6cc18f2850d924eac690338dcdf45a23b (patch)
tree85fdcc0edf74a374f36c9db77e295919ba0617ba
parentda1bb49787b2f65ca3a4c3c3fb0d9eda822f3275 (diff)
parent6e06ad1c1f3a0e02d70de2e5b66657ed08380c8f (diff)
downloadmeson-6253bbc6cc18f2850d924eac690338dcdf45a23b.zip
meson-6253bbc6cc18f2850d924eac690338dcdf45a23b.tar.gz
meson-6253bbc6cc18f2850d924eac690338dcdf45a23b.tar.bz2
Merge pull request #5039 from scivision/submod
BUGFIX: allow Fortran submodule to have same name as module
-rw-r--r--mesonbuild/backend/ninjabackend.py50
-rw-r--r--mesonbuild/compilers/fortran.py13
-rw-r--r--test cases/fortran/12 submodule/child.f904
-rw-r--r--test cases/fortran/12 submodule/meson.build2
-rw-r--r--test cases/fortran/12 submodule/parent.f909
5 files changed, 48 insertions, 30 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 0e6311a..64ea5a6 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -36,6 +36,8 @@ from ..mesonlib import get_compiler_for_source, has_path_sep
from .backends import CleanTrees
from ..build import InvalidArguments
+FORTRAN_SUBMOD_PAT = r"\s*submodule\s*\((\w+:?\w+)\)\s*(\w+)\s*$"
+
if mesonlib.is_windows():
quote_func = lambda s: '"{}"'.format(s)
execute_wrapper = 'cmd /c'
@@ -1812,6 +1814,9 @@ rule FORTRAN_DEP_HACK%s
elem.write(outfile)
def scan_fortran_module_outputs(self, target):
+ """
+ Find all module and submodule made available in a Fortran code file.
+ """
compiler = None
for lang, c in self.build.compilers.items():
if lang == 'fortran':
@@ -1822,8 +1827,9 @@ rule FORTRAN_DEP_HACK%s
return
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)
+ submodre = re.compile(FORTRAN_SUBMOD_PAT, re.IGNORECASE)
module_files = {}
+ submodule_files = {}
for s in target.get_sources():
# FIXME, does not work for Fortran sources generated by
# custom_target() and generator() as those are run after
@@ -1847,19 +1853,22 @@ rule FORTRAN_DEP_HACK%s
else:
submodmatch = submodre.match(line)
if submodmatch is not None:
- submodname = submodmatch.group(2).lower()
- if submodname in module_files:
+ # '_' is arbitrarily used to distinguish submod from mod.
+ parents = submodmatch.group(1).lower().split(':')
+ submodname = parents[0] + '_' + submodmatch.group(2).lower()
+
+ if submodname in submodule_files:
raise InvalidArguments(
'Namespace collision: submodule %s defined in '
'two files %s and %s.' %
- (submodname, module_files[submodname], s))
- module_files[submodname] = s
+ (submodname, submodule_files[submodname], s))
+ submodule_files[submodname] = s
- self.fortran_deps[target.get_basename()] = module_files
+ self.fortran_deps[target.get_basename()] = {**module_files, **submodule_files}
def get_fortran_deps(self, compiler: FortranCompiler, src: str, target) -> List[str]:
"""
- Find all modules and submodules needed by a target
+ Find all module and submodule needed by a Fortran target
"""
dirname = Path(self.get_target_private_dir(target))
@@ -2774,7 +2783,7 @@ def _scan_fortran_file_deps(src: str, srcdir: Path, dirname: Path, tdeps, compil
incre = re.compile(r"#?include\s*['\"](\w+\.\w+)['\"]\s*$", 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(FORTRAN_SUBMOD_PAT, re.IGNORECASE)
mod_files = []
src = Path(src)
@@ -2822,17 +2831,18 @@ def _scan_fortran_file_deps(src: str, srcdir: Path, dirname: Path, tdeps, compil
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))
- submodsrcfile = srcdir / tdeps[parent].fname
- if not submodsrcfile.is_file():
- if submodsrcfile.name != src.name: # generated source file
- pass
- else: # subproject
- continue
- elif submodsrcfile.samefile(src): # self-reference
+
+ ancestor_child = '_'.join(parents)
+ if ancestor_child not in tdeps:
+ raise MesonException("submodule {} relies on ancestor module {} that was not found.".format(submodmatch.group(2).lower(), ancestor_child.split('_')[0]))
+ submodsrcfile = srcdir / tdeps[ancestor_child].fname
+ if not submodsrcfile.is_file():
+ if submodsrcfile.name != src.name: # generated source file
+ pass
+ else: # subproject
continue
- mod_name = compiler.module_name_to_filename(parent)
- mod_files.append(str(dirname / mod_name))
+ elif submodsrcfile.samefile(src): # self-reference
+ continue
+ mod_name = compiler.module_name_to_filename(ancestor_child)
+ mod_files.append(str(dirname / mod_name))
return mod_files
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 15234ee..a16f2b5 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -180,7 +180,18 @@ class FortranCompiler(Compiler):
return parameter_list
def module_name_to_filename(self, module_name: str) -> str:
- return module_name.lower() + '.mod'
+ if '_' in module_name: # submodule
+ s = module_name.lower()
+ if self.id in ('gcc', 'intel'):
+ filename = s.replace('_', '@') + '.smod'
+ elif self.id in ('pgi', 'flang'):
+ filename = s.replace('_', '-') + '.mod'
+ else:
+ filename = s + '.mod'
+ else: # module
+ filename = module_name.lower() + '.mod'
+
+ return filename
def get_std_shared_lib_link_args(self):
return CCompiler.get_std_shared_lib_link_args(self)
diff --git a/test cases/fortran/12 submodule/child.f90 b/test cases/fortran/12 submodule/child.f90
index aa5bb5e..45b5b41 100644
--- a/test cases/fortran/12 submodule/child.f90
+++ b/test cases/fortran/12 submodule/child.f90
@@ -1,4 +1,4 @@
-submodule (mother) daughter
+submodule (parent) parent
contains
@@ -6,5 +6,5 @@ module procedure pi2tau
pi2tau = 2*pi
end procedure pi2tau
-end submodule daughter
+end submodule parent
diff --git a/test cases/fortran/12 submodule/meson.build b/test cases/fortran/12 submodule/meson.build
index cd62a30..b3ed9de 100644
--- a/test cases/fortran/12 submodule/meson.build
+++ b/test cases/fortran/12 submodule/meson.build
@@ -1,6 +1,6 @@
project('submodule single level', 'fortran')
-hier2 = executable('single', 'parent.f90','child.f90')
+hier2 = executable('single', 'parent.f90', 'child.f90')
test('single-level hierarchy', hier2)
hierN = executable('multi', 'a1.f90', 'a2.f90', 'a3.f90')
diff --git a/test cases/fortran/12 submodule/parent.f90 b/test cases/fortran/12 submodule/parent.f90
index 05fe431..9d087d0 100644
--- a/test cases/fortran/12 submodule/parent.f90
+++ b/test cases/fortran/12 submodule/parent.f90
@@ -1,4 +1,4 @@
-module mother
+module parent
real, parameter :: pi = 4.*atan(1.)
real :: tau
@@ -8,13 +8,10 @@ module elemental real function pi2tau(pi)
end function pi2tau
end interface
-contains
+end module parent
-end module mother
-
-program hier1
-use mother
+use parent
tau = pi2tau(pi)