#!/usr/bin/env python2 # Copyright 1999-2011 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import os, re, signal, subprocess, sys, fnmatch options=[ '--get-hosts', '--set-hosts', '--get-verbose', '--set-verbose', '--get-log', '--set-log', '--update-masquerade', '--update-masquerade-with-crossdev', '--update-masquerade-with-cc32_64', '--generate-cmdlist', '--help', '--get-env', '--set-env' ] tmpcmdline=sys.argv[1:] cmdline=[] eprefix = '@EPREFIX@' bindir = os.path.join(eprefix, 'usr', 'bin') sbindir = os.path.join(eprefix, 'usr', 'sbin') libdir = os.path.join(eprefix, '@libdir@') sysconfdir = os.path.join(eprefix, 'etc') gcc_config = os.path.join(bindir, 'gcc-config') env_update = os.path.join(sbindir, 'env-update') envfile = os.path.join(sysconfdir, 'env.d', '02distcc') default_distcc_dir = os.path.join(sysconfdir, 'distcc') cmdlist_file = os.path.join(default_distcc_dir, 'commands.allow') hostfile = os.path.join(default_distcc_dir, 'hosts') distcc_path = os.path.join(bindir, 'distcc') dccc_dir = os.path.join(libdir, 'distcc', 'bin') def exithandler(foo,bar): os.kill(0,signal.SIGKILL) sys.exit(1) signal.signal(signal.SIGINT,exithandler) def isroot(ret=0): if os.getuid() != 0: if ret == 0: print('!!! %s %s must be run as root' % (sys.argv[:1][0],tmpcmdline[0])) sys.exit(1) else: retval = 0 else: retval = 1 return retval def run_env_update(): subprocess.Popen(env_update, shell=True) print('If you want to use these new settings in an existing shell,') print('you need to "source /etc/profile" to get the changes.') def writeenv(var,value): isroot() distcc_env = [] distcc_env = open(envfile, 'r').readlines() distcc_env_new = open(envfile, 'w') for i in range(len(distcc_env)): if re.compile(var+'="(.*)"').match(distcc_env[i]): distcc_env[i] = var+'="'+value+'"\n' distcc_env_new.write(distcc_env[i]) #print('Set %s to: %s ' % (var,value)) run_env_update() def readenv(var): distcc_env = open(envfile, 'r').read() match = re.compile(var+'="(.*)"').search(distcc_env) if match: print(var+'='+match.group(1)) else: print(var,'not set.') def installlink(chost='', version='', cc_arch=''): for file in ['gcc', 'cc', 'c++', 'g++']: if cc_arch == '': src_path = distcc_path else: if chost == '': if file == 'cc': src_path = 'gcc' else: src_path = os.path.join(bindir, cc_arch+'-pc-linux-gnu-'+file) else: src_path = distcc_path src_path_cc = file if not chost == '': if cc_arch != '': file2 = '%s-pc-linux-gnu-%s' % (cc_arch,file) file = '%s-%s' % (chost,file) if not version == '': if cc_arch != '': file2 = '%s-%s' % (file2,version) file = '%s-%s' % (file,version) path = os.path.join(dccc_dir,file) if os.path.exists(os.path.join(bindir,file)): if not os.path.exists(path): print('Creating %s symlink...' % (path)) os.symlink(src_path,path) if cc_arch != '' and chost != '': path = os.path.join(dccc_dir,file2) print('Creating %s symlink...' % (path)) os.symlink(src_path_cc,path) def installlinks(cc_arch=''): installlink('', '', cc_arch) p = subprocess.Popen([gcc_config+" -C -l"], shell=True, stdout=subprocess.PIPE) lines = p.stdout.read().rstrip().split('\n') for line in lines: columns = line.split() if len(columns) >= 2: matches = re.match("(.*)-(.*)", columns[1]) chost = matches.group(1) version = matches.group(2) installlink(chost, '', cc_arch) installlink(chost, version, cc_arch) def uninstalllinks(): for root, dirs, files in os.walk(dccc_dir): for file in files: path = os.path.join(root, file) if os.path.islink(path): os.remove(path) def createdistccdir(dir): if not os.path.exists(dir): os.mkdir(dir) os.chmod(dir, 0o755) for x in tmpcmdline: if not x: continue if x[0:2]=="--": if not x in options: print("!!! Error: %s is an invalid option." % (x)) sys.exit(1) else: cmdline = x if '--get-hosts' in tmpcmdline: HOSTS_ENV = os.environ.get('DISTCC_HOSTS') HOSTS_HOME = os.path.join(os.environ.get('HOME'), '.distcc', 'hosts') if HOSTS_ENV: print(HOSTS_ENV) elif os.path.isfile(HOSTS_HOME) and os.path.getsize(HOSTS_HOME) != 0: print(HOSTS_HOME) elif os.path.exists(hostfile): print(open(hostfile, 'r').read().rstrip()) else: print('No configuration file found. Setup your hosts with --set-hosts.') elif '--set-hosts' in tmpcmdline: if isroot(1): PATH = default_distcc_dir else: PATH = os.path.join(os.environ.get('HOME'), '.distcc') createdistccdir(PATH) open(os.path.join(PATH, 'hosts'), 'w').write(cmdline + '\n') elif '--get-verbose' in tmpcmdline: readenv('DISTCC_VERBOSE') elif '--set-verbose' in tmpcmdline: writeenv('DISTCC_VERBOSE',tmpcmdline[1]) elif '--get-log' in tmpcmdline: readenv('DISTCC_LOG') elif '--set-log' in tmpcmdline: writeenv('DISTCC_LOG',tmpcmdline[1]) elif '--update-masquerade' in tmpcmdline: isroot() uninstalllinks() print('Creating symlinks...') installlinks() elif '--update-masquerade-with-crossdev' in tmpcmdline: isroot() uninstalllinks() print('Creating symlinks...') installlinks() elif '--update-masquerade-with-cc32_64' in tmpcmdline: isroot() arch_curr = os.uname()[4] arch_supp = set(['i686', 'x86_64']) if not arch_curr in arch_supp: print('Architecure %s is not supported for cross-compilation i686<->x86_64 setup' % (arch)) sys.exit(1) # normal setup uninstalllinks() print('Creating symlinks for host arch...') createdistccdir(dccc_dir) installlinks() # cross-compile helpers cc_arch = (arch_supp - set([arch_curr])).pop() dccc_dir = os.path.join(libdir, 'distcc', 'bin-'+cc_arch) uninstalllinks() print('Creating symlinks for cross-compile arch...') createdistccdir(dccc_dir) installlinks(cc_arch) elif '--generate-cmdlist' in tmpcmdline: isroot() names = [] # search for files in the root distcc dir for root, dirs, files in os.walk(os.path.join(libdir, 'distcc')): for f in fnmatch.filter(files,"[!.]*"): names.append(f) cmdfile = open(cmdlist_file, 'w') for name in sorted(set(names)): cmdfile.write(name + "\n") run_env_update() elif '--get-env' in tmpcmdline: if len(tmpcmdline) == 1: print(open(envfile, 'r').read().rstrip()) elif len(tmpcmdline) == 2: readenv(tmpcmdline[1]) else: print('!!! Error: Specify only one variable.') elif '--set-env' in tmpcmdline: if len(tmpcmdline) > 2 and len(tmpcmdline) <= 3: isroot() writeenv(tmpcmdline[1],tmpcmdline[2]) else: print('!!! Error: Awaiting two parameters.') else: cmd = sys.argv[:1][0] print('Usage: %s --set-hosts DISTCC_HOSTS | --get-hosts' % (cmd)) print(' %s --set-verbose { 0 | 1 } | --get-verbose' % (cmd)) print(' %s --set-log FILE | --get-log' % (cmd)) print(' %s --set-env VARIABLE VALUE | --get-env [VARIABLE]' % (cmd)) print(' %s --update-masquerade' % (cmd)) print(' %s --update-masquerade-with-crossdev' % (cmd)) print(' %s --update-masquerade-with-cc32_64' % (cmd)) print(' %s --generate-cmdlist' % (cmd))