def fake_interpreter(id_str): return PythonInterpreter('/fake/binary', PythonIdentity.from_id_string(id_str))
def main(): parser = optparse.OptionParser(usage="usage: %prog [options] output") parser.add_option("--entry-point", default="__main__") parser.add_option("--directory", action="store_true", default=False) parser.add_option( "--no-zip-safe", action="store_false", dest="zip_safe", default=True ) parser.add_option("--python", default="") parser.add_option("--python-version", default="") parser.add_option("--python-shebang", default=None) parser.add_option("--preload", action="append", default=[]) options, args = parser.parse_args() if len(args) == 1: output = args[0] else: parser.error("'output' positional argument is required") return 1 # The manifest is passed via stdin, as it can sometimes get too large # to be passed as a CLA. manifest = json.load(sys.stdin) # The version of pkg_resources.py (from setuptools) on some distros is # too old for PEX. So we keep a recent version in the buck repo and # force it into the process by constructing a custom PythonInterpreter # instance using it. if not options.python: options.python = sys.executable identity = PythonIdentity.get() elif not options.python_version: # Note: this is expensive (~500ms). prefer passing --python-version when possible. identity = PythonInterpreter.from_binary(options.python).identity else: # Convert "CPython 2.7" to "CPython 2 7 0" python_version = options.python_version.replace(".", " ").split() if len(python_version) == 3: python_version.append("0") identity = PythonIdentity.from_id_string(" ".join(python_version)) interpreter = PythonInterpreter(options.python, identity, extras={}) pex_builder = PEXBuilder( path=output if options.directory else None, interpreter=interpreter ) if options.python_shebang is not None: pex_builder.set_shebang(options.python_shebang) # Set whether this PEX as zip-safe, meaning everything will stayed zipped up # and we'll rely on python's zip-import mechanism to load modules from # the PEX. This may not work in some situations (e.g. native # libraries, libraries that want to find resources via the FS). pex_builder.info.zip_safe = options.zip_safe # Set the starting point for this PEX. pex_builder.info.entry_point = options.entry_point # Copy in our version of `pkg_resources` & `_markerlib`. copy_package(pex_builder, "pkg_resources", prefix=pex_builder.BOOTSTRAP_DIR) copy_package(pex_builder, "_markerlib", prefix=pex_builder.BOOTSTRAP_DIR) # Add the sources listed in the manifest. for dst, src in manifest["modules"].iteritems(): # NOTE(agallagher): calls the `add_source` and `add_resource` below # hard-link the given source into the PEX temp dir. Since OS X and # Linux behave different when hard-linking a source that is a # symbolic link (Linux does *not* follow symlinks), resolve any # layers of symlinks here to get consistent behavior. try: pex_builder.add_source(dereference_symlinks(src), dst) except OSError as e: raise Exception("Failed to add {}: {}".format(src, e)) # Add resources listed in the manifest. for dst, src in manifest["resources"].iteritems(): # NOTE(agallagher): see rationale above. pex_builder.add_resource(dereference_symlinks(src), dst) # Add resources listed in the manifest. for dst, src in manifest["nativeLibraries"].iteritems(): # NOTE(agallagher): see rationale above. pex_builder.add_resource(dereference_symlinks(src), dst) if options.directory: pex_builder.freeze(code_hash=False, bytecode_compile=False) else: pex_builder.build(output)
def fake_interpreter(id_str): return PythonInterpreter('/fake/binary', PythonIdentity.from_id_string(id_str))
def main(): parser = optparse.OptionParser(usage="usage: %prog [options] output") parser.add_option('--entry-point', default='__main__') parser.add_option('--directory', action='store_true', default=False) parser.add_option('--no-zip-safe', action='store_false', dest='zip_safe', default=True) parser.add_option('--python', default='') parser.add_option('--python-version', default='') parser.add_option('--python-shebang', default=None) parser.add_option('--preload', action='append', default=[]) options, args = parser.parse_args() if len(args) == 1: output = args[0] else: parser.error("'output' positional argument is required") return 1 # The manifest is passed via stdin, as it can sometimes get too large # to be passed as a CLA. manifest = json.load(sys.stdin) # The version of pkg_resources.py (from setuptools) on some distros is # too old for PEX. So we keep a recent version in the buck repo and # force it into the process by constructing a custom PythonInterpreter # instance using it. if not options.python: options.python = sys.executable identity = PythonIdentity.get() elif not options.python_version: # Note: this is expensive (~500ms). prefer passing --python-version when possible. identity = PythonInterpreter.from_binary(options.python).identity else: # Convert "CPython 2.7" to "CPython 2 7 0" python_version = options.python_version.replace('.', ' ').split() if len(python_version) == 3: python_version.append('0') identity = PythonIdentity.from_id_string(' '.join(python_version)) interpreter = PythonInterpreter(options.python, identity, extras={}) pex_builder = PEXBuilder( path=output if options.directory else None, interpreter=interpreter, ) if options.python_shebang is not None: pex_builder.set_shebang(options.python_shebang) # Set whether this PEX as zip-safe, meaning everything will stayed zipped up # and we'll rely on python's zip-import mechanism to load modules from # the PEX. This may not work in some situations (e.g. native # libraries, libraries that want to find resources via the FS). pex_builder.info.zip_safe = options.zip_safe # Set the starting point for this PEX. pex_builder.info.entry_point = options.entry_point # Copy in our version of `pkg_resources` & `_markerlib`. copy_package(pex_builder, 'pkg_resources', prefix=pex_builder.BOOTSTRAP_DIR) copy_package(pex_builder, '_markerlib', prefix=pex_builder.BOOTSTRAP_DIR) # Add the sources listed in the manifest. for dst, src in manifest['modules'].iteritems(): # NOTE(agallagher): calls the `add_source` and `add_resource` below # hard-link the given source into the PEX temp dir. Since OS X and # Linux behave different when hard-linking a source that is a # symbolic link (Linux does *not* follow symlinks), resolve any # layers of symlinks here to get consistent behavior. try: pex_builder.add_source(dereference_symlinks(src), dst) except OSError as e: raise Exception("Failed to add {}: {}".format(src, e)) # Add resources listed in the manifest. for dst, src in manifest['resources'].iteritems(): # NOTE(agallagher): see rationale above. pex_builder.add_resource(dereference_symlinks(src), dst) # Add resources listed in the manifest. for dst, src in manifest['nativeLibraries'].iteritems(): # NOTE(agallagher): see rationale above. pex_builder.add_resource(dereference_symlinks(src), dst) if options.directory: pex_builder.freeze(code_hash=False, bytecode_compile=False) else: pex_builder.build(output)