Moving to a ninja-based build system

This commit is contained in:
Justin C. Miller
2019-02-02 02:59:45 -08:00
parent 523d0b3b8c
commit 0f8efdb55e
24 changed files with 604 additions and 507 deletions

4
.gitignore vendored
View File

@@ -1,11 +1,9 @@
.lock* .lock*
build /build*
*.bak *.bak
tags tags
.gdbinit .gdbinit
popcorn.log popcorn.log
.waf-*
*.o *.o
*.a *.a
sysroot sysroot
.sconsign*

View File

@@ -122,40 +122,6 @@ to assume any extra rights that may not actually be granted) for it here:
Popcorn's UEFI loader uses code from Intel's EFI Application toolkit. Relevant Popcorn's UEFI loader uses code from Intel's EFI Application toolkit. Relevant
code includes license statements at the top of each file. code includes license statements at the top of each file.
## Waf
Popcorn's build system uses [Waf](https://waf.io/), which claims to be released
under the BSD license. I could not find its specific license file, so I am
reproducing a generic 3-clause BSD license (the most restrictive, so as not to
assume any extra rights that may not actually be granted) for it here:
> Copyright © 2005-2018 Thomas Nagy
>
> Redistribution and use in source and binary forms, with or without
> modification, are permitted provided that the following conditions are met:
>
> 1. Redistributions of source code must retain the above copyright notice, this
> list of conditions and the following disclaimer.
>
> 2. Redistributions in binary form must reproduce the above copyright notice,
> this list of conditions and the following disclaimer in the documentation
> and/or other materials provided with the distribution.
>
> 3. Neither the name of the copyright holder nor the names of its contributors
> may be used to endorse or promote products derived from this software
> without specific prior written permission.
>
> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
> ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
> FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
> SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
> OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Vendored 'external' works # Vendored 'external' works
The `external` directory has several libraries' built outputs vendored into it. The `external` directory has several libraries' built outputs vendored into it.

View File

@@ -1,53 +0,0 @@
from os.path import join
import SCons.Node
def target_from_source_nosplit(node, prefix, suffix, splitext):
return node.dir.Entry(prefix + node.name + suffix)
SCons.Node._target_from_source_map['nosplit'] = target_from_source_nosplit
SCons.Node._target_from_source_map[1] = target_from_source_nosplit
def RGlob(path, pattern):
from os import walk
from itertools import chain
return list(chain.from_iterable([Glob(join(d, pattern)) for d, _, _ in walk(path)]))
def subdirs(path):
from os import listdir
from os.path import isdir, join
return [d for d in listdir(path) if isdir(join(path, d))]
SetOption('implicit_cache', 1)
Decider('MD5-timestamp')
VariantDir('src', 'build', duplicate=0)
env = SConscript('scons/default_env.scons')
target = SConscript('scons/target_env.scons', 'env')
libs = {}
for lib in subdirs('src/libraries'):
libs[lib] = SConscript(join('src/libraries', lib, 'SConscript'), 'target RGlob')
kernel = target.Clone()
kernel.Append(CCFLAGS = [
'-mno-sse',
'-mno-red-zone',
])
kernel.Append(
CPPPATH = [
'src/kernel',
'src/libraries/elf/include',
'src/libraries/initrd/include',
'src/libraries/kutil/include',
],
ASFLAGS = ['-I', 'src/kernel/'],
LIBS = libs.values() + ['c'],
LINKFLAGS = ['-T', File('#src/arch/x86_64/kernel.ld').abspath],
)
kernel.Program(
'popcorn.elf',
RGlob('src/kernel', '*.cpp') +
RGlob('src/kernel', '*.s'))
# vim: ft=python et

120
generate_build.py Executable file
View File

