152 lines
6.4 KiB
Python
Executable file
152 lines
6.4 KiB
Python
Executable file
#!/usr/bin/python3 -u
|
|
from pathlib import Path
|
|
import glob
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
|
|
if len(sys.argv) < 2:
|
|
raise ValueError('wrong number of arguments')
|
|
|
|
project_path = sys.argv[1] + '/'
|
|
project_name = project_path.rsplit('/')[-2]
|
|
|
|
isoc_file = project_path + 'build/isoc/MuJS.ISO.C'
|
|
redsea_path = project_path + 'build/redsea'
|
|
|
|
home_path = str(Path.home()) + '/'
|
|
|
|
qemu_slipstream_iso_file = project_path + 'build/isoc/bootable.iso'
|
|
|
|
qemu_bin_path = "qemu-system-x86_64"
|
|
qemu_display = "-display sdl,grab-mod=rctrl"
|
|
|
|
templeos_iso_file = home_path + 'iso/TempleOS.ISO'
|
|
|
|
qemu_run_cmd = qemu_bin_path + ' ' + qemu_display + ' -enable-kvm -m 1024 -cdrom ' + qemu_slipstream_iso_file + ' -audiodev pa,id=snd0 -machine pcspk-audiodev=snd0 -debugcon stdio -boot d'
|
|
|
|
def clang_format_src_files():
|
|
print("build-all: clang-format-src-files")
|
|
exclude_paths = ["mujs", "openlibm", ".iso.c"]
|
|
format_file_extensions = [".c", ".cpp", ".h", ".hc"]
|
|
for src_file in glob.glob(project_path + "**", recursive=True):
|
|
exclude_file = False
|
|
for exclude_path in exclude_paths:
|
|
if src_file.lower().find(exclude_path) > 0:
|
|
exclude_file = True
|
|
if exclude_file:
|
|
continue
|
|
for format_file_extension in format_file_extensions:
|
|
if src_file.lower().endswith(format_file_extension):
|
|
print(src_file)
|
|
res = os.system('clang-format -i --style=file:' + project_path + '.clang-format ' + src_file)
|
|
if res:
|
|
raise ValueError("build-all: step 'clang-format-src-files' failed, error code " + str(res))
|
|
|
|
def refresh_build_path():
|
|
print("build-all: refresh-build-path")
|
|
res = os.system('rm -rf ' + project_path + 'build && mkdir -p ' + project_path + 'build/bin && mkdir -p ' + project_path + 'build/isoc && mkdir -p ' + project_path + 'build/lib && mkdir -p ' + project_path + 'build/redsea')
|
|
if res:
|
|
raise ValueError("build-all: step 'refresh-build-path' failed, error code " + str(res))
|
|
|
|
def build_image():
|
|
print("build-all: build-image")
|
|
build_specific_options = '-Wl,--section-start=.text=0x1004000 -Wl,--section-start=.plt=0x1002020 -no-pie'
|
|
res = os.system('cd ' + project_path + '&& cd src/image && gcc -o ../../build/bin/image ' + build_specific_options + ' -O0 -mno-mmx -mno-red-zone image.c')
|
|
if res:
|
|
raise ValueError("build-all: step 'build-image' failed, error code " + str(res))
|
|
|
|
def build_libtemple():
|
|
print("build-all: build-libtemple")
|
|
res = os.system('cd ' + project_path + 'src/libtemple && gcc -c -o ../../build/libtemple.o libtemple.c && gcc -shared -o ../../build/lib/libtemple.so ../../build/libtemple.o && rm ' + project_path + 'build/libtemple.o')
|
|
if res:
|
|
raise ValueError("build-all: step 'build-libtemple' failed, error code " + str(res))
|
|
|
|
def build_openlibm():
|
|
print("build-all: build-openlibm")
|
|
res = os.system('cd ' + project_path + '&& cd src/openlibm && make clean && make ARCH=amd64')
|
|
if res:
|
|
raise ValueError("build-all: step 'build-image' failed, error code " + str(res))
|
|
|
|
def build_mujs():
|
|
print("build-all: build-mujs")
|
|
#build_specific_options = '-Wl,--section-start=.text=0x1004000 -Wl,--section-start=.plt=0x1002020 -no-pie'
|
|
res = os.system('cd ' + project_path + '&& cd src/mujs && rm -f one.c && make && cp build/debug/mujs ../../build/bin/mujs')
|
|
if res:
|
|
raise ValueError("build-all: step 'build-mujs' failed, error code " + str(res))
|
|
|
|
def address_string_for_symbol(file, symbol):
|
|
p = subprocess.Popen('readelf -s --wide "' + file + '" | grep \'' + symbol + '$\' | awk \'{sub("000000000", "0x", $2); print $2}\'', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
return str(p.communicate()[0][:-1].decode(encoding='utf-8'))
|
|
|
|
def hc_fixup(macro, symbol, bin_path, hc_path):
|
|
os.system('echo -e "#define ' + macro + ' ' + address_string_for_symbol(bin_path, symbol) + '\n" | cat - ' + hc_path + ' | sponge ' + hc_path)
|
|
return
|
|
|
|
def exit_address_for_bin(file):
|
|
p = subprocess.Popen('objdump -d "' + file + '" | grep exit@plt\\>: | awk \'{sub("000000000", "0x", $1); print $1}\'', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
|
return str(p.communicate()[0][:-1].decode(encoding='utf-8'))
|
|
|
|
def exit_fixup(bin_path, hc_path):
|
|
os.system('echo -e "#define MUJS_EXIT ' + exit_address_for_bin(bin_path) + '\n" | cat - ' + hc_path + ' | sponge ' + hc_path)
|
|
|
|
def generate_iso_c_file():
|
|
print("build-all: generate-iso-c-file")
|
|
step_error_message = "build-all: step 'generate-iso-c-file' failed, error code "
|
|
|
|
res = os.system('isoc-mount --rw ' + isoc_file + ' ' + redsea_path)
|
|
if res:
|
|
raise ValueError(step_error_message + str(res))
|
|
time.sleep(0.25)
|
|
|
|
copy_files_cmd_line = 'rsync -av --inplace --progress ' + project_path + ' ' + redsea_path
|
|
copy_files_cmd_line += ' --exclude .clang-format'
|
|
copy_files_cmd_line += ' --exclude .git'
|
|
copy_files_cmd_line += ' --exclude .gitignore'
|
|
copy_files_cmd_line += ' --exclude build/isoc'
|
|
copy_files_cmd_line += ' --exclude build/lib'
|
|
copy_files_cmd_line += ' --exclude build/redsea'
|
|
copy_files_cmd_line += ' --exclude scripts'
|
|
copy_files_cmd_line += ' --exclude src'
|
|
res = os.system(copy_files_cmd_line)
|
|
if res:
|
|
raise ValueError(step_error_message + str(res))
|
|
|
|
# Fixup addresses for MuJS
|
|
mujs_bin_path = redsea_path + '/build/bin/mujs'
|
|
mujs_hc_path = redsea_path + '/MuJS.HC'
|
|
|
|
hc_fixup('MUJS_MAIN', 'main', mujs_bin_path, mujs_hc_path)
|
|
exit_fixup(mujs_bin_path, mujs_hc_path)
|
|
|
|
time.sleep(0.25)
|
|
|
|
res = os.system('sync && fusermount -u ' + redsea_path)
|
|
if res:
|
|
raise ValueError(step_error_message + str(res))
|
|
time.sleep(0.25)
|
|
|
|
def generate_slipstream_iso_file():
|
|
print("build-all: generate-slipstream-iso-file")
|
|
res = os.system('templeos-slipstream ' + templeos_iso_file + ' ' + isoc_file + ' ' + qemu_slipstream_iso_file)
|
|
if res:
|
|
raise ValueError("build-all: step 'generate-slipstream-iso-file' failed, error code " + str(res))
|
|
|
|
def run():
|
|
print("build-all: run")
|
|
res = os.system(qemu_run_cmd)
|
|
if res:
|
|
raise ValueError("build-all: step 'run' failed, error code " + str(res))
|
|
|
|
def build_all():
|
|
clang_format_src_files()
|
|
refresh_build_path()
|
|
build_libtemple()
|
|
build_openlibm()
|
|
build_mujs()
|
|
generate_iso_c_file()
|
|
generate_slipstream_iso_file()
|
|
run()
|
|
|
|
build_all()
|