1#!/usr/bin/env python3 2from __future__ import print_function 3import os, re, shutil, sys 4 5if 'PETSC_DIR' in os.environ: 6 PETSC_DIR = os.environ['PETSC_DIR'] 7else: 8 fd = open(os.path.join('lib','petsc','conf','petscvariables')) 9 a = fd.readline() 10 a = fd.readline() 11 PETSC_DIR = a.split('=')[1][0:-1] 12 fd.close() 13 14if 'PETSC_ARCH' in os.environ: 15 PETSC_ARCH = os.environ['PETSC_ARCH'] 16else: 17 fd = open(os.path.join('lib','petsc','conf','petscvariables')) 18 a = fd.readline() 19 PETSC_ARCH = a.split('=')[1][0:-1] 20 fd.close() 21 22print('*** Using PETSC_DIR='+PETSC_DIR+' PETSC_ARCH='+PETSC_ARCH+' ***') 23sys.path.insert(0, os.path.join(PETSC_DIR, 'config')) 24sys.path.insert(0, os.path.join(PETSC_DIR, 'config', 'BuildSystem')) 25 26import script 27 28try: 29 WindowsError 30except NameError: 31 WindowsError = None 32 33class Installer(script.Script): 34 def __init__(self, clArgs = None): 35 import RDict 36 argDB = RDict.RDict(None, None, 0, 0, readonly = True) 37 argDB.saveFilename = os.path.join(PETSC_DIR, PETSC_ARCH, 'lib','petsc','conf', 'RDict.db') 38 argDB.load() 39 script.Script.__init__(self, argDB = argDB) 40 if not clArgs is None: self.clArgs = clArgs 41 self.copies = [] 42 return 43 44 def setupHelp(self, help): 45 import nargs 46 script.Script.setupHelp(self, help) 47 help.addArgument('Installer', '-destDir=<path>', nargs.Arg(None, '', 'Destination Directory for install')) 48 help.addArgument('Installer', '-no-examples', nargs.Arg(None, '', 'Skip installing examples')) 49 return 50 51 52 def setupModules(self): 53 self.setCompilers = self.framework.require('config.setCompilers', None) 54 self.arch = self.framework.require('PETSc.options.arch', None) 55 self.petscdir = self.framework.require('PETSc.options.petscdir', None) 56 self.compilers = self.framework.require('config.compilers', None) 57 self.mpi = self.framework.require('config.packages.MPI', None) 58 return 59 60 def setup(self): 61 script.Script.setup(self) 62 self.framework = self.loadConfigure() 63 self.setupModules() 64 return 65 66 def setupDirectories(self): 67 self.rootDir = self.petscdir.dir 68 self.installDir = os.path.abspath(os.path.expanduser(self.framework.argDB['prefix'])) 69 self.destDir = os.path.abspath(self.argDB['destDir']+self.installDir) 70 self.arch = self.arch.arch 71 self.archDir = os.path.join(self.rootDir, self.arch) 72 self.rootIncludeDir = os.path.join(self.rootDir, 'include') 73 self.archIncludeDir = os.path.join(self.rootDir, self.arch, 'include') 74 self.rootConfDir = os.path.join(self.rootDir, 'lib','petsc','conf') 75 self.archConfDir = os.path.join(self.rootDir, self.arch, 'lib','petsc','conf') 76 self.rootBinDir = os.path.join(self.rootDir, 'lib','petsc','bin') 77 self.archBinDir = os.path.join(self.rootDir, self.arch, 'bin') 78 self.archLibDir = os.path.join(self.rootDir, self.arch, 'lib') 79 self.destIncludeDir = os.path.join(self.destDir, 'include') 80 self.destConfDir = os.path.join(self.destDir, 'lib','petsc','conf') 81 self.destLibDir = os.path.join(self.destDir, 'lib') 82 self.destBinDir = os.path.join(self.destDir, 'lib','petsc','bin') 83 self.installIncludeDir = os.path.join(self.installDir, 'include') 84 self.installLibDir = os.path.join(self.installDir, 'lib') 85 self.installBinDir = os.path.join(self.installDir, 'lib','petsc','bin') 86 self.rootShareDir = os.path.join(self.rootDir, 'share') 87 self.destShareDir = os.path.join(self.destDir, 'share') 88 self.rootSrcDir = os.path.join(self.rootDir, 'src') 89 90 self.ranlib = self.compilers.RANLIB 91 self.arLibSuffix = self.compilers.AR_LIB_SUFFIX 92 return 93 94 def checkPrefix(self): 95 if not self.installDir: 96 print('********************************************************************') 97 print('PETSc is built without prefix option. So "make install" is not appropriate.') 98 print('If you need a prefix install of PETSc - rerun configure with --prefix option.') 99 print('********************************************************************') 100 sys.exit(1) 101 return 102 103 def checkDestdir(self): 104 if os.path.exists(self.destDir): 105 if os.path.samefile(self.destDir, self.rootDir): 106 print('********************************************************************') 107 print('Incorrect prefix usage. Specified destDir same as current PETSC_DIR') 108 print('********************************************************************') 109 sys.exit(1) 110 if os.path.samefile(self.destDir, os.path.join(self.rootDir,self.arch)): 111 print('********************************************************************') 112 print('Incorrect prefix usage. Specified destDir same as current PETSC_DIR/PETSC_ARCH') 113 print('********************************************************************') 114 sys.exit(1) 115 if not os.path.isdir(os.path.realpath(self.destDir)): 116 print('********************************************************************') 117 print('Specified destDir', self.destDir, 'is not a directory. Cannot proceed!') 118 print('********************************************************************') 119 sys.exit(1) 120 if not os.access(self.destDir, os.W_OK): 121 print('********************************************************************') 122 print('Unable to write to ', self.destDir, 'Perhaps you need to do "sudo make install"') 123 print('********************************************************************') 124 sys.exit(1) 125 return 126 127 def copyfile(self, src, dst, symlinks = False, copyFunc = shutil.copy2): 128 """Copies a single file """ 129 copies = [] 130 errors = [] 131 if not os.path.exists(dst): 132 os.makedirs(dst) 133 elif not os.path.isdir(dst): 134 raise shutil.Error('Destination is not a directory') 135 srcname = src 136 dstname = os.path.join(dst, os.path.basename(src)) 137 try: 138 if symlinks and os.path.islink(srcname): 139 linkto = os.readlink(srcname) 140 os.symlink(linkto, dstname) 141 else: 142 copyFunc(srcname, dstname) 143 copies.append((srcname, dstname)) 144 except (IOError, os.error) as why: 145 errors.append((srcname, dstname, str(why))) 146 except shutil.Error as err: 147 errors.append((srcname,dstname,str(err.args[0]))) 148 if errors: 149 raise shutil.Error(errors) 150 return copies 151 152 def fixExamplesMakefile(self, src): 153 '''Change ././${PETSC_ARCH} in makefile in root petsc directory with ${PETSC_DIR}''' 154 lines = [] 155 oldFile = open(src, 'r') 156 alllines=oldFile.read() 157 oldFile.close() 158 newlines=alllines.split('\n')[0]+'\n' # Firstline 159 # Hardcode PETSC_DIR and PETSC_ARCH to avoid users doing the wrong thing 160 newlines+='PETSC_DIR='+self.installDir+'\n' 161 newlines+='PETSC_ARCH=\n' 162 for line in alllines.split('\n')[1:]: 163 if line.startswith('TESTLOGFILE'): 164 newlines+='TESTLOGFILE = $(TESTDIR)/examples-install.log\n' 165 elif line.startswith('CONFIGDIR'): 166 newlines+='CONFIGDIR:=$(PETSC_DIR)/$(PETSC_ARCH)/share/petsc/examples/config\n' 167 elif line.startswith('$(generatedtest)') and 'petscvariables' in line: 168 newlines+='all: test\n\n'+line+'\n' 169 else: 170 newlines+=line+'\n' 171 newFile = open(src, 'w') 172 newFile.write(newlines) 173 newFile.close() 174 return 175 176 def copyConfig(self, src, dst): 177 """Copy configuration/testing files 178 """ 179 if not os.path.isdir(dst): 180 raise shutil.Error('Destination is not a directory') 181 182 self.copies.extend(self.copyfile('gmakefile.test',dst)) 183 newConfigDir=os.path.join(dst,'config') # Am not renaming at present 184 if not os.path.isdir(newConfigDir): os.mkdir(newConfigDir) 185 testConfFiles="gmakegentest.py gmakegen.py testparse.py example_template.py".split() 186 testConfFiles+="petsc_harness.sh report_tests.py query_tests.py".split() 187 for tf in testConfFiles: 188 self.copies.extend(self.copyfile(os.path.join('config',tf),newConfigDir)) 189 return 190 191 def copyExamples(self, src, dst): 192 """copy the examples directories 193 """ 194 for root, dirs, files in os.walk(src, topdown=False): 195 if os.path.basename(root) not in ("tests", "tutorials"): continue 196 self.copies.extend(self.copytree(root, root.replace(src,dst))) 197 return 198 199 def copytree(self, src, dst, symlinks = False, copyFunc = shutil.copy2, exclude = [], exclude_ext= ['.DSYM','.o','.pyc'], recurse = 1): 200 """Recursively copy a directory tree using copyFunc, which defaults to shutil.copy2(). 201 202 The copyFunc() you provide is only used on the top level, lower levels always use shutil.copy2 203 204 The destination directory must not already exist. 205 If exception(s) occur, an shutil.Error is raised with a list of reasons. 206 207 If the optional symlinks flag is true, symbolic links in the 208 source tree result in symbolic links in the destination tree; if 209 it is false, the contents of the files pointed to by symbolic 210 links are copied. 211 """ 212 copies = [] 213 names = os.listdir(src) 214 if not os.path.exists(dst): 215 os.makedirs(dst) 216 elif not os.path.isdir(dst): 217 raise shutil.Error('Destination is not a directory') 218 errors = [] 219 srclinks = [] 220 dstlinks = [] 221 for name in names: 222 srcname = os.path.join(src, name) 223 dstname = os.path.join(dst, name) 224 try: 225 if symlinks and os.path.islink(srcname): 226 linkto = os.readlink(srcname) 227 os.symlink(linkto, dstname) 228 elif os.path.isdir(srcname) and recurse and not os.path.basename(srcname) in exclude: 229 copies.extend(self.copytree(srcname, dstname, symlinks,exclude = exclude, exclude_ext = exclude_ext)) 230 elif os.path.isfile(srcname) and not os.path.basename(srcname) in exclude and os.path.splitext(name)[1] not in exclude_ext : 231 if os.path.islink(srcname): 232 srclinks.append(srcname) 233 dstlinks.append(dstname) 234 else: 235 copyFunc(srcname, dstname) 236 copies.append((srcname, dstname)) 237 # XXX What about devices, sockets etc.? 238 except (IOError, os.error) as why: 239 errors.append((srcname, dstname, str(why))) 240 # catch the Error from the recursive copytree so that we can 241 # continue with other files 242 except shutil.Error as err: 243 errors.append((srcname,dstname,str(err.args[0]))) 244 for srcname, dstname in zip(srclinks, dstlinks): 245 try: 246 copyFunc(srcname, dstname) 247 copies.append((srcname, dstname)) 248 except (IOError, os.error) as why: 249 errors.append((srcname, dstname, str(why))) 250 # catch the Error from the recursive copytree so that we can 251 # continue with other files 252 except shutil.Error as err: 253 errors.append((srcname,dstname,str(err.args[0]))) 254 try: 255 shutil.copystat(src, dst) 256 except OSError as e: 257 if WindowsError is not None and isinstance(e, WindowsError): 258 # Copying file access times may fail on Windows 259 pass 260 else: 261 errors.append((src, dst, str(e))) 262 if errors: 263 raise shutil.Error(errors) 264 return copies 265 266 267 def fixConfFile(self, src): 268 lines = [] 269 oldFile = open(src, 'r') 270 for line in oldFile.readlines(): 271 if line.startswith('PETSC_CC_INCLUDES =') or line.startswith('PETSC_FC_INCLUDES ='): 272 continue 273 line = line.replace('PETSC_CC_INCLUDES_INSTALL', 'PETSC_CC_INCLUDES') 274 line = line.replace('PETSC_FC_INCLUDES_INSTALL', 'PETSC_FC_INCLUDES') 275 # remove PETSC_DIR/PETSC_ARCH variables from conf-makefiles. They are no longer necessary 276 line = line.replace('${PETSC_DIR}/${PETSC_ARCH}', self.installDir) 277 line = line.replace('PETSC_ARCH=${PETSC_ARCH}', '') 278 line = line.replace('${PETSC_DIR}', self.installDir) 279 # replace PETSC_DIR/PETSC_ARCH/lib (i.e., build location) with prefix/lib 280 line = line.replace(self.archLibDir,self.installLibDir) 281 # replace PETSC_DIR/lib/petsc/bin with prefix/lib/petsc/bin 282 line = line.replace(self.rootBinDir,self.destBinDir) 283 lines.append(line) 284 oldFile.close() 285 newFile = open(src, 'w') 286 newFile.write(''.join(lines)) 287 newFile.close() 288 return 289 290 def fixConf(self): 291 import shutil 292 for file in ['rules', 'rules_doc.mk', 'rules_util.mk', 'variables', 'petscrules', 'petscvariables']: 293 self.fixConfFile(os.path.join(self.destConfDir,file)) 294 return 295 296 def fixPythonWheel(self): 297 import glob 298 import shutil 299 # 300 for pattern in ( 301 self.destLibDir + '/*.a', 302 self.destLibDir + '/*.la', 303 self.destLibDir + '/pkgconfig', # TODO: keep? 304 self.destConfDir + '/configure-hash', 305 self.destConfDir + '/uninstall.py', 306 self.destConfDir + '/reconfigure-*.py', 307 self.destConfDir + '/pkg.conf.*', 308 self.destConfDir + '/pkg.git*.*', 309 self.destConfDir + '/modules', # TODO: keep? 310 self.destShareDir + '/*/examples/src/*', 311 self.destShareDir + '/*/datafiles', 312 ): 313 for pathname in glob.glob(pattern): 314 if os.path.isdir(pathname): 315 shutil.rmtree(pathname) 316 elif os.path.exists(pathname): 317 os.remove(pathname) 318 # 319 for filename in ( 320 self.destIncludeDir + '/petscconf.h', 321 self.destIncludeDir + '/petscconfiginfo.h', 322 self.destIncludeDir + '/petscmachineinfo.h', 323 self.destShareDir + '/petsc/examples/gmakefile.test', 324 self.destConfDir + '/rules', 325 self.destConfDir + '/rules_doc.mk', 326 self.destConfDir + '/rules_util.mk', 327 self.destConfDir + '/petscrules', 328 self.destConfDir + '/variables', 329 self.destConfDir + '/petscvariables', 330 ): 331 with open(filename, 'r') as oldFile: 332 contents = oldFile.read() 333 contents = contents.replace(self.installDir, '${PETSC_DIR}') 334 contents = contents.replace(self.rootDir, '${PETSC_DIR}') 335 contents = re.sub( 336 r'^(PYTHON(_EXE)?) = (.*)$', 337 r'\1 = python%d' % sys.version_info[0], 338 contents, flags=re.MULTILINE, 339 ) 340 with open(filename, 'w') as newFile: 341 newFile.write(contents) 342 # 343 def lsdir(dirname, *patterns): 344 return glob.glob(os.path.join(dirname, *patterns)) 345 def shell(*args): 346 return self.executeShellCommand(' '.join(args))[0] 347 libdir = os.path.join(self.installDir, 'lib') 348 if sys.platform == 'linux': 349 libraries = [ 350 lib for lib in lsdir(self.destLibDir, 'lib*.so*') 351 if not os.path.islink(lib) 352 ] 353 for shlib in libraries: 354 # fix shared library rpath 355 rpath = shell('patchelf', '--print-rpath', shlib) 356 rpath = rpath.split(os.path.pathsep) 357 if libdir in rpath: 358 rpath.insert(0, '$ORIGIN') 359 while libdir in rpath: 360 rpath.remove(libdir) 361 if rpath: 362 rpath = os.path.pathsep.join(rpath) 363 shell('patchelf', '--set-rpath', "'%s'" % rpath, shlib) 364 # fix shared library file and symlink 365 basename = os.path.basename(shlib) 366 libname, ext, _ = basename.partition('.so') 367 liblink = libname + ext 368 soname = shell('patchelf', '--print-soname', shlib) 369 for symlink in lsdir(self.destLibDir, liblink + '*'): 370 if os.path.islink(symlink): 371 os.unlink(symlink) 372 curdir = os.getcwd() 373 try: 374 os.chdir(os.path.dirname(shlib)) 375 if soname != basename: 376 os.rename(basename, soname) 377 if soname != liblink: 378 os.symlink(soname, liblink) 379 finally: 380 os.chdir(curdir) 381 if sys.platform == 'darwin': 382 def otool(cmd, dylib): 383 pattern = r''' 384 ^\s+ cmd \s %s$\n 385 ^\s+ cmdsize \s \d+$\n 386 ^\s+ (?:name|path) \s (.*) \s \(offset \s \d+\)$ 387 ''' % cmd 388 return re.findall( 389 pattern, shell('otool', '-l', dylib), 390 flags=re.VERBOSE | re.MULTILINE, 391 ) 392 libraries = [ 393 lib for lib in lsdir(self.destLibDir, 'lib*.dylib') 394 if not os.path.islink(lib) 395 ] 396 for dylib in libraries: 397 install_name = otool('LC_ID_DYLIB', dylib)[0] 398 dependencies = otool('LC_LOAD_DYLIB', dylib) 399 runtime_path = otool('LC_RPATH', dylib) 400 # fix shared library install name and rpath 401 install_name = '@rpath/' + os.path.basename(install_name) 402 shell('install_name_tool', '-id', install_name, dylib) 403 if libdir in runtime_path: 404 shell('install_name_tool', '-delete_rpath', libdir, dylib) 405 for rpath in ('@loader_path',): 406 if rpath not in runtime_path: 407 shell('install_name_tool', '-add_rpath', rpath, dylib) 408 for dep in dependencies: 409 if os.path.dirname(dep) in (libdir,): 410 newid = '@rpath/' + os.path.basename(dep) 411 shell('install_name_tool', '-change', dep, newid, dylib) 412 # fix shared library file and symlink 413 basename = os.path.basename(dylib) 414 libname, ext = os.path.splitext(basename) 415 libname = libname.partition('.')[0] 416 liblink = libname + ext 417 dyname = os.path.basename(install_name) 418 for symlink in lsdir(self.destLibDir, libname + '*' + ext): 419 if os.path.islink(symlink): 420 os.unlink(symlink) 421 curdir = os.getcwd() 422 try: 423 os.chdir(os.path.dirname(dylib)) 424 if dyname != basename: 425 os.rename(basename, dyname) 426 if dyname != liblink: 427 os.symlink(dyname, liblink) 428 finally: 429 os.chdir(curdir) 430 # 431 return 432 433 def createUninstaller(self): 434 uninstallscript = os.path.join(self.destConfDir, 'uninstall.py') 435 f = open(uninstallscript, 'w') 436 # Could use the Python AST to do this 437 f.write('#!'+sys.executable+'\n') 438 f.write('import os\n') 439 f.write('prefixdir = "'+self.installDir+'"\n') 440 files = [dst.replace(self.destDir,self.installDir) for src, dst in self.copies] 441 files.append(uninstallscript.replace(self.destDir,self.installDir)) 442 f.write('files = '+repr(files)) 443 f.write(''' 444for file in files: 445 if os.path.exists(file) or os.path.islink(file): 446 os.remove(file) 447 dir = os.path.dirname(file) 448 while dir not in [os.path.dirname(prefixdir),'/']: 449 try: os.rmdir(dir) 450 except: break 451 dir = os.path.dirname(dir) 452''') 453 f.close() 454 os.chmod(uninstallscript,0o744) 455 return 456 457 def installIncludes(self): 458 exclude = ['makefile'] 459 if not hasattr(self.compilers.setCompilers, 'FC'): 460 exclude.append('finclude') 461 if not self.mpi.usingMPIUni: 462 exclude.append('mpiuni') 463 self.copies.extend(self.copytree(self.rootIncludeDir, self.destIncludeDir,exclude = exclude)) 464 self.copies.extend(self.copytree(self.archIncludeDir, self.destIncludeDir)) 465 return 466 467 def installConf(self): 468 self.copies.extend(self.copytree(self.rootConfDir, self.destConfDir, exclude = ['uncrustify.cfg','bfort-base.txt','bfort-petsc.txt','bfort-mpi.txt','test.log'])) 469 self.copies.extend(self.copytree(self.archConfDir, self.destConfDir, exclude = ['sowing', 'configure.log.bkp','configure.log','make.log','gmake.log','test.log','error.log','memoryerror.log','files','testfiles','RDict.db'])) 470 return 471 472 def installBin(self): 473 exclude = ['bfort','bib2html','doc2lt','doctext','mapnames', 'pstogif','pstoxbm','tohtml'] 474 self.copies.extend(self.copytree(self.archBinDir, self.destBinDir, exclude = exclude )) 475 exclude = ['maint'] 476 if not self.mpi.usingMPIUni: 477 exclude.append('petsc-mpiexec.uni') 478 self.setCompilers.pushLanguage('C') 479 if self.setCompilers.getCompiler().find('win32fe') < 0: 480 exclude.append('win32fe') 481 self.setCompilers.popLanguage() 482 self.copies.extend(self.copytree(self.rootBinDir, self.destBinDir, exclude = exclude )) 483 return 484 485 def installShare(self): 486 self.copies.extend(self.copytree(self.rootShareDir, self.destShareDir)) 487 examplesdir=os.path.join(self.destShareDir,'petsc','examples') 488 if os.path.exists(examplesdir): 489 shutil.rmtree(examplesdir) 490 os.mkdir(examplesdir) 491 os.mkdir(os.path.join(examplesdir,'src')) 492 self.copyConfig(self.rootDir,examplesdir) 493 if not self.argDB['no-examples']: 494 self.copyExamples(self.rootSrcDir,os.path.join(examplesdir,'src')) 495 self.fixExamplesMakefile(os.path.join(examplesdir,'gmakefile.test')) 496 return 497 498 def copyLib(self, src, dst): 499 '''Run ranlib on the destination library if it is an archive. Also run install_name_tool on dylib on Mac''' 500 # Symlinks (assumed local) are recreated at dst 501 if os.path.islink(src): 502 linkto = os.readlink(src) 503 try: 504 os.remove(dst) # In case it already exists 505 except OSError: 506 pass 507 os.symlink(linkto, dst) 508 return 509 shutil.copy2(src, dst) 510 if self.setCompilers.getCompiler().find('win32fe') < 0 and os.path.splitext(dst)[1] == '.'+self.arLibSuffix: 511 import shlex 512 self.executeShellCommand(shlex.split(self.ranlib) + [dst]) 513 if os.path.splitext(dst)[1] == '.dylib' and shutil.which('otool') and shutil.which('install_name_tool'): 514 [output,err,flg] = self.executeShellCommand(['otool', '-D', src]) 515 oldname = output[output.find("\n")+1:] 516 installName = oldname.replace(os.path.realpath(self.archDir), self.installDir) 517 self.executeShellCommand(['install_name_tool', '-id', installName, dst]) 518 # preserve the original timestamps - so that the .a vs .so time order is preserved 519 shutil.copystat(src,dst) 520 return 521 522 def installLib(self): 523 self.copies.extend(self.copytree(self.archLibDir, self.destLibDir, copyFunc = self.copyLib, exclude = ['.DIR'],recurse = 0)) 524 self.copies.extend(self.copytree(os.path.join(self.archLibDir,'pkgconfig'), os.path.join(self.destLibDir,'pkgconfig'), copyFunc = self.copyLib, exclude = ['.DIR'],recurse = 0)) 525 return 526 527 528 def outputInstallDone(self): 529 from config.packages.make import getMakeUserPath 530 print('''\ 531==================================== 532Install complete. 533Now to check if the libraries are working do (in current directory): 534%s PETSC_DIR=%s PETSC_ARCH="" check 535====================================\ 536''' % (getMakeUserPath(self.arch), self.installDir)) 537 return 538 539 def outputDestDirDone(self): 540 print('''\ 541==================================== 542Copy to DESTDIR %s is now complete. 543Before use - please copy/install over to specified prefix: %s 544====================================\ 545''' % (self.destDir,self.installDir)) 546 return 547 548 def runsetup(self): 549 self.setup() 550 self.setupDirectories() 551 self.checkPrefix() 552 self.checkDestdir() 553 return 554 555 def runcopy(self): 556 if self.destDir == self.installDir: 557 print('*** Installing PETSc at prefix location:',self.destDir, ' ***') 558 else: 559 print('*** Copying PETSc to DESTDIR location:',self.destDir, ' ***') 560 if not os.path.exists(self.destDir): 561 try: 562 os.makedirs(self.destDir) 563 except: 564 print('********************************************************************') 565 print('Unable to create', self.destDir, 'Perhaps you need to do "sudo make install"') 566 print('********************************************************************') 567 sys.exit(1) 568 self.installIncludes() 569 self.installConf() 570 self.installBin() 571 self.installLib() 572 self.installShare() 573 self.createUninstaller() 574 return 575 576 def runfix(self): 577 self.fixConf() 578 using_build_backend = any( 579 os.environ.get(prefix + '_BUILD_BACKEND') 580 for prefix in ('_PYPROJECT_HOOKS', 'PEP517') 581 ) 582 if using_build_backend: 583 self.fixPythonWheel() 584 return 585 586 def rundone(self): 587 if self.destDir == self.installDir: 588 self.outputInstallDone() 589 else: 590 self.outputDestDirDone() 591 return 592 593 def run(self): 594 self.runsetup() 595 self.runcopy() 596 self.runfix() 597 self.rundone() 598 return 599 600if __name__ == '__main__': 601 Installer(sys.argv[1:]).run() 602 # temporary hack - delete log files created by BuildSystem - when 'sudo make install' is invoked 603 delfiles=['RDict.db','RDict.log','buildsystem.log','default.log','buildsystem.log.bkp','default.log.bkp'] 604 for delfile in delfiles: 605 if os.path.exists(delfile) and (os.stat(delfile).st_uid==0): 606 os.remove(delfile) 607