-
Notifications
You must be signed in to change notification settings - Fork 3
/
get_deps
executable file
·114 lines (101 loc) · 3.9 KB
/
get_deps
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# get_deps
#
# Copyright 2016 Christopher MacMackin <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
# A script which prints the dependencies for a given Fortran source file in
# a format suitable for inclusion into a Makefile.
#
# Invocation:
#
# ./get_deps FORTRAN_FILE MOD_DIRECTORY IGNORE [INCLUDE_DIR [INCLUDE_DIR ...]]
#
# FORTRAN_FILE
# The path to the source file for which dependencies are to be
# printed.
#
# MOD_DIRECTORY
# The directory into which compiled module files will be placed.
#
# IGNORE
# A regular expression for module names which should not be listed as
# dependencies (i.e. because they are for external libraries or
# intrinsic modules).
#
# INCLUDE_DIR
# Directories which may contain an include file (when it is not
# next to or below the file doing the including in the source
# tree).
#
import re
from sys import argv
import os
# Taken from my project FORD
USE_RE = re.compile(r"""^[^!'"#]*use(?:\s*(?:,\s*((?:non_)?intrinsic)\s*)?::\s*|\s+)(\w+)\s*""",re.IGNORECASE)
MODULE_RE = re.compile(r"""^[^!'"#]*(?<!end)\s*(?<!sub)module(?!procedure|function|subroutine)(?:\s+(\w+))?""",re.IGNORECASE)
SUBMODULE_RE = re.compile(r"""^[^!'"#]*(?<!end)\s*submodule\s*\(\s*(\w+)\s*(?::\s*(\w+))?\s*\)\s*(?:::|\s)\s*(\w+)""",re.IGNORECASE)
INCLUDE_RE = re.compile(r"""^(\s*|\#)include\s+('|")\s*(.*?)\s*\2""",re.IGNORECASE)
filename = argv[1]
moddir = argv[2]
ignore_re = re.compile(argv[3],re.IGNORECASE)
incdirs = [item[0] for item in os.walk(os.path.dirname(filename))]
if len(argv) > 4:
incdirs += argv[4:]
def get_moddir(modname):
return os.path.join(moddir, modname)
modules = set()
dependencies = set()
includes = set()
src = open(filename,'r')
for line in src:
use = USE_RE.search(line)
if use:
if not use.group(1) == 'intrinsic' and not ignore_re.search(use.group(2)):
dependencies.add(get_moddir(use.group(2).lower() + '.mod'))
else:
mod = MODULE_RE.search(line)
if mod:
modules.add(get_moddir(mod.group(1).lower() + '.mod'))
modules.add(get_moddir(mod.group(1).lower() + '.smod'))
else:
submod = SUBMODULE_RE.search(line)
if submod:
modules.add(get_moddir(submod.group(1).lower() + '@'
+ submod.group(3).lower() + '.smod'))
if submod.group(2) and not ignore_re.search(mod.group(1)):
dependencies.add(get_moddir(submod.group(1).lower() + '@'
+ submod.group(2).lower()
+ '.smod'))
elif not ignore_re.search(submod.group(1)):
dependencies.add(get_moddir(submod.group(1).lower() + '.smod'))
else:
inc = INCLUDE_RE.search(line)
if inc:
ifile = inc.group(3)
includes.update(tuple(os.path.join(idir,ifile) for idir in incdirs))
src.close()
basename = os.path.splitext(filename)[0]
if len(modules) > 0:
print(' '.join(modules) + ': ' + filename + ' ' + basename + '.o')
if len(dependencies) + len(includes) > 0:
print(basename + '.o: ' + ' '.join(dependencies) +
' $(wildcard ' + ' '.join(includes) + ')')
# for dep in dependencies:
# print(dep + ':')