[build] Move to python build scripts per module

This change moves Bonnibel from a separate project into the jsix tree,
and alters the project configuration to be jsix-specific. (I stopped
using bonnibel for any other projects, so it's far easier to make it a
custom generator for jsix.) The build system now also uses actual python
code in `*.module` files to configure modules instead of TOML files.
Target configs (boot, kernel-mode, user-mode) now moved to separate TOML
files under `configs/` and can inherit from one another.
This commit is contained in:
Justin C. Miller
2021-08-26 01:47:58 -07:00
parent e19177d3ed
commit f79fe2e056
42 changed files with 1242 additions and 595 deletions

1
.gitignore vendored
View File

@@ -10,3 +10,4 @@ sysroot
.gdb_history .gdb_history
.peru .peru
__pycache__ __pycache__
/venv

View File

@@ -97,38 +97,52 @@ Major tasks still to do:
## Building ## Building
jsix uses the [Ninja][] build tool, and generates the build files for it with a jsix uses the [Ninja][] build tool, and generates the build files for it with
custom tool called [Bonnibel][]. The build also relies on a custom sysroot, the `configure` script. The build also relies on a custom sysroot, which can be
which can be downloaded via the [Peru][] tool, or built locally. downloaded via the [Peru][] tool, or built locally.
[Ninja]: https://ninja-build.org [Ninja]: https://ninja-build.org
[Bonnibel]: https://github.com/justinian/bonnibel [Peru]: https://github.com/buildinspace/peru
[Pery]: https://github.com/buildinspace/peru
Requrirements: Other build dependencies:
* Bonnibel * [clang][]: the C/C++ compiler
* ninja * [nasm][]: the assembler
* clang & lld * [lld][]: the linker
* nasm * [mtools][]: for creating the FAT image
* mtools * [curl][]: if using `peru` below to download the sysroot
* curl and Peru if downloading the toolchain
Both Bonnibel and Peru can be installed via `pip`: [clang]: https://clang.llvm.org
[nasm]: https://www.nasm.us
[lld]: https://lld.llvm.org
[mtools]: https://www.gnu.org/software/mtools/
[curl]: https://curl.se
```sh The `configure` script has some Python dependencies - these can be installed via
pip3 install --user -U bonnibel peru `pip`, though doing so in a python virtual environment is recommended.
Installing via `pip` will also install `ninja`.
A Debian 11 (Bullseye) system can be configured with the necessary build
dependencies by running the following commands from the jsix repository root:
```bash
sudo apt install clang lld nasm mtools python3-pip python3-venv
python3 -m venv ./venv
source venv/bin/activate
pip install -r requirements.txt
peru sync
``` ```
### Setting up the sysroot ### Setting up the sysroot
Running `peru sync` will download and unpack the toolchain into `sysroot`. Running `peru sync` as in the above section will download and unpack the
toolchain into `sysroot`.
#### Compiling the sysroot yourself #### Compiling the sysroot yourself
If you have CMake installed, runing the `scripts/build_sysroot.sh` If you have CMake installed, runing the `scripts/build_sysroot.sh` script will
script will download and build a LLVM toolchain configured for building the download and build a LLVM toolchain configured for building the sysroot, and
sysroot, and then build the sysroot with it. then build the sysroot with it.
Built sysroots are actually stored in `~/.local/lib/jsix/sysroots` and installed Built sysroots are actually stored in `~/.local/lib/jsix/sysroots` and installed
in the project dir via symbolic link, so having mulitple jsix working trees or in the project dir via symbolic link, so having mulitple jsix working trees or
@@ -136,22 +150,12 @@ switching sysroot versions is easy.
### Building and running jsix ### Building and running jsix
Once the toolchain has been set up, running Bonnibel's `pb init` command will Once the toolchain has been set up, running the `./configure` script (see
set up the build configuration, and `pb build` will actually run the build. If `./configure --help` for available options) will set up the build configuration,
you have `qemu-system-x86_64` installed, the `qemu.sh` script will to run jsix and `ninja -C build` (or wherever you put the build directory) will actually run
in QEMU `-nographic` mode. the build. If you have `qemu-system-x86_64` installed, the `qemu.sh` script will
to run jsix in QEMU `-nographic` mode.
I personally run this either from a real debian amd64 testing/buster machine or I personally run this either from a real debian amd64 bullseye machine or
a windows WSL debian testing/buster installation. After installing a windows WSL debian bullseye installation. Your mileage may vary with other
[the LLVM APT sources][llvm], the following should be enough to set up such a setups and distros.
system to build the kernel:
```sh
pip3 install --user -U bonnibel peru
sudo apt install qemu-system-x86 nasm clang-11 lld-11 mtools curl ninja-build
sudo update-alternatives /usr/bin/clang clang /usr/bin/clang-11 1100
sudo update-alternatives /usr/bin/clang++ clang++ /usr/bin/clang++-11 1100
sudo update-alternatives /usr/bin/ld.lld ld.lld /usr/bin/ld.lld-11 1100
```
[llvm]: https://apt.llvm.org

View File

@@ -1,28 +0,0 @@
# This is the manifest for the initial ramdisk, read by the `makerd` tool.
# The contents should be a table array of files to add to the ramdistk:
#
# [[files]]
# dest = "foo.bar" # Name of the file in the ramdisk
# source = "build/foo/foo.bar" # Location of the file from the project root
# executable = true # Optional, default false. Whether this is an
# # initial application for the kernel to execute
# # on startup
[[files]]
dest = "screenfont.psf"
source = "../assets/fonts/tamsyn8x16r.psf"
[[files]]
dest = "symbol_table.dat"
source = "symbol_table.dat"
symbols = true
[[files]]
dest = "nulldrv1"
source = "user/nulldrv"
executable = true
[[files]]
dest = "nulldrv2"
source = "user/nulldrv"
executable = true

5
assets/manifests/default Normal file
View File

@@ -0,0 +1,5 @@
kernel,kernel
kernel,panic.serial
user,drv.uefi_fb
user,testapp
user,srv.init

43
configs/base.toml Normal file
View File

