1df3bd252SSatish Balay#!/usr/bin/env python3 20ee81e68SLisandro Dalcin 30ee81e68SLisandro Dalcinimport os 4becf0a19SJed Brownfrom sysconfig import _parse_makefile as parse_makefile 50ee81e68SLisandro Dalcinimport sys 60ee81e68SLisandro Dalcinimport logging 70ee81e68SLisandro Dalcinsys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) 87b8851e6SJed Brownfrom collections import defaultdict 90ee81e68SLisandro Dalcin 10b892d579SJed BrownAUTODIRS = set('ftn-auto ftn-custom f90-custom ftn-auto-interfaces'.split()) # Automatically recurse into these, if they exist 11f22bedf1SBarry SmithSKIPDIRS = set('benchmarks build'.split()) # Skip these during the build 12dc0529c6SBarry SmithNOWARNDIRS = set('tests tutorials'.split()) # Do not warn about mismatch in these 13dc0529c6SBarry Smith 14dc0529c6SBarry Smithdef pathsplit(path): 15dc0529c6SBarry Smith """Recursively split a path, returns a tuple""" 16dc0529c6SBarry Smith stem, basename = os.path.split(path) 17dc0529c6SBarry Smith if stem == '': 18dc0529c6SBarry Smith return (basename,) 19dc0529c6SBarry Smith if stem == path: # fixed point, likely '/' 20dc0529c6SBarry Smith return (path,) 21dc0529c6SBarry Smith return pathsplit(stem) + (basename,) 22dc0529c6SBarry Smith 23c0558f20SBarry Smithdef getlangext(name): 24c0558f20SBarry Smith """Returns everything after the first . in the filename, including the .""" 25c0558f20SBarry Smith file = os.path.basename(name) 26c0558f20SBarry Smith loc = file.find('.') 27c0558f20SBarry Smith if loc > -1: return file[loc:] 28c0558f20SBarry Smith else: return '' 29c0558f20SBarry Smith 30c0558f20SBarry Smithdef getlangsplit(name): 31c0558f20SBarry Smith """Returns everything before the first . in the filename, excluding the .""" 32c0558f20SBarry Smith file = os.path.basename(name) 33c0558f20SBarry Smith loc = file.find('.') 34c0558f20SBarry Smith if loc > -1: return os.path.join(os.path.dirname(name),file[:loc]) 35c0558f20SBarry Smith raise RuntimeError("No . in filename") 36c0558f20SBarry Smith 37dc0529c6SBarry Smithclass Mistakes(object): 38dc0529c6SBarry Smith def __init__(self, log, verbose=False): 39dc0529c6SBarry Smith self.mistakes = [] 40dc0529c6SBarry Smith self.verbose = verbose 41dc0529c6SBarry Smith self.log = log 42dc0529c6SBarry Smith 43dc0529c6SBarry Smith def compareDirLists(self,root, mdirs, dirs): 44dc0529c6SBarry Smith if NOWARNDIRS.intersection(pathsplit(root)): 45dc0529c6SBarry Smith return 46dc0529c6SBarry Smith smdirs = set(mdirs) 47dc0529c6SBarry Smith sdirs = set(dirs).difference(AUTODIRS) 48dc0529c6SBarry Smith if not smdirs.issubset(sdirs): 49cca3327aSJed Brown self.mistakes.append('%s/makefile contains a directory not on the filesystem: %r' % (root, sorted(smdirs - sdirs))) 50dc0529c6SBarry Smith if not self.verbose: return 51dc0529c6SBarry Smith if smdirs != sdirs: 52dc0529c6SBarry Smith from sys import stderr 53dc0529c6SBarry Smith stderr.write('Directory mismatch at %s:\n\t%s: %r\n\t%s: %r\n\t%s: %r\n' 54dc0529c6SBarry Smith % (root, 55dc0529c6SBarry Smith 'in makefile ',sorted(smdirs), 56dc0529c6SBarry Smith 'on filesystem ',sorted(sdirs), 57dc0529c6SBarry Smith 'symmetric diff',sorted(smdirs.symmetric_difference(sdirs)))) 58dc0529c6SBarry Smith 59dc0529c6SBarry Smith def summary(self): 60dc0529c6SBarry Smith for m in self.mistakes: 61dc0529c6SBarry Smith self.log.write(m + '\n') 62dc0529c6SBarry Smith if self.mistakes: 63a943032dSBarry Smith raise RuntimeError('\n\nThe PETSc makefiles contain mistakes or files are missing on the filesystem.\n%s\nPossible reasons:\n\t1. Files were deleted locally, try "git checkout filename", where "filename" is the missing file.\n\t2. Files were deleted from the repository, but were not removed from the makefile. Send mail to petsc-maint@mcs.anl.gov.\n\t3. Someone forgot to "add" new files to the repository. Send mail to petsc-maint@mcs.anl.gov.\n\n' % ('\n'.join(self.mistakes))) 64dc0529c6SBarry Smith 65dc0529c6SBarry Smithdef stripsplit(line): 66dc0529c6SBarry Smith return line[len('#requires'):].replace("'","").split() 67dc0529c6SBarry Smith 6847fd361eSStefano ZampiniPetscPKGS = 'sys vec mat dm ksp snes ts tao'.split() 69c0558f20SBarry Smith# the key is actually the language suffix, it won't work for suffixes such as 'kokkos.cxx' so use an _ and replace the _ as needed with . 70*5a7ab478SBarry SmithLANGS = dict(kokkos_cxx='KOKKOS', hip_cpp='HIP', sycl_cxx='SYCL', raja_cxx='RAJA', c='C', cxx='CXX', cpp='CPP', cu='CU', F='F', F90='F90') 710ee81e68SLisandro Dalcin 720ee81e68SLisandro Dalcinclass debuglogger(object): 730ee81e68SLisandro Dalcin def __init__(self, log): 740ee81e68SLisandro Dalcin self._log = log 750ee81e68SLisandro Dalcin 760ee81e68SLisandro Dalcin def write(self, string): 770ee81e68SLisandro Dalcin self._log.debug(string) 780ee81e68SLisandro Dalcin 790ee81e68SLisandro Dalcinclass Petsc(object): 8047fd361eSStefano Zampini def __init__(self, petsc_dir=None, petsc_arch=None, pkg_dir=None, pkg_name=None, pkg_arch=None, pkg_pkgs=None, verbose=False): 810ee81e68SLisandro Dalcin if petsc_dir is None: 820ee81e68SLisandro Dalcin petsc_dir = os.environ.get('PETSC_DIR') 830ee81e68SLisandro Dalcin if petsc_dir is None: 840ee81e68SLisandro Dalcin try: 85af0996ceSBarry Smith petsc_dir = parse_makefile(os.path.join('lib','petsc','conf', 'petscvariables')).get('PETSC_DIR') 860ee81e68SLisandro Dalcin finally: 870ee81e68SLisandro Dalcin if petsc_dir is None: 880ee81e68SLisandro Dalcin raise RuntimeError('Could not determine PETSC_DIR, please set in environment') 890ee81e68SLisandro Dalcin if petsc_arch is None: 900ee81e68SLisandro Dalcin petsc_arch = os.environ.get('PETSC_ARCH') 910ee81e68SLisandro Dalcin if petsc_arch is None: 920ee81e68SLisandro Dalcin try: 93af0996ceSBarry Smith petsc_arch = parse_makefile(os.path.join(petsc_dir, 'lib','petsc','conf', 'petscvariables')).get('PETSC_ARCH') 940ee81e68SLisandro Dalcin finally: 950ee81e68SLisandro Dalcin if petsc_arch is None: 960ee81e68SLisandro Dalcin raise RuntimeError('Could not determine PETSC_ARCH, please set in environment') 97add6df95SStefano Zampini self.petsc_dir = os.path.normpath(petsc_dir) 98add6df95SStefano Zampini self.petsc_arch = petsc_arch.rstrip(os.sep) 99add6df95SStefano Zampini self.pkg_dir = pkg_dir 100add6df95SStefano Zampini self.pkg_name = pkg_name 101c4bccdb5SStefano Zampini self.pkg_arch = pkg_arch 102add6df95SStefano Zampini if self.pkg_dir is None: 103add6df95SStefano Zampini self.pkg_dir = petsc_dir 104add6df95SStefano Zampini self.pkg_name = 'petsc' 105c4bccdb5SStefano Zampini self.pkg_arch = self.petsc_arch 106add6df95SStefano Zampini if self.pkg_name is None: 107add6df95SStefano Zampini self.pkg_name = os.path.basename(os.path.normpath(self.pkg_dir)) 108c4bccdb5SStefano Zampini if self.pkg_arch is None: 109c4bccdb5SStefano Zampini self.pkg_arch = self.petsc_arch 11047fd361eSStefano Zampini self.pkg_pkgs = PetscPKGS 11147fd361eSStefano Zampini if pkg_pkgs is not None: 11247fd361eSStefano Zampini self.pkg_pkgs += list(set(pkg_pkgs.split(','))-set(self.pkg_pkgs)) 11347fd361eSStefano Zampini self.read_conf() 1148e69c5ecSJed Brown try: 115add6df95SStefano Zampini logging.basicConfig(filename=self.pkg_arch_path('lib',self.pkg_name,'conf', 'gmake.log'), level=logging.DEBUG) 1168e69c5ecSJed Brown except IOError: 1178e69c5ecSJed Brown # Disable logging if path is not writeable (e.g., prefix install) 1188e69c5ecSJed Brown logging.basicConfig(filename='/dev/null', level=logging.DEBUG) 1190ee81e68SLisandro Dalcin self.log = logging.getLogger('gmakegen') 1200ee81e68SLisandro Dalcin self.mistakes = Mistakes(debuglogger(self.log), verbose=verbose) 1210ee81e68SLisandro Dalcin self.gendeps = [] 1220ee81e68SLisandro Dalcin 1230ee81e68SLisandro Dalcin def arch_path(self, *args): 1240ee81e68SLisandro Dalcin return os.path.join(self.petsc_dir, self.petsc_arch, *args) 1250ee81e68SLisandro Dalcin 126add6df95SStefano Zampini def pkg_arch_path(self, *args): 127c4bccdb5SStefano Zampini return os.path.join(self.pkg_dir, self.pkg_arch, *args) 128add6df95SStefano Zampini 1290ee81e68SLisandro Dalcin def read_conf(self): 1300ee81e68SLisandro Dalcin self.conf = dict() 131021a2b48SJed Brown with open(self.arch_path('include', 'petscconf.h')) as petscconf_h: 132021a2b48SJed Brown for line in petscconf_h: 1330ee81e68SLisandro Dalcin if line.startswith('#define '): 1340ee81e68SLisandro Dalcin define = line[len('#define '):] 1350ee81e68SLisandro Dalcin space = define.find(' ') 1360ee81e68SLisandro Dalcin key = define[:space] 1370ee81e68SLisandro Dalcin val = define[space+1:] 1380ee81e68SLisandro Dalcin self.conf[key] = val 139af0996ceSBarry Smith self.conf.update(parse_makefile(self.arch_path('lib','petsc','conf', 'petscvariables'))) 14047fd361eSStefano Zampini # allow parsing package additional configurations (if any) 14147fd361eSStefano Zampini if self.pkg_name != 'petsc' : 14247fd361eSStefano Zampini f = self.pkg_arch_path('include', self.pkg_name + 'conf.h') 14347fd361eSStefano Zampini if os.path.isfile(f): 144021a2b48SJed Brown with open(self.pkg_arch_path('include', self.pkg_name + 'conf.h')) as pkg_conf_h: 145021a2b48SJed Brown for line in pkg_conf_h: 14647fd361eSStefano Zampini if line.startswith('#define '): 14747fd361eSStefano Zampini define = line[len('#define '):] 14847fd361eSStefano Zampini space = define.find(' ') 14947fd361eSStefano Zampini key = define[:space] 15047fd361eSStefano Zampini val = define[space+1:] 15147fd361eSStefano Zampini self.conf[key] = val 15247fd361eSStefano Zampini f = self.pkg_arch_path('lib',self.pkg_name,'conf', self.pkg_name + 'variables') 15347fd361eSStefano Zampini if os.path.isfile(f): 15447fd361eSStefano Zampini self.conf.update(parse_makefile(self.pkg_arch_path('lib',self.pkg_name,'conf', self.pkg_name + 'variables'))) 1550ee81e68SLisandro Dalcin self.have_fortran = int(self.conf.get('PETSC_HAVE_FORTRAN', '0')) 1560ee81e68SLisandro Dalcin 1570ee81e68SLisandro Dalcin def inconf(self, key, val): 1580ee81e68SLisandro Dalcin if key in ['package', 'function', 'define']: 1590ee81e68SLisandro Dalcin return self.conf.get(val) 1600ee81e68SLisandro Dalcin elif key == 'precision': 1610ee81e68SLisandro Dalcin return val == self.conf['PETSC_PRECISION'] 1620ee81e68SLisandro Dalcin elif key == 'scalar': 1630ee81e68SLisandro Dalcin return val == self.conf['PETSC_SCALAR'] 1640ee81e68SLisandro Dalcin elif key == 'language': 1650ee81e68SLisandro Dalcin return val == self.conf['PETSC_LANGUAGE'] 1660ee81e68SLisandro Dalcin raise RuntimeError('Unknown conf check: %s %s' % (key, val)) 1670ee81e68SLisandro Dalcin 1680ee81e68SLisandro Dalcin def relpath(self, root, src): 169add6df95SStefano Zampini return os.path.relpath(os.path.join(root, src), self.pkg_dir) 1700ee81e68SLisandro Dalcin 171*5a7ab478SBarry Smith def get_sources_from_files(self, files): 1720ee81e68SLisandro Dalcin """Return dict {lang: list_of_source_files}""" 1730ee81e68SLisandro Dalcin source = dict() 1740ee81e68SLisandro Dalcin for lang, sourcelang in LANGS.items(): 175*5a7ab478SBarry Smith source[lang] = [f for f in files if f.endswith('.'+lang.replace('_','.'))] 176*5a7ab478SBarry Smith files = [f for f in files if not f.endswith('.'+lang.replace('_','.'))] 1770ee81e68SLisandro Dalcin return source 1780ee81e68SLisandro Dalcin 1790ee81e68SLisandro Dalcin def gen_pkg(self, pkg): 1800ee81e68SLisandro Dalcin pkgsrcs = dict() 1810ee81e68SLisandro Dalcin for lang in LANGS: 1820ee81e68SLisandro Dalcin pkgsrcs[lang] = [] 183add6df95SStefano Zampini for root, dirs, files in os.walk(os.path.join(self.pkg_dir, 'src', pkg)): 184*5a7ab478SBarry Smith if NOWARNDIRS.intersection(pathsplit(root)): continue 18509a6cbfcSBernhard M. Wiedemann dirs.sort() 18609a6cbfcSBernhard M. Wiedemann files.sort() 1870ee81e68SLisandro Dalcin makefile = os.path.join(root,'makefile') 1880ee81e68SLisandro Dalcin if not os.path.exists(makefile): 1890ee81e68SLisandro Dalcin dirs[:] = [] 1900ee81e68SLisandro Dalcin continue 191021a2b48SJed Brown with open(makefile) as mklines: 1920ee81e68SLisandro Dalcin conditions = set(tuple(stripsplit(line)) for line in mklines if line.startswith('#requires')) 1930ee81e68SLisandro Dalcin if not all(self.inconf(key, val) for key, val in conditions): 1940ee81e68SLisandro Dalcin dirs[:] = [] 1950ee81e68SLisandro Dalcin continue 1960ee81e68SLisandro Dalcin makevars = parse_makefile(makefile) 1970ee81e68SLisandro Dalcin mdirs = makevars.get('DIRS','').split() # Directories specified in the makefile 1980ee81e68SLisandro Dalcin self.mistakes.compareDirLists(root, mdirs, dirs) # diagnostic output to find unused directories 1990ee81e68SLisandro Dalcin candidates = set(mdirs).union(AUTODIRS).difference(SKIPDIRS) 2000ee81e68SLisandro Dalcin dirs[:] = list(candidates.intersection(dirs)) 2010ee81e68SLisandro Dalcin allsource = [] 2020ee81e68SLisandro Dalcin def mkrel(src): 2030ee81e68SLisandro Dalcin return self.relpath(root, src) 204*5a7ab478SBarry Smith source = self.get_sources_from_files(files) 2050ee81e68SLisandro Dalcin for lang, s in source.items(): 2062b757757SJed Brown pkgsrcs[lang] += [mkrel(t) for t in s] 2070ee81e68SLisandro Dalcin self.gendeps.append(self.relpath(root, 'makefile')) 2080ee81e68SLisandro Dalcin return pkgsrcs 2090ee81e68SLisandro Dalcin 210b0790570SJed Brown def gen_gnumake(self, fd): 2110ee81e68SLisandro Dalcin def write(stem, srcs): 2120ee81e68SLisandro Dalcin for lang in LANGS: 213c0558f20SBarry Smith fd.write('%(stem)s.%(lang)s := %(srcs)s\n' % dict(stem=stem, lang=lang.replace('_','.'), srcs=' '.join(srcs[lang]))) 21447fd361eSStefano Zampini for pkg in self.pkg_pkgs: 2150ee81e68SLisandro Dalcin srcs = self.gen_pkg(pkg) 216b0790570SJed Brown write('srcs-' + pkg, srcs) 2170ee81e68SLisandro Dalcin return self.gendeps 2180ee81e68SLisandro Dalcin 2190ee81e68SLisandro Dalcin def gen_ninja(self, fd): 2200ee81e68SLisandro Dalcin libobjs = [] 22147fd361eSStefano Zampini for pkg in self.pkg_pkgs: 2220ee81e68SLisandro Dalcin srcs = self.gen_pkg(pkg) 2230ee81e68SLisandro Dalcin for lang in LANGS: 2240ee81e68SLisandro Dalcin for src in srcs[lang]: 2250ee81e68SLisandro Dalcin obj = '$objdir/%s.o' % src 226add6df95SStefano Zampini fd.write('build %(obj)s : %(lang)s_COMPILE %(src)s\n' % dict(obj=obj, lang=lang.upper(), src=os.path.join(self.pkg_dir,src))) 2270ee81e68SLisandro Dalcin libobjs.append(obj) 2280ee81e68SLisandro Dalcin fd.write('\n') 2290ee81e68SLisandro Dalcin fd.write('build $libdir/libpetsc.so : %s_LINK_SHARED %s\n\n' % ('CF'[self.have_fortran], ' '.join(libobjs))) 2300ee81e68SLisandro Dalcin fd.write('build petsc : phony || $libdir/libpetsc.so\n\n') 2310ee81e68SLisandro Dalcin 2320ee81e68SLisandro Dalcin def summary(self): 2330ee81e68SLisandro Dalcin self.mistakes.summary() 2340ee81e68SLisandro Dalcin 2350ee81e68SLisandro Dalcindef WriteGnuMake(petsc): 236add6df95SStefano Zampini arch_files = petsc.pkg_arch_path('lib',petsc.pkg_name,'conf', 'files') 237021a2b48SJed Brown with open(arch_files, 'w') as fd: 2380ee81e68SLisandro Dalcin gendeps = petsc.gen_gnumake(fd) 2390ee81e68SLisandro Dalcin fd.write('\n') 2400ee81e68SLisandro Dalcin fd.write('# Dependency to regenerate this file\n') 241add6df95SStefano Zampini fd.write('%s : %s %s\n' % (os.path.relpath(arch_files, petsc.pkg_dir), 242add6df95SStefano Zampini os.path.relpath(__file__, os.path.realpath(petsc.pkg_dir)), 2430ee81e68SLisandro Dalcin ' '.join(gendeps))) 2440ee81e68SLisandro Dalcin fd.write('\n') 2450ee81e68SLisandro Dalcin fd.write('# Dummy dependencies in case makefiles are removed\n') 2460ee81e68SLisandro Dalcin fd.write(''.join([dep + ':\n' for dep in gendeps])) 2470ee81e68SLisandro Dalcin 2480ee81e68SLisandro Dalcindef WriteNinja(petsc): 2490ee81e68SLisandro Dalcin conf = dict() 250af0996ceSBarry Smith parse_makefile(os.path.join(petsc.petsc_dir, 'lib', 'petsc','conf', 'variables'), conf) 251af0996ceSBarry Smith parse_makefile(petsc.arch_path('lib','petsc','conf', 'petscvariables'), conf) 2520ee81e68SLisandro Dalcin build_ninja = petsc.arch_path('build.ninja') 253021a2b48SJed Brown with open(build_ninja, 'w') as fd: 2540ee81e68SLisandro Dalcin fd.write('objdir = obj-ninja\n') 2550ee81e68SLisandro Dalcin fd.write('libdir = lib\n') 2560ee81e68SLisandro Dalcin fd.write('c_compile = %(PCC)s\n' % conf) 2570ee81e68SLisandro Dalcin fd.write('c_flags = %(PETSC_CC_INCLUDES)s %(PCC_FLAGS)s %(CCPPFLAGS)s\n' % conf) 2580ee81e68SLisandro Dalcin fd.write('c_link = %(PCC_LINKER)s\n' % conf) 2590ee81e68SLisandro Dalcin fd.write('c_link_flags = %(PCC_LINKER_FLAGS)s\n' % conf) 2600ee81e68SLisandro Dalcin if petsc.have_fortran: 2610ee81e68SLisandro Dalcin fd.write('f_compile = %(FC)s\n' % conf) 2620ee81e68SLisandro Dalcin fd.write('f_flags = %(PETSC_FC_INCLUDES)s %(FC_FLAGS)s %(FCPPFLAGS)s\n' % conf) 2630ee81e68SLisandro Dalcin fd.write('f_link = %(FC_LINKER)s\n' % conf) 2640ee81e68SLisandro Dalcin fd.write('f_link_flags = %(FC_LINKER_FLAGS)s\n' % conf) 2650ee81e68SLisandro Dalcin fd.write('petsc_external_lib = %(PETSC_EXTERNAL_LIB_BASIC)s\n' % conf) 2660ee81e68SLisandro Dalcin fd.write('python = %(PYTHON)s\n' % conf) 2670ee81e68SLisandro Dalcin fd.write('\n') 2680ee81e68SLisandro Dalcin fd.write('rule C_COMPILE\n' 2690ee81e68SLisandro Dalcin ' command = $c_compile -MMD -MF $out.d $c_flags -c $in -o $out\n' 2700ee81e68SLisandro Dalcin ' description = CC $out\n' 2710ee81e68SLisandro Dalcin ' depfile = $out.d\n' 2720ee81e68SLisandro Dalcin # ' deps = gcc\n') # 'gcc' is default, 'msvc' only recognized by newer versions of ninja 2730ee81e68SLisandro Dalcin '\n') 2740ee81e68SLisandro Dalcin fd.write('rule C_LINK_SHARED\n' 2750ee81e68SLisandro Dalcin ' command = $c_link $c_link_flags -shared -o $out $in $petsc_external_lib\n' 2760ee81e68SLisandro Dalcin ' description = CLINK_SHARED $out\n' 2770ee81e68SLisandro Dalcin '\n') 2780ee81e68SLisandro Dalcin if petsc.have_fortran: 2790ee81e68SLisandro Dalcin fd.write('rule F_COMPILE\n' 2800ee81e68SLisandro Dalcin ' command = $f_compile -MMD -MF $out.d $f_flags -c $in -o $out\n' 2810ee81e68SLisandro Dalcin ' description = FC $out\n' 2820ee81e68SLisandro Dalcin ' depfile = $out.d\n' 2830ee81e68SLisandro Dalcin '\n') 2840ee81e68SLisandro Dalcin fd.write('rule F_LINK_SHARED\n' 2850ee81e68SLisandro Dalcin ' command = $f_link $f_link_flags -shared -o $out $in $petsc_external_lib\n' 2860ee81e68SLisandro Dalcin ' description = FLINK_SHARED $out\n' 2870ee81e68SLisandro Dalcin '\n') 2880ee81e68SLisandro Dalcin fd.write('rule GEN_NINJA\n' 2890ee81e68SLisandro Dalcin ' command = $python $in --output=ninja\n' 2900ee81e68SLisandro Dalcin ' generator = 1\n' 2910ee81e68SLisandro Dalcin '\n') 2920ee81e68SLisandro Dalcin petsc.gen_ninja(fd) 2930ee81e68SLisandro Dalcin fd.write('\n') 2940ee81e68SLisandro Dalcin fd.write('build %s : GEN_NINJA | %s %s %s %s\n' % (build_ninja, 2950ee81e68SLisandro Dalcin os.path.abspath(__file__), 296af0996ceSBarry Smith os.path.join(petsc.petsc_dir, 'lib','petsc','conf', 'variables'), 297af0996ceSBarry Smith petsc.arch_path('lib','petsc','conf', 'petscvariables'), 298add6df95SStefano Zampini ' '.join(os.path.join(petsc.pkg_dir, dep) for dep in petsc.gendeps))) 2990ee81e68SLisandro Dalcin 30047fd361eSStefano Zampinidef main(petsc_dir=None, petsc_arch=None, pkg_dir=None, pkg_name=None, pkg_arch=None, pkg_pkgs=None, output=None, verbose=False): 3010ee81e68SLisandro Dalcin if output is None: 3020ee81e68SLisandro Dalcin output = 'gnumake' 3030ee81e68SLisandro Dalcin writer = dict(gnumake=WriteGnuMake, ninja=WriteNinja) 30447fd361eSStefano Zampini petsc = Petsc(petsc_dir=petsc_dir, petsc_arch=petsc_arch, pkg_dir=pkg_dir, pkg_name=pkg_name, pkg_arch=pkg_arch, pkg_pkgs=pkg_pkgs, verbose=verbose) 3050ee81e68SLisandro Dalcin writer[output](petsc) 3060ee81e68SLisandro Dalcin petsc.summary() 3070ee81e68SLisandro Dalcin 3080ee81e68SLisandro Dalcinif __name__ == '__main__': 3090ee81e68SLisandro Dalcin import optparse 3100ee81e68SLisandro Dalcin parser = optparse.OptionParser() 3110ee81e68SLisandro Dalcin parser.add_option('--verbose', help='Show mismatches between makefiles and the filesystem', action='store_true', default=False) 3120ee81e68SLisandro Dalcin parser.add_option('--petsc-arch', help='Set PETSC_ARCH different from environment', default=os.environ.get('PETSC_ARCH')) 313add6df95SStefano Zampini parser.add_option('--pkg-dir', help='Set the directory of the package (different from PETSc) you want to generate the makefile rules for', default=None) 314add6df95SStefano Zampini parser.add_option('--pkg-name', help='Set the name of the package you want to generate the makefile rules for', default=None) 315c4bccdb5SStefano Zampini parser.add_option('--pkg-arch', help='Set the package arch name you want to generate the makefile rules for', default=None) 31647fd361eSStefano Zampini parser.add_option('--pkg-pkgs', help='Set the package folders (comma separated list, different from the usual sys,vec,mat etc) you want to generate the makefile rules for', default=None) 3170ee81e68SLisandro Dalcin parser.add_option('--output', help='Location to write output file', default=None) 3180ee81e68SLisandro Dalcin opts, extra_args = parser.parse_args() 3190ee81e68SLisandro Dalcin if extra_args: 3200ee81e68SLisandro Dalcin import sys 3210ee81e68SLisandro Dalcin sys.stderr.write('Unknown arguments: %s\n' % ' '.join(extra_args)) 3220ee81e68SLisandro Dalcin exit(1) 32347fd361eSStefano Zampini main(petsc_arch=opts.petsc_arch, pkg_dir=opts.pkg_dir, pkg_name=opts.pkg_name, pkg_arch=opts.pkg_arch, pkg_pkgs=opts.pkg_pkgs, output=opts.output, verbose=opts.verbose) 324