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 11*b75c6efcSBarry SmithSKIPDIRS = set('benchmarks build mex-scripts tests tutorials'.split()) # Skip these during the build 12dc0529c6SBarry Smith 13dc0529c6SBarry Smithdef pathsplit(path): 14dc0529c6SBarry Smith """Recursively split a path, returns a tuple""" 15dc0529c6SBarry Smith stem, basename = os.path.split(path) 16dc0529c6SBarry Smith if stem == '': 17dc0529c6SBarry Smith return (basename,) 18dc0529c6SBarry Smith if stem == path: # fixed point, likely '/' 19dc0529c6SBarry Smith return (path,) 20dc0529c6SBarry Smith return pathsplit(stem) + (basename,) 21dc0529c6SBarry Smith 22c0558f20SBarry Smithdef getlangext(name): 23c0558f20SBarry Smith """Returns everything after the first . in the filename, including the .""" 24c0558f20SBarry Smith file = os.path.basename(name) 25c0558f20SBarry Smith loc = file.find('.') 26c0558f20SBarry Smith if loc > -1: return file[loc:] 27c0558f20SBarry Smith else: return '' 28c0558f20SBarry Smith 29c0558f20SBarry Smithdef getlangsplit(name): 30c0558f20SBarry Smith """Returns everything before the first . in the filename, excluding the .""" 31c0558f20SBarry Smith file = os.path.basename(name) 32c0558f20SBarry Smith loc = file.find('.') 33c0558f20SBarry Smith if loc > -1: return os.path.join(os.path.dirname(name),file[:loc]) 34c0558f20SBarry Smith raise RuntimeError("No . in filename") 35c0558f20SBarry Smith 36dc0529c6SBarry Smithclass Mistakes(object): 37dc0529c6SBarry Smith def __init__(self, log, verbose=False): 38dc0529c6SBarry Smith self.mistakes = [] 39dc0529c6SBarry Smith self.verbose = verbose 40dc0529c6SBarry Smith self.log = log 41dc0529c6SBarry Smith 42dc0529c6SBarry Smith def compareDirLists(self,root, mdirs, dirs): 43*b75c6efcSBarry Smith if SKIPDIRS.intersection(pathsplit(root)): 44dc0529c6SBarry Smith return 45dc0529c6SBarry Smith smdirs = set(mdirs) 46dc0529c6SBarry Smith sdirs = set(dirs).difference(AUTODIRS) 47dc0529c6SBarry Smith if not smdirs.issubset(sdirs): 48cca3327aSJed Brown self.mistakes.append('%s/makefile contains a directory not on the filesystem: %r' % (root, sorted(smdirs - sdirs))) 49dc0529c6SBarry Smith if not self.verbose: return 50dc0529c6SBarry Smith if smdirs != sdirs: 51dc0529c6SBarry Smith from sys import stderr 52dc0529c6SBarry Smith stderr.write('Directory mismatch at %s:\n\t%s: %r\n\t%s: %r\n\t%s: %r\n' 53dc0529c6SBarry Smith % (root, 54dc0529c6SBarry Smith 'in makefile ',sorted(smdirs), 55dc0529c6SBarry Smith 'on filesystem ',sorted(sdirs), 56dc0529c6SBarry Smith 'symmetric diff',sorted(smdirs.symmetric_difference(sdirs)))) 57dc0529c6SBarry Smith 58dc0529c6SBarry Smith def summary(self): 59dc0529c6SBarry Smith for m in self.mistakes: 60dc0529c6SBarry Smith self.log.write(m + '\n') 61dc0529c6SBarry Smith if self.mistakes: 62a943032dSBarry 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))) 63dc0529c6SBarry Smith 64dc0529c6SBarry Smithdef stripsplit(line): 65dc0529c6SBarry Smith return line[len('#requires'):].replace("'","").split() 66dc0529c6SBarry Smith 6747fd361eSStefano ZampiniPetscPKGS = 'sys vec mat dm ksp snes ts tao'.split() 68c0558f20SBarry 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 . 695a7ab478SBarry 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') 700ee81e68SLisandro Dalcin 710ee81e68SLisandro Dalcinclass debuglogger(object): 720ee81e68SLisandro Dalcin def __init__(self, log): 730ee81e68SLisandro Dalcin self._log = log 740ee81e68SLisandro Dalcin 750ee81e68SLisandro Dalcin def write(self, string): 760ee81e68SLisandro Dalcin self._log.debug(string) 770ee81e68SLisandro Dalcin 780ee81e68SLisandro Dalcinclass Petsc(object): 7947fd361eSStefano Zampini def __init__(self, petsc_dir=None, petsc_arch=None, pkg_dir=None, pkg_name=None, pkg_arch=None, pkg_pkgs=None, verbose=False): 800ee81e68SLisandro Dalcin if petsc_dir is None: 810ee81e68SLisandro Dalcin petsc_dir = os.environ.get('PETSC_DIR') 820ee81e68SLisandro Dalcin if petsc_dir is None: 830ee81e68SLisandro Dalcin try: 84af0996ceSBarry Smith petsc_dir = parse_makefile(os.path.join('lib','petsc','conf', 'petscvariables')).get('PETSC_DIR') 850ee81e68SLisandro Dalcin finally: 860ee81e68SLisandro Dalcin if petsc_dir is None: 870ee81e68SLisandro Dalcin raise RuntimeError('Could not determine PETSC_DIR, please set in environment') 880ee81e68SLisandro Dalcin if petsc_arch is None: 890ee81e68SLisandro Dalcin petsc_arch = os.environ.get('PETSC_ARCH') 900ee81e68SLisandro Dalcin if petsc_arch is None: 910ee81e68SLisandro Dalcin try: 92af0996ceSBarry Smith petsc_arch = parse_makefile(os.path.join(petsc_dir, 'lib','petsc','conf', 'petscvariables')).get('PETSC_ARCH') 930ee81e68SLisandro Dalcin finally: 940ee81e68SLisandro Dalcin if petsc_arch is None: 950ee81e68SLisandro Dalcin raise RuntimeError('Could not determine PETSC_ARCH, please set in environment') 96add6df95SStefano Zampini self.petsc_dir = os.path.normpath(petsc_dir) 97add6df95SStefano Zampini self.petsc_arch = petsc_arch.rstrip(os.sep) 98add6df95SStefano Zampini self.pkg_dir = pkg_dir 99add6df95SStefano Zampini self.pkg_name = pkg_name 100c4bccdb5SStefano Zampini self.pkg_arch = pkg_arch 101add6df95SStefano Zampini if self.pkg_dir is None: 102add6df95SStefano Zampini self.pkg_dir = petsc_dir 103add6df95SStefano Zampini self.pkg_name = 'petsc' 104c4bccdb5SStefano Zampini self.pkg_arch = self.petsc_arch 105add6df95SStefano Zampini if self.pkg_name is None: 106add6df95SStefano Zampini self.pkg_name = os.path.basename(os.path.normpath(self.pkg_dir)) 107c4bccdb5SStefano Zampini if self.pkg_arch is None: 108c4bccdb5SStefano Zampini self.pkg_arch = self.petsc_arch 10947fd361eSStefano Zampini self.pkg_pkgs = PetscPKGS 11047fd361eSStefano Zampini if pkg_pkgs is not None: 11147fd361eSStefano Zampini self.pkg_pkgs += list(set(pkg_pkgs.split(','))-set(self.pkg_pkgs)) 11247fd361eSStefano Zampini self.read_conf() 1138e69c5ecSJed Brown try: 114add6df95SStefano Zampini logging.basicConfig(filename=self.pkg_arch_path('lib',self.pkg_name,'conf', 'gmake.log'), level=logging.DEBUG) 1158e69c5ecSJed Brown except IOError: 1168e69c5ecSJed Brown # Disable logging if path is not writeable (e.g., prefix install) 1178e69c5ecSJed Brown logging.basicConfig(filename='/dev/null', level=logging.DEBUG) 1180ee81e68SLisandro Dalcin self.log = logging.getLogger('gmakegen') 1190ee81e68SLisandro Dalcin self.mistakes = Mistakes(debuglogger(self.log), verbose=verbose) 1200ee81e68SLisandro Dalcin self.gendeps = [] 1210ee81e68SLisandro Dalcin 1220ee81e68SLisandro Dalcin def arch_path(self, *args): 1230ee81e68SLisandro Dalcin return os.path.join(self.petsc_dir, self.petsc_arch, *args) 1240ee81e68SLisandro Dalcin 125add6df95SStefano Zampini def pkg_arch_path(self, *args): 126c4bccdb5SStefano Zampini return os.path.join(self.pkg_dir, self.pkg_arch, *args) 127add6df95SStefano Zampini 1280ee81e68SLisandro Dalcin def read_conf(self): 1290ee81e68SLisandro Dalcin self.conf = dict() 130021a2b48SJed Brown with open(self.arch_path('include', 'petscconf.h')) as petscconf_h: 131021a2b48SJed Brown for line in petscconf_h: 1320ee81e68SLisandro Dalcin if line.startswith('#define '): 1330ee81e68SLisandro Dalcin define = line[len('#define '):] 1340ee81e68SLisandro Dalcin space = define.find(' ') 1350ee81e68SLisandro Dalcin key = define[:space] 1360ee81e68SLisandro Dalcin val = define[space+1:] 1370ee81e68SLisandro Dalcin self.conf[key] = val 138af0996ceSBarry Smith self.conf.update(parse_makefile(self.arch_path('lib','petsc','conf', 'petscvariables'))) 13947fd361eSStefano Zampini # allow parsing package additional configurations (if any) 14047fd361eSStefano Zampini if self.pkg_name != 'petsc' : 14147fd361eSStefano Zampini f = self.pkg_arch_path('include', self.pkg_name + 'conf.h') 14247fd361eSStefano Zampini if os.path.isfile(f): 143021a2b48SJed Brown with open(self.pkg_arch_path('include', self.pkg_name + 'conf.h')) as pkg_conf_h: 144021a2b48SJed Brown for line in pkg_conf_h: 14547fd361eSStefano Zampini if line.startswith('#define '): 14647fd361eSStefano Zampini define = line[len('#define '):] 14747fd361eSStefano Zampini space = define.find(' ') 14847fd361eSStefano Zampini key = define[:space] 14947fd361eSStefano Zampini val = define[space+1:] 15047fd361eSStefano Zampini self.conf[key] = val 15147fd361eSStefano Zampini f = self.pkg_arch_path('lib',self.pkg_name,'conf', self.pkg_name + 'variables') 15247fd361eSStefano Zampini if os.path.isfile(f): 15347fd361eSStefano Zampini self.conf.update(parse_makefile(self.pkg_arch_path('lib',self.pkg_name,'conf', self.pkg_name + 'variables'))) 1540ee81e68SLisandro Dalcin self.have_fortran = int(self.conf.get('PETSC_HAVE_FORTRAN', '0')) 1550ee81e68SLisandro Dalcin 1560ee81e68SLisandro Dalcin def inconf(self, key, val): 1570ee81e68SLisandro Dalcin if key in ['package', 'function', 'define']: 1580ee81e68SLisandro Dalcin return self.conf.get(val) 1590ee81e68SLisandro Dalcin elif key == 'precision': 1600ee81e68SLisandro Dalcin return val == self.conf['PETSC_PRECISION'] 1610ee81e68SLisandro Dalcin elif key == 'scalar': 1620ee81e68SLisandro Dalcin return val == self.conf['PETSC_SCALAR'] 1630ee81e68SLisandro Dalcin elif key == 'language': 1640ee81e68SLisandro Dalcin return val == self.conf['PETSC_LANGUAGE'] 1650ee81e68SLisandro Dalcin raise RuntimeError('Unknown conf check: %s %s' % (key, val)) 1660ee81e68SLisandro Dalcin 1670ee81e68SLisandro Dalcin def relpath(self, root, src): 168add6df95SStefano Zampini return os.path.relpath(os.path.join(root, src), self.pkg_dir) 1690ee81e68SLisandro Dalcin 1705a7ab478SBarry Smith def get_sources_from_files(self, files): 1710ee81e68SLisandro Dalcin """Return dict {lang: list_of_source_files}""" 1720ee81e68SLisandro Dalcin source = dict() 1730ee81e68SLisandro Dalcin for lang, sourcelang in LANGS.items(): 1745a7ab478SBarry Smith source[lang] = [f for f in files if f.endswith('.'+lang.replace('_','.'))] 1755a7ab478SBarry Smith files = [f for f in files if not f.endswith('.'+lang.replace('_','.'))] 1760ee81e68SLisandro Dalcin return source 1770ee81e68SLisandro Dalcin 1780ee81e68SLisandro Dalcin def gen_pkg(self, pkg): 1790ee81e68SLisandro Dalcin pkgsrcs = dict() 1800ee81e68SLisandro Dalcin for lang in LANGS: 1810ee81e68SLisandro Dalcin pkgsrcs[lang] = [] 182add6df95SStefano Zampini for root, dirs, files in os.walk(os.path.join(self.pkg_dir, 'src', pkg)): 183*b75c6efcSBarry Smith if SKIPDIRS.intersection(pathsplit(root)): continue 18409a6cbfcSBernhard M. Wiedemann dirs.sort() 18509a6cbfcSBernhard M. Wiedemann files.sort() 1860ee81e68SLisandro Dalcin makefile = os.path.join(root,'makefile') 1870ee81e68SLisandro Dalcin if not os.path.exists(makefile): 1880ee81e68SLisandro Dalcin dirs[:] = [] 1890ee81e68SLisandro Dalcin continue 190021a2b48SJed Brown with open(makefile) as mklines: 1910ee81e68SLisandro Dalcin conditions = set(tuple(stripsplit(line)) for line in mklines if line.startswith('#requires')) 1920ee81e68SLisandro Dalcin if not all(self.inconf(key, val) for key, val in conditions): 1930ee81e68SLisandro Dalcin dirs[:] = [] 1940ee81e68SLisandro Dalcin continue 1950ee81e68SLisandro Dalcin makevars = parse_makefile(makefile) 1960ee81e68SLisandro Dalcin mdirs = makevars.get('DIRS','').split() # Directories specified in the makefile 1970ee81e68SLisandro Dalcin self.mistakes.compareDirLists(root, mdirs, dirs) # diagnostic output to find unused directories 1980ee81e68SLisandro Dalcin candidates = set(mdirs).union(AUTODIRS).difference(SKIPDIRS) 1990ee81e68SLisandro Dalcin dirs[:] = list(candidates.intersection(dirs)) 2000ee81e68SLisandro Dalcin allsource = [] 2010ee81e68SLisandro Dalcin def mkrel(src): 2020ee81e68SLisandro Dalcin return self.relpath(root, src) 2035a7ab478SBarry Smith source = self.get_sources_from_files(files) 2040ee81e68SLisandro Dalcin for lang, s in source.items(): 2052b757757SJed Brown pkgsrcs[lang] += [mkrel(t) for t in s] 2060ee81e68SLisandro Dalcin self.gendeps.append(self.relpath(root, 'makefile')) 2070ee81e68SLisandro Dalcin return pkgsrcs 2080ee81e68SLisandro Dalcin 209b0790570SJed Brown def gen_gnumake(self, fd): 2100ee81e68SLisandro Dalcin def write(stem, srcs): 2110ee81e68SLisandro Dalcin for lang in LANGS: 212c0558f20SBarry Smith fd.write('%(stem)s.%(lang)s := %(srcs)s\n' % dict(stem=stem, lang=lang.replace('_','.'), srcs=' '.join(srcs[lang]))) 21347fd361eSStefano Zampini for pkg in self.pkg_pkgs: 2140ee81e68SLisandro Dalcin srcs = self.gen_pkg(pkg) 215b0790570SJed Brown write('srcs-' + pkg, srcs) 2160ee81e68SLisandro Dalcin return self.gendeps 2170ee81e68SLisandro Dalcin 2180ee81e68SLisandro Dalcin def gen_ninja(self, fd): 2190ee81e68SLisandro Dalcin libobjs = [] 22047fd361eSStefano Zampini for pkg in self.pkg_pkgs: 2210ee81e68SLisandro Dalcin srcs = self.gen_pkg(pkg) 2220ee81e68SLisandro Dalcin for lang in LANGS: 2230ee81e68SLisandro Dalcin for src in srcs[lang]: 2240ee81e68SLisandro Dalcin obj = '$objdir/%s.o' % src 225add6df95SStefano 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))) 2260ee81e68SLisandro Dalcin libobjs.append(obj) 2270ee81e68SLisandro Dalcin fd.write('\n') 2280ee81e68SLisandro Dalcin fd.write('build $libdir/libpetsc.so : %s_LINK_SHARED %s\n\n' % ('CF'[self.have_fortran], ' '.join(libobjs))) 2290ee81e68SLisandro Dalcin fd.write('build petsc : phony || $libdir/libpetsc.so\n\n') 2300ee81e68SLisandro Dalcin 2310ee81e68SLisandro Dalcin def summary(self): 2320ee81e68SLisandro Dalcin self.mistakes.summary() 2330ee81e68SLisandro Dalcin 2340ee81e68SLisandro Dalcindef WriteGnuMake(petsc): 235add6df95SStefano Zampini arch_files = petsc.pkg_arch_path('lib',petsc.pkg_name,'conf', 'files') 236021a2b48SJed Brown with open(arch_files, 'w') as fd: 2370ee81e68SLisandro Dalcin gendeps = petsc.gen_gnumake(fd) 2380ee81e68SLisandro Dalcin fd.write('\n') 2390ee81e68SLisandro Dalcin fd.write('# Dependency to regenerate this file\n') 240add6df95SStefano Zampini fd.write('%s : %s %s\n' % (os.path.relpath(arch_files, petsc.pkg_dir), 241add6df95SStefano Zampini os.path.relpath(__file__, os.path.realpath(petsc.pkg_dir)), 2420ee81e68SLisandro Dalcin ' '.join(gendeps))) 2430ee81e68SLisandro Dalcin fd.write('\n') 2440ee81e68SLisandro Dalcin fd.write('# Dummy dependencies in case makefiles are removed\n') 2450ee81e68SLisandro Dalcin fd.write(''.join([dep + ':\n' for dep in gendeps])) 2460ee81e68SLisandro Dalcin 2470ee81e68SLisandro Dalcindef WriteNinja(petsc): 2480ee81e68SLisandro Dalcin conf = dict() 249af0996ceSBarry Smith parse_makefile(os.path.join(petsc.petsc_dir, 'lib', 'petsc','conf', 'variables'), conf) 250af0996ceSBarry Smith parse_makefile(petsc.arch_path('lib','petsc','conf', 'petscvariables'), conf) 2510ee81e68SLisandro Dalcin build_ninja = petsc.arch_path('build.ninja') 252021a2b48SJed Brown with open(build_ninja, 'w') as fd: 2530ee81e68SLisandro Dalcin fd.write('objdir = obj-ninja\n') 2540ee81e68SLisandro Dalcin fd.write('libdir = lib\n') 2550ee81e68SLisandro Dalcin fd.write('c_compile = %(PCC)s\n' % conf) 2560ee81e68SLisandro Dalcin fd.write('c_flags = %(PETSC_CC_INCLUDES)s %(PCC_FLAGS)s %(CCPPFLAGS)s\n' % conf) 2570ee81e68SLisandro Dalcin fd.write('c_link = %(PCC_LINKER)s\n' % conf) 2580ee81e68SLisandro Dalcin fd.write('c_link_flags = %(PCC_LINKER_FLAGS)s\n' % conf) 2590ee81e68SLisandro Dalcin if petsc.have_fortran: 2600ee81e68SLisandro Dalcin fd.write('f_compile = %(FC)s\n' % conf) 2610ee81e68SLisandro Dalcin fd.write('f_flags = %(PETSC_FC_INCLUDES)s %(FC_FLAGS)s %(FCPPFLAGS)s\n' % conf) 2620ee81e68SLisandro Dalcin fd.write('f_link = %(FC_LINKER)s\n' % conf) 2630ee81e68SLisandro Dalcin fd.write('f_link_flags = %(FC_LINKER_FLAGS)s\n' % conf) 2640ee81e68SLisandro Dalcin fd.write('petsc_external_lib = %(PETSC_EXTERNAL_LIB_BASIC)s\n' % conf) 2650ee81e68SLisandro Dalcin fd.write('python = %(PYTHON)s\n' % conf) 2660ee81e68SLisandro Dalcin fd.write('\n') 2670ee81e68SLisandro Dalcin fd.write('rule C_COMPILE\n' 2680ee81e68SLisandro Dalcin ' command = $c_compile -MMD -MF $out.d $c_flags -c $in -o $out\n' 2690ee81e68SLisandro Dalcin ' description = CC $out\n' 2700ee81e68SLisandro Dalcin ' depfile = $out.d\n' 2710ee81e68SLisandro Dalcin # ' deps = gcc\n') # 'gcc' is default, 'msvc' only recognized by newer versions of ninja 2720ee81e68SLisandro Dalcin '\n') 2730ee81e68SLisandro Dalcin fd.write('rule C_LINK_SHARED\n' 2740ee81e68SLisandro Dalcin ' command = $c_link $c_link_flags -shared -o $out $in $petsc_external_lib\n' 2750ee81e68SLisandro Dalcin ' description = CLINK_SHARED $out\n' 2760ee81e68SLisandro Dalcin '\n') 2770ee81e68SLisandro Dalcin if petsc.have_fortran: 2780ee81e68SLisandro Dalcin fd.write('rule F_COMPILE\n' 2790ee81e68SLisandro Dalcin ' command = $f_compile -MMD -MF $out.d $f_flags -c $in -o $out\n' 2800ee81e68SLisandro Dalcin ' description = FC $out\n' 2810ee81e68SLisandro Dalcin ' depfile = $out.d\n' 2820ee81e68SLisandro Dalcin '\n') 2830ee81e68SLisandro Dalcin fd.write('rule F_LINK_SHARED\n' 2840ee81e68SLisandro Dalcin ' command = $f_link $f_link_flags -shared -o $out $in $petsc_external_lib\n' 2850ee81e68SLisandro Dalcin ' description = FLINK_SHARED $out\n' 2860ee81e68SLisandro Dalcin '\n') 2870ee81e68SLisandro Dalcin fd.write('rule GEN_NINJA\n' 2880ee81e68SLisandro Dalcin ' command = $python $in --output=ninja\n' 2890ee81e68SLisandro Dalcin ' generator = 1\n' 2900ee81e68SLisandro Dalcin '\n') 2910ee81e68SLisandro Dalcin petsc.gen_ninja(fd) 2920ee81e68SLisandro Dalcin fd.write('\n') 2930ee81e68SLisandro Dalcin fd.write('build %s : GEN_NINJA | %s %s %s %s\n' % (build_ninja, 2940ee81e68SLisandro Dalcin os.path.abspath(__file__), 295af0996ceSBarry Smith os.path.join(petsc.petsc_dir, 'lib','petsc','conf', 'variables'), 296af0996ceSBarry Smith petsc.arch_path('lib','petsc','conf', 'petscvariables'), 297add6df95SStefano Zampini ' '.join(os.path.join(petsc.pkg_dir, dep) for dep in petsc.gendeps))) 2980ee81e68SLisandro Dalcin 29947fd361eSStefano Zampinidef main(petsc_dir=None, petsc_arch=None, pkg_dir=None, pkg_name=None, pkg_arch=None, pkg_pkgs=None, output=None, verbose=False): 3000ee81e68SLisandro Dalcin if output is None: 3010ee81e68SLisandro Dalcin output = 'gnumake' 3020ee81e68SLisandro Dalcin writer = dict(gnumake=WriteGnuMake, ninja=WriteNinja) 30347fd361eSStefano 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) 3040ee81e68SLisandro Dalcin writer[output](petsc) 3050ee81e68SLisandro Dalcin petsc.summary() 3060ee81e68SLisandro Dalcin 3070ee81e68SLisandro Dalcinif __name__ == '__main__': 3080ee81e68SLisandro Dalcin import optparse 3090ee81e68SLisandro Dalcin parser = optparse.OptionParser() 3100ee81e68SLisandro Dalcin parser.add_option('--verbose', help='Show mismatches between makefiles and the filesystem', action='store_true', default=False) 3110ee81e68SLisandro Dalcin parser.add_option('--petsc-arch', help='Set PETSC_ARCH different from environment', default=os.environ.get('PETSC_ARCH')) 312add6df95SStefano 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) 313add6df95SStefano Zampini parser.add_option('--pkg-name', help='Set the name of the package you want to generate the makefile rules for', default=None) 314c4bccdb5SStefano Zampini parser.add_option('--pkg-arch', help='Set the package arch name you want to generate the makefile rules for', default=None) 31547fd361eSStefano 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) 3160ee81e68SLisandro Dalcin parser.add_option('--output', help='Location to write output file', default=None) 3170ee81e68SLisandro Dalcin opts, extra_args = parser.parse_args() 3180ee81e68SLisandro Dalcin if extra_args: 3190ee81e68SLisandro Dalcin import sys 3200ee81e68SLisandro Dalcin sys.stderr.write('Unknown arguments: %s\n' % ' '.join(extra_args)) 3210ee81e68SLisandro Dalcin exit(1) 32247fd361eSStefano 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) 323