redo build system

This commit is contained in:
Benji Dial 2024-07-31 19:53:02 -04:00
parent e6915fb6dd
commit cc9a1811fd
16 changed files with 221 additions and 266 deletions

6
.gitignore vendored
View file

@ -4,7 +4,5 @@ build/*
dependencies/*
toolchain/*
euler/build/*
kernel/build/*
applications/*/build/*
libraries/*/build/*
.setup-complete
.setup-started

10
0bsd.txt Normal file
View file

@ -0,0 +1,10 @@
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View file

@ -1,12 +0,0 @@
SOURCES = \
main.cpp
build/%.cpp.o: source/%.cpp
@mkdir -p $(@D)
$(HILBERT_CC) -c $^ -o $@
build/clock.elf: $(SOURCES:%=build/%.o)
$(HILBERT_CC) $^ -ldaguerre -lpake -o $@
clean:
rm -rf build

View file

@ -1,12 +0,0 @@
SOURCES = \
main.cpp renderer.cpp input.cpp socket.cpp window.cpp
build/%.cpp.o: source/%.cpp
@mkdir -p $(@D)
$(HILBERT_CC) -c $^ -o $@
build/goldman.elf: $(SOURCES:%=build/%.o)
$(HILBERT_CC) $^ -ldaguerre -o $@
clean:
rm -rf build

View file

@ -1,12 +0,0 @@
SOURCES = \
main.cpp
build/%.cpp.o: source/%.cpp
@mkdir -p $(@D)
$(HILBERT_CC) -c $^ -o $@
build/hello.elf: $(SOURCES:%=build/%.o)
$(HILBERT_CC) $^ -ldaguerre -lpake -o $@
clean:
rm -rf build

View file

@ -1,12 +0,0 @@
SOURCES = \
main.cpp
build/%.cpp.o: source/%.cpp
@mkdir -p $(@D)
$(HILBERT_CC) -c $^ -o $@
build/init.elf: $(SOURCES:%=build/%.o)
$(HILBERT_CC) $^ -o $@
clean:
rm -rf build

3
clean-setup.sh Normal file
View file

@ -0,0 +1,3 @@
#!/bin/sh
rm -rf dependencies toolchain .setup-started .setup-complete

View file

@ -1,26 +0,0 @@
LIBC_SOURCES = \
entry.cpp std/string.cpp std/cstring.cpp syscall.cpp std/cstdlib.cpp \
heap.cpp syscall.asm std/cctype.cpp std/cstdio.cpp stream.cpp std/ctime.cpp
clean:
rm -rf build
build/%.asm.o: source/%.asm
@mkdir -p $(@D)
$(HILBERT_NASM) $^ -o $@
build/%.cpp.o: source/%.cpp
@mkdir -p $(@D)
$(HILBERT_CC) -ffreestanding -c $^ -o $@
build/crt0.o: build/empty.asm.o
cp $^ $@
build/libc.a: ${LIBC_SOURCES:%=build/%.o}
$(HILBERT_AR) rcs $@ $^
build/libg.a: build/empty.asm.o
$(HILBERT_AR) rcs $@ $^
build/libm.a: build/empty.asm.o
$(HILBERT_AR) rcs $@ $^

View file

View file

@ -1,20 +0,0 @@
SOURCES = \
storage/bd/memory.cpp storage/fs/tarfs.cpp application.asm application.cpp \
framebuffer.cpp interrupts.asm interrupts.cpp allocator.cpp storage.cpp \
syscall.cpp utility.cpp paging.asm paging.cpp entry.cpp input.cpp panic.cpp \
vfile.cpp serial.asm app-memory.cpp load-app.cpp timer.cpp timer.asm
build/%.asm.o: source/%.asm
@mkdir -p $(@D)
$(HILBERT_NASM) $^ -o $@
build/%.cpp.o: source/%.cpp
@mkdir -p $(@D)
$(HILBERT_CC) -c -ffreestanding -fno-exceptions -fno-rtti \
-mcmodel=kernel -I ${LIMINE_DIR} -I ${MINTSUKI_HEADERS_DIR} $^ -o $@
build/kernel.elf: $(SOURCES:%=build/%.o)
$(HILBERT_LD) -T link.ld $^ -o $@
clean:
rm -rf build

View file

@ -1,12 +0,0 @@
SOURCES = \
framebuffer.cpp ppm.cpp psf.cpp
build/%.cpp.o: source/%.cpp
@mkdir -p $(@D)
$(HILBERT_CC) -c $^ -o $@
build/libdaguerre.a: $(SOURCES:%=build/%.o)
$(HILBERT_AR) rcs $@ $^
clean:
rm -rf build

View file

@ -1,12 +0,0 @@
SOURCES = \
widgets/fixed-text.cpp dirtiable-image.cpp window.cpp
build/%.cpp.o: source/%.cpp
@mkdir -p $(@D)
$(HILBERT_CC) -c $^ -o $@
build/libpake.a: $(SOURCES:%=build/%.o)
$(HILBERT_AR) rcs $@ $^
clean:
rm -rf build

233
makefile
View file

@ -1,165 +1,118 @@
LIMINE_DIR = $(abspath dependencies/limine)
MINTSUKI_HEADERS_DIR = $(abspath dependencies/mintsuki-headers)
TOOLCHAIN_DIR = $(abspath toolchain)
# arguments are not strictly necessary to build
EXTRA_CC_ARGS = -Wall -Wextra -Og -ggdb -fno-exceptions
HILBERT_NASM = nasm -f elf64
HILBERT_CC = ${TOOLCHAIN_DIR}/usr/bin/x86_64-elf-c++ -std=c++20 \
${EXTRA_CC_ARGS} -static -mno-sse -I include -I $(abspath euler/include) \
-I $(abspath libraries/daguerre/include) -I ${MINTSUKI_HEADERS_DIR} \
-I $(abspath libraries/pake/include)
HILBERT_AR = ${TOOLCHAIN_DIR}/usr/bin/x86_64-elf-ar
HILBERT_LD = ${TOOLCHAIN_DIR}/usr/bin/x86_64-elf-ld -z noexecstack
.EXPORT_ALL_VARIABLES:
LIB_DIR = ${TOOLCHAIN_DIR}/usr/x86_64-elf/lib
LIMINE_DEP = dependencies/.limine-done
MINTSUKI_HEADERS_DEP = dependencies/.mintsuki-headers-done
BINUTILS_DEP = toolchain/.binutils-done
GCC_DEP = toolchain/.gcc-done
LIBGCC_DEP = toolchain/.libgcc-done
LIBSTDCPP_DEP = toolchain/.libstdcpp-done
EULER_DEP = toolchain/.euler-done
DAGUERRE_DEP = toolchain/.daguerre-done
PAKE_DEP = toolchain/.pake-done
APP_DEPS = ${EULER_DEP}
LIBRARY_DEPS = ${LIBSTDCPP_DEP}
.PHONY: default run clean clean-dependencies
CC_EXTRA_ARGS = -Wall -Wextra -Og -ggdb
.PHONY: default
default: build/disk.iso
run: build/disk.iso
gdb -x qemu.gdb
# command and arguments that you should be careful about changing
clean:
rm -rf build ${EULER_DEP} ${DAGUERRE_DEP} ${PAKE_DEP}
make -C euler clean
make -C kernel clean
make -C applications/init clean
make -C applications/goldman clean
make -C applications/hello clean
make -C applications/clock clean
make -C libraries/daguerre clean
make -C libraries/pake clean
NASM = nasm
CC = toolchain/usr/bin/x86_64-elf-c++
AR = toolchain/usr/bin/x86_64-elf-ar
LD = toolchain/usr/bin/x86_64-elf-ld
clean-dependencies: clean
rm -rf toolchain dependencies
KERNEL_INCLUDES = \
dependencies/limine \
dependencies/mintsuki-headers \
kernel/include
${LIMINE_DEP}:
mkdir -p dependencies
test -e dependencies/limine || git clone --depth 1 -b v7.5.1 https://github.com/limine-bootloader/limine dependencies/limine
cd ${LIMINE_DIR} && ./bootstrap
cd ${LIMINE_DIR} && ./configure --enable-bios --enable-bios-cd
+make -C ${LIMINE_DIR}
touch $@
USER_INCLUDES = \
dependencies/mintsuki-headers \
euler/include \
$(wildcard libraries/*/include)
${MINTSUKI_HEADERS_DEP}:
mkdir -p dependencies
test -e dependencies/mintsuki-headers || git clone --depth 1 https://github.com/osdev0/freestanding-headers dependencies/mintsuki-headers
cd dependencies/mintsuki-headers && git fetch --depth=1 origin dd3abd2d7147efc4170dff478d3b7730bed14147
cd dependencies/mintsuki-headers && git checkout dd3abd2d7147efc4170dff478d3b7730bed14147
patch dependencies/mintsuki-headers/stddef.h patches/mintsuki-stddef.patch
touch $@
NASM_ARGS = -f elf64
${BINUTILS_DEP}:
mkdir -p dependencies toolchain/usr
test -e dependencies/binutils || git clone --depth 1 -b binutils-2_42 https://sourceware.org/git/binutils-gdb dependencies/binutils
mkdir -p dependencies/binutils/build
cd dependencies/binutils/build && ../configure --disable-gdb \
--target=x86_64-elf --prefix=${TOOLCHAIN_DIR}/usr
+make -C dependencies/binutils/build
+make -C dependencies/binutils/build install
touch $@
CC_ARGS_COMMON = -std=c++20 -static -mno-sse -Iinclude ${CC_EXTRA_ARGS}
CC_ARGS_KERNEL = \
${CC_ARGS_COMMON} -ffreestanding -fno-exceptions \
-fno-rtti -mcmodel=kernel ${KERNEL_INCLUDES:%=-I%}
CC_ARGS_USER = ${CC_ARGS_COMMON} ${USER_INCLUDES:%=-I%}
${GCC_DEP}: ${BINUTILS_DEP}
mkdir -p toolchain/usr/include
test -e dependencies/gcc || git clone --depth 1 -b releases/gcc-14.1.0 https://gcc.gnu.org/git/gcc dependencies/gcc
mkdir -p dependencies/gcc/build
cd dependencies/gcc/build && ../configure --disable-fixed-point \
--disable-gcov --disable-multilib --disable-shared \
--disable-hosted-libstdcxx \
--enable-languages=c++ --target=x86_64-elf --enable-cstdio=stdio_pure \
--prefix=${TOOLCHAIN_DIR}/usr --without-headers --enable-cxx-flags=-mno-sse
+make -C dependencies/gcc/build all-gcc
+make -C dependencies/gcc/build install-gcc
touch $@
LD_ARGS = -z noexecstack
${LIBGCC_DEP}: ${GCC_DEP}
+make -C dependencies/gcc/build all-target-libgcc
+make -C dependencies/gcc/build install-target-libgcc
touch $@
LIBDIR = toolchain/usr/x86_64-elf/lib
${LIBSTDCPP_DEP}: ${LIBGCC_DEP}
+make -C dependencies/gcc/build all-target-libstdc++-v3
+make -C dependencies/gcc/build install-target-libstdc++-v3
patch toolchain/usr/x86_64-elf/include/c++/14.1.0/memory patches/gcc-memory.patch
touch $@
SOURCES_FIND = -type f -regex '.*\.\(asm\|cpp\)'
.PHONY: ${EULER_DEP}
${EULER_DEP}: ${LIBRARY_DEPS}
+make -C euler build/crt0.o build/libc.a build/libg.a build/libm.a
mkdir -p ${LIB_DIR}
cp euler/build/crt0.o euler/build/libc.a \
euler/build/libg.a euler/build/libm.a ${LIB_DIR}/
touch $@
# kernel section
.PHONY: ${DAGUERRE_DEP}
${DAGUERRE_DEP}: ${LIBRARY_DEPS}
+make -C libraries/daguerre build/libdaguerre.a
cp libraries/daguerre/build/libdaguerre.a ${LIB_DIR}/
touch $@
build/kernel/%.asm.o: kernel/%.asm
@mkdir -p ${@D}
${NASM} ${NASM_ARGS} $^ -o $@
.PHONY: ${PAKE_DEP}
${PAKE_DEP}: ${LIBRARY_DEPS}
+make -C libraries/pake build/libpake.a
cp libraries/pake/build/libpake.a ${LIB_DIR}/
touch $@
build/kernel/%.cpp.o: kernel/%.cpp
@mkdir -p ${@D}
${CC} -c ${CC_ARGS_KERNEL} $^ -o $@
.PHONY: kernel/build/kernel.elf
kernel/build/kernel.elf: ${GCC_DEP} ${MINTSUKI_HEADERS_DEP} ${LIMINE_DEP}
+make -C kernel build/kernel.elf
KERNEL_SOURCES = $(shell find kernel/source ${SOURCES_FIND})
build/kernel.elf: ${KERNEL_SOURCES:%=build/%.o}
${LD} ${LD_ARGS} -T kernel/link.ld $^ -o $@
.PHONY: applications/init/build/init.elf
applications/init/build/init.elf: ${APP_DEPS}
+make -C applications/init build/init.elf
# euler section
.PHONY: applications/goldman/build/goldman.elf
applications/goldman/build/goldman.elf: ${APP_DEPS} ${DAGUERRE_DEP}
+make -C applications/goldman build/goldman.elf
build/euler/%.asm.o: euler/%.asm
@mkdir -p ${@D}
${NASM} ${NASM_ARGS} $^ -o $@
.PHONY: applications/hello/build/hello.elf
applications/hello/build/hello.elf: ${APP_DEPS} ${DAGUERRE_DEP} ${PAKE_DEP}
+make -C applications/hello build/hello.elf
build/euler/%.cpp.o: euler/%.cpp
@mkdir -p ${@D}
${CC} -c ${CC_ARGS_USER} -ffreestanding $^ -o $@
.PHONY: applications/clock/build/clock.elf
applications/clock/build/clock.elf: ${APP_DEPS} ${DAGUERRE_DEP} ${PAKE_DEP}
+make -C applications/clock build/clock.elf
EULER_SOURCES = $(shell find euler/source ${SOURCES_FIND})
${LIBDIR}/crt0.o ${LIBDIR}/libc.a ${LIBDIR}/libg.a ${LIBDIR}/libm.a build/euler.a&: ${EULER_SOURCES:%=build/%.o}
${AR} rcs build/euler.a $^
cp build/euler.a ${LIBDIR}/libc.a
${NASM} ${NASM_ARGS} /dev/null -o ${LIBDIR}/crt0.o
${AR} rcs ${LIBDIR}/libg.a ${LIBDIR}/crt0.o
${AR} rcs ${LIBDIR}/libm.a ${LIBDIR}/crt0.o
build/initfs.tgz: applications/init/build/init.elf \
applications/goldman/build/goldman.elf \
applications/hello/build/hello.elf \
applications/clock/build/clock.elf
@mkdir -p build
# libraries and applications section
ALL_LIBRARIES = daguerre pake
ALL_APPLICATIONS = clock goldman hello init
clock_LIBRARIES = daguerre pake
goldman_LIBRARIES = daguerre
hello_LIBRARIES = daguerre pake
init_LIBRARIES =
build/%.cpp.o: %.cpp
@mkdir -p ${@D}
${CC} -c ${CC_ARGS_USER} $^ -o $@
# ${1} = library name
define LIBRARY_TEMPLATE =
${1}_SOURCES = $$(shell find libraries/${1}/source $${SOURCES_FIND})
$${LIBDIR}/lib${1}.a build/libraries/lib${1}.a&: $${${1}_SOURCES:%=build/%.o}
$${AR} rcs build/libraries/lib${1}.a $$^
cp build/libraries/lib${1}.a $${LIBDIR}/lib${1}.a
endef
# ${1} = application name
define APPLICATION_TEMPLATE =
${1}_SOURCES = $$(shell find applications/${1}/source $${SOURCES_FIND})
build/applications/${1}.elf: $${${1}_SOURCES:%=build/%.o} $${${1}_LIBRARIES:%=$${LIBDIR}/lib%.a} $${LIBDIR}/libc.a
$${CC} ${CC_ARGS_USER} $${${1}_SOURCES:%=build/%.o} $$(patsubst %,-l%,$${${1}_LIBRARIES}) -o $$@
endef
$(foreach library,${ALL_LIBRARIES},$(eval $(call LIBRARY_TEMPLATE,${library})))
$(foreach application,${ALL_APPLICATIONS},$(eval $(call APPLICATION_TEMPLATE,${application})))
# initfs and disk section
build/initfs.tgz: ${ALL_APPLICATIONS:%=build/applications/%.elf}
rm -rf build/initfs
cp -r skeleton build/initfs
cp applications/init/build/init.elf build/initfs/bin/init
cp applications/goldman/build/goldman.elf build/initfs/bin/goldman
cp applications/hello/build/hello.elf build/initfs/bin/hello
cp applications/clock/build/clock.elf build/initfs/bin/clock
$(foreach application,${ALL_APPLICATIONS},cp build/applications/${application}.elf build/initfs/bin/${application}; )
cd build/initfs && tar czf ../initfs.tgz .
build/disk.iso: kernel/build/kernel.elf build/initfs.tgz ${LIMINE_DEP}
@mkdir -p build
build/disk.iso: build/kernel.elf build/initfs.tgz
rm -rf build/iso
mkdir build/iso
cp kernel/build/kernel.elf ${LIMINE_DIR}/bin/limine-bios.sys \
${LIMINE_DIR}/bin/limine-bios-cd.bin build/initfs.tgz build/iso/
cp dependencies/limine/bin/limine-bios.sys dependencies/limine/bin/limine-bios-cd.bin \
build/kernel.elf build/initfs.tgz build/iso/
echo 'TIMEOUT=0' > build/iso/limine.cfg
echo ':Hilbert OS' >> build/iso/limine.cfg
echo 'PROTOCOL=limine' >> build/iso/limine.cfg
@ -168,3 +121,13 @@ build/disk.iso: kernel/build/kernel.elf build/initfs.tgz ${LIMINE_DEP}
echo 'MODULE_CMDLINE=initfs' >> build/iso/limine.cfg
xorriso -as mkisofs -b limine-bios-cd.bin -no-emul-boot -boot-load-size 4 \
-boot-info-table --protective-msdos-label build/iso -o $@
# phony targets
.PHONY: run
run: build/disk.iso
gdb -x qemu.gdb
.PHONY: clean
clean:
rm -rf build ${LIBDIR}/crt0.o ${LIBDIR}/libc.a ${LIBDIR}/libg.a ${LIBDIR}/libm.a $(foreach library,${ALL_LIBRARIES},${LIBDIR}/lib${library}.a)