@@ -0,0 +1,120 @@
#!/usr/bin/env python3
from collections import namedtuple
library = namedtuple('library', ['path', 'deps'])
program = namedtuple('program', ['path', 'deps', 'output', 'targets'])
source = namedtuple('source', ['name', 'input', 'output', 'action'])
version = namedtuple('version', ['major', 'minor', 'patch', 'sha'])
MODULES = {
"elf": library('src/libraries/elf', ['kutil']),
"initrd": library('src/libraries/initrd', ["kutil"]),
"kutil": library('src/libraries/kutil', []),
"makerd": program('src/tools/makerd', ["initrd", "kutil"], "makerd", ["native"]),
"boot": program('src/boot', ["elf"], "boot.elf", ["host"]),
"kernel": program('src/kernel', ["elf", "initrd", "kutil"], "popcorn.elf", ["host"]),
}
def get_template(env, typename, name):
from jinja2.exceptions import TemplateNotFound
try:
return env.get_template("{}.{}.ninja.j2".format(typename, name))
except TemplateNotFound:
return env.get_template("{}.default.ninja.j2".format(typename))
def get_sources(path):
import os
from os.path import abspath, join, splitext
actions = {'.c': 'cc', '.cpp': 'cxx', '.s': 'nasm'}
sources = []
for root, dirs, files in os.walk(path):
for f in files:
base, ext = splitext(f)
if not ext in actions: continue
name = join(root, f)
sources.append(
source(
name,
abspath(name),
f + ".o",
actions[ext]))
return sources
def get_git_version():
return version(0,5,0,'aaaaaa')
def main(buildroot):
import os
from os.path import abspath, dirname, isdir, join
buildroot = abspath(buildroot)
srcroot = dirname(abspath(__file__))
if not isdir(buildroot):
os.mkdir(buildroot)
git_version = get_git_version()
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader("scripts/templates"))
targets = {}
for name, mod in MODULES.items():
if isinstance(mod, program):
for target in mod.targets:
if not target in targets:
targets[target] = set()
open_list = [name]
while open_list:
depname = open_list.pop()
dep = MODULES[depname]
open_list.extend(dep.deps)
targets[target].add(depname)
sources = get_sources(mod.path)
with open(join(buildroot, name + ".ninja"), 'w') as out:
print("Generating module", name)
template = get_template(env, type(mod).__name__, name)
out.write(template.render(
name=name,
module=mod,
sources=sources,
version=git_version))
for target, mods in targets.items():
root = join(buildroot, target)
if not isdir(root):
os.mkdir(root)
with open(join(root, "target.ninja"), 'w') as out:
print("Generating target", target)
template = get_template(env, "target", target)
out.write(template.render(
target=target,
modules=mods,
version=git_version))
with open(join(buildroot, 'build.ninja'), 'w') as out:
print("Generating main build.ninja")
template = env.get_template('build.ninja.j2')
out.write(template.render(
targets=targets,
buildroot=buildroot,
srcroot=srcroot,
version=git_version))
if __name__ == "__main__":
import sys
buildroot = "build"
if len(sys.argv) > 1:
buildroot = sys.argv[1]
main(buildroot)

View File

@@ -1,85 +0,0 @@
from subprocess import check_output
target = 'x86_64-elf'
version = check_output("git describe --always", shell=True).strip()
git_sha = check_output("git rev-parse --short HEAD", shell=True).strip()
major, minor, patch_dirty = version.split(".")
dirty = 'dirty' in patch_dirty
patch = patch_dirty.split('-')[0]
defines = {
'GIT_VERSION': r'\"{}\"'.format(version),
'GIT_VERSION_WIDE': r'L\"{}\"'.format(version),
'VERSION_MAJOR': major,
'VERSION_MINOR': minor,
'VERSION_PATCH': patch,
'VERSION_GITSHA': '0x{}{}'.format({True:1}.get(dirty, 0), git_sha),
}
warnings = [
'format=2',
'init-self',
'float-equal',
'inline',
'missing-format-attribute',
'missing-include-dirs',
'switch',
'undef',
'disabled-optimization',
'pointer-arith',
'no-attributes',
'no-sign-compare',
'no-multichar',
'no-div-by-zero',
'no-endif-labels',
'no-pragmas',
'no-format-extra-args',
'no-unused-result',
'no-deprecated-declarations',
'no-unused-function',
'error'
]
asflags = ['-felf64']
asflags += ['-D{}={}'.format(k,v) for k, v in defines.items()]
ccflags = [
'--sysroot={}'.format(Dir('#sysroot').abspath),
]
ccflags += ['-W{}'.format(opt) for opt in warnings]
env = Environment(
#CC = File('#sysroot/bin/' + target + '-gcc').abspath,
#CXX = File('#sysroot/bin/' + target + '-g++').abspath,
LINK = File('#sysroot/bin/' + target + '-ld').abspath,
CC = File('#sysroot/bin/clang').abspath,
CXX = File('#sysroot/bin/clang++').abspath,
#LINK = File('#sysroot/bin/ld.lld').abspath,
AS = File('#sysroot/bin/nasm').abspath,
ASFLAGS = asflags,
CXXFLAGS = [
'-std=c++14',
'-isystem', Dir('#sysroot/include/c++/v1').abspath,
],
CFLAGS = ['-std=c11'],
CCFLAGS = ccflags,
CPPPATH = ['src/include'],
CPPDEFINES = defines,
LINKFLAGS = ['-static'],
LIBPATH = ['#sysroot/lib'],
#CCCOMSTR = ' compile $TARGET',
#CXXCOMSTR = ' compile $TARGET',
#ASCOMSTR = ' assemble $TARGET',
#LINKCOMSTR = ' link $TARGET',
ARCOMSTR = ' archive $TARGET',
RANLIBCOMSTR = ' ranlib $TARGET',
)
Return('env')
# vim: ft=python et

View File

@@ -1,2 +0,0 @@
# vim: ft=python et

View File

@@ -1,47 +0,0 @@
Import('env')
env = env.Clone()
env.Append(
CCFLAGS = [
'-nodefaultlibs',
'-nostdinc',
'-nostdlib',
#'-nolibc',
'-ffreestanding',
'-fno-omit-frame-pointer',
'-isystem', 'sysroot/include',
'-mcmodel=large',
'-fno-PIC',
],
LINKFLAGS = [
'-g',
'-nostdlib',
#'-znocombreloc',
#'-Bsymbolic',
'-nostartfiles',
],
LIBS = [
#'c++',
#'c++abi',
'unwind',
],
CXXFLAGS = [
#'-nostdlibinc',
'-fno-exceptions',
'-fno-rtti',
'-D_LIBCPP_NO_EXCEPTIONS',
'-D_LIBCPP_HAS_NO_THREADS',
'-D__ELF__',
'-mcmodel=large',
],
)
Return('env')
# vim: ft=python et

