#!/usr/bin/env python3 import sys import os import os.path from pathlib import Path import socket import subprocess import re import argparse reCoriolisPattern = re.compile( r".*coriolis.*" ) reReleaseSharedPattern = re.compile( r".*Release\.Shared.*" ) reReleaseStaticPattern = re.compile( r".*Release\.Static.*" ) reDebugSharedPattern = re.compile( r".*Debug\.Shared.*" ) reDebugStaticPattern = re.compile( r".*Debug\.Static.*" ) def scrubPath ( pathName ): """ Remove from the PATH like environment variable ``pathName`` any previous path item referring to a Coriolis location. """ if not pathName in os.environ: return '' value = os.environ[ pathName ] elements = value.split( ':' ) scrubbed = [] for element in elements: if element == '': continue if reCoriolisPattern .match(element) \ or reReleaseSharedPattern.match(element) \ or reReleaseStaticPattern.match(element) \ or reDebugSharedPattern .match(element) \ or reDebugStaticPattern .match(element): continue scrubbed.append( element ) if len(scrubbed) == 0: return '' return ':'.join( scrubbed ) def envWriteBack ( pathName, pathValue ): """ Add to the environment PATH like variable ``pathName`` the components given in ``pathValue`` and export it back. To avoid having multiple Coriolis in the path, it is scrubbed beforehand. """ if pathName in os.environ: scrubbed = scrubPath( pathName ) if scrubbed != '': pathValue += ':' + scrubbed os.environ[ pathName ] = pathValue return pathValue def setupPaths ( verbose, debug=False ): """ Guess and setup the main variables to use Coriolis: * ``PATH``, to find the binaries. * ``LD_LIBRARY_PATH``, to access the dynamic libraries. * ``DYLD_LIBRARY_PATH``, same as above under MacOS. * ``PYTHONPATH``, to access the various Python modules provided by Coriolis. :param verbose: Self explanatory. :param debug: Use the version compiled with debugging support. Be aware that it is roughly 4 times slower... It's the tree rooted at ``Debug.Shared/install`` instead of ``Release.Shared/install``. """ # Setup CORIOLIS_TOP. osEL9 = re.compile (".*Linux.*el9.*x86_64.*") osSlsoc7x_64 = re.compile (".*Linux.*el7.*x86_64.*") osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*") osSlsoc6x = re.compile (".*Linux.*(el|slsoc)6.*") osSLSoC5x_64 = re.compile (".*Linux.*el5.*x86_64.*") osSLSoC5x = re.compile (".*Linux.*(el5|2.6.23.13.*SoC).*") osFedora_64 = re.compile (".*Linux.*fc.*x86_64.*") osFedora = re.compile (".*Linux.*fc.*") osLinux_64 = re.compile (".*Linux.*x86_64.*") osLinux = re.compile (".*Linux.*") osDarwin = re.compile (".*Darwin.*") osUbuntu1004 = re.compile (".*Linux.*ubuntu.*") osUbuntu1004_64 = re.compile (".*Linux.*ubuntu.*x86_64.*") osFreeBSD8x_amd64 = re.compile (".*FreeBSD 8.*amd64.*") osFreeBSD8x_64 = re.compile (".*FreeBSD 8.*x86_64.*") osFreeBSD8x = re.compile (".*FreeBSD 8.*") osCygwinW7_64 = re.compile (".*CYGWIN_NT-6\.1.*x86_64.*") osCygwinW7 = re.compile (".*CYGWIN_NT-6\.1.*i686.*") osCygwinW8_64 = re.compile (".*CYGWIN_NT-6\.[2-3].*x86_64.*") osCygwinW8 = re.compile (".*CYGWIN_NT-6\.[2-3].*i686.*") osCygwinW10_64 = re.compile (".*CYGWIN_NT-10\.[0-3].*x86_64.*") osCygwinW10 = re.compile (".*CYGWIN_NT-10\.[0-3].*i686.*") uname = subprocess.Popen( ["uname", "-srm"], stdout=subprocess.PIPE ) lines = uname.stdout.readlines() line = lines[0].decode( 'ascii' ) if osSlsoc7x_64 .match(line): osDir = "Linux.el7_64" elif osEL9 .match(line): osDir = "Linux.el9" elif osSlsoc6x_64 .match(line): osDir = "Linux.slsoc6x_64" elif osSlsoc6x .match(line): osDir = "Linux.slsoc6x" elif osSLSoC5x_64 .match(line): osDir = "Linux.SLSoC5x_64" elif osSLSoC5x .match(line): osDir = "Linux.SLSoC5x" elif osFedora_64 .match(line): osDir = "Linux.fc_64" elif osFedora .match(line): osDir = "Linux.fc" elif osUbuntu1004 .match(line): osDir = "Linux.Ubuntu1004" elif osUbuntu1004_64 .match(line): osDir = "Linux.Ubuntu1004_64" elif osLinux_64 .match(line): osDir = "Linux.x86_64" elif osLinux .match(line): osDir = "Linux.i386" elif osFreeBSD8x_64 .match(line): osDir = "FreeBSD.8x.x86_64" elif osFreeBSD8x_amd64.match(line): osDir = "FreeBSD.8x.amd64" elif osFreeBSD8x .match(line): osDir = "FreeBSD.8x.i386" elif osDarwin .match(line): osDir = "Darwin" elif osCygwinW7_64 .match(line): osDir = "Cygwin.W7_64" elif osCygwinW7 .match(line): osDir = "Cygwin.W7" elif osCygwinW8_64 .match(line): osDir = "Cygwin.W8_64" elif osCygwinW8 .match(line): osDir = "Cygwin.W8" elif osCygwinW10_64 .match(line): osDir = "Cygwin.W10_64" elif osCygwinW10 .match(line): osDir = "Cygwin.W10" else: uname = subprocess.Popen( ["uname", "-sr"], stdout=subprocess.PIPE ) osDir = uname.stdout.readlines()[0][:-1] print( '[WARNING] environment.setupPaths(): Unrecognized OS: "{}".'.format( line[:-1] )) print( ' (using: "{}")'.format( osDir )) osDir = Path( osDir ) homeDir = Path( os.environ['HOME'] ) buildType = Path( 'Debug.Shared' if debug else 'Release.Shared' ) scriptPath = Path( __file__ ).resolve() topDirs = [] topDirs += [ homeDir / 'coriolis-2.x' / osDir / buildType / 'install' , Path( '/soc/coriolis2' ) , Path( '/usr' ) ] if not debug and 'CORIOLIS_TOP' in os.environ: topDirs.insert( 0, Path( os.environ['CORIOLIS_TOP'] )) for part in scriptPath.parts: if part == 'nightly': topDirs.insert( 0, homeDir / 'nightly' / 'coriolis-2.x' / osDir / buildType / 'install' ) break if verbose: print( ' o Self locating Coriolis:' ) coriolisTop = None for topDir in topDirs: if coriolisTop or not (topDir / 'bin' / 'cgt').is_file(): if verbose: print( ' - {}'.format(topDir) ) continue if verbose: print( ' - {} *'.format(topDir) ) coriolisTop = topDir if not coriolisTop: print( '[ERROR] environment.setupPaths(): Unable to locate Coriolis.' ) return False os.environ[ 'CORIOLIS_TOP' ] = coriolisTop.as_posix() #if coriolisTop == '/usr': sysconfDir = Path( 'etc', 'coriolis2' ) #else: sysconfDir = coriolisTop / 'etc' / 'coriolis2' if coriolisTop == '/usr': sysconfDir = Path( 'etc' ) else: sysconfDir = coriolisTop / 'etc' # Setup PATH. binPath = envWriteBack( 'PATH', (coriolisTop/'bin').as_posix() ) # Setup LD_LIBRARY_PATH. libDirs = [] for lib in [ Path('lib'), Path('lib64') ]: libDir = lib absLibDir = coriolisTop / lib if absLibDir.is_dir(): libDirs.append( absLibDir ) libDir = None if not len(libDirs): print( '[ERROR] environment.setupPaths(): Library directory not found.' ) return False libraryPath = '' ldPathName = 'LD_LIBRARY_PATH' if osDir.as_posix().startswith( 'Darwin' ): ldPathName = 'DYLD_LIBRARY_PATH' for libDir in libDirs: if len(libraryPath): libraryPath = libraryPath + ':' libraryPath = libraryPath + libDir.as_posix() libraryPath = envWriteBack( ldPathName, libraryPath ) # Setup PYTHONPATH. v = sys.version_info sitePackagesDir = None for pyPackageDir in [ Path('python{}.{}'.format(v.major,v.minor)) / 'site-packages' , Path('python{}.{}'.format(v.major,v.minor)) / 'dist-packages' , Path('{}.{}'.format(v.major,v.minor)) / 'site-packages' , Path('python{}'.format(v.major)) / 'site-packages' , Path('python{}'.format(v.major)) / 'dist-packages' , Path('{}'.format(v.major)) / 'site-packages' ]: sitePackagesDir = libDirs[-1] / pyPackageDir if sitePackagesDir.is_dir(): if verbose: print( ' - {} *'.format(sitePackagesDir) ) break if verbose: print( ' - {}'.format(sitePackagesDir) ) sitePackagesDir = None if sitePackagesDir is None: print( '[ERROR] environment.setupPaths(): Python {site,dist}-packages directory not found.' ) return False pythonPath = '' for packageDir in [ sitePackagesDir #, sitePackagesDir / 'crlcore' #, sitePackagesDir / 'cumulus' #, sitePackagesDir / 'cumulus/plugins' #, sitePackagesDir / 'status' #, sysconfDir ]: sys.path.append( str(packageDir) ) if len(pythonPath): pythonPath += ':' pythonPath += str(packageDir) pythonPath = envWriteBack( 'PYTHONPATH', pythonPath ) return True def printVariable ( name ): if not name in os.environ: print( '{}:'.format( name )) print( '- variable_not_set' ) return values = os.environ[ name ].split( ':' ) print( '{}:'.format( name )) for value in values: print( '- {}'.format( value )) def printEnvironment (): """ Display the environment setup, using YAML formatting. """ print( '# crlenv.py: Alliance/Coriolis finder, guessed values.' ) print( '---' ) for name in ('CORIOLIS_TOP', 'PATH', 'DYLD_LIBRARY_PATH' , 'LD_LIBRARY_PATH', 'PYTHONPATH'): printVariable( name ) if __name__ == '__main__': """ Run any script in a environmnent set for Coriolis. Example: .. code:: bash ego@home:~> crlenv.py -- doit clean_flow b2v Run . cgt Run plain CGT (no loaded design) clean_flow Clean all generated (targets) files. gds Run . pnr Run . yosys Run . ego@home:~> crlenv.py -- bash [ego@home]$ echo $CORIOLIS_TOP /home/ego/coriolis-2.x/Linux.el9/Release.Shared/install [ego@home]$ exit ego@home:~> """ parser = argparse.ArgumentParser() parser.add_argument( '-v', '--verbose', action='store_true', dest='verbose' ) parser.add_argument( '-d', '--debug' , action='store_true', dest='debug' ) parser.add_argument( 'command', nargs='*' ) args = parser.parse_args() setupPaths( args.verbose, args.debug ) if not len(args.command): printEnvironment() sys.exit( 0 ) state = subprocess.run( args.command ) sys.exit( state.returncode )