ninja_required_version = 1.3
builddir = {{ buildroot }}
srcroot = {{ srcroot }}
modulefile = {{ modulefile }}

{%- for var, value in vars %}
{{ var }} = {{ value }}
{%- endfor %}

warnflags = $
    -Wformat=2 $
    -Winit-self $
    -Wfloat-equal $
    -Winline $
    -Wmissing-format-attribute $
    -Wmissing-include-dirs $
    -Wswitch $
    -Wundef $
    -Wdisabled-optimization $
    -Wpointer-arith $
    -Wno-attributes $
    -Wno-sign-compare $
    -Wno-multichar $
    -Wno-div-by-zero $
    -Wno-endif-labels $
    -Wno-pragmas $
    -Wno-format-extra-args $
    -Wno-unused-result $
    -Wno-deprecated-declarations $
    -Wno-unused-function $
    -Wno-address-of-packed-member $
    -Werror

ccflags = $
    -I${srcroot}/src/include $
    -I${srcroot}/src/include/x86_64 $
    -fcolor-diagnostics $
    -DVERSION_MAJOR={{ version_major }} $
    -DVERSION_MINOR={{ version_minor }} $
    -DVERSION_PATCH={{ version_patch }} $
    -DVERSION_GITSHA=0x0{{ version_sha }} $
    -DGIT_VERSION=\"{{ version }}\" $
    -DGIT_VERSION_WIDE=L\"{{ version }}\" $
    $warnflags

asflags = $
    -DVERSION_MAJOR={{ version_major }} $
    -DVERSION_MINOR={{ version_minor }} $
    -DVERSION_PATCH={{ version_patch }} $
    -DVERSION_GITSHA=0x{{ version_sha }} $
    -I${srcroot}/src/include

cflags = -std=c11
cxxflags = -std=c++17
libs =

rule c
    deps = gcc
    depfile = $out.d
    description = Compiling $name
    command = $cc -MMD -MF $out.d $ccflags $cflags -o $out -c $in

rule dump_c_defs
    description = Dumping C defines for $target
    command = echo "" | $cc $ccflags $cflags -dM -E - > $out

rule dump_c_run
    description = Dumping C arguments for $target
    command = $
        echo "#!/bin/bash" > $out; $
        echo '$cc $ccflags $cflags $$*' >> $out; $
        chmod a+x $out

rule cpp
    deps = gcc
    depfile = $out.d
    description = Compiling $name
    command = $cxx -MMD -MF $out.d $cxxflags $ccflags -o $out -c $in

rule dump_cpp_defs
    description = Dumping C++ defines for $target
    command = echo "" | $cxx -x c++ $cxxflags $ccflags -dM -E - > $out

rule dump_cpp_run
    description = Dumping C++ arguments for $target
    command = $
        echo "#!/bin/bash" > $out; $
        echo '$cc $cxxflags $ccflags $$*' >> $out; $
        chmod a+x $out

rule s
    deps = gcc
    depfile = $out.d
    description = Assembling $name
    command = $nasm -o $out -felf64 -MD $out.d $asflags $in

rule exe
    description = Linking $name
    command = $ld $ldflags -o $out $in $libs

rule lib
    description = Archiving $name
    command = $ar qcs $out $in

rule regen
    generator = true
    description = Regenrating build files
    command = $
        {{ generator }} $
        --file $modulefile $
        --dir $builddir $
        generate

rule cp
    description = Copying $name
    command = cp $in $out

rule dump
    description = Dumping decompiled $name
    command = objdump -DSC -M intel $in > $out

rule makest
    description = Making symbol table
    command = nm $in | ${srcroot}/scripts/build_symbol_table.py $out

rule makeefi
    description = Converting $name
    command = objcopy $
        -j .text $
        -j .sdata $
        -j .data $
        -j .dynamic $
        -j .dynsym $
        -j .rel $
        -j .rela $
        -j .reloc $
        --target=efi-app-x86_64 $
        $in $out

rule makefat
    description = Creating $name
    command = $
        cp $srcroot/assets/diskbase.img $out; $
        mcopy -s -D o -i $out@@1M $builddir/fatroot/* ::/

rule strip
    description = Stripping $name
    command = $
        cp $in $out; $
        objcopy --only-keep-debug $out $out.debug; $
        strip -g $out; $
        objcopy --add-gnu-debuglink=$out.debug $out

{% for target in targets %}
subninja {{ target }}/target.ninja
{% endfor %}

build $
    {%- for buildfile in buildfiles %}
    {{ buildfile }} $
    {%- endfor %}
    : regen | $
    {%- for template in templates %}
    {{ template }} $
    {%- endfor %}
    $modulefile $
    {{ generator }}

build $builddir/ovmf_vars.fd : cp $srcroot/assets/ovmf/x64/ovmf_vars.fd
    name = ovmf_vars.fd

build $builddir/ovmf_vars_d.fd : cp $srcroot/assets/ovmf/x64/ovmf_vars_d.fd
    name = ovmf_vars_d.fd

build $builddir/jsix.elf | $builddir/jsix.elf.debug : strip $builddir/host/jsix.elf
    name = kernel

build $builddir/jsix.dump : dump $builddir/host/jsix.elf
    name = kernel

build $builddir/jsix.elf-gdb.py : cp ${srcroot}/assets/debugging/jsix.elf-gdb.py
    name = kernel debug python scripts

build $builddir/fatroot/jsix.elf : cp $builddir/jsix.elf
    name = kernel to FAT image

build $builddir/fatroot/efi/boot/bootx64.efi : cp $builddir/boot/boot.efi
    name = bootloader to FAT image

build $builddir/fatroot/nulldrv.elf : cp $builddir/user/nulldrv.elf
    name = null driver to FAT image

build $builddir/fatroot/fb.elf : cp $builddir/user/fb.elf
    name = fb driver to FAT image

build ${builddir}/fatroot/symbol_table.dat : makest ${builddir}/jsix.elf

build $builddir/jsix.img : makefat | $
    $builddir/fatroot/symbol_table.dat $
    $builddir/fatroot/nulldrv.elf $
    $builddir/fatroot/fb.elf $
    $builddir/fatroot/jsix.elf $
    $builddir/fatroot/efi/boot/bootx64.efi
    name = jsix.img

default $
    $builddir/ovmf_vars.fd $
    $builddir/ovmf_vars_d.fd $
    $builddir/jsix.dump $
    $builddir/jsix.elf-gdb.py $
    $builddir/jsix.img

# vim: ft=ninja et ts=4 sts=4 sw=4