View file

@ -1,5 +1,5 @@
target remote | qemu-system-x86_64 -gdb stdio -cdrom build/disk.iso -boot d
symbol-file kernel/build/kernel.elf
symbol-file build/kernel.elf
set disassembly-flavor intel
set print asm-demangle on
layout src

View file

@ -1,14 +1,31 @@
hilbert os is a 64-bit hobby operating system, which is not very mature yet. to
build and test it, you will need some software installed. on debian, i believe
running command [1] below as root (e.g. with sudo) is sufficient. the default
makefile target builds a disk image at build/disk.iso that can be booted on a
64-bit bios system. you can use command [2] to build that. finally, use
command [3] to run the disk in qemu with gdb attached.
the packages listed below are sufficient.
[1] apt install bison flex g++ gdb git libgmp-dev libmpfr-dev
libmpc-dev make nasm qemu-system-x86 texinfo xorriso
[2] make -j$(nproc)
[3] make run
- bison
- flex
- g++
- gdb
- git
- libgmp-dev
- libmpfr-dev
- libmpc-dev
- make
- nasm
- qemu-system-x86
- texinfo
- xorriso
next, you will need to download and compile some dependencies. the script in
setup.sh will do this for you. if it sees an environment variables MAKEOPTS, it
will pass the contents of that as arguments to invocations of make. otherwise,
it defaults to "-j$(nproc)". if you nead to clean that setup for any reason,
you can use the script in clean-setup.sh.
now that we have all the dependencies, just run "make". the default target is
build/disk.iso, a bios-bootable disk image. you can run "make debug" to start
qemu with that disk, and attach gdb to it. you can also use "make clean" to
remove all of the files that "make" creates.
acknowledgements (any under "dependencies" are downloaded during build):
@ -59,6 +76,12 @@ license in isc.txt (isc license):
- libraries
- makefile
the following file are released under the text in 0bsd.txt (zero-clause bsd):
- clean-setup.sh
- makefile
- setup.sh
the following directories and files are released under the text in cc0.txt
(creative commons cc0 1.0 universal public domain dedication):

