def main(): """Create empty local toolchain repository. Only one instance of this stage should be run, and it should run before any instances of the make_package stage run. We don't want to be creating the local repository several times concurrently. """ parser = get_argparser() args = parser.parse_args() # We can't create an empty database. We need to add a fake package # to a new database, then remove it again. path = "/tmp/dummy_pack" pkg_name = "dummy-pack" os.makedirs(path, exist_ok=True) pkg_info = (textwrap.dedent("""\ # Generated by makepkg 4.1.2 # using fakeroot version 1.20 # Mon 20 Oct 21 14:19:27 UTC 2013 pkgname = %s pkgver = 1.0.0-0 url = abc.xyz builddate 1382364167 packager = bog size = 1000000 arch = any """) % (pkg_name)) log("info", "Writing fake package .PKGINFO:", pkg_info.splitlines()) with open(os.path.join(path, ".PKGINFO"), "w") as f: print(pkg_info, file=f) log("info", "Building fake package") pkg = create_package(path, pkg_name, args) log("info", "Initializing toolchain repo") add_package_to_toolchain_repo(pkg, args.toolchain_directory, remove_name=pkg_name)
def create_hybrid_packages(args): os.chdir(args.build_dir) toolchain_packages = glob("*.pkg.tar.xz") if not toolchain_packages: die(Status.failure, "No built packages found in %s" % args.build_dir) hybrid_package_paths = [] hybrid_packages_dir = "/tmp/hybrid_packages" dir_toolchain = "/tmp/toolchain" dir_vanilla = "/tmp/vanilla" dir_hybrid = "/tmp/hybrid" for pkg in toolchain_packages: for d in [dir_toolchain, dir_vanilla, dir_hybrid]: shutil.rmtree(d, ignore_errors=True) os.makedirs(d) cmd = "pacman --query --file " + pkg cp = subprocess.run(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) log("command", cmd, cp.stdout.splitlines()) if cp.returncode: exit(1) pkg_name = cp.stdout.splitlines()[0].split()[0] log("info", "Creating hybrid package for '%s'" % pkg_name) vanilla_pkg = path_to_vanilla_pkg(pkg_name, args) with tarfile.open(pkg) as t: t.extractall(dir_toolchain) with tarfile.open(vanilla_pkg) as t: t.extractall(dir_vanilla) # Copy various directories from dir_toolchain and dir_vanilla # into dir_hybrid, and then tar dir_hybrid up. # # Every top-level directory should be recursively copied from # dir_vanilla into the top-level of dir_hybrid. # # Additionally, /usr/{lib,include} should be copied into # dir_hybrid/toolchain/usr/{lib,include}. # # Note that in Arch Linux, many of the traditional Unix # directories that contain (binaries,libraries) are symlinked to # (/usr/bin,/usr/lib). see # https://wiki.archlinux.org/index.php/Arch_filesystem_hierarchy # # There are some additional files in Arch packages, as noted in # # https://wiki.archlinux.org/index.php/Creating_packages # # .PKGINFO: This should be the same for vanilla and toolchain, # so just copy from vanilla # .INSTALL: Not sure if the instructions in this file will # always be portable across toolchains, but just copy # from vanilla and treat failures at INSTALL stage as # edge cases. # .MTREE: This one is evil, it's a binary file containing # hashes that are used to verify integrity. We need to # build our own one; this is handled by the # create_package method in utilities. for d in os.listdir(dir_vanilla): src = os.path.join(dir_vanilla, d) dst = os.path.join(dir_hybrid, d) try: shutil.copytree(src, dst, symlinks=True) except NotADirectoryError: # This will be .INSTALL, .MTREE or .PKGINFO, noted above shutil.copyfile(src, dst) for d in ["usr/lib", "usr/include"]: src = os.path.join(dir_toolchain, d) dst = os.path.join(dir_hybrid, "toolchain_root", d) try: shutil.copytree(src, dst, symlinks=True) except FileNotFoundError: pass structure = [] for root, dirs, files in os.walk(dir_hybrid): for f in files: path = re.sub(dir_hybrid, "", os.path.join(root, f)) structure.append(path) log("info", "Package file has the following structure:", structure) pkg_path = create_package(dir_hybrid, pkg_name, args) hybrid_package_paths.append(pkg_path) return hybrid_package_paths
def create_hybrid_packages(args): os.chdir(args.build_dir) toolchain_packages = glob("*.pkg.tar.xz") if not toolchain_packages: die(Status.failure, "No built packages found in %s" % args.build_dir) hybrid_package_paths = [] hybrid_packages_dir = "/tmp/hybrid_packages" dir_toolchain = "/tmp/toolchain" dir_vanilla = "/tmp/vanilla" dir_hybrid = "/tmp/hybrid" for pkg in toolchain_packages: for d in [dir_toolchain, dir_vanilla, dir_hybrid]: shutil.rmtree(d, ignore_errors=True) os.makedirs(d) cmd = "pacman --query --file " + pkg cp = subprocess.run(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) log("command", cmd, cp.stdout.splitlines()) if cp.returncode: exit(1) pkg_name = cp.stdout.splitlines()[0].split()[0] log("info", "Creating hybrid package for '%s'" % pkg_name) vanilla_pkg = path_to_vanilla_pkg(pkg_name, args) with tarfile.open(pkg) as t: t.extractall(dir_toolchain) with tarfile.open(vanilla_pkg) as t: t.extractall(dir_vanilla) # Copy various directories from dir_toolchain and dir_vanilla # into dir_hybrid, and then tar dir_hybrid up. # # Every top-level directory should be recursively copied from # dir_vanilla into the top-level of dir_hybrid. # # Additionally, /usr/{lib,include} should be copied into # dir_hybrid/toolchain/usr/{lib,include}. # # Note that in Arch Linux, many of the traditional Unix # directories that contain (binaries,libraries) are symlinked to # (/usr/bin,/usr/lib). see # https://wiki.archlinux.org/index.php/Arch_filesystem_hierarchy # # There are some additional files in Arch packages, as noted in # # https://wiki.archlinux.org/index.php/Creating_packages # # .PKGINFO: This should be the same for vanilla and toolchain, # so just copy from vanilla # .INSTALL: Not sure if the instructions in this file will # always be portable across toolchains, but just copy # from vanilla and treat failures at INSTALL stage as # edge cases. # .MTREE: This one is evil, it's a binary file containing # hashes that are used to verify integrity. We need to # build our own one; this is handled by the # create_package method in utilities. for d in os.listdir(dir_vanilla): src = os.path.join(dir_vanilla, d) dst = os.path.join(dir_hybrid, d) try: shutil.copytree(src, dst, symlinks=True) except NotADirectoryError: # This will be .INSTALL, .MTREE or .PKGINFO, noted above shutil.copyfile(src, dst) for d in ["usr/lib", "usr/include"]: src = os.path.join(dir_toolchain, d) dst = os.path.join(dir_hybrid, args.sysroot, d) try: shutil.copytree(src, dst, symlinks=True) except FileNotFoundError: pass structure = [] for root, dirs, files in os.walk(dir_hybrid): for f in files: path = re.sub(dir_hybrid, "", os.path.join(root, f)) structure.append(path) log("info", "Package file has the following structure:", structure) pkg_path = create_package(dir_hybrid, pkg_name, args) hybrid_package_paths.append(pkg_path) return hybrid_package_paths