View File

@@ -18,6 +18,7 @@ mkdir -p "${WORK}"
export CC=clang export CC=clang
export CXX=clang++ export CXX=clang++
function build_nasm() {
if [[ ! -d "${WORK}/nasm-${NASM_VERSION}" ]]; then if [[ ! -d "${WORK}/nasm-${NASM_VERSION}" ]]; then
echo "Downloading NASM..." echo "Downloading NASM..."
tarball="nasm-${NASM_VERSION}.tar.gz" tarball="nasm-${NASM_VERSION}.tar.gz"
@@ -25,6 +26,25 @@ if [[ ! -d "${WORK}/nasm-${NASM_VERSION}" ]]; then
tar xzf "${tarball}" -C "${WORK}" && rm "${tarball}" tar xzf "${tarball}" -C "${WORK}" && rm "${tarball}"
fi fi
mkdir -p "${WORK}/build/nasm"
pushd "${WORK}/build/nasm"
if [[ ! -f "${WORK}/build/nasm/config.cache" ]]; then
echo "Configuring NASM..."
"${WORK}/nasm-${NASM_VERSION}/configure" \
--quiet \
--config-cache \
--disable-werror \
--prefix="${SYSROOT}" \
--srcdir="${WORK}/nasm-${NASM_VERSION}"
fi
echo "Building NASM..."
(make -j && make install) > "${WORK}/build/nasm_build.log"
popd
}
function build_binutils() {
if [[ ! -d "${WORK}/binutils-${BINUTILS_VERSION}" ]]; then if [[ ! -d "${WORK}/binutils-${BINUTILS_VERSION}" ]]; then
echo "Downloading binutils..." echo "Downloading binutils..."
tarball="binutils-${BINUTILS_VERSION}.tar.gz" tarball="binutils-${BINUTILS_VERSION}.tar.gz"
@@ -32,6 +52,28 @@ if [[ ! -d "${WORK}/binutils-${BINUTILS_VERSION}" ]]; then
tar xzf "${tarball}" -C "${WORK}" && rm "${tarball}" tar xzf "${tarball}" -C "${WORK}" && rm "${tarball}"
fi fi
mkdir -p "${WORK}/build/binutils"
pushd "${WORK}/build/binutils"
if [[ ! -f "${WORK}/build/binutils/config.cache" ]]; then
echo "Configuring binutils..."
"${WORK}/binutils-${BINUTILS_VERSION}/configure" \
--quiet \
--config-cache \
--target="${TARGET}" \
--prefix="${SYSROOT}" \
--with-sysroot="${SYSROOT}" \
--with-lib-path="${SYSROOT}/lib" \
--disable-nls \
--disable-werror
fi
echo "Building binutils..."
(make -j && make install) > "${WORK}/build/binutils_build.log"
popd
}
function build_llvm() {
if [[ ! -d "${WORK}/llvm" ]]; then if [[ ! -d "${WORK}/llvm" ]]; then
echo "Downloading LLVM..." echo "Downloading LLVM..."
git clone -q \ git clone -q \
@@ -78,69 +120,22 @@ for proj in ${RUNTIMES}; do
fi fi
done done
if [[ ! -d "${WORK}/poplibc" ]]; then
echo "Downloading poplibc..."
git clone \
"https://github.com/justinian/poplibc.git" \
"${WORK}/poplibc"
else
echo "Updating poplibc..."
git -C "${WORK}/poplibc" pull
fi
mkdir -p "${WORK}/build/nasm"
pushd "${WORK}/build/nasm"
echo "Configuring NASM..."
"${WORK}/nasm-${NASM_VERSION}/configure" \
--quiet \
--config-cache \
--prefix="${SYSROOT}" \
--srcdir="${WORK}/nasm-${NASM_VERSION}"
echo "Building NASM..."
(make -j && make install) > nasm_build.log
popd
mkdir -p "${WORK}/build/binutils"
pushd "${WORK}/build/binutils"
echo "Configuring binutils..."
"${WORK}/binutils-${BINUTILS_VERSION}/configure" \
--quiet \
--target="${TARGET}" \
--prefix="${SYSROOT}" \
--with-sysroot \
--disable-nls \
--disable-werror
echo "Building binutils..."
(make -j && make install) > "${WORK}/build/binutils_build.log"
popd
mkdir -p "${WORK}/build/llvm" mkdir -p "${WORK}/build/llvm"
pushd "${WORK}/build/llvm" pushd "${WORK}/build/llvm"
echo "Configuring LLVM..." echo "Configuring LLVM..."
cmake -G Ninja \ cmake -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCLANG_DEFAULT_RTLIB=compiler-rt \ -DCLANG_DEFAULT_RTLIB=compiler-rt \
-DCLANG_DEFAULT_STD_C=c11 \ -DCLANG_DEFAULT_STD_C=c11 \
-DCLANG_DEFAULT_STD_CXX=cxx14 \ -DCLANG_DEFAULT_STD_CXX=cxx14 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="clang" \ -DCMAKE_C_COMPILER="clang" \
-DCMAKE_CXX_COMPILER="clang++" \ -DCMAKE_CXX_COMPILER="clang++" \
-DCMAKE_CXX_FLAGS="-Wno-unused-parameter -D_LIBCPP_HAS_NO_ALIGNED_ALLOCATION -D_LIBUNWIND_IS_BAREMETAL=1 -U_LIBUNWIND_SUPPORT_DWARF_UNWIND" \ -DCMAKE_CXX_FLAGS="-Wno-unused-parameter -D_LIBCPP_HAS_NO_ALIGNED_ALLOCATION -D_LIBUNWIND_IS_BAREMETAL=1 -U_LIBUNWIND_SUPPORT_DWARF_UNWIND" \
-DCMAKE_INSTALL_PREFIX="${SYSROOT}" \ -DCMAKE_INSTALL_PREFIX="${SYSROOT}" \
-DCMAKE_MAKE_PROGRAM=`which ninja` \ -DCMAKE_MAKE_PROGRAM=`which ninja` \
-DDEFAULT_SYSROOT="${SYSROOT}" \ -DDEFAULT_SYSROOT="${SYSROOT}" \
-DLLVM_CONFIG_PATH="${SYSROOT}/bin/llvm-config" \
-DLLVM_DEFAULT_TARGET_TRIPLE="x86_64-unknown-elf" \
-DLLVM_INSTALL_BINUTILS_SYMLINKS=ON \
-DLLVM_TARGETS_TO_BUILD="X86" \
-DCMAKE_INSTALL_PREFIX="${SYSROOT}" \
-DCMAKE_MAKE_PROGRAM=`which ninja` \
-DLIBCXX_CXX_ABI=libcxxabi \ -DLIBCXX_CXX_ABI=libcxxabi \
-DLIBCXX_CXX_ABI_INCLUDE_PATHS="${WORK}/llvm/projects/libcxxabi/include" \ -DLIBCXX_CXX_ABI_INCLUDE_PATHS="${WORK}/llvm/projects/libcxxabi/include" \
-DLIBCXX_CXX_ABI_LIBRARY_PATH=lib \ -DLIBCXX_CXX_ABI_LIBRARY_PATH=lib \
@@ -152,9 +147,9 @@ cmake -G Ninja \
-DLIBCXX_INCLUDE_BENCHMARKS=OFF \ -DLIBCXX_INCLUDE_BENCHMARKS=OFF \
-DLIBCXX_USE_COMPILER_RT=ON \ -DLIBCXX_USE_COMPILER_RT=ON \
-DLIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS=OFF \ -DLIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS=OFF \
-DLIBCXXABI_ENABLE_THREADS=OFF \
-DLIBCXXABI_ENABLE_SHARED=OFF \ -DLIBCXXABI_ENABLE_SHARED=OFF \
-DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON \ -DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON \
-DLIBCXXABI_ENABLE_THREADS=OFF \
-DLIBCXXABI_LIBCXX_PATH="${WORK}/llvm/projects/libcxx" \ -DLIBCXXABI_LIBCXX_PATH="${WORK}/llvm/projects/libcxx" \
-DLIBCXXABI_USE_COMPILER_RT=ON \ -DLIBCXXABI_USE_COMPILER_RT=ON \
-DLIBCXXABI_USE_LLVM_UNWINDER=ON \ -DLIBCXXABI_USE_LLVM_UNWINDER=ON \
@@ -166,90 +161,60 @@ cmake -G Ninja \
-DLLVM_ENABLE_LIBCXX=ON \ -DLLVM_ENABLE_LIBCXX=ON \
-DLLVM_ENABLE_PIC=OFF \ -DLLVM_ENABLE_PIC=OFF \
-DLLVM_ENABLE_THREADS=OFF \ -DLLVM_ENABLE_THREADS=OFF \
-DLLVM_ENABLE_THREADS=OFF \
-DLLVM_INSTALL_BINUTILS_SYMLINKS=ON \ -DLLVM_INSTALL_BINUTILS_SYMLINKS=ON \
-DLLVM_TARGETS_TO_BUILD="X86" \ -DLLVM_TARGETS_TO_BUILD="X86" \
${WORK}/llvm > cmake_configure.log ${WORK}/llvm > cmake_configure.log
# -DCMAKE_ASM_COMPILER=nasm \
# -DCMAKE_LINKER="${SYSROOT}/bin/ld.lld" \
# -DCOMPILER_RT_ENABLE_LLD=ON \
# -DLIBCXX_ENABLE_LLD=ON \
# -DLIBCXX_ENABLE_STATIC_UNWINDER=ON \
# -DLIBCXXABI_ENABLE_LLD=ON \
# -DLIBUNWIND_ENABLE_LLD=ON \
# -DLLVM_ENABLE_LLD=ON \
# -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi;libunwind;compiler-rt" \
# -DCOMPILER_RT_BAREMETAL_BUILD=ON \
# -DLIBCXXABI_BAREMETAL=ON \
echo "Building LLVM..." echo "Building LLVM..."
ninja && ninja install ninja && ninja install
ninja cxx cxxabi compiler-rt ninja cxx cxxabi compiler-rt
ninja install-compiler-rt install-cxx install-cxxabi ninja install-compiler-rt install-cxx install-cxxabi
popd popd
}
function build_libc() {
if [[ ! -d "${WORK}/poplibc" ]]; then
echo "Downloading poplibc..."
git clone \
"https://github.com/justinian/poplibc.git" \
"${WORK}/poplibc"
else
echo "Updating poplibc..."
git -C "${WORK}/poplibc" pull
fi
pushd "${WORK}/poplibc" pushd "${WORK}/poplibc"
echo "Building poplibc..." echo "Building poplibc..."
export CC="${SYSROOT}/bin/clang" make install PREFIX="${SYSROOT}"
export LD="${SYSROOT}/bin/${TARGET}-ld"
export AR="${SYSROOT}/bin/${TARGET}-ar"
make -j install PREFIX="${SYSROOT}"
popd popd
}
function update_links() {
for exe in `ls "${SYSROOT}/bin/${TARGET}-"*`; do
base=$(echo "$exe" | sed -e "s/${TARGET}-//")
ln -fs "${exe}" "${base}"
done
}
# build_nasm
# mkdir -p ${WORK}/build/llvm build_binutils
# pushd ${WORK}/build/llvm build_libc
# build_llvm
# cmake -G Ninja \ update_links
# -DCLANG_DEFAULT_RTLIB=compiler-rt \
# -DCLANG_DEFAULT_STD_C=c11 \ export CC="${SYSROOT}/bin/clang"
# -DCLANG_DEFAULT_STD_CXX=cxx14 \ export CXX="${SYSROOT}/bin/clang++"
# -DCMAKE_ASM_COMPILER=nasm \ export LD="${SYSROOT}/bin/ld.lld"
# -DCMAKE_C_COMPILER="clang" \ build_libc
# -DCMAKE_CXX_COMPILER="clang++" \
# -DDEFAULT_SYSROOT="${SYSROOT}" \
# -DCMAKE_CXX_FLAGS="-v" \
# -DCMAKE_INSTALL_PREFIX="${SYSROOT}" \
# -DCMAKE_LINKER="${SYSROOT}/bin/ld.lld" \
# -DCMAKE_MAKE_PROGRAM=`which ninja` \
# -DCOMPILER_RT_ENABLE_LLD=ON \
# -DLIBCXX_CXX_ABI=libcxxabi \
# -DLIBCXX_CXX_ABI_INCLUDE_PATHS=${WORK}/libcxxabi/include \
# -DLIBCXX_CXX_ABI_LIBRARY_PATH=lib \
# -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF \
# -DLIBCXX_ENABLE_LLD=ON \
# -DLIBCXX_ENABLE_NEW_DELETE_DEFINITIONS=ON \
# -DLIBCXX_ENABLE_SHARED=OFF \
# -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=ON \
# -DLIBCXX_ENABLE_STATIC_UNWINDER=ON \
# -DLIBCXX_ENABLE_THREADS=OFF \
# -DLIBCXX_INCLUDE_BENCHMARKS=OFF \
# -DLIBCXX_USE_COMPILER_RT=ON \
# -DLIBCXXABI_ENABLE_LLD=ON \
# -DLIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS=OFF \
# -DLIBCXXABI_ENABLE_THREADS=OFF \
# -DLIBCXXABI_ENABLE_SHARED=OFF \
# -DLIBCXXABI_ENABLE_STATIC_UNWINDER=ON \
# -DLIBCXXABI_LIBCXX_PATH=${WORK}/libcxx \
# -DLIBCXXABI_USE_COMPILER_RT=ON \
# -DLIBCXXABI_USE_LLVM_UNWINDER=ON \
# -DLIBUNWIND_ENABLE_LLD=ON \
# -DLIBUNWIND_ENABLE_SHARED=OFF \
# -DLIBUNWIND_ENABLE_THREADS=OFF \
# -DLIBUNWIND_USE_COMPILER_RT=ON \
# -DLLVM_CONFIG_PATH="${SYSROOT}/bin/llvm-config" \
# -DLLVM_DEFAULT_TARGET_TRIPLE="x86_64-unknown-elf" \
# -DLLVM_ENABLE_LIBCXX=ON \
# -DLLVM_ENABLE_LLD=ON \
# -DLLVM_ENABLE_PIC=OFF \
# -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi;libunwind;compiler-rt" \
# -DLLVM_ENABLE_THREADS=OFF \
# -DLLVM_ENABLE_THREADS=OFF \
# -DLLVM_INSTALL_BINUTILS_SYMLINKS=ON \
# -DLLVM_TARGETS_TO_BUILD="X86" \
# ${WORK}/llvm
#
# ninja && ninja install
# ninja unwind cxx cxxabi compiler-rt
# ninja install-compiler-rt install-unwind install-cxx install-cxxabi
# popd
#
#
#export CC="${SYSROOT}/bin/clang"
#export CXX="${SYSROOT}/bin/clang++"
#export LD="${SYSROOT}/bin/ld.lld"
## -DCOMPILER_RT_BAREMETAL_BUILD=ON \
## -DLIBCXXABI_BAREMETAL=ON \
## -DCMAKE_C_COMPILER="${SYSROOT}/bin/clang" \
## -DCMAKE_CXX_COMPILER="${SYSROOT}/bin/clang++" \
## -DDEFAULT_SYSROOT="${SYSROOT}" \