@@ -0,0 +1,43 @@
[variables]
cc = "clang"
cxx = "clang++"
ld = "ld.lld"
ar = "ar"
nasm = "nasm"
objcopy = "objcopy"
cog = "cog"
ccflags = [
"-I${source_root}/src/include",
"-I${source_root}/src/include/x86_64",
"-fcolor-diagnostics",
"-DVERSION_MAJOR=${version_major}",
"-DVERSION_MINOR=${version_minor}",
"-DVERSION_PATCH=${version_patch}",
"-DVERSION_GITSHA=0x${version_sha}",
'-DGIT_VERSION=\"${version_major}.${version_minor}.${version_patch}+${version_sha}\"',
'-DGIT_VERSION_WIDE=L\"${version_major}.${version_minor}.${version_patch}+${version_sha}\"',
"-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", "-Wno-invalid-offsetof", "-Werror",
]
asflags = [
"-DVERSION_MAJOR=${version_major}",
"-DVERSION_MINOR=${version_minor}",
"-DVERSION_PATCH=${version_patch}",
"-DVERSION_GITSHA=0x${version_sha}",
"-I${source_root}/src/include",
]
cflags = ["-std=c11"]
cxxflags = ["-std=c++17"]
cogflags = [
"-I", "${source_root}/scripts",
"-D", "definitions_path=${source_root}/definitions"
]

35
configs/boot-debug.toml Normal file
View File

@@ -0,0 +1,35 @@
extends = "base"
[variables]
ld = "clang++"
ccflags = [
"-I${source_root}/external",
"--target=x86_64-unknown-windows",
"-ffreestanding",
"-mno-red-zone",
"-fshort-wchar",
"-fno-omit-frame-pointer",
"-ggdb",
"-g3",
'-DKERNEL_FILENAME=L"jsix.elf"',
]
cflags = [
]
cxxflags = [
"-fno-exceptions",
"-fno-rtti",
]
ldflags = [
"--target=x86_64-unknown-windows",
"-nostdlib",
"-Wl,-entry:efi_main",
"-Wl,-subsystem:efi_application",
"-fuse-ld=lld-link",
"-g"
]

View File

@@ -1,76 +0,0 @@
rule makest
description = Making symbol table
command = nm -n -S --demangle $in | ${source_root}/scripts/build_symbol_table.py $out
rule makefat
description = Creating $name
command = $
cp ${source_root}/assets/diskbase.img $out; $
mcopy -s -D o -i $out@@1M ${build_root}/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
build ${build_root}/ovmf_vars.fd : cp ${source_root}/assets/ovmf/x64/ovmf_vars.fd
name = ovmf_vars.fd
build ${build_root}/ovmf_vars_d.fd : cp ${source_root}/assets/ovmf/x64/ovmf_vars_d.fd
name = ovmf_vars_d.fd
build ${build_root}/jsix.elf | ${build_root}/jsix.elf.debug : strip ${build_root}/kernel/jsix.elf
name = kernel
build ${build_root}/jsix.dump : dump ${build_root}/kernel/jsix.elf
name = kernel
build ${build_root}/jsix.elf-gdb.py : cp ${source_root}/assets/debugging/jsix.elf-gdb.py
name = kernel debug python scripts
build ${build_root}/fatroot/jsix.elf : cp ${build_root}/jsix.elf
name = kernel to FAT image
build ${build_root}/fatroot/efi/boot/bootx64.efi : cp ${build_root}/boot/boot.efi
name = bootloader to FAT image
build ${build_root}/fatroot/testapp.elf : cp ${build_root}/user/testapp.elf
name = null driver to FAT image
build ${build_root}/panic.serial.elf : strip ${build_root}/kernel/panic.serial.elf
name = Serial panic handler
build ${build_root}/fatroot/panic.serial.elf : cp ${build_root}/panic.serial.elf
name = Serial panic handler to FAT image
build ${build_root}/fatroot/drv.uefi_fb.elf : cp ${build_root}/user/drv.uefi_fb.elf
name = UEFI framebuffer driver to FAT image
build ${build_root}/fatroot/srv.init.elf : cp ${build_root}/user/srv.init.elf
name = Init server to FAT image
build ${build_root}/fatroot/symbol_table.dat : makest ${build_root}/jsix.elf
build ${build_root}/jsix.img : makefat | $
${build_root}/fatroot/symbol_table.dat $
${build_root}/fatroot/testapp.elf $
${build_root}/fatroot/drv.uefi_fb.elf $
${build_root}/fatroot/srv.init.elf $
${build_root}/fatroot/jsix.elf $
${build_root}/fatroot/panic.serial.elf $
${build_root}/fatroot/efi/boot/bootx64.efi
name = jsix.img
default $
${build_root}/ovmf_vars.fd $
${build_root}/ovmf_vars_d.fd $
${build_root}/jsix.dump $
${build_root}/jsix.elf-gdb.py $
${build_root}/jsix.img
# vim: ft=ninja et ts=4 sts=4 sw=4

View File

@@ -1,132 +0,0 @@
[targets.boot]
cc = "clang"
cxx = "clang++"
ld = "clang++"
ar = "ar"
nasm = "nasm"
objcopy = "objcopy"
ccflags = [
"${ccflags}",
"-I${source_root}/external",
"--target=x86_64-unknown-windows",
"-ffreestanding",
"-mno-red-zone",
"-fshort-wchar",
"-fno-omit-frame-pointer",
"-ggdb",
"-g3",
'-DKERNEL_FILENAME=L"jsix.elf"',
]
cxxflags = [
"${cxxflags}",
"-fno-exceptions",
"-fno-rtti",
]
ldflags = [
"${ldflags}",
"--target=x86_64-unknown-windows",
"-nostdlib",
"-Wl,-entry:efi_main",
"-Wl,-subsystem:efi_application",
"-fuse-ld=lld-link",
"-g"
]
[targets.kernel]
cc = "clang"
cxx = "clang++"
ld = "ld.lld"
ar = "ar"
nasm = "nasm"
objcopy = "objcopy"
asflags = [
"${asflags}",
"-I${source_root}/src/kernel/",
]
ccflags = [
"${ccflags}",
"--target=x86_64-unknown-elf",
"-I${source_root}/external",
"-nostdlib",
"-ffreestanding",
"-nodefaultlibs",
"-fno-builtin",
"-mno-sse",
"-fno-omit-frame-pointer",
"-mno-red-zone",
"-g",
"-mcmodel=large",
"-D__ELF__",
"-D__JSIX__",
"-isystem${source_root}/sysroot/include",
"-isystem${source_root}/src/libraries/libc/include",
"--sysroot='${source_root}/sysroot'",
"-U__linux",
"-U__linux__",
]
cxxflags = [
"${cxxflags}",
"-fno-exceptions",
"-fno-rtti",
"-isystem${source_root}/sysroot/include/c++/v1"
]
ldflags = [
"${ldflags}",
"-g",
"-nostdlib",
"-Bstatic",
"-z", "norelro",
"-z", "separate-code",
]
[targets.user]
cc = "clang"
cxx = "clang++"
ld = "ld.lld"
ar = "ar"
nasm = "nasm"
objcopy = "objcopy"
asflags = [
"${asflags}",
"-I${source_root}/src/kernel/",
]
ccflags = [
"${ccflags}",
"-mno-sse",
"-fno-omit-frame-pointer",
"-g",
"-D__ELF__",
"-D__JSIX__",
"-isystem${source_root}/sysroot/include",
"-isystem${source_root}/src/libraries/libc/include",
"--sysroot='${source_root}/sysroot'",
"-U__linux",
"-U__linux__",
]
cxxflags = [
"${cxxflags}",
"-fno-exceptions",
"-fno-rtti",
"-isystem${source_root}/sysroot/include/c++/v1"
]
ldflags = [
"${ldflags}",
"-g",
"-Bstatic",
"--sysroot='${source_root}/sysroot'",
"-L", "${source_root}/sysroot/lib",
"-z", "separate-code",
]

