20from pathlib
import Path
21from concurrent.futures
import ThreadPoolExecutor, as_completed
31 os.chdir(Path(__file__).resolve().parents[1])
32 print(
"Working from:", os.getcwd())
34 obj =
"objs/" + file.replace(
".asm",
".o")
35 src_time = os.path.getmtime(file)
36 obj_time = os.path.getmtime(obj)
if os.path.exists(obj)
else -1
38 if src_time <= obj_time:
41 print(f
"Assembling {file}")
43 subprocess.run([AS, *ASFLAGS, file,
"-o", obj], check=
True)
44 except subprocess.CalledProcessError
as e:
45 print(f
"Failed with code {e.returncode}", file=sys.stderr)
54 obj =
"objs/" + file.replace(
".c",
".o")
55 src_time = os.path.getmtime(file)
56 obj_time = os.path.getmtime(obj)
if os.path.exists(obj)
else -1
58 if src_time <= obj_time:
61 print(f
"Compiling {file}")
63 subprocess.run([CC, *CCFLAGS,
"-c", file,
"-o", obj], check=
True)
64 return f
"Compiled {file}"
65 except subprocess.CalledProcessError
as e:
66 return f
"Failed {file} with code {e.returncode}"
74 os.chdir(Path(__file__).resolve().parents[1])
75 print(
"Working from:", os.getcwd())
77 with ThreadPoolExecutor(max_workers=8)
as executor:
78 futures = {executor.submit(compile_file, f): f
for f
in SRCS}
80 for future
in as_completed(futures):
81 result = future.result()
82 if result.startswith(
"Failed"):
83 print(result, file=sys.stderr)
96 os.chdir(Path(__file__).resolve().parents[1])
97 os.makedirs(
"objs/modules", exist_ok=
True)
99 for modname, files
in MODULES.items():
100 obj_files = [f
"objs/{src.replace('.c', '.o')}" for src
in files]
101 output = f
"objs/modules/{modname}.o"
103 if os.path.exists(output):
104 out_time = os.path.getmtime(output)
105 if all(os.path.exists(f)
and os.path.getmtime(f) <= out_time
for f
in obj_files):
106 print(f
"Module {modname} is up to date")
109 print(f
"Linking module: {modname}")
111 subprocess.run([
"i686-elf-ld",
"-r",
"-o", output, *obj_files], check=
True)
112 except subprocess.CalledProcessError
as e:
113 print(f
"Error linking module {modname}: {e}", file=sys.stderr)
122 os.chdir(Path(__file__).resolve().parents[1])
123 print(
"Working from:", os.getcwd())
125 if os.path.exists(OUT):
126 out_time = os.path.getmtime(OUT)
127 if all(os.path.exists(obj)
and os.path.getmtime(obj) <= out_time
for obj
in OBJS):
128 print(
"Kernel is up to date")
131 print(
"Linking kernel")
133 subprocess.run([
"i686-elf-ld", *LDFLAGS,
"-T",
"link.ld",
"-o", OUT, *OBJS], check=
True)
134 except subprocess.CalledProcessError
as e:
135 print(f
"Final link failed: {e}", file=sys.stderr)
144 os.chdir(Path(__file__).resolve().parents[1])
145 src_time = os.path.getmtime(
"kernel.elf")
146 obj_time = os.path.getmtime(ISO)
if os.path.exists(ISO)
else -1
147 if src_time <= obj_time:
150 print(
"Working from:", os.getcwd())
152 shutil.copy(GRUBCFG, GRUBCFGTARG)
153 shutil.copy(OUT, OUTARG)
155 [GRUB,
"-o", ISO,
"iso"],
156 stdout=subprocess.DEVNULL,
157 stderr=subprocess.DEVNULL
compilec()
Compiles all C sources in parallel from SRCS.
link()
Links the final kernel ELF binary from object files.
partial_link()
Performs partial linking on modules from MODULES.
compileasm()
Compiles all NASM assembly files in NASMSRCS.
iso()
Generates a bootable ISO using GRUB and kernel ELF.
compile_file(file)
Compile a single C file if out of date.