View File

@@ -8,6 +8,9 @@ BINUTILS_VERSION="2.31.1"
SYSROOT=$(realpath "$(dirname $0)/../sysroot") SYSROOT=$(realpath "$(dirname $0)/../sysroot")
WORK=$(realpath "$(dirname $0)/sysroot") WORK=$(realpath "$(dirname $0)/sysroot")
echo "Not currently supported"
exit 1
set -e set -e
mkdir -p "${SYSROOT}" mkdir -p "${SYSROOT}"
mkdir -p "${WORK}" mkdir -p "${WORK}"
@@ -24,6 +27,7 @@ function build_nasm() {
mkdir -p "${WORK}/build/nasm" mkdir -p "${WORK}/build/nasm"
pushd "${WORK}/build/nasm" pushd "${WORK}/build/nasm"
if [[ ! -f "${WORK}/build/nasm/config.cache" ]]; then
echo "Configuring NASM..." echo "Configuring NASM..."
"${WORK}/nasm-${NASM_VERSION}/configure" \ "${WORK}/nasm-${NASM_VERSION}/configure" \
--quiet \ --quiet \
@@ -31,6 +35,7 @@ function build_nasm() {
--disable-werror \ --disable-werror \
--prefix="${SYSROOT}" \ --prefix="${SYSROOT}" \
--srcdir="${WORK}/nasm-${NASM_VERSION}" --srcdir="${WORK}/nasm-${NASM_VERSION}"
fi
echo "Building NASM..." echo "Building NASM..."
(make -j && make install) > "${WORK}/build/nasm_build.log" (make -j && make install) > "${WORK}/build/nasm_build.log"
@@ -48,14 +53,18 @@ function build_binutils() {
mkdir -p "${WORK}/build/binutils" mkdir -p "${WORK}/build/binutils"
pushd "${WORK}/build/binutils" pushd "${WORK}/build/binutils"
if [[ ! -f "${WORK}/build/binutils/config.cache" ]]; then
echo "Configuring binutils..." echo "Configuring binutils..."
"${WORK}/binutils-${BINUTILS_VERSION}/configure" \ "${WORK}/binutils-${BINUTILS_VERSION}/configure" \
--quiet \ --quiet \
--config-cache \
--target="${TARGET}" \ --target="${TARGET}" \
--prefix="${SYSROOT}" \ --prefix="${SYSROOT}" \
--with-sysroot \ --with-sysroot="${SYSROOT}" \
--with-lib-path="${SYSROOT}/lib" \
--disable-nls \ --disable-nls \
--disable-werror --disable-werror
fi
echo "Building binutils..." echo "Building binutils..."
(make -j && make install) > "${WORK}/build/binutils_build.log" (make -j && make install) > "${WORK}/build/binutils_build.log"
@@ -85,17 +94,35 @@ EOF
mkdir -p "${WORK}/build/gcc" mkdir -p "${WORK}/build/gcc"
pushd "${WORK}/build/gcc" pushd "${WORK}/build/gcc"
if [[ ! -f "${WORK}/build/gcc/config.cache" ]]; then
echo "Configuring GCC..." echo "Configuring GCC..."
"${WORK}/gcc-${GCC_VERSION}/configure" \ "${WORK}/gcc-${GCC_VERSION}/configure" \
--quiet \ --quiet \
--config-cache \
--target="${TARGET}" \ --target="${TARGET}" \
--prefix="${SYSROOT}" \ --prefix="${SYSROOT}" \
--with-sysroot="${SYSROOT}" \
--with-native-system-header-dir="${SYSROOT}/include" \
--with-newlib \
--without-headers \
--disable-nls \ --disable-nls \
--enable-languages=c,c++ \ --enable-languages=c,c++ \
--without-headers --disable-shared \
--disable-multilib \
--disable-decimal-float \
--disable-threads \
--disable-libatomic \
--disable-libgomp \
--disable-libmpx \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx
fi
echo "Building GCC..." echo "Building GCC..."
(make -j all-gcc && make -j all-target-libgcc && make install-gcc && make install-target-libgcc) > "${WORK}/build/gcc_build.log" (make -j all-gcc && make -j all-target-libgcc && \
make install-gcc && make install-target-libgcc) > "${WORK}/build/gcc_build.log"
popd popd
} }
@@ -103,14 +130,22 @@ function build_libstdcxx() {
mkdir -p "${WORK}/build/libstdcxx" mkdir -p "${WORK}/build/libstdcxx"
pushd "${WORK}/build/libstdcxx" pushd "${WORK}/build/libstdcxx"
if [[ ! -f "${WORK}/build/libstdcxx/config.cache" ]]; then
echo "Configuring libstdc++..." echo "Configuring libstdc++..."
CFLAGS="-I${SYSROOT}/include" \
CXXFLAGS="-I${SYSROOT}/include" \
"${WORK}/gcc-${GCC_VERSION}/libstdc++-v3/configure" \ "${WORK}/gcc-${GCC_VERSION}/libstdc++-v3/configure" \
--config-cache \
--host="${TARGET}" \
--target="${TARGET}" \ --target="${TARGET}" \
--prefix="${SYSROOT}" \ --prefix="${SYSROOT}" \
--disable-nls \ --disable-nls \
--disable-multilib \ --disable-multilib \
--with-newlib --with-newlib \
--disable-libstdcxx-threads --disable-libstdcxx-threads \
--disable-libstdcxx-pch \
--with-gxx-include-dir="${SYSROOT}/include/c++"
fi
echo "Building libstdc++..." echo "Building libstdc++..."
(make -j && make install) > "${WORK}/build/libstdcxx_build.log" (make -j && make install) > "${WORK}/build/libstdcxx_build.log"
@@ -148,3 +183,4 @@ build_gcc
update_links update_links
export PATH="${SYSROOT}/bin:${PATH}" export PATH="${SYSROOT}/bin:${PATH}"
build_libc build_libc
build_libstdcxx

View File

@@ -0,0 +1,54 @@
builddir = {{ buildroot }}
srcroot = {{ srcroot }}
ccflags = $
-I${srcroot}/src/include $
-I${srcroot}/src/include/x86_64 $
-DVERSION_MAJOR={{ version.major }} $
-DVERSION_MINOR={{ version.minor }} $
-DVERSION_PATCH={{ version.patch }} $
-DVERSION_GITSHA=\"{{ version.sha }}\" $
-DGIT_VERSION=\"{{ version.major }}.{{ version.minor }}.{{ version.patch }}-{{ version.sha }}\"
asflags = $
-DVERSION_MAJOR={{ version.major }} $
-DVERSION_MINOR={{ version.minor }} $
-DVERSION_PATCH={{ version.patch }} $
-DVERSION_GITSHA=\"{{ version.sha }}\"
cflags = -std=c11
cxxflags = -std=c++14
libs =
rule cc
deps = gcc
depfile = $out.d
description = Compiling $name
command = $cc -MMD -MF $out.d $ccflags $cflags -o $out -c $in
rule cxx
deps = gcc
depfile = $out.d
description = Compiling $name
command = $cxx -MMD -MF $out.d $cxxflags $ccflags -o $out -c $in
rule nasm
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 -o $out $in $libs
rule lib
description = Archiving $name
command = $ar qcs $out $in
{% for target in targets %}
subninja {{ target }}/target.ninja
{% endfor %}
# vim: et ts=4 sts=4 sw=4

View File

@@ -0,0 +1 @@
{% extends "module.base.ninja.j2" %}

View File

@@ -0,0 +1,26 @@
moddir = ${builddir}/{{ name }}.dir
{% block variables %}
ccflags = $ccflags $
{%- for dep in module.deps %}
-I${srcroot}/src/libraries/{{ dep }}/include $
{%- endfor %}
-I${srcroot}/{{ module.path }} $
-I${srcroot}/{{ module.path }}/include
{% endblock %}
{% for source in sources %}
build ${moddir}/{{ source.output }} : {{ source.action }} {{ source.input }}
name = {{ source.name }}
{% endfor %}
build {% block artifact %} ${builddir}/lib{{ name }}.a : lib {% endblock %} $
{%- block extrasources %}{% endblock -%}
{%- for source in sources %}
${moddir}/{{ source.output }}{% if not loop.last %} ${% endif %}
{%- endfor -%}
{%- if module.deps %}| {% for dep in module.deps %} ${builddir}/lib{{ dep }}.a {% endfor %}{% endif %}
name = {{ name }}
# End

View File

@@ -0,0 +1,18 @@
{% extends "program.default.ninja.j2" %}
{% block variables %}
{{ super() }}
cflags = $cflags $
-DKERNEL_FILENAME=L\"popcorn.elf\" $
-DGNU_EFI_USE_MS_ABI $
-DHAVE_USE_MS_ABI $
-DEFI_DEBUG=0 $
-DEFI_DEBUG_CLEAR_MEMORY=0 $
-fPIC $
-fshort-wchar
ldflags = $ldflags $
-shared $
-T ${srcroot}/src/arch/x86_64/boot.ld
{% endblock %}

View File

@@ -0,0 +1,13 @@
{% extends "module.base.ninja.j2" %}
{% block variables %}
{{ super() }}
libs = $
-L${builddir} $
{%- for dep in module.deps %}
-l{{dep}} $
{%- endfor %}
$libs
{% endblock %}
{% block artifact %}{{ module.output }} : exe{% endblock %}

View File

@@ -0,0 +1,8 @@
{% extends "program.default.ninja.j2" %}
{% block variables %}
{{ super() }}
asflags = $asflags -I${srcroot}/src/kernel/
libs = $libs -lc
{% endblock %}

View File

@@ -0,0 +1,16 @@
builddir = $builddir/{{ target }}
{% block variables %}
{% endblock %}
{% block binaries %}
cc = clang
cxx = clang++
ld = clang++
ar = ar
nasm = nasm
{% endblock %}
{% for module in modules %}
subninja {{ module }}.ninja
{% endfor %}

View File

@@ -0,0 +1,39 @@
{% extends "target.default.ninja.j2" %}
{% block binaries %}
cc = ${srcroot}/sysroot/bin/clang
cxx = ${srcroot}/sysroot/bin/clang++
ld = ${srcroot}/sysroot/bin/x86_64-elf-ld
ar = ${srcroot}/sysroot/bin/x86_64-elf-ar
nasm = ${srcroot}/sysroot/bin/nasm
{% endblock %}
{% block variables %}
ccflags = $ccflags $
-D__ELF__ $
-nodefaultlibs $
-nostdinc $
-nostdlib $
-ffreestanding $
-mno-sse $
-fno-omit-frame-pointer $
-mno-red-zone $
-mcmodel=large $
-isystem${srcroot}/sysroot/include $
--sysroot="${srcroot}/sysroot"
cxxflags = $cxxflags $
-nostdlibinc $
-isystem${srcroot}/sysroot/include/c++/v1 $
-fno-exceptions $
-fno-rtti
ldflags = $ldflags $
-g $
-nostdlib $
-nostartfiles $
-znocombreloc $
-Bsymbolic $
-nostartfiles
{% endblock %}

View File

@@ -0,0 +1 @@
{% extends "target.default.ninja.j2" %}

View File

@@ -4,7 +4,16 @@
#include <efi/eficompiler.h> #include <efi/eficompiler.h>
#include <efi/efisetjmp_arch.h> #include <efi/efisetjmp_arch.h>
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
#if ! __has_builtin(setjmp)
extern UINTN setjmp(jmp_buf *env) __attribute__((returns_twice)); extern UINTN setjmp(jmp_buf *env) __attribute__((returns_twice));
#endif
#if ! __has_builtin(longjmp)
extern VOID longjmp(jmp_buf *env, UINTN value) __attribute__((noreturn)); extern VOID longjmp(jmp_buf *env, UINTN value) __attribute__((noreturn));
#endif
#endif /* GNU_EFI_SETJMP_H */ #endif /* GNU_EFI_SETJMP_H */

48
src/include/elf.h Normal file
View File

@@ -0,0 +1,48 @@
#pragma once
/* elf.h - basic defines for external code written assuming <elf.h> works. Only
* Elf64 values are included.
*/
typedef uint16_t Elf64_Half;
typedef uint32_t Elf64_Word;
typedef int32_t Elf64_Sword;
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;
typedef uint64_t Elf64_Addr;
typedef uint64_t Elf64_Off;
typedef uint16_t Elf64_Section;
typedef Elf64_Half Elf64_Versym;
typedef struct {
Elf64_Addr r_offset;
Elf64_Xword r_info;
} Elf64_Rel;
typedef struct {
Elf64_Addr r_offset;
Elf64_Word r_info;
Elf64_Sword r_addend;
} Elf64_Rela;
typedef struct {
Elf64_Sxword d_tag;
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;
#define ELF64_R_TYPE(x) ((x) & 0xffffffff)
typedef enum {
DT_NULL = 0,
DT_RELA = 7,
DT_RELASZ = 8,
DT_RELAENT = 9
} ElfDynTag;
typedef enum {
R_X86_64_NONE = 0,
R_X86_64_RELATIVE = 8
} Elf_x86_64_RelType;

View File

@@ -1,12 +0,0 @@
Import('target')
env = target.Clone()
env.Append(
CPPPATH = ['.', 'include', '#src/libraries/kutil/include'],
)
lib = env.Library('elf', Glob('*.cpp'))
Return('lib')
# vim: ft=python et

View File

@@ -1,12 +0,0 @@
Import('target')
env = target.Clone()
env.Append(
CPPPATH = ['.', 'include', '#src/libraries/kutil/include'],
)
lib = env.Library('initrd', Glob('*.cpp'))
Return('lib')
# vim: ft=python et

View File

@@ -1,12 +0,0 @@
Import('target')
env = target.Clone()
env.Append(
CPPPATH = ['.', 'include'],
)
lib = env.Library('kutil', Glob('*.cpp'))
Return('lib')
# vim: ft=python et

View File

@@ -5,11 +5,13 @@ namespace std {
enum class __attribute__ ((__type_visibility("default"))) align_val_t : size_t { }; enum class __attribute__ ((__type_visibility("default"))) align_val_t : size_t { };
} }
#ifndef KUTIL_EXCLUDE_NEW_DELETE
void * operator new(size_t n, std::align_val_t) { return kutil::malloc(n); } void * operator new(size_t n, std::align_val_t) { return kutil::malloc(n); }
void * operator new (size_t n) { return kutil::malloc(n); } void * operator new (size_t n) { return kutil::malloc(n); }
void * operator new[] (size_t n) { return kutil::malloc(n); } void * operator new[] (size_t n) { return kutil::malloc(n); }
void operator delete (void *p) noexcept { return kutil::free(p); } void operator delete (void *p) noexcept { return kutil::free(p); }
void operator delete[] (void *p) noexcept { return kutil::free(p); } void operator delete[] (void *p) noexcept { return kutil::free(p); }
#endif
namespace kutil { namespace kutil {