47
configs/kernel-debug.toml Normal file
View File

@@ -0,0 +1,47 @@
extends = "base"
[variables]
asflags = [
"-I${source_root}/src/kernel/",
]
ccflags = [
"--target=x86_64-unknown-elf",
"-I${source_root}/external",
"-nostdlib",
"-ffreestanding",
"-nodefaultlibs",
"-fno-builtin",
"-mno-sse",
"-fno-omit-frame-pointer",
"-mno-red-zone",
"-g",
"-mcmodel=large",
"-D__ELF__",
"-D__JSIX__",
"-isystem${source_root}/sysroot/include",
"-isystem${source_root}/src/libraries/libc/include",
"--sysroot='${source_root}/sysroot'",
"-U__linux",
"-U__linux__",
]
cflags = [
'-nostdinc',
]
cxxflags = [
"-fno-exceptions",
"-fno-rtti",
'-nostdinc',
"-isystem${source_root}/sysroot/include/c++/v1"
]
ldflags = [
"-g",
"-nostdlib",
"-Bstatic",
"-z", "norelro",
"-z", "separate-code",
]

75
configs/rules.ninja Normal file
View File

@@ -0,0 +1,75 @@
# This file is automatically generated by bonnibel
rule compile_c
command = $cc -MMD -MF $out.d $cflags $ccflags -o $out -c $in
description = Compiling $name
depfile = $out.d
deps = gcc
rule dump_c_defs
command = echo | $cc $ccflags $cflags -dM -E - > $out
description = Dumping C defines for $target
rule dump_c_run
command = echo '#!/bin/bash' > $out; echo '$cc $ccflags $cflags $$*' >> $
$out; chmod a+x $out
description = Dumping C arguments for $target
rule compile_cxx
command = $cxx -MMD -MF $out.d $cxxflags $ccflags -o $out -c $in
description = Compiling $name
depfile = $out.d
deps = gcc
rule dump_cpp_defs
command = echo | $cxx -x c++ $ccflags $cxxflags -dM -E - > $out
description = Dumping C++ defines for $target
rule dump_cpp_run
command = echo '#!/bin/bash' > $out; echo '$cxx $ccflags $cxxflags $$*' $
>> $out; chmod a+x $out
description = Dumping C++ arguments for $target
rule compile_asm
command = $nasm -o $out -felf64 -MD $out.d $asflags $in
description = Assembling $name
depfile = $out.d
deps = gcc
rule parse_cog
command = $cog -o $out -d $cogflags $in
description = Parsing $name
rule exe
command = $ld $ldflags -o $out $in $libs
description = Linking $name
rule lib
command = $ar qcs $out $in
description = Archiving $name
rule cp
command = cp $in $out
description = Copying $name
rule dump
command = objdump -DSC -M intel $in > $out
description = Dumping decompiled $name
rule makest
description = Making symbol table
command = nm -n -S --demangle $in | ${source_root}/scripts/build_symbol_table.py $out
rule makefat
description = Creating $name
command = $
cp $in $out; $
mcopy -s -D o -i $out@@1M ${build_root}/fatroot/* ::/
rule strip
description = Stripping $name
command = $
cp $in $out; $
objcopy --only-keep-debug $out $debug; $
strip -g $out; $
objcopy --add-gnu-debuglink=$debug $out

34
configs/user-debug.toml Normal file
View File

@@ -0,0 +1,34 @@
extends = "base"
[variables]
asflags = [
"-I${source_root}/src/kernel/",
]
ccflags = [
"-mno-sse",
"-fno-omit-frame-pointer",
"-g",
"-D__ELF__",
"-D__JSIX__",
"-isystem${source_root}/sysroot/include",
"-isystem${source_root}/src/libraries/libc/include",
"--sysroot='${source_root}/sysroot'",
"-U__linux",
"-U__linux__",
]
cxxflags = [
"-fno-exceptions",
"-fno-rtti",
"-isystem${source_root}/sysroot/include/c++/v1"
]
ldflags = [
"-g",
"-Bstatic",
"--sysroot='${source_root}/sysroot'",
"-L", "${source_root}/sysroot/lib",
"-z", "separate-code",
]

65
configure vendored Executable file
View File

@@ -0,0 +1,65 @@
#!/usr/bin/env python3
def generate(output, config, manifest):
from os import makedirs, walk
from pathlib import Path
from bonnibel.module import Module
from bonnibel.project import Project
root = Path(__file__).parent
project = Project(root)
output = root / output
sources = root / "src"
manifest = root / manifest
modules = {}
for base, dirs, files in walk(sources):
path = Path(base)
for f in files:
if f.endswith(".module"):
fullpath = path / f
def module_init(name, **kwargs):
m = Module(name, fullpath, path, **kwargs)
modules[m.name] = m
return m
glo = {'module': module_init}
code = compile(open(fullpath, 'r').read(), fullpath, "exec")
loc = {}
exec(code, glo, loc)
Module.update(modules)
makedirs(output.resolve(), exist_ok=True)
project.generate(root, output, modules, config, manifest)
for mod in modules.values():
mod.generate(output)
if __name__ == "__main__":
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent / "scripts"))
from argparse import ArgumentParser
from bonnibel import BonnibelError
p = ArgumentParser(description="Generate jsix build files")
p.add_argument("--manifest", "-m", metavar="FILE", default="assets/manifests/default",
help="File to use as the system manifest")
p.add_argument("--config", "-c", metavar="NAME", default="debug",
help="Configuration to build (eg, 'debug' or 'release')")
p.add_argument("output", metavar="DIR", default="build", nargs='?',
help="Where to create the build root")
args = p.parse_args()
try:
generate(args.output, args.config, args.manifest)
except BonnibelError as be:
import sys
print(f"Error: {be}", file=sys.stderr)
sys.exit(1)

4
requirements.txt Normal file
View File

@@ -0,0 +1,4 @@
cogapp >= 3
ninja >= 1.10.2
peru >= 1.2.1
toml >= 0.10.2

View File

@@ -0,0 +1,3 @@
class BonnibelError(Exception):
def __init__(self, message):
self.message = message

View File

@@ -0,0 +1,18 @@
class Action:
_action_map = {
'.c': Action_c,
'.C': Action_cxx,
'.cc': Action_cxx,
'.cpp': Action_cxx,
'.cxx': Action_cxx,
'.c++': Action_cxx,
'.s': Action_asm,
'.S': Action_asm,
'.cog': Action_cog,
}
@classmethod
def find(cls, ext):
return cls._action_map.get(ext)
class Action_c:

181
scripts/bonnibel/module.py Normal file
View File

@@ -0,0 +1,181 @@
class Module:
__fields = {
# name: (type, default)
"kind": (str, "exe"),
"output": (str, None),
"targets": (set, ()),
"deps": (set, ()),
"includes": (tuple, ()),
"sources": (tuple, ()),
"variables": (dict, ()),
"default": (bool, False),
}
def __init__(self, name, modfile, root, **kwargs):
from .source import Source
# Required fields
self.root = root
self.name = name
self.modfile = modfile
for name, data in self.__fields.items():
ctor, default = data
value = kwargs.get(name, default)
if value is not None:
value = ctor(value)
setattr(self, name, value)
for name in kwargs:
if not name in self.__fields:
raise AttributeError(f"No attribute named {name} on Module")
# Turn strings into real Source objects
self.sources = [Source(root, f) for f in self.sources]
# Filled by Module.update
self.depmods = set()
def __str__(self):
return "Module {} {}\n\t{}".format(self.kind, self.name, "\n\t".join(map(str, self.sources)))
@property
def output(self):
if self.__output is not None:
return self.__output
if self.kind == "lib":
return f"lib{self.name}.a"
else:
return f"{self.name}.elf"
@output.setter
def output(self, value):
self.__output = value
@classmethod
def update(cls, mods):
from . import BonnibelError
for mod in mods.values():
for dep in mod.deps:
if not dep in mods:
raise BonnibelError(f"module '{mod.name}' references unknown module '{dep}'")
depmod = mods[dep]
mod.depmods.add(depmod)
target_mods = [mod for mod in mods.values() if mod.targets]
for mod in target_mods:
closed = set()
children = set(mod.depmods)
while children:
child = children.pop()
closed.add(child)
child.targets |= mod.targets
children |= {m for m in child.depmods if not m in closed}
def generate(self, output):
filename = str(output / f"{self.name}.ninja")
with open(filename, "w") as buildfile:
from pathlib import Path
from ninja.ninja_syntax import Writer
build = Writer(buildfile)
build.comment("This file is automatically generated by bonnibel")
build.newline()
build.variable("module_dir", f"${{target_dir}}/{self.name}.dir")
for key, value in self.variables.items():
build.variable(key, value)
build.newline()
includes = [self.root, "${module_dir}"]
for include in self.includes:
p = Path(include)
if p.is_absolute():
if not p in includes:
includes.append(str(p.resolve()))
elif include != ".":
includes.append(str(self.root / p))
includes.append(f"${{module_dir}}/{p}")
libs = []
order_only = []
closed = set()
children = set(self.depmods)
while children:
child = children.pop()
closed.add(child)
includes += [f"${{target_dir}}/{child.name}.dir/{i}" for i in child.includes]
includes += [f"{child.root}/{i}" for i in child.includes]
if child.kind == "lib":
libs.append(f"${{target_dir}}/{child.output}")
else:
order_only.append(f"${{target_dir}}/{child.output}")
children |= {m for m in child.depmods if not m in closed}
if includes:
build.variable("ccflags", ["${ccflags}"] + [f"-I{i}" for i in includes])
if libs:
build.variable("libs", ["${libs}"] + libs)
inputs = []
implicits = []
for start in self.sources:
source = start
while source and source.action:
output = source.get_output('${module_dir}')
if source.action.rule:
build.build(
rule = source.action.rule,
outputs = output.input,
inputs = source.input,
implicit = [f'${{source_root}}/{p}' for p in source.deps or tuple()],
variables = {"name": source.name},
)
elif source.action.implicit:
implicits.append(source.input)
else:
inputs.append(source.input)
source = output
build.newline()
output = f"${{target_dir}}/{self.output}"
dump = f"${{target_dir}}/{self.output}.dump"
build.build(
rule = self.kind,
outputs = output,
inputs = inputs,
implicit = implicits + libs,
order_only = order_only,
)
build.newline()
build.build(
rule = "dump",
outputs = dump,
inputs = output,
variables = {"name": self.name},
)
if self.default:
build.newline()
build.default(output)
build.default(dump)
def add_input(self, path, **kwargs):
from .source import Source
self.sources.append(Source(self.root, path, **kwargs))

177
scripts/bonnibel/project.py Normal file
View File

@@ -0,0 +1,177 @@
from . import BonnibelError
class Project:
def __init__(self, root):
from .version import git_version
self.root = root
self.version = git_version(root)
def __str__(self):
return f"{self.name} {self.version.major}.{self.version.minor}.{self.version.patch}-{self.version.sha}"
def generate(self, root, output, modules, config, manifest):
import sys
import bonnibel
from os.path import join
from ninja.ninja_syntax import Writer
from .target import Target
targets = set()
for mod in modules.values():
targets.update({Target.load(root, t, config) for t in mod.targets})
with open(output / "build.ninja", "w") as buildfile:
build = Writer(buildfile)
build.comment("This file is automatically generated by bonnibel")
build.variable("ninja_required_version", "1.3")
build.variable("build_root", output)
build.variable("source_root", root)
build.newline()
build.include(root / "configs" / "rules.ninja")
build.newline()
build.variable("version_major", self.version.major)
build.variable("version_minor", self.version.minor)
build.variable("version_patch", self.version.patch)
build.variable("version_sha", self.version.sha)
build.newline()
for target in targets:
build.subninja(output / target.name / "target.ninja")
build.newline()
fatroot = output / "fatroot"
fatroot.mkdir(exist_ok=True)
fatroot_content = []
for line in open(manifest, 'r'):
target, name = line.split(",", 1)
target = target.strip()
name = name.strip()
if not name in modules:
raise BonnibelError(f"Manifest item '{name}' is not a known module")
mod = modules[name]
fatroot_output = f"${{build_root}}/fatroot/{mod.output}"
build.build(
rule = "strip",
outputs = [fatroot_output],
inputs = [f"${{build_root}}/{target}/{mod.output}"],
variables = {
"name": f"Installing {name}",
"debug": f"${{build_root}}/{mod.output}.debug",
})
fatroot_content.append(fatroot_output)
build.newline()
symbol_table = "${build_root}/fatroot/symbol_table.dat"
build.build(
rule = "makest",
outputs = [symbol_table],
inputs = ["${build_root}/fatroot/jsix.elf"],
)
fatroot_content.append(symbol_table)
build.newline()
bootloader = "${build_root}/fatroot/efi/boot/bootx64.efi"
build.build(
rule = "cp",
outputs = [bootloader],
inputs = ["${build_root}/boot/boot.efi"],
variables = {
"name": "Installing bootloader",
})
fatroot_content.append(bootloader)
build.newline()
build.build(
rule = "makefat",
outputs = ["${build_root}/jsix.img"],
inputs = ["${source_root}/assets/diskbase.img"],
implicit = fatroot_content,
variables = {"name": "jsix.img"},
)
build.newline()
default_assets = {
"ovmf/x64/ovmf_vars.fd": "UEFI Variables",
"debugging/jsix.elf-gdb.py": "GDB Debug Helpers",
}
for asset, name in default_assets.items():
p = root / "assets" / asset
out = f"${{build_root}}/{p.name}"
build.build(
rule = "cp",
outputs = [out],
inputs = [str(p)],
variables = {"name": name},
)
build.default([out])
build.newline()
build.rule("regen",
command = " ".join([str(root / 'configure')] + sys.argv[1:]),
description = "Regenerate build files",
generator = True,
)
build.newline()
regen_implicits = \
[f"{self.root}/configure", str(manifest)] + \
[str(mod.modfile) for mod in modules.values()]
for target in targets:
regen_implicits += target.depfiles
build.build(
rule = "regen",
outputs = ['build.ninja'],
implicit = regen_implicits,
implicit_outputs =
[f"{mod.name}.ninja" for mod in modules.values()] +
[f"{target.name}/target.ninja" for target in targets],
)
build.newline()
build.default(["${build_root}/jsix.img"])
for target in targets:
mods = [m.name for m in modules.values() if target.name in m.targets]
targetdir = output / target.name
targetdir.mkdir(exist_ok=True)
buildfilename = str(targetdir / "target.ninja")
with open(buildfilename, "w") as buildfile:
build = Writer(buildfile)
build.comment("This file is automatically generated by bonnibel")
build.newline()
build.variable("target", target.name)
build.variable("target_dir", output / target.name)
build.newline()
for name, value in target.items():
build.variable(name, value)
build.newline()
for kind in ('defs', 'run'):
for lang in ('c', 'cpp'):
deffile = str(output / target.name / f"{lang}.{kind}")
build.build(
rule = f"dump_{lang}_{kind}",
outputs = [deffile],
implicit = [buildfilename],
)
build.default(deffile)
build.newline()
for mod in mods:
build.subninja(f"{mod}.ninja")

View File

@@ -0,0 +1,78 @@
class Action:
name = property(lambda self: self.__name)
implicit = property(lambda self: False)
rule = property(lambda self: None)
def __init__(self, name):
self.__name = name
def output_of(self, path):
return None
class Compile(Action):
rule = property(lambda self: f'compile_{self.name}')
def __init__(self, name, suffix = ".o"):
super().__init__(name)
self.__suffix = suffix
def output_of(self, path):
return str(path) + self.__suffix
class Parse(Action):
rule = property(lambda self: f'parse_{self.name}')
def output_of(self, path):
suffix = "." + self.name
if path.suffix == suffix:
return path.with_suffix('')
return path
class Link(Action): pass
class Header(Action):
implicit = property(lambda self: True)
class Source:
Actions = {
'.c': Compile('c'),
'.cpp': Compile('cxx'),
'.s': Compile('asm'),
'.cog': Parse('cog'),
'.o': Link('o'),
'.h': Header('h'),
}
def __init__(self, root, path, output=None, deps=tuple()):
from pathlib import Path
self.__root = Path(root)
self.__path = Path(path)
self.__output = output
self.__deps = deps
def __str__(self):
return "{} {}:{}:{}".format(self.action, self.output, self.name, self.input)
@property
def action(self):
suffix = self.__path.suffix
return self.Actions.get(suffix)
def get_output(self, output_root):
if not self.action:
return None
path = self.__output
if path is None:
path = self.action.output_of(self.__path)
return path and Source(output_root, path)
deps = property(lambda self: self.__deps)
name = property(lambda self: str(self.__path))
input = property(lambda self: str(self.__root / self.__path))

View File

@@ -0,0 +1,50 @@
class Target(dict):
__targets = {}
@classmethod
def load(cls, root, name, config=None):
import toml
if (name, config) in cls.__targets:
return cls.__targets[(name, config)]
configs = root / "configs"
dicts = []
depfiles = []
basename = name
if config:
basename += f"-{config}"
while basename is not None:
filename = str(configs / (basename + ".toml"))
depfiles.append(filename)
desc = toml.load(filename)
basename = desc.get("extends")
dicts.append(desc.get("variables", dict()))
t = Target(name, config, depfiles)
for d in reversed(dicts):
for k, v in d.items():
if isinstance(v, (list, tuple)):
t[k] = t.get(k, list()) + list(v)
elif isinstance(v, dict):
t[k] = t.get(k, dict())
t[k].update(v)
else:
t[k] = v
cls.__targets[(name, config)] = t
return t
def __init__(self, name, config, depfiles):
self.__name = name
self.__config = config
self.__depfiles = tuple(depfiles)
def __hash__(self):
return hash((self.__name, self.__config))
name = property(lambda self: self.__name)
config = property(lambda self: self.__config)
depfiles = property(lambda self: self.__depfiles)

View File

@@ -0,0 +1,41 @@
from collections import namedtuple as _namedtuple
version = _namedtuple('version', [
'major',
'minor',
'patch',
'sha',
'dirty',
])
def _run_git(root, *args):
from subprocess import run
git = run(['git', '-C', root] + list(args),
check=True, capture_output=True)
return git.stdout.decode('utf-8').strip()
def git_version(root):
full_version = _run_git(root, 'describe', '--dirty')
full_sha = _run_git(root, 'rev-parse', 'HEAD')
dirty = False
parts1 = full_version.split('-')
if parts1[-1] == "dirty":
dirty = True
parts1 = parts1[:-1]
if parts1[0][0] == 'v':
parts1[0] = parts1[0][1:]
parts2 = parts1[0].split('.')
return version(
parts2[0],
parts2[1],
parts2[2],
full_sha[:7],
dirty)

22
src/boot/boot.module Normal file
View File

@@ -0,0 +1,22 @@
# vim: ft=python
module("boot",
kind = "exe",
output = "boot.efi",
targets = [ "boot" ],
deps = [ "cpu", "elf", "kutil" ],
sources = [
"allocator.cpp",
"console.cpp",
"error.cpp",
"fs.cpp",
"hardware.cpp",
"loader.cpp",
"main.cpp",
"memory.cpp",
"memory_map.cpp",
"paging.cpp",
"status.cpp",
"support.cpp",
"video.cpp",
])

View File

@@ -1,20 +0,0 @@
name = "boot"
kind = "exe"
output = "boot.efi"
targets = ["boot"]
deps = ["cpu", "elf", "kutil"]
sources = [
"allocator.cpp",
"console.cpp",
"error.cpp",
"fs.cpp",
"hardware.cpp",
"loader.cpp",
"main.cpp",
"memory.cpp",
"memory_map.cpp",
"paging.cpp",
"status.cpp",
"support.cpp",
"video.cpp",
]

59
src/kernel/kernel.module Normal file
View File

@@ -0,0 +1,59 @@
# vim: ft=python
kernel = module("kernel",
kind = "exe",
default = True,
output = "jsix.elf",
targets = [ "kernel" ],
deps = [ "kutil", "cpu" ],
includes = [ "." ],
sources = [
"apic.cpp",
"ap_startup.s",
"boot.s",
"clock.cpp",
"console.cpp",
"cpprt.cpp",
"cpu.cpp",
"debug.cpp",
"debug.s",
"device_manager.cpp",
"frame_allocator.cpp",
"gdt.cpp",
"gdtidt.s",
"hpet.cpp",
"idt.cpp",
"interrupts.cpp",
"interrupts.s",
"io.cpp",
"log.cpp",
"main.cpp",
"memory_bootstrap.cpp",
"msr.cpp",
"objects/channel.cpp",
"objects/endpoint.cpp",
"objects/kobject.cpp",
"objects/thread.cpp",
"objects/process.cpp",
"objects/system.cpp",
"objects/vm_area.cpp",
"page_table.cpp",
"page_tree.cpp",
"pci.cpp",
"scheduler.cpp",
"serial.cpp",
"syscall.cpp",
"syscall.s",
"syscalls/channel.cpp",
"syscalls/endpoint.cpp",
"syscalls/object.cpp",
"syscalls/process.cpp",
"syscalls/system.cpp",
"syscalls/thread.cpp",
"syscalls/vm_area.cpp",
"task.s",
"tss.cpp",
"vm_space.cpp",
])
kernel.variables['ldflags'] = ["${ldflags}", "-T", "${source_root}/src/kernel/kernel.ld"]

View File

@@ -1,57 +0,0 @@
name = "kernel"
kind = "exe"
output = "jsix.elf"
targets = ["kernel"]
deps = ["kutil", "cpu"]
includes = ["src/kernel"]
sources = [
"apic.cpp",
"ap_startup.s",
"boot.s",
"clock.cpp",
"console.cpp",
"cpprt.cpp",
"cpu.cpp",
"debug.cpp",
"debug.s",
"device_manager.cpp",
"frame_allocator.cpp",
"gdt.cpp",
"gdtidt.s",
"hpet.cpp",
"idt.cpp",
"interrupts.cpp",
"interrupts.s",
"io.cpp",
"log.cpp",
"main.cpp",
"memory_bootstrap.cpp",
"msr.cpp",
"objects/channel.cpp",
"objects/endpoint.cpp",
"objects/kobject.cpp",
"objects/thread.cpp",
"objects/process.cpp",
"objects/system.cpp",
"objects/vm_area.cpp",
"page_table.cpp",
"page_tree.cpp",
"pci.cpp",
"scheduler.cpp",
"serial.cpp",
"syscall.cpp",
"syscall.s",
"syscalls/channel.cpp",
"syscalls/endpoint.cpp",
"syscalls/object.cpp",
"syscalls/process.cpp",
"syscalls/system.cpp",
"syscalls/thread.cpp",
"syscalls/vm_area.cpp",
"task.s",
"tss.cpp",
"vm_space.cpp",
]
[variables]
ldflags = ["${ldflags}", "-T", "${source_root}/src/kernel/kernel.ld"]

View File

@@ -1,16 +0,0 @@
name = "panic.serial"
kind = "exe"
output = "panic.serial.elf"
targets = ["kernel"]
deps = ["kutil", "elf"]
includes = ["src/kernel/panic.serial", "src/kernel"]
sources = [
"display.cpp",
"entry.s",
"main.cpp",
"serial.cpp",
"symbol_table.cpp",
]
[variables]
ldflags = ["${ldflags}", "-T", "${source_root}/src/kernel/panic.serial/panic.serial.ld"]

View File

@@ -0,0 +1,16 @@
# vim: ft=python
panic = module("panic.serial",
kind = "exe",
output = "panic.serial.elf",
targets = [ "kernel" ],
deps = [ "kutil", "elf", "kernel" ],
sources = [
"display.cpp",
"entry.s",
"main.cpp",
"serial.cpp",
"symbol_table.cpp",
])
panic.variables['ldflags'] = ["${ldflags}", "-T", "${source_root}/src/kernel/panic.serial/panic.serial.ld"]

View File

@@ -0,0 +1,8 @@
# vim: ft=python
module("cpu",
kind = "lib",
includes = ["include"],
sources = [
"cpu_id.cpp",
])

View File

@@ -1,4 +0,0 @@
name = "cpu"
kind = "lib"
includes = ["src/libraries/cpu/include"]
sources = ["cpu_id.cpp"]

View File

@@ -0,0 +1,8 @@
# vim: ft=python
module("elf",
kind = "lib",
includes = [ "include" ],
sources = [
"file.cpp",
])

View File

@@ -1,6 +0,0 @@
name = "elf"
kind = "lib"
includes = [ "src/libraries/elf/include" ]
sources = [
"file.cpp",
]

View File

@@ -0,0 +1,9 @@
# vim: ft=python
module("j6",
kind = "lib",
includes = [ "include" ],
sources = [
"init.cpp",
"syscalls.s",
])

View File

@@ -1,4 +0,0 @@
name = "j6"
kind = "lib"
includes = ["src/libraries/j6/include"]
sources = ["init.cpp", "syscalls.s"]

View File

@@ -0,0 +1,14 @@
# vim: ft=python
module("kutil",
kind = "lib",
includes = [ "include" ],
sources = [
"assert.cpp",
"bip_buffer.cpp",
"heap_allocator.cpp",
"logger.cpp",
"memory.cpp",
"printf.c",
"spinlock.cpp",
])

View File

@@ -1,12 +0,0 @@
name = "kutil"
kind = "lib"
includes = [ "src/libraries/kutil/include" ]
sources = [
"assert.cpp",
"bip_buffer.cpp",
"heap_allocator.cpp",
"logger.cpp",
"memory.cpp",
"printf.c",
"spinlock.cpp",
]

View File

@@ -0,0 +1,176 @@
# vim: ft=python
libc = module("libc",
kind = "lib",
output = "libc.a",
includes = [ "include" ],
deps = [ "j6" ],
sources = [
"arch/x86_64/_Exit.s",
"arch/x86_64/crt0.s",
"ctype/isalnum.c",
"ctype/isalpha.c",
"ctype/isblank.c",
"ctype/iscntrl.c",
"ctype/isdigit.c",
"ctype/isgraph.c",
"ctype/islower.c",
"ctype/isprint.c",
"ctype/ispunct.c",
"ctype/isspace.c",
"ctype/isupper.c",
"ctype/isxdigit.c",
"ctype/tolower.c",
"ctype/toupper.c",
"inttypes/imaxabs.c",
"inttypes/imaxdiv.c",
"inttypes/strtoimax.c",
"inttypes/strtoumax.c",
"locale/localeconv.c",
"locale/setlocale.c",
"j6libc/assert.c",
"j6libc/errno.c",
"j6libc/allocpages.c",
"j6libc/atomax.c",
"j6libc/closeall.c",
"j6libc/close.c",
"j6libc/digits.c",
"j6libc/filemode.c",
"j6libc/fillbuffer.c",
"j6libc/flushbuffer.c",
"j6libc/is_leap.c",
"j6libc/load_lc_collate.c",
"j6libc/load_lc_ctype.c",
"j6libc/load_lc_messages.c",
"j6libc/load_lc_monetary.c",
"j6libc/load_lc_numeric.c",
"j6libc/load_lc_time.c",
"j6libc/load_lines.c",
"j6libc/open.c",
"j6libc/prepread.c",
"j6libc/prepwrite.c",
"j6libc/print.c",
"j6libc/rename.c",
"j6libc/scan.c",
"j6libc/seed.c",
"j6libc/seek.c",
"j6libc/stdinit.c",
"j6libc/strtox_main.c",
"j6libc/strtox_prelim.c",
"j6libc/sbrk.c",
"signal/raise.c",
"signal/signal.c",
"stdio/clearerr.c",
"stdio/fclose.c",
"stdio/feof.c",
"stdio/ferror.c",
"stdio/fflush.c",
"stdio/fgetc.c",
"stdio/fgetpos.c",
"stdio/fgets.c",
"stdio/fopen.c",
"stdio/fprintf.c",
"stdio/fputc.c",
"stdio/fputs.c",
"stdio/fread.c",
"stdio/freopen.c",
"stdio/fscanf.c",
"stdio/fseek.c",
"stdio/fsetpos.c",
"stdio/ftell.c",
"stdio/fwrite.c",
"stdio/getc.c",
"stdio/getchar.c",
"stdio/perror.c",
"stdio/printf.c",
"stdio/putc.c",
"stdio/putchar.c",
"stdio/puts.c",
"stdio/remove.c",
"stdio/rename.c",
"stdio/rewind.c",
"stdio/scanf.c",
"stdio/setbuf.c",
"stdio/setvbuf.c",
"stdio/snprintf.c",
"stdio/sprintf.c",
"stdio/sscanf.c",
"stdio/tmpfile.c",
"stdio/tmpnam.c",
"stdio/ungetc.c",
"stdio/vfprintf.c",
"stdio/vfscanf.c",
"stdio/vprintf.c",
"stdio/vscanf.c",
"stdio/vsnprintf.c",
"stdio/vsprintf.c",
"stdio/vsscanf.c",
"stdlib/abort.c",
"stdlib/abs.c",
"stdlib/atexit.c",
"stdlib/atoi.c",
"stdlib/atol.c",
"stdlib/atoll.c",
"stdlib/bsearch.c",
"stdlib/div.c",
"stdlib/exit.c",
"stdlib/_Exit.c",
"stdlib/getenv.c",
"stdlib/labs.c",
"stdlib/ldiv.c",
"stdlib/llabs.c",
"stdlib/lldiv.c",
"stdlib/malloc.c",
"stdlib/qsort.c",
"stdlib/rand.c",
"stdlib/srand.c",
"stdlib/strtol.c",
"stdlib/strtoll.c",
"stdlib/strtoul.c",
"stdlib/strtoull.c",
"stdlib/system.c",
"string/memchr.c",
"string/memcmp.c",
"string/memcpy.c",
"string/memmove.c",
"string/memset.c",
"string/strcat.c",
"string/strchr.c",
"string/strcmp.c",
"string/strcoll.c",
"string/strcpy.c",
"string/strcspn.c",
"string/strerror.c",
"string/strlen.c",
"string/strncat.c",
"string/strncmp.c",
"string/strncpy.c",
"string/strpbrk.c",
"string/strrchr.c",
"string/strspn.c",
"string/strstr.c",
"string/strtok.c",
"string/strxfrm.c",
"time/asctime.c",
"time/clock.c",
"time/ctime.c",
"time/difftime.c",
"time/gmtime.c",
"time/localtime.c",
"time/mktime.c",
"time/strftime.c",
"time/time.c",
"time/timespec_get.c",
])
libc.variables["ccflags"] = [
"${ccflags}",
"-DDISABLE_SSE",
"-DLACKS_UNISTD_H",
"-DLACKS_FCNTL_H",
"-DLACKS_SYS_PARAM_H",
"-DLACKS_SYS_MMAN_H",
"-DLACKS_SCHED_H",
"-DLACKS_STRINGS_H",
"-DHAVE_MMAP=0",
]

View File

@@ -1,177 +0,0 @@
name = "libc"
kind = "lib"
output = "libc.a"
includes = "src/libraries/libc/include"
deps = ["j6"]
sources = [
"arch/x86_64/_Exit.s",
"arch/x86_64/crt0.s",
"ctype/isalnum.c",
"ctype/isalpha.c",
"ctype/isblank.c",
"ctype/iscntrl.c",
"ctype/isdigit.c",
"ctype/isgraph.c",
"ctype/islower.c",
"ctype/isprint.c",
"ctype/ispunct.c",
"ctype/isspace.c",
"ctype/isupper.c",
"ctype/isxdigit.c",
"ctype/tolower.c",
"ctype/toupper.c",
"inttypes/imaxabs.c",
"inttypes/imaxdiv.c",
"inttypes/strtoimax.c",
"inttypes/strtoumax.c",
"locale/localeconv.c",
"locale/setlocale.c",
"j6libc/assert.c",
"j6libc/errno.c",
"j6libc/allocpages.c",
"j6libc/atomax.c",
"j6libc/closeall.c",
"j6libc/close.c",
"j6libc/digits.c",
"j6libc/filemode.c",
"j6libc/fillbuffer.c",
"j6libc/flushbuffer.c",
"j6libc/is_leap.c",
"j6libc/load_lc_collate.c",
"j6libc/load_lc_ctype.c",
"j6libc/load_lc_messages.c",
"j6libc/load_lc_monetary.c",
"j6libc/load_lc_numeric.c",
"j6libc/load_lc_time.c",
"j6libc/load_lines.c",
"j6libc/open.c",
"j6libc/prepread.c",
"j6libc/prepwrite.c",
"j6libc/print.c",
"j6libc/rename.c",
"j6libc/scan.c",
"j6libc/seed.c",
"j6libc/seek.c",
"j6libc/stdinit.c",
"j6libc/strtox_main.c",
"j6libc/strtox_prelim.c",
"j6libc/sbrk.c",
"signal/raise.c",
"signal/signal.c",
"stdio/clearerr.c",
"stdio/fclose.c",
"stdio/feof.c",
"stdio/ferror.c",
"stdio/fflush.c",
"stdio/fgetc.c",
"stdio/fgetpos.c",
"stdio/fgets.c",
"stdio/fopen.c",
"stdio/fprintf.c",
"stdio/fputc.c",
"stdio/fputs.c",
"stdio/fread.c",
"stdio/freopen.c",
"stdio/fscanf.c",
"stdio/fseek.c",
"stdio/fsetpos.c",
"stdio/ftell.c",
"stdio/fwrite.c",
"stdio/getc.c",
"stdio/getchar.c",
"stdio/perror.c",
"stdio/printf.c",
"stdio/putc.c",
"stdio/putchar.c",
"stdio/puts.c",
"stdio/remove.c",
"stdio/rename.c",
"stdio/rewind.c",
"stdio/scanf.c",
"stdio/setbuf.c",
"stdio/setvbuf.c",
"stdio/snprintf.c",
"stdio/sprintf.c",
"stdio/sscanf.c",
"stdio/tmpfile.c",
"stdio/tmpnam.c",
"stdio/ungetc.c",
"stdio/vfprintf.c",
"stdio/vfscanf.c",
"stdio/vprintf.c",
"stdio/vscanf.c",
"stdio/vsnprintf.c",
"stdio/vsprintf.c",
"stdio/vsscanf.c",
"stdlib/abort.c",
"stdlib/abs.c",
"stdlib/atexit.c",
"stdlib/atoi.c",
"stdlib/atol.c",
"stdlib/atoll.c",
"stdlib/bsearch.c",
"stdlib/div.c",
"stdlib/exit.c",
"stdlib/_Exit.c",
"stdlib/getenv.c",
"stdlib/labs.c",
"stdlib/ldiv.c",
"stdlib/llabs.c",
"stdlib/lldiv.c",
"stdlib/malloc.c",
"stdlib/qsort.c",
"stdlib/rand.c",
"stdlib/srand.c",
"stdlib/strtol.c",
"stdlib/strtoll.c",
"stdlib/strtoul.c",
"stdlib/strtoull.c",
"stdlib/system.c",
"string/memchr.c",
"string/memcmp.c",
"string/memcpy.c",
"string/memmove.c",
"string/memset.c",
"string/strcat.c",
"string/strchr.c",
"string/strcmp.c",
"string/strcoll.c",
"string/strcpy.c",
"string/strcspn.c",
"string/strerror.c",
"string/strlen.c",
"string/strncat.c",
"string/strncmp.c",
"string/strncpy.c",
"string/strpbrk.c",
"string/strrchr.c",
"string/strspn.c",
"string/strstr.c",
"string/strtok.c",
"string/strxfrm.c",
"time/asctime.c",
"time/clock.c",
"time/ctime.c",
"time/difftime.c",
"time/gmtime.c",
"time/localtime.c",
"time/mktime.c",
"time/strftime.c",
"time/time.c",
"time/timespec_get.c",
]
[variables]
ccflags = [
"${ccflags}",
"-DDISABLE_SSE",
"-DLACKS_UNISTD_H",
"-DLACKS_FCNTL_H",
"-DLACKS_SYS_PARAM_H",
"-DLACKS_SYS_MMAN_H",
"-DLACKS_SCHED_H",
"-DLACKS_STRINGS_H",
"-DHAVE_MMAP=0",
]

View File

@@ -1,10 +0,0 @@
name = "drv.uefi_fb"
targets = ["user"]
deps = ["libc"]
sources = [
"font.cpp",
"main.cpp",
"screen.cpp",
"scrollback.cpp",
]

View File

@@ -0,0 +1,12 @@
# vim: ft=python
module("drv.uefi_fb",
targets = [ "user" ],
deps = [ "libc" ],
sources = [
"font.cpp",
"main.cpp",
"screen.cpp",
"scrollback.cpp",
])

View File

@@ -0,0 +1,10 @@
# vim: ft=python
module("srv.init",
targets = [ "user" ],
deps = [ "libc" ],
sources = [
"main.cpp",
"modules.cpp",
"start.s",
])

View File

@@ -1,8 +0,0 @@
name = "srv.init"
targets = ["user"]
deps = ["libc"]
sources = [
"main.cpp",
"modules.cpp",
"start.s",
]

View File

@@ -1,8 +0,0 @@
name = "testapp"
targets = ["user"]
deps = ["libc"]
sources = [
"io.cpp",
"main.cpp",
"serial.cpp",
]

View File

@@ -0,0 +1,10 @@
# vim: ft=python
module("testapp",
targets = [ "user" ],
deps = [ "libc" ],
sources = [
"io.cpp",
"main.cpp",
"serial.cpp",
])