76
setup.sh Normal file
View file

@ -0,0 +1,76 @@
#!/bin/sh
LIMINE_TAG=v7.5.1
MINTSUKI_HEADERS_COMMIT=dd3abd2d7147efc4170dff478d3b7730bed14147
BINUTILS_TAG=binutils-2_42
GCC_TAG=releases/gcc-14.1.0
PROJECT_ROOT="$(pwd)"
if [ -e .setup-complete ]; then
echo setup has already completed. refusing to run again.
echo to run again anyway, delete .setup-complete
echo to clean the dependencies, run clean-dependencies.sh
exit 1
fi
if [ -e .setup-started ]; then
echo setup has already been started, but failed. refusing to run again.
echo to run again anyway, delete .setup-started
echo to clean the dependencies, run clean-dependencies.sh
exit 1
fi
if [ -z "$MAKEOPTS" ]; then
MAKEOPTS=-j$(nproc)
fi
touch .setup-started
set -e
mkdir -p dependencies toolchain/usr
cd dependencies
git clone --depth 1 -b "$LIMINE_TAG" https://github.com/limine-bootloader/limine limine
cd limine
./bootstrap
./configure --enable-bios --enable-bios-cd
make $MAKEOPTS
cd ..
git clone --depth 1 https://github.com/osdev0/freestanding-headers mintsuki-headers
cd mintsuki-headers
git fetch --depth=1 origin "$MINTSUKI_HEADERS_COMMIT"
git checkout "$MINTSUKI_HEADERS_COMMIT"
patch stddef.h "$PROJECT_ROOT"/patches/mintsuki-stddef.patch
cd ..
git clone --depth 1 -b "$BINUTILS_TAG" https://sourceware.org/git/binutils-gdb binutils
mkdir binutils/build
cd binutils/build
../configure --disable-gdb --target=x86_64-elf --prefix="$PROJECT_ROOT"/toolchain/usr
make $MAKEOPTS
make $MAKEOPTS install
cd ../..
git clone --depth 1 -b "$GCC_TAG" https://gcc.gnu.org/git/gcc gcc
mkdir gcc/build
cd gcc/build
../configure --disable-fixed-point --disable-gcov --disable-multilib \
--disable-shared --disable-hosted-libstdcxx --enable-languages=c++ \
--target=x86_64-elf --enable-cstdio=stdio_pure \
--prefix="$PROJECT_ROOT"/toolchain/usr --without-headers \
--enable-cxx-flags=-mno-sse
make $MAKEOPTS all-gcc
make $MAKEOPTS install-gcc
make $MAKEOPTS all-target-libgcc
make $MAKEOPTS install-target-libgcc
make $MAKEOPTS all-target-libstdc++-v3
make $MAKEOPTS install-target-libstdc++-v3
patch "$PROJECT_ROOT"/toolchain/usr/x86_64-elf/include/c++/14.1.0/memory \
"$PROJECT_ROOT"/patches/gcc-memory.patch
cd ../..
cd ..
touch .setup-complete