From 5303b1d0f499118c9dda82309fb23652511acb10 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sun, 3 Aug 2014 20:37:03 +0300 Subject: [PATCH] Scan Fortran dependencies, but it fails currently due to a deficiency in Ninja. --- environment.py | 4 +++- ninjabackend.py | 28 +++++++++++++++++++++++- test cases/fortran/2 modules/meson.build | 4 ++++ test cases/fortran/2 modules/prog.f95 | 7 ++++++ test cases/fortran/2 modules/stuff.f95 | 5 +++++ 5 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 test cases/fortran/2 modules/meson.build create mode 100644 test cases/fortran/2 modules/prog.f95 create mode 100644 test cases/fortran/2 modules/stuff.f95 diff --git a/environment.py b/environment.py index c5b51f60b..1292577be 100644 --- a/environment.py +++ b/environment.py @@ -1152,7 +1152,7 @@ end program prog cmdlist = self.exe_wrapper + [binary_name] else: cmdlist = [binary_name] - pe = subprocess.Popen(cmdlist) + pe = subprocess.Popen(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) pe.wait() if pe.returncode != 0: raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string()) @@ -1211,6 +1211,8 @@ end program prog def build_rpath_args(self, build_dir, rpath_paths, install_rpath): return build_unix_rpath_args(build_dir, rpath_paths, install_rpath) + def module_name_to_filename(self, module_name): + return module_name.lower() + '.mod' class VisualStudioLinker(): always_args = ['/NOLOGO'] diff --git a/ninjabackend.py b/ninjabackend.py index b165ef571..c5c45b1f4 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -854,7 +854,26 @@ class NinjaBackend(backends.Backend): elem.add_item('COMMAND', cmdlist) elem.write(outfile) + def get_fortran_deps(self, compiler, src, target): + module_files = [] + use_files = [] + modre = re.compile(r"\s*module\s+(\w+)", re.IGNORECASE) + usere = re.compile(r"\s*use\s+(\w+)", re.IGNORECASE) + dirname = os.path.join(self.get_target_dir(target), target.get_basename() + '.dir') + for line in open(src): + modmatch = modre.match(line) + usematch = usere.match(line) + if modmatch is not None: + fname = compiler.module_name_to_filename(modmatch.group(1)) + module_files.append(os.path.join(dirname, fname)) + if usematch is not None: + fname = compiler.module_name_to_filename(usematch.group(1)) + use_files.append(os.path.join(dirname, fname)) + return (module_files, use_files) + def generate_single_compile(self, target, outfile, src, is_generated=False, header_deps=[], order_deps=[]): + extra_outputs = [] + extra_deps = [] compiler = self.get_compiler_for_source(src) commands = self.generate_basic_compiler_args(target, compiler) commands.append(compiler.get_include_arg(self.get_target_private_dir(target))) @@ -865,8 +884,10 @@ class NinjaBackend(backends.Backend): rel_src = src else: rel_src = os.path.join(self.get_target_private_dir(target), src) + abs_src = os.path.join(self.environment.get_source_dir(), rel_src) else: rel_src = os.path.join(self.build_to_src, target.get_source_subdir(), src) + abs_src = os.path.join(self.environment.get_build_dir(), rel_src) if os.path.isabs(src): src_filename = os.path.basename(src) else: @@ -903,8 +924,12 @@ class NinjaBackend(backends.Backend): if target.is_cross: crstr = '_CROSS' compiler_name = '%s%s_COMPILER' % (compiler.get_language(), crstr) + if compiler.get_language() == 'fortran': + # Currently check only current file. We may need to change this + # to do the scanning for the entire target at once. + (extra_outputs, extra_deps) = self.get_fortran_deps(compiler, abs_src, target) - element = NinjaBuildElement(rel_obj, compiler_name, rel_src) + element = NinjaBuildElement([rel_obj] + extra_outputs, compiler_name, rel_src) for d in header_deps: if isinstance(d, backends.RawFilename): d = d.fname @@ -918,6 +943,7 @@ class NinjaBackend(backends.Backend): d = os.path.join(self.get_target_private_dir(target), d) element.add_orderdep(d) element.add_orderdep(pch_dep) + element.add_orderdep(extra_deps) element.add_item('DEPFILE', dep_file) element.add_item('ARGS', commands) element.write(outfile) diff --git a/test cases/fortran/2 modules/meson.build b/test cases/fortran/2 modules/meson.build new file mode 100644 index 000000000..0087c26ec --- /dev/null +++ b/test cases/fortran/2 modules/meson.build @@ -0,0 +1,4 @@ +project('modules', 'fortran') + +e = executable('modprog', 'stuff.f95', 'prog.f95') +test('moduletest', e) diff --git a/test cases/fortran/2 modules/prog.f95 b/test cases/fortran/2 modules/prog.f95 new file mode 100644 index 000000000..c3998cc5e --- /dev/null +++ b/test cases/fortran/2 modules/prog.f95 @@ -0,0 +1,7 @@ +PROGRAM prog + +use Circle +IMPLICIT NONE + +END PROGRAM prog + diff --git a/test cases/fortran/2 modules/stuff.f95 b/test cases/fortran/2 modules/stuff.f95 new file mode 100644 index 000000000..4a6399bb6 --- /dev/null +++ b/test cases/fortran/2 modules/stuff.f95 @@ -0,0 +1,5 @@ +MODULE Circle + REAL, PARAMETER :: Pi = 3.1415927 + REAL :: radius +END MODULE Circle +