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 11b75c6efcSBarry SmithSKIPDIRS = set('benchmarks build mex-scripts tests tutorials'.split()) # Skip these during the build 12dc0529c6SBarry Smith 134bfab837SSebastian Grimbergdef pathsplit(pkg_dir, path): 14dc0529c6SBarry Smith """Recursively split a path, returns a tuple""" 15dc0529c6SBarry Smith stem, basename = os.path.split(path) 164bfab837SSebastian Grimberg if stem == '' or stem == pkg_dir: 17dc0529c6SBarry Smith return (basename,) 18dc0529c6SBarry Smith if stem == path: # fixed point, likely '/' 1951de3720SJed Brown return (None,) 204bfab837SSebastian Grimberg return pathsplit(pkg_dir, 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): 4351de3720SJed Brown if SKIPDIRS.intersection(pathsplit(None, root)): 44dc0529c6SBarry Smith return 45183d35a2SBarry Smith smdirs = set(mdirs).difference(AUTODIRS) 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: 111*8d5d1ea2SBarry Smith if pkg_pkgs.find(',') > 0: npkgs = set(pkg_pkgs.split(',')) 112*8d5d1ea2SBarry Smith else: npkgs = set(pkg_pkgs.split(' ')) 113*8d5d1ea2SBarry Smith self.pkg_pkgs += list(npkgs - set(self.pkg_pkgs)) 11447fd361eSStefano Zampini self.read_conf() 1158e69c5ecSJed Brown try: 116add6df95SStefano Zampini logging.basicConfig(filename=self.pkg_arch_path('lib',self.pkg_name,'conf', 'gmake.log'), level=logging.DEBUG) 1178e69c5ecSJed Brown except IOError: 1188e69c5ecSJed Brown # Disable logging if path is not writeable (e.g., prefix install) 1198e69c5ecSJed Brown logging.basicConfig(filename='/dev/null', level=logging.DEBUG) 1200ee81e68SLisandro Dalcin self.log = logging.getLogger('gmakegen') 1210ee81e68SLisandro Dalcin self.mistakes = Mistakes(debuglogger(self.log), verbose=verbose) 1220ee81e68SLisandro Dalcin self.gendeps = [] 1230ee81e68SLisandro Dalcin 1240ee81e68SLisandro Dalcin def arch_path(self, *args): 1250ee81e68SLisandro Dalcin return os.path.join(self.petsc_dir, self.petsc_arch, *args) 1260ee81e68SLisandro Dalcin 127add6df95SStefano Zampini def pkg_arch_path(self, *args): 128c4bccdb5SStefano Zampini return os.path.join(self.pkg_dir, self.pkg_arch, *args) 129add6df95SStefano Zampini 1300ee81e68SLisandro Dalcin def read_conf(self): 1310ee81e68SLisandro Dalcin self.conf = dict() 132021a2b48SJed Brown with open(self.arch_path('include', 'petscconf.h')) as petscconf_h: 133021a2b48SJed Brown for line in petscconf_h: 1340ee81e68SLisandro Dalcin if line.startswith('#define '): 1350ee81e68SLisandro Dalcin define = line[len('#define '):] 1360ee81e68SLisandro Dalcin space = define.find(' ') 1370ee81e68SLisandro Dalcin key = define[:space] 1380ee81e68SLisandro Dalcin val = define[space+1:] 1390ee81e68SLisandro Dalcin self.conf[key] = val 140af0996ceSBarry Smith self.conf.update(parse_makefile(self.arch_path('lib','petsc','conf', 'petscvariables'))) 14147fd361eSStefano Zampini # allow parsing package additional configurations (if any) 14247fd361eSStefano Zampini if self.pkg_name != 'petsc' : 14347fd361eSStefano Zampini f = self.pkg_arch_path('include', self.pkg_name + 'conf.h') 14447fd361eSStefano Zampini if os.path.isfile(f): 145021a2b48SJed Brown with open(self.pkg_arch_path('include', self.pkg_name + 'conf.h')) as pkg_conf_h: 146021a2b48SJed Brown for line in pkg_conf_h: 14747fd361eSStefano Zampini if line.startswith('#define '): 14847fd361eSStefano Zampini define = line[len('#define '):] 14947fd361eSStefano Zampini space = define.find(' ') 15047fd361eSStefano Zampini key = define[:space] 15147fd361eSStefano Zampini val = define[space+1:] 15247fd361eSStefano Zampini self.conf[key] = val 15347fd361eSStefano Zampini f = self.pkg_arch_path('lib',self.pkg_name,'conf', self.pkg_name + 'variables') 15447fd361eSStefano Zampini if os.path.isfile(f): 15547fd361eSStefano Zampini self.conf.update(parse_makefile(self.pkg_arch_path('lib',self.pkg_name,'conf', self.pkg_name + 'variables'))) 156fbf9dbe5SBarry Smith self.have_fortran = int(self.conf.get('PETSC_USE_FORTRAN_BINDINGS', '0')) 1570ee81e68SLisandro Dalcin 1580ee81e68SLisandro Dalcin def inconf(self, key, val): 1590ee81e68SLisandro Dalcin if key in ['package', 'function', 'define']: 1600ee81e68SLisandro Dalcin return self.conf.get(val) 1610ee81e68SLisandro Dalcin elif key == 'precision': 1620ee81e68SLisandro Dalcin return val == self.conf['PETSC_PRECISION'] 1630ee81e68SLisandro Dalcin elif key == 'scalar': 1640ee81e68SLisandro Dalcin return val == self.conf['PETSC_SCALAR'] 1650ee81e68SLisandro Dalcin elif key == 'language': 1660ee81e68SLisandro Dalcin return val == self.conf['PETSC_LANGUAGE'] 1670ee81e68SLisandro Dalcin raise RuntimeError('Unknown conf check: %s %s' % (key, val)) 1680ee81e68SLisandro Dalcin 1690ee81e68SLisandro Dalcin def relpath(self, root, src): 170add6df95SStefano Zampini return os.path.relpath(os.path.join(root, src), self.pkg_dir) 1710ee81e68SLisandro Dalcin 1725a7ab478SBarry Smith def get_sources_from_files(self, files): 1730ee81e68SLisandro Dalcin """Return dict {lang: list_of_source_files}""" 1740ee81e68SLisandro Dalcin source = dict() 1750ee81e68SLisandro Dalcin for lang, sourcelang in LANGS.items(): 1765a7ab478SBarry Smith source[lang] = [f for f in files if f.endswith('.'+lang.replace('_','.'))] 1775a7ab478SBarry Smith files = [f for f in files if not f.endswith('.'+lang.replace('_','.'))] 1780ee81e68SLisandro Dalcin return source 1790ee81e68SLisandro Dalcin 1800ee81e68SLisandro Dalcin def gen_pkg(self, pkg): 18113d87ab8SBarry Smith from itertools import chain 1820ee81e68SLisandro Dalcin pkgsrcs = dict() 1830ee81e68SLisandro Dalcin for lang in LANGS: 1840ee81e68SLisandro Dalcin pkgsrcs[lang] = [] 185c729af5eSJose E. Roman for root, dirs, files in chain.from_iterable(os.walk(path) for path in [os.path.join(self.pkg_dir, 'src', pkg),os.path.join(self.pkg_dir, self.pkg_arch, 'src', pkg)]): 1864bfab837SSebastian Grimberg if SKIPDIRS.intersection(pathsplit(self.pkg_dir, root)): continue 18709a6cbfcSBernhard M. Wiedemann dirs.sort() 18809a6cbfcSBernhard M. Wiedemann files.sort() 1890ee81e68SLisandro Dalcin makefile = os.path.join(root,'makefile') 19013d87ab8SBarry Smith if os.path.isfile(makefile): 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) 20413d87ab8SBarry Smith if files: 2055a7ab478SBarry Smith source = self.get_sources_from_files(files) 2060ee81e68SLisandro Dalcin for lang, s in source.items(): 2072b757757SJed Brown pkgsrcs[lang] += [mkrel(t) for t in s] 20813d87ab8SBarry Smith if os.path.isfile(makefile): self.gendeps.append(self.relpath(root, 'makefile')) 2090ee81e68SLisandro Dalcin return pkgsrcs 2100ee81e68SLisandro Dalcin 211b0790570SJed Brown def gen_gnumake(self, fd): 2120ee81e68SLisandro Dalcin def write(stem, srcs): 2130ee81e68SLisandro Dalcin for lang in LANGS: 214c0558f20SBarry Smith fd.write('%(stem)s.%(lang)s := %(srcs)s\n' % dict(stem=stem, lang=lang.replace('_','.'), srcs=' '.join(srcs[lang]))) 21547fd361eSStefano Zampini for pkg in self.pkg_pkgs: 2160ee81e68SLisandro Dalcin srcs = self.gen_pkg(pkg) 217b0790570SJed Brown write('srcs-' + pkg, srcs) 2180ee81e68SLisandro Dalcin return self.gendeps 2190ee81e68SLisandro Dalcin 2200ee81e68SLisandro Dalcin def gen_ninja(self, fd): 2210ee81e68SLisandro Dalcin libobjs = [] 22247fd361eSStefano Zampini for pkg in self.pkg_pkgs: 2230ee81e68SLisandro Dalcin srcs = self.gen_pkg(pkg) 2240ee81e68SLisandro Dalcin for lang in LANGS: 2250ee81e68SLisandro Dalcin for src in srcs[lang]: 2260ee81e68SLisandro Dalcin obj = '$objdir/%s.o' % src 227add6df95SStefano 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))) 2280ee81e68SLisandro Dalcin libobjs.append(obj) 2290ee81e68SLisandro Dalcin fd.write('\n') 2300ee81e68SLisandro Dalcin fd.write('build $libdir/libpetsc.so : %s_LINK_SHARED %s\n\n' % ('CF'[self.have_fortran], ' '.join(libobjs))) 2310ee81e68SLisandro Dalcin fd.write('build petsc : phony || $libdir/libpetsc.so\n\n') 2320ee81e68SLisandro Dalcin 2330ee81e68SLisandro Dalcin def summary(self): 2340ee81e68SLisandro Dalcin self.mistakes.summary() 2350ee81e68SLisandro Dalcin 2360ee81e68SLisandro Dalcindef WriteGnuMake(petsc): 237add6df95SStefano Zampini arch_files = petsc.pkg_arch_path('lib',petsc.pkg_name,'conf', 'files') 238021a2b48SJed Brown with open(arch_files, 'w') as fd: 2390ee81e68SLisandro Dalcin gendeps = petsc.gen_gnumake(fd) 2400ee81e68SLisandro Dalcin fd.write('\n') 2410ee81e68SLisandro Dalcin fd.write('# Dependency to regenerate this file\n') 242add6df95SStefano Zampini fd.write('%s : %s %s\n' % (os.path.relpath(arch_files, petsc.pkg_dir), 243add6df95SStefano Zampini os.path.relpath(__file__, os.path.realpath(petsc.pkg_dir)), 2440ee81e68SLisandro Dalcin ' '.join(gendeps))) 2450ee81e68SLisandro Dalcin fd.write('\n') 2460ee81e68SLisandro Dalcin fd.write('# Dummy dependencies in case makefiles are removed\n') 2470ee81e68SLisandro Dalcin fd.write(''.join([dep + ':\n' for dep in gendeps])) 2480ee81e68SLisandro Dalcin 2490ee81e68SLisandro Dalcindef WriteNinja(petsc): 2500ee81e68SLisandro Dalcin conf = dict() 251af0996ceSBarry Smith parse_makefile(os.path.join(petsc.petsc_dir, 'lib', 'petsc','conf', 'variables'), conf) 252af0996ceSBarry Smith parse_makefile(petsc.arch_path('lib','petsc','conf', 'petscvariables'), conf) 2530ee81e68SLisandro Dalcin build_ninja = petsc.arch_path('build.ninja') 254021a2b48SJed Brown with open(build_ninja, 'w') as fd: 2550ee81e68SLisandro Dalcin fd.write('objdir = obj-ninja\n') 2560ee81e68SLisandro Dalcin fd.write('libdir = lib\n') 2570ee81e68SLisandro Dalcin fd.write('c_compile = %(PCC)s\n' % conf) 2580ee81e68SLisandro Dalcin fd.write('c_flags = %(PETSC_CC_INCLUDES)s %(PCC_FLAGS)s %(CCPPFLAGS)s\n' % conf) 2590ee81e68SLisandro Dalcin fd.write('c_link = %(PCC_LINKER)s\n' % conf) 2600ee81e68SLisandro Dalcin fd.write('c_link_flags = %(PCC_LINKER_FLAGS)s\n' % conf) 2610ee81e68SLisandro Dalcin if petsc.have_fortran: 2620ee81e68SLisandro Dalcin fd.write('f_compile = %(FC)s\n' % conf) 2630ee81e68SLisandro Dalcin fd.write('f_flags = %(PETSC_FC_INCLUDES)s %(FC_FLAGS)s %(FCPPFLAGS)s\n' % conf) 2640ee81e68SLisandro Dalcin fd.write('f_link = %(FC_LINKER)s\n' % conf) 2650ee81e68SLisandro Dalcin fd.write('f_link_flags = %(FC_LINKER_FLAGS)s\n' % conf) 2660ee81e68SLisandro Dalcin fd.write('petsc_external_lib = %(PETSC_EXTERNAL_LIB_BASIC)s\n' % conf) 2670ee81e68SLisandro Dalcin fd.write('python = %(PYTHON)s\n' % conf) 2680ee81e68SLisandro Dalcin fd.write('\n') 2690ee81e68SLisandro Dalcin fd.write('rule C_COMPILE\n' 2700ee81e68SLisandro Dalcin ' command = $c_compile -MMD -MF $out.d $c_flags -c $in -o $out\n' 2710ee81e68SLisandro Dalcin ' description = CC $out\n' 2720ee81e68SLisandro Dalcin ' depfile = $out.d\n' 2730ee81e68SLisandro Dalcin # ' deps = gcc\n') # 'gcc' is default, 'msvc' only recognized by newer versions of ninja 2740ee81e68SLisandro Dalcin '\n') 2750ee81e68SLisandro Dalcin fd.write('rule C_LINK_SHARED\n' 2760ee81e68SLisandro Dalcin ' command = $c_link $c_link_flags -shared -o $out $in $petsc_external_lib\n' 2770ee81e68SLisandro Dalcin ' description = CLINK_SHARED $out\n' 2780ee81e68SLisandro Dalcin '\n') 2790ee81e68SLisandro Dalcin if petsc.have_fortran: 2800ee81e68SLisandro Dalcin fd.write('rule F_COMPILE\n' 2810ee81e68SLisandro Dalcin ' command = $f_compile -MMD -MF $out.d $f_flags -c $in -o $out\n' 2820ee81e68SLisandro Dalcin ' description = FC $out\n' 2830ee81e68SLisandro Dalcin ' depfile = $out.d\n' 2840ee81e68SLisandro Dalcin '\n') 2850ee81e68SLisandro Dalcin fd.write('rule F_LINK_SHARED\n' 2860ee81e68SLisandro Dalcin ' command = $f_link $f_link_flags -shared -o $out $in $petsc_external_lib\n' 2870ee81e68SLisandro Dalcin ' description = FLINK_SHARED $out\n' 2880ee81e68SLisandro Dalcin '\n') 2890ee81e68SLisandro Dalcin fd.write('rule GEN_NINJA\n' 2900ee81e68SLisandro Dalcin ' command = $python $in --output=ninja\n' 2910ee81e68SLisandro Dalcin ' generator = 1\n' 2920ee81e68SLisandro Dalcin '\n') 2930ee81e68SLisandro Dalcin petsc.gen_ninja(fd) 2940ee81e68SLisandro Dalcin fd.write('\n') 2950ee81e68SLisandro Dalcin fd.write('build %s : GEN_NINJA | %s %s %s %s\n' % (build_ninja, 2960ee81e68SLisandro Dalcin os.path.abspath(__file__), 297af0996ceSBarry Smith os.path.join(petsc.petsc_dir, 'lib','petsc','conf', 'variables'), 298af0996ceSBarry Smith petsc.arch_path('lib','petsc','conf', 'petscvariables'), 299add6df95SStefano Zampini ' '.join(os.path.join(petsc.pkg_dir, dep) for dep in petsc.gendeps))) 3000ee81e68SLisandro Dalcin 30147fd361eSStefano Zampinidef main(petsc_dir=None, petsc_arch=None, pkg_dir=None, pkg_name=None, pkg_arch=None, pkg_pkgs=None, output=None, verbose=False): 3020ee81e68SLisandro Dalcin if output is None: 3030ee81e68SLisandro Dalcin output = 'gnumake' 3040ee81e68SLisandro Dalcin writer = dict(gnumake=WriteGnuMake, ninja=WriteNinja) 30547fd361eSStefano 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) 3060ee81e68SLisandro Dalcin writer[output](petsc) 3070ee81e68SLisandro Dalcin petsc.summary() 3080ee81e68SLisandro Dalcin 3090ee81e68SLisandro Dalcinif __name__ == '__main__': 3100ee81e68SLisandro Dalcin import optparse 3110ee81e68SLisandro Dalcin parser = optparse.OptionParser() 3120ee81e68SLisandro Dalcin parser.add_option('--verbose', help='Show mismatches between makefiles and the filesystem', action='store_true', default=False) 3130ee81e68SLisandro Dalcin parser.add_option('--petsc-arch', help='Set PETSC_ARCH different from environment', default=os.environ.get('PETSC_ARCH')) 314add6df95SStefano 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) 315add6df95SStefano Zampini parser.add_option('--pkg-name', help='Set the name of the package you want to generate the makefile rules for', default=None) 316c4bccdb5SStefano Zampini parser.add_option('--pkg-arch', help='Set the package arch name you want to generate the makefile rules for', default=None) 31747fd361eSStefano 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) 3180ee81e68SLisandro Dalcin parser.add_option('--output', help='Location to write output file', default=None) 3190ee81e68SLisandro Dalcin opts, extra_args = parser.parse_args() 3200ee81e68SLisandro Dalcin if extra_args: 3210ee81e68SLisandro Dalcin import sys 3220ee81e68SLisandro Dalcin sys.stderr.write('Unknown arguments: %s\n' % ' '.join(extra_args)) 3230ee81e68SLisandro Dalcin exit(1) 32447fd361eSStefano 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) 325