2023-07-26 22:17:57 +00:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
2023-08-26 05:52:59 +00:00
|
|
|
import argparse
|
2023-08-25 09:18:28 +00:00
|
|
|
import importlib
|
2023-07-26 22:17:57 +00:00
|
|
|
import platform # Checking current OS
|
|
|
|
import os
|
|
|
|
import sys
|
2023-08-01 23:34:37 +00:00
|
|
|
import re
|
2023-08-26 05:52:59 +00:00
|
|
|
|
|
|
|
arg_parser = argparse.ArgumentParser(description="Build ciabatta", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
|
|
arg_parser.add_argument("-t", "--test", help="Specify a file to compile with ciabatta")
|
2023-08-26 06:08:46 +00:00
|
|
|
arg_parser.add_argument("-m", "--mode", help="Specify mode (release, debug)")
|
|
|
|
arg_parser.add_argument("--ld", action="store_true", help="Enable loader debugging (only works with --mode debug)")
|
2023-08-26 05:52:59 +00:00
|
|
|
args = vars(arg_parser.parse_args())
|
2023-07-26 22:17:57 +00:00
|
|
|
|
2023-08-26 05:52:59 +00:00
|
|
|
test_file = args['test']
|
2023-08-26 06:08:46 +00:00
|
|
|
build_mode = args['mode']
|
|
|
|
loader_debugging_enabled = args['ld']
|
|
|
|
|
|
|
|
if build_mode == None:
|
|
|
|
build_mode = 'debug'
|
2023-08-25 09:18:28 +00:00
|
|
|
|
2023-07-30 22:43:01 +00:00
|
|
|
class colors:
|
2023-08-01 23:34:37 +00:00
|
|
|
grey='\033[38;5;243m'
|
2023-07-30 22:43:01 +00:00
|
|
|
cyan='\033[38;5;80m'
|
|
|
|
red='\033[38;5;196m'
|
2023-08-01 23:34:37 +00:00
|
|
|
purple='\033[38;5;141m'
|
|
|
|
yellow='\033[38;5;220m'
|
2023-07-30 22:43:01 +00:00
|
|
|
green='\033[32m'
|
|
|
|
reset='\033[0m'
|
2023-07-26 22:17:57 +00:00
|
|
|
|
2023-08-01 23:34:37 +00:00
|
|
|
def print_step(step):
|
|
|
|
print(f'{colors.green}==>{colors.reset} {step}', end='')
|
|
|
|
|
|
|
|
def path(str):
|
|
|
|
l = str.split('/')
|
|
|
|
return os.path.join(*l)
|
2023-08-25 09:18:28 +00:00
|
|
|
|
2023-07-26 22:17:57 +00:00
|
|
|
def quote(s):
|
|
|
|
return '"' + s + '"'
|
2023-08-25 09:18:28 +00:00
|
|
|
|
2023-07-26 22:17:57 +00:00
|
|
|
def prefix(prefix):
|
|
|
|
return (lambda s: prefix + s)
|
|
|
|
|
2023-08-01 23:34:37 +00:00
|
|
|
def run(cmdline):
|
|
|
|
cmdline_colored = re.sub(r'"(.+?)"', f'{colors.grey}"\\1"{colors.reset}', cmdline)
|
|
|
|
cmdline_colored = re.sub(r'^([a-zA-Z0-9-_]*)', f'{colors.yellow}\\1{colors.reset}', cmdline_colored)
|
|
|
|
print(' $', cmdline_colored)
|
|
|
|
code = os.system(cmdline)
|
|
|
|
if code != 0:
|
|
|
|
sys.exit(code)
|
|
|
|
|
2023-08-25 09:18:28 +00:00
|
|
|
cc_flags = []
|
|
|
|
cc_defines = []
|
|
|
|
cc_includes = []
|
|
|
|
|
2023-08-26 06:08:46 +00:00
|
|
|
cc_flags_stack = []
|
|
|
|
def cc_flags_push():
|
|
|
|
global cc_flags
|
|
|
|
global cc_flags_stack
|
|
|
|
cc_flags_stack.append(cc_flags)
|
|
|
|
cc_flags = cc_flags.copy()
|
|
|
|
def cc_flags_pop():
|
|
|
|
global cc_flags
|
|
|
|
global cc_flags_stack
|
|
|
|
cc_flags = cc_flags_stack.pop()
|
|
|
|
|
|
|
|
cc_defines_stack = []
|
|
|
|
def cc_defines_push():
|
|
|
|
global cc_defines
|
|
|
|
global cc_defines_stack
|
|
|
|
cc_defines_stack.append(cc_defines)
|
|
|
|
cc_defines = cc_defines.copy()
|
|
|
|
def cc_defines_pop():
|
|
|
|
global cc_defines
|
|
|
|
global cc_defines_stack
|
|
|
|
cc_defines = cc_defines_stack.pop()
|
|
|
|
|
2023-08-25 09:18:28 +00:00
|
|
|
def compile(output, inputs, additional_flags=[]):
|
|
|
|
flags_cmdline = ' '.join(cc_flags + additional_flags)
|
|
|
|
defines_cmdline = ' '.join(map(prefix('-D '), map(quote, cc_defines)))
|
|
|
|
includes_cmdline = ' '.join(map(prefix('-I '), map(quote, cc_includes)))
|
|
|
|
inputs_cmdline = ' '.join(inputs)
|
|
|
|
cmdline = f'clang {flags_cmdline} {includes_cmdline} {defines_cmdline} {inputs_cmdline} -o {output}'
|
2023-08-01 23:34:37 +00:00
|
|
|
run(cmdline)
|
2023-07-26 22:17:57 +00:00
|
|
|
|
2023-08-25 09:18:28 +00:00
|
|
|
def compile_obj(output, inputs, additional_flags=[]):
|
|
|
|
compile(output, inputs, ['-c -fpic'] + additional_flags)
|
|
|
|
|
|
|
|
def compile_exe(output, inputs, additional_flags=[]):
|
2023-09-04 07:52:58 +00:00
|
|
|
compile(output, inputs, ['-pie', '-fPIE'] + additional_flags)
|
2023-08-25 09:18:28 +00:00
|
|
|
|
|
|
|
def compile_shared(output, inputs, additional_flags=[]):
|
|
|
|
compile(output, inputs, ['-shared'] + additional_flags)
|
|
|
|
|
|
|
|
def assemble_obj(output, inputs, flags=[]):
|
|
|
|
flags_cmdline = ' '.join(flags)
|
|
|
|
inputs_cmdline = ' '.join(inputs)
|
|
|
|
cmdline = f'nasm {flags_cmdline} {inputs_cmdline} -o {output}'
|
2023-08-01 23:34:37 +00:00
|
|
|
run(cmdline)
|
2023-07-26 22:17:57 +00:00
|
|
|
|
2023-08-25 09:18:28 +00:00
|
|
|
def archive(output, inputs):
|
|
|
|
inputs_cmdline = ' '.join(inputs)
|
|
|
|
cmdline = f'llvm-ar -rcs {output} {inputs_cmdline}'
|
2023-08-01 23:34:37 +00:00
|
|
|
run(cmdline)
|
2023-07-26 22:17:57 +00:00
|
|
|
|
|
|
|
# Ciabatta build spec
|
|
|
|
if not os.path.exists('lib'):
|
|
|
|
os.mkdir('lib')
|
|
|
|
if not os.path.exists('bin'):
|
|
|
|
os.mkdir('bin')
|
|
|
|
|
2023-09-02 00:47:40 +00:00
|
|
|
if platform.system().lower() == 'windows':
|
|
|
|
sys.exit(1);
|
|
|
|
|
2023-08-25 23:36:26 +00:00
|
|
|
target_abi = 'sysv'
|
2023-08-25 09:18:28 +00:00
|
|
|
target_arch = 'x86-64'
|
|
|
|
target_os = 'linux'
|
|
|
|
|
|
|
|
cc_defines.append(f'_CIA_OS_CONF=\\"os/{target_os}/conf.h\\"')
|
2023-09-02 00:45:00 +00:00
|
|
|
cc_flags.extend(['-nostdlib'])
|
2023-08-26 06:08:46 +00:00
|
|
|
|
|
|
|
if build_mode == 'debug':
|
|
|
|
cc_flags.extend(['-g', '-O0'])
|
|
|
|
cc_defines.append('_DEBUG')
|
|
|
|
elif build_mode == 'release':
|
|
|
|
cc_flags.extend(['-O3'])
|
|
|
|
cc_defines.append('NDEBUG')
|
2023-08-25 09:18:28 +00:00
|
|
|
|
|
|
|
cc_includes.append('include')
|
|
|
|
cc_includes.append('include/linux')
|
2023-07-28 08:53:06 +00:00
|
|
|
|
2023-08-25 09:18:28 +00:00
|
|
|
# Build the dynamic loader
|
2023-08-26 06:08:46 +00:00
|
|
|
cc_flags_push()
|
|
|
|
cc_defines_push()
|
|
|
|
cc_flags.extend([
|
2023-09-04 07:52:58 +00:00
|
|
|
'-fPIC',
|
2023-09-02 00:45:00 +00:00
|
|
|
'-fno-stack-protector',
|
2023-08-26 06:11:12 +00:00
|
|
|
'-fno-builtin',
|
2023-08-25 23:36:26 +00:00
|
|
|
'-Wl,-e,_dlstart',
|
|
|
|
'-Wl,--sort-section,alignment',
|
|
|
|
'-Wl,--sort-common',
|
|
|
|
'-Wl,--gc-sections',
|
|
|
|
'-Wl,--hash-style=both',
|
|
|
|
'-Wl,--no-undefined',
|
|
|
|
'-Wl,--exclude-libs=ALL'
|
2023-08-26 06:08:46 +00:00
|
|
|
])
|
|
|
|
if loader_debugging_enabled:
|
|
|
|
cc_defines.append('_CIA_LD_DEBUG')
|
2023-08-25 09:18:28 +00:00
|
|
|
print_step("Building lib/ld-cia.so\n")
|
2023-08-25 23:36:26 +00:00
|
|
|
assemble_obj('bin/loader-entry.o', [f'arch/{target_abi}_{target_arch}/loader-entry.asm'], ['-f "elf64"'])
|
2023-08-30 08:52:29 +00:00
|
|
|
assemble_obj('bin/loader-trampoline.o', [f'arch/{target_abi}_{target_arch}/loader-trampoline.asm'], ['-f "elf64"'])
|
|
|
|
compile_shared('lib/ld-cia.so', ['bin/loader-entry.o','loader/loader-self-reloc.c','loader/loader.c','bin/loader-trampoline.o'])
|
2023-08-26 06:08:46 +00:00
|
|
|
cc_defines_pop()
|
|
|
|
cc_flags_pop()
|
2023-08-01 23:34:37 +00:00
|
|
|
|
2023-08-25 09:18:28 +00:00
|
|
|
# Build the ciabatta
|
2023-09-12 10:07:02 +00:00
|
|
|
cc_flags_push()
|
|
|
|
cc_flags.append('-Wno-format'); # until i find way to disable clang warning on %I64d
|
2023-08-25 23:36:26 +00:00
|
|
|
print_step("Building lib/cia.a\n")
|
|
|
|
assemble_obj('bin/thread-entry.o', [f'arch/{target_abi}_{target_arch}/thread-entry.asm'], ['-f "elf64"'])
|
2023-08-25 09:18:28 +00:00
|
|
|
compile_obj('bin/cia.o', ['cia.c'])
|
2023-08-25 23:36:26 +00:00
|
|
|
archive('lib/cia.a', ['bin/cia.o', 'bin/thread-entry.o'])
|
2023-07-26 22:17:57 +00:00
|
|
|
|
2023-08-25 09:18:28 +00:00
|
|
|
# Build the test
|
2023-08-26 05:52:59 +00:00
|
|
|
if test_file != None:
|
|
|
|
compile_exe('a', [test_file, 'lib/cia.a'], ['-Wl,-dynamic-linker,lib/ld-cia.so'])
|
2023-09-12 10:07:02 +00:00
|
|
|
|
|
|
|
cc_flags_pop()
|