def RunBuildSh(self, stdout, args=None): build_port = os.path.join(TOOLS_DIR, 'build_port.sh') cmd = [build_port] if args is not None: cmd += args env = os.environ.copy() env['TOOLCHAIN'] = self.config.toolchain env['NACL_ARCH'] = self.config.arch env['NACL_DEBUG'] = self.config.debug and '1' or '0' if naclports.verbose: rtn = subprocess.call(cmd, cwd=self.root, env=env) if rtn != 0: raise Error("Building %s: failed." % (self.NAME)) else: with open(stdout, 'a+') as log_file: rtn = subprocess.call(cmd, cwd=self.root, env=env, stdout=log_file, stderr=subprocess.STDOUT) if rtn != 0: with open(stdout) as log_file: sys.stdout.write(log_file.read()) raise Error("Building '%s' failed." % (self.NAME))
def CmdInfo(config, options, args): if len(args) != 1: raise Error('info command takes a single package name') package_name = args[0] info_file = naclports.GetInstallStamp(package_name, config) print 'Install receipt: %s' % info_file if not os.path.exists(info_file): raise Error('package not installed: %s [%s]' % (package_name, config)) with open(info_file) as f: sys.stdout.write(f.read())
def CmdContents(config, options, args): if len(args) != 1: raise Error('contents command takes a single package name') package_name = args[0] list_file = naclports.GetFileList(package_name, config) if not os.path.exists(list_file): raise Error('package not installed: %s [%s]' % (package_name, config)) install_root = naclports.GetInstallRoot(config) with open(list_file) as f: if options.verbose: for line in f: sys.stdout.write(os.path.join(install_root, line)) else: sys.stdout.write(f.read())
def ExtractInto(self, output_path): """Extract the package archive into the given location. This method assumes the package has already been downloaded. """ archive = self.DownloadLocation() if not archive: return if not os.path.exists(output_path): os.makedirs(output_path) new_foldername = os.path.basename(self.GetBuildLocation()) dest = os.path.join(output_path, new_foldername) if os.path.exists(dest): Trace('Already exists: %s' % dest) return tmp_output_path = tempfile.mkdtemp(dir=OUT_DIR) try: ext = os.path.splitext(archive)[1] if ext in ('.gz', '.tgz', '.bz2'): cmd = ['tar', 'xf', archive, '-C', tmp_output_path] elif ext in ('.zip', ): cmd = ['unzip', '-q', '-d', tmp_output_path, archive] else: raise Error('unhandled extension: %s' % ext) Log("Extracting '%s'" % self.NAME) Trace(cmd) subprocess.check_call(cmd) src = os.path.join(tmp_output_path, new_foldername) os.rename(src, dest) finally: shutil.rmtree(tmp_output_path)
def Uninstall(self, ignore_missing): if not os.path.exists(naclports.GetInstallStamp( self.NAME, self.config)): if ignore_missing: return raise Error('Package not installed: %s [%s]' % (self.NAME, self.config)) Log("Uninstalling '%s' [%s]" % (self.NAME, self.config)) file_list = naclports.GetFileList(self.NAME, self.config) if not os.path.exists(file_list): Log('No files to uninstall') else: root = naclports.GetInstallRoot(self.config) with open(file_list) as f: for line in f: filename = os.path.join(root, line.strip()) if not os.path.lexists(filename): Warn('File not found while uninstalling: %s' % filename) continue Trace('rm %s' % filename) os.remove(filename) RemoveEmptyDirs(os.path.dirname(filename)) os.remove(file_list) os.remove(naclports.GetInstallStamp(self.NAME, self.config))
def GetLock(): lock_file_name = os.path.join(naclports.OUT_DIR, 'naclports.lock') if not os.path.exists(naclports.OUT_DIR): os.makedirs(naclports.OUT_DIR) f = open(lock_file_name, 'w') try: fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB) except Exception as e: raise Error("Unable to lock file (%s): Is naclports already running?" % lock_file_name) return f
def CreatePackage(package_name, config=None): """Create a Package object given a package name or path. Returns: Package object """ if os.path.isdir(package_name): return Package(package_name, config) for subdir in DEFAULT_LOCATIONS: pkg_root = os.path.join(NACLPORTS_ROOT, subdir, package_name) info = os.path.join(pkg_root, 'pkg_info') if os.path.exists(info): return Package(pkg_root, config) raise Error("Package not found: %s" % package_name)
def CmdList(config, options, args): if len(args): raise Error('list command takes no arguments') stamp_root = naclports.GetInstallStampRoot(config) if os.path.exists(stamp_root): for filename in os.listdir(stamp_root): basename, ext = os.path.splitext(filename) if ext != '.info': continue if options.verbose: fullname = os.path.join(stamp_root, filename) valid_keys = naclports.VALID_KEYS + naclports.binary_package.EXTRA_KEYS info = naclports.ParsePkgInfoFile(fullname, valid_keys) sys.stdout.write('%-15s %s\n' % (info['NAME'], info['VERSION'])) else: sys.stdout.write(basename + '\n') return 0
def __init__(self, pkg_root, config=None): if config is None: config = Configuration() for key in naclports.VALID_KEYS: setattr(self, key, None) self.config = config self.DEPENDS = [] self.CONFLICTS = [] self.root = os.path.abspath(pkg_root) self.info = os.path.join(self.root, 'pkg_info') if not os.path.isdir(self.root) or not os.path.exists(self.info): raise Error('Invalid package folder: %s' % pkg_root) # Parse pkg_info file info = naclports.ParsePkgInfoFile(self.info) # Set attributres based on pkg_info setttings. for key, value in info.items(): setattr(self, key, value) if '_' in self.NAME: raise Error('%s: package NAME cannot contain underscores' % self.info) if self.NAME != self.NAME.lower(): raise Error( '%s: package NAME cannot contain uppercase characters' % self.info) if '_' in self.VERSION: raise Error('%s: package VERSION cannot contain underscores' % self.info) if self.NAME != os.path.basename(self.root): raise Error('%s: package NAME must match directory name' % self.info) if self.DISABLED_ARCH is not None and self.ARCH is not None: raise Error('%s: contains both ARCH and DISABLED_ARCH' % self.info) if self.DISABLED_LIBC is not None and self.LIBC is not None: raise Error('%s: contains both LIBC and DISABLED_LIBC' % self.info)
def run_main(args): usage = 'Usage: %prog [options] <command> [<package_dir>]' parser = optparse.OptionParser(prog='naclports', description=__doc__, usage=usage) parser.add_option('-v', '--verbose', action='store_true', help='Output extra information.') parser.add_option('-V', '--verbose-build', action='store_true', help='Make the build itself version (e.g. pass V=1 to make') parser.add_option('--all', action='store_true', help='Perform action on all known ports.') parser.add_option('-f', '--force', action='store_const', const='build', help='Force building specified targets, ' 'even if timestamps would otherwise skip it.') parser.add_option('--from-source', action='store_true', help='Always build from source rather than downloading ' 'prebuilt packages.') parser.add_option('-F', '--force-all', action='store_const', const='all', dest='force', help='Force building target and all ' 'dependencies, even if timestamps would otherwise skip ' 'them.') parser.add_option('--no-deps', dest='build_deps', action='store_false', default=True, help='Disable automatic building of dependencies.') parser.add_option('--ignore-disabled', action='store_true', help='Ignore attempts to build disabled packages.\n' 'Normally attempts to build such packages will result\n' 'in an error being returned.') parser.add_option('--toolchain', help='Set toolchain to use when building (newlib, glibc, or' ' pnacl)"') parser.add_option('--debug', help='Build debug configuration (release is the default)') parser.add_option('--arch', help='Set architecture to use when building (x86_64,' ' x86_32, arm, pnacl)') options, args = parser.parse_args(args) if not args: parser.error('You must specify a sub-command. See --help.') command = args[0] args = args[1:] lock_file = GetLock() naclports.verbose = options.verbose or os.environ.get('VERBOSE') == '1' if options.verbose_build: os.environ['VERBOSE'] = '1' else: if 'VERBOSE' in os.environ: del os.environ['VERBOSE'] if 'V' in os.environ: del os.environ['V'] if not NACL_SDK_ROOT: raise Error('$NACL_SDK_ROOT not set') if not os.path.isdir(NACL_SDK_ROOT): raise Error('$NACL_SDK_ROOT does not exist: %s' % NACL_SDK_ROOT) sentinel = os.path.join(NACL_SDK_ROOT, 'tools', 'getos.py') if not os.path.exists(sentinel): raise Error("$NACL_SDK_ROOT (%s) doesn't look right. " "Couldn't find sentinel file (%s)" % (NACL_SDK_ROOT, sentinel)) config = Configuration(options.arch, options.toolchain, options.debug) base_commands = { 'list': CmdList, 'info': CmdInfo, 'contents': CmdContents } pkg_commands = { 'download': CmdPkgDownload, 'check': CmdPkgCheck, 'build': CmdPkgBuild, 'uninstall': CmdPkgUninstall, 'install': CmdPkgInstall, 'verify': CmdPkgVerify, 'clean': CmdPkgClean, } if command in base_commands: base_commands[command](config, options, args) return 0 if command not in pkg_commands: parser.error("Unknown subcommand: '%s'\n" 'See --help for available commands.' % command) if len(args) and options.all: parser.error('Package name(s) and --all cannot be specified together') if args: package_dirs = args else: package_dirs = [os.getcwd()] def DoCmd(package): try: pkg_commands[command](package, options) except DisabledError as e: if options.ignore_disabled: naclports.Log('naclports: %s' % e) else: raise e def rmtree(path): naclports.Log('removing %s' % path) if os.path.exists(path): shutil.rmtree(path) if options.all: options.ignore_disabled = True if command == 'clean': rmtree(naclports.STAMP_DIR) rmtree(naclports.BUILD_ROOT) rmtree(naclports.PUBLISH_ROOT) rmtree(naclports.package.PACKAGES_ROOT) rmtree(naclports.GetInstallStampRoot(config)) rmtree(naclports.GetInstallRoot(config)) else: for p in PackageIterator(): if not p.DISABLED: DoCmd(p) else: for package_dir in package_dirs: p = naclports.package.CreatePackage(package_dir, config) DoCmd(p)