@@ -1,10 +1,12 @@ #!/usr/bin/env bash +export out=${out:-out} . global/common.sh noimpl() { say "$1 is not currently implemented on your system. an exciting chance for you to contribute, no?" exit 1 } +timestamp() { date "+%H:%M:%S %A"; } if test "$os$arch$bits" = ""; then say "set the following environment variables to the appropriate atoms describing your system. for help determining the appropriate atoms, see libk.md" say ' - $os={lin|fbsd|hai|osx…}' @@ -11,8 +13,13 @@ say ' - $arch={x86|arm|ia64|mips…}' say ' - $bits={|32|64…}' exit 1 fi + +if test "$1" = "-C"; then + say "precleaning repo" + ./clean.sh +fi # TODO: make it possible for user to change # default set with environment vars modules=(kcore kmem kstr kio kgraft kfile) @@ -34,23 +41,23 @@ osx.32|dar.32) bin_fmt=macho32;; osx.64|dar.64) bin_fmt=macho64;; dos.*) bin_fmt=dosexe;; none.*) bin_fmt=bin;; - 32) bin_fmt=elf32;; - 64) bin_fmt=elf64;; + *.32) bin_fmt=elf32;; + *.64) bin_fmt=elf64;; + *) say "cannot determine correct binary format to use for target $target"; exit 1;; esac # first, we establish the # parameters of the build -has gcc && _cc=gcc -has clang && _cc=clang has cc && _cc=cc +has clang && _cc=clang +has gcc && _cc=gcc cc=${cc:-$_cc} has m4 && _m4=m4 m4=${m4:-$_m4} -has yasm && asm=yasm has nasm && asm=nasm -export out=${out:-out} +has yasm && asm=yasm export gen=${gen:-gen} library=${libkind:-static} # {static|shared|both} case $library in @@ -88,27 +95,22 @@ if test "$bits" != ""; then macro_compile_env="$macro_compile_env -Datom_target_bits=$bits" fi -for mod in ${modules[@]}; do - say "building libk with $mod" -done comp_mac() { $m4 $macro_compile_env -I "$gen" $3 "$1" > "$2"; } -comp_asm() { $asm "-f$bin_fmt" "-i$gen" $1 -o "$2"; } -comp_co() { comp_clib $1 $2 -c; } -comp_clib(){ +comp_asm() { $asm "-f$bin_fmt" -i "$gen" $1 -o "$2"; } +comp_co() { comp_c $1 $2 "-c -fPIC"; } +comp_c(){ src=$1 output=$2 flags=$3 - $cc $src $3 -std=c11 -isystem "$out" -isystem "$gen" -isystem "arch/" -fPIC -nostdlib "-L$out" "-o$output" + $cc $src $3 -std=c11 -isystem "$out" -isystem "$gen" -isystem "arch/" -nostdlib "-L$out" "-o$output" } scan() { find "$1" -name "$2"; } -# now we make sure all the appropriate -# directories exist - +say "commencing libk build $build at $(timestamp)" set -x # get type data mkdir -p $gen @@ -135,28 +137,25 @@ awk -f global/gen-conds.awk $out/k/internal.egroup.h awk -f global/gen-ident.awk $gen/internal.ident.c comp_co $gen/internal.ident.c $out/internal.ident.o -# first pass: copy all raw headers into place +# first pass: copy all headers into place, +# including ones we need to generate + for mod in ${modules[@]}; do for h in $(scan $mod '*.h'); do base=$(basename $h) cp "$h" "$out/k/$base" done -done -# second pass: run macro headers through m4 and -# copy the resulting file into place - -for mod in ${modules[@]}; do for h in $(scan $mod '*.h.m'); do base=$(basename $h) dest=${base%%.m} comp_mac "$h" "$out/k/$dest" done done -# third pass: generate manpage, html, and pdf +# second pass: generate manpage, html, and pdf # versions of the documentation from the md src mkdir -p $out/doc/{man,html,pdf} global/build-manpage.sh libk.md @@ -164,14 +163,14 @@ for doc in $(scan $mod '*.md'); do base="$(basename $doc)" stem="${base%%.md}" global/build-manpage.sh "$doc" - # TODO html - # TODO pdf + global/build-html.sh "$doc" + global/build-pdf.sh "$doc" done done -# fourth pass: compile sources and save the +# third pass: compile sources and save the # resulting object files to $out, tracking # which is a runtime or function unit. exe's # will not be compiled until a later pass @@ -182,31 +181,61 @@ for fn in $(scan $mod '*.fn.c'); do base="$(basename $fn)" dest="$out/$mod.${base%%.c}.o" comp_co "$fn" "$dest" - fn_objects+="$dest" + fn_objects+=("$dest") done for rt in $(scan $mod '*.rt.c'); do base="$(basename $rt)" dest="$out/$mod.${base%%.c}.o" comp_co "$rt" "$dest" - rt_objects+="$dest" + rt_objects+=("$dest") done for fn in $(scan $mod "*.fn.$target.s"); do base="$(basename $fn)" dest="$out/$mod.${base%%.s}.o" comp_asm "$fn" "$dest" - fn_objects+="$dest" + fn_objects+=("$dest") done for rt in $(scan $mod "*.rt.$target.s"); do base="$(basename $rt)" dest="$out/$mod.${base%%.s}.o" comp_asm "$rt" "$dest" - rt_objects+="$dest" + rt_objects+=("$dest") + done +done + +# fourth pass: link the libraries that are +# configured to be built + +if test $build_static_library == yes; then + for obj in ${fn_objects[@]} ${rt_objects[@]} ${data_objects[@]}; do + ar rc $out/libk.a $obj + done + ranlib $out/libk.a +fi + +if test $build_shared_library == yes; then + ld -r ${rt_objects[@]} -o $out/boot.o + ld -shared ${fn_objects[@]} -o $out/libk.so +fi + +# fifth pass: compile the executable tools +# against the libraries created in pass 5 + +for mod in ${modules[@]}; do + for exe in $(scan $mod '*.exe.c'); do + base="$(basename $exe)" + dest="$out/$mod.${base%%.exe.c}" + if test $build_shared_library == yes; then + comp_c "$out/boot.o $exe" "$dest" -lk + else + comp_c "$exe" "$dest" -lk + fi done done -echo fns: ${fn_objects[@]} -echo rts: ${rt_objects[@]} +set +x +say "all passes finished; build $build complete at $(timestamp)"