feat: add support of atom builds
Signed-off-by: sisungo <[email protected]>
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
from . import packie
|
||||
|
||||
BASE_REQUIREMENTS = [
|
||||
"mksh",
|
||||
"coreutils",
|
||||
"python",
|
||||
"packie",
|
||||
"sqlite",
|
||||
"libgcc-compat",
|
||||
"aws-lc-libssl",
|
||||
"aws-lc-tools",
|
||||
"libcxx",
|
||||
"semi-libc",
|
||||
"ca-certificates",
|
||||
"certutil",
|
||||
"libz-ng",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
|
||||
def _prepare_build_env_base_files(root: str):
|
||||
os.makedirs(root, exist_ok=True)
|
||||
os.mkdir(f"{root}/var")
|
||||
os.mkdir(f"{root}/var/tmp")
|
||||
os.mkdir(f"{root}/var/run")
|
||||
os.mkdir(f"{root}/tmp")
|
||||
os.mkdir(f"{root}/run")
|
||||
os.makedirs(f"{root}/var/db/packie")
|
||||
shutil.copytree("/var/config/packie/repos.d", f"{root}/var/config/packie/repos.d")
|
||||
os.mkdir(f"{root}/dev")
|
||||
os.mkdir(f"{root}/sys")
|
||||
os.mkdir(f"{root}/proc")
|
||||
os.makedirs(f"{root}/home/root")
|
||||
|
||||
|
||||
def prepare_build_env(root: str, extreq: list[str] = []):
|
||||
# Skip if the environment is already initialized
|
||||
if os.path.exists(f"{root}/.INIT"):
|
||||
return
|
||||
try:
|
||||
shutil.rmtree(root)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Prepare basic filesystem hierarchy
|
||||
_prepare_build_env_base_files(root)
|
||||
|
||||
# Install packages
|
||||
packie.chroot_update(root)
|
||||
packie.chroot_install(root, BASE_REQUIREMENTS + extreq)
|
||||
|
||||
# Refresh certificates
|
||||
enter_build_env(root, ["certutil", "refresh"])
|
||||
|
||||
# Copy DNS config
|
||||
os.makedirs(f"{root}/etc", exist_ok=True)
|
||||
shutil.copy2("/etc/resolv.conf", f"{root}/etc/resolv.conf")
|
||||
|
||||
# Create initialized tag
|
||||
with open(f"{root}/.INIT", "wt+") as file:
|
||||
file.write("OK")
|
||||
|
||||
|
||||
def enter_build_env(root: str, cmd: list[str], chdir: str = "/"):
|
||||
subprocess.run(
|
||||
[
|
||||
"bwrap",
|
||||
"--bind",
|
||||
root,
|
||||
"/",
|
||||
"--unshare-pid",
|
||||
"--unshare-user",
|
||||
"--uid",
|
||||
"0",
|
||||
"--gid",
|
||||
"0",
|
||||
"--dev",
|
||||
"/dev",
|
||||
"--bind",
|
||||
"/sys",
|
||||
"/sys",
|
||||
"--proc",
|
||||
"/proc",
|
||||
"--clearenv",
|
||||
"--setenv",
|
||||
"HOME",
|
||||
"/home/root",
|
||||
"--setenv",
|
||||
"PATH",
|
||||
"/bin",
|
||||
"--setenv",
|
||||
"SEMIOS_PKGBUILD_IN_ATOMIC",
|
||||
"1",
|
||||
"--chdir",
|
||||
chdir,
|
||||
]
|
||||
+ cmd
|
||||
)
|
||||
|
||||
|
||||
def copy_pkgbuild_tree(repo_root: str, pkgname: str, build_env_root: str):
|
||||
build_dir = f"{build_env_root}/Atom"
|
||||
if os.path.exists(build_dir):
|
||||
return
|
||||
os.mkdir(build_dir)
|
||||
shutil.copytree(f"{repo_root}/hooks", f"{build_dir}/hooks")
|
||||
shutil.copytree(f"{repo_root}/lib", f"{build_dir}/lib")
|
||||
shutil.copy2(f"{repo_root}/x", f"{build_dir}/x")
|
||||
shutil.copy2(f"{repo_root}/x.py", f"{build_dir}/x.py")
|
||||
os.makedirs(f"{build_dir}/packages/{pkgname}")
|
||||
for i in os.listdir(f"{repo_root}/packages/{pkgname}"):
|
||||
srcpath = f"{repo_root}/packages/{pkgname}/{i}"
|
||||
dstpath = f"{build_dir}/packages/{pkgname}/{i}"
|
||||
if i in ["target", "__pycache__"]:
|
||||
continue
|
||||
if os.path.isdir(srcpath):
|
||||
shutil.copytree(srcpath, dstpath)
|
||||
elif os.path.isfile(srcpath):
|
||||
shutil.copy2(srcpath, dstpath)
|
||||
@@ -24,9 +24,16 @@ _pkginfo: dict[str, dict[str, typing.Any]] = {
|
||||
_supported_arch: typing.Callable[[str], bool] = lambda x: True
|
||||
_on_build: typing.Callable[[], None] | None = None
|
||||
|
||||
_builddep: list[str] = []
|
||||
|
||||
_blocked_hooks: list[str] = []
|
||||
|
||||
|
||||
def builddep(s: str):
|
||||
global _builddep
|
||||
_builddep += [s]
|
||||
|
||||
|
||||
def package(s: str):
|
||||
global _current_pkgname
|
||||
_current_pkgname = s
|
||||
|
||||
+22
-2
@@ -1,11 +1,31 @@
|
||||
import subprocess
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
PACKIE_EXEC = os.getenv("PACKIE", "packie")
|
||||
|
||||
|
||||
def host_arch() -> str:
|
||||
result = subprocess.run(
|
||||
[PACKIE_EXEC, "print", "profile.host_arch"],
|
||||
check=True, capture_output=True,
|
||||
check=True,
|
||||
capture_output=True,
|
||||
)
|
||||
return result.stdout.decode().strip()
|
||||
|
||||
|
||||
def chroot_update(root: str):
|
||||
subprocess.run([PACKIE_EXEC, "--chroot", root, "update"], check=True)
|
||||
|
||||
|
||||
def chroot_install(root: str, requirements: list[str]):
|
||||
subprocess.run(
|
||||
[PACKIE_EXEC, "--chroot", root, "install", "--yes"] + requirements, check=True
|
||||
)
|
||||
|
||||
|
||||
def update():
|
||||
subprocess.run([PACKIE_EXEC, "update"], check=True)
|
||||
|
||||
|
||||
def install(requirements: list[str]):
|
||||
subprocess.run([PACKIE_EXEC, "install", "--yes"] + requirements, check=True)
|
||||
|
||||
@@ -2,10 +2,12 @@ import lib.arch as arch
|
||||
from lib.cpp import *
|
||||
from lib.make import *
|
||||
|
||||
|
||||
version("1.2.6")
|
||||
source_url("https://gitea.semilabs.org/semios/semi-libc/archive/v1.2.6.tar.gz")
|
||||
|
||||
builddep("clang")
|
||||
|
||||
|
||||
def build():
|
||||
configure(["--prefix=/"])
|
||||
make()
|
||||
|
||||
@@ -7,7 +7,9 @@ import typing
|
||||
|
||||
import hooks
|
||||
import lib.arch
|
||||
import lib.atombuild
|
||||
import lib.make
|
||||
import lib.packie
|
||||
import lib.pkgcomposer
|
||||
import lib.sources
|
||||
|
||||
@@ -20,6 +22,7 @@ argparser = argparse.ArgumentParser(
|
||||
argparser.add_argument(
|
||||
"--target", type=str, help="Target architecture to build the package for"
|
||||
)
|
||||
argparser.add_argument("--atombuild", action="store_true", help="Enable Atom Build")
|
||||
subparsers = argparser.add_subparsers(dest="subcommand")
|
||||
parser_build = subparsers.add_parser("build")
|
||||
parser_build.add_argument("BUILD_PKGNAME")
|
||||
@@ -64,6 +67,9 @@ def run_build_package(package: str):
|
||||
print(f"Architecture {lib.arch.get_target()} is not supported for this package")
|
||||
exit(1)
|
||||
|
||||
if os.environ.get("SEMIOS_PKGBUILD_IN_ATOMIC", "0") == "1":
|
||||
lib.packie.install(lib.make._builddep)
|
||||
|
||||
# Run `pre_build` hooks
|
||||
run_hooks(hooks.pre_build)
|
||||
|
||||
@@ -151,8 +157,38 @@ def run_list(item):
|
||||
print(i)
|
||||
|
||||
|
||||
def run_build_atom(pkgname: str):
|
||||
# Declare necessary paths
|
||||
repo_root = os.getcwd()
|
||||
package_dir = f"{repo_root}/packages/{pkgname}"
|
||||
target_dir = f"{package_dir}/target"
|
||||
build_env_root = f"{target_dir}/atombuild_root"
|
||||
|
||||
# Read `pkgbuild.py` of that package
|
||||
try:
|
||||
os.chdir(package_dir)
|
||||
os.makedirs(target_dir, exist_ok=True)
|
||||
except Exception:
|
||||
print(f"No such package {pkgname}")
|
||||
exit(1)
|
||||
importlib.import_module(f"packages.{pkgname}.pkgbuild")
|
||||
os.chdir(repo_root)
|
||||
|
||||
# Initialize build environment
|
||||
lib.atombuild.prepare_build_env(build_env_root, lib.make._builddep)
|
||||
lib.atombuild.copy_pkgbuild_tree(repo_root, pkgname, build_env_root)
|
||||
lib.atombuild.enter_build_env(
|
||||
build_env_root,
|
||||
["./x", "--target", lib.arch.get_target(), "build", pkgname],
|
||||
chdir="/Atom",
|
||||
)
|
||||
|
||||
|
||||
if args.subcommand == "build":
|
||||
run_build_package(args.BUILD_PKGNAME)
|
||||
if args.atombuild:
|
||||
run_build_atom(args.BUILD_PKGNAME)
|
||||
else:
|
||||
run_build_package(args.BUILD_PKGNAME)
|
||||
elif args.subcommand == "clean":
|
||||
run_clean_package(args.CLEAN_PKGNAME)
|
||||
elif args.subcommand == "list":
|
||||
|
||||
Reference in New Issue
Block a user