libk  Check-in [b590aba21d]

Overview
Comment:rename $out build var to $to for nixos compat; refactor announce command to choose a color automatically instead of forcing it to be specified on every command line
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: b590aba21d8cd866a17cf394925d47d3996f2fed2af3972b85fd7bb8dd9aab75
User & Date: lexi on 2019-08-21 01:20:41
Other Links: manifest | tags
Context
2019-08-21
01:58
enable debugging and add -ffreestanding to gcc cmd line to squash attempts to "optimize" functions by converting them to libc calls, e.g. turning kmzero() calls into memset() calls check-in: 49bf71fb47 user: lexi tags: trunk
01:20
rename $out build var to $to for nixos compat; refactor announce command to choose a color automatically instead of forcing it to be specified on every command line check-in: b590aba21d user: lexi tags: trunk
00:28
Switch to using command -v to check for commands instead of which check-in: fd95e5bc93 user: glow tags: trunk
Changes

Modified build.sh from [520c125701] to [b2a27b403b].

     1      1   #!/usr/bin/env bash
     2         -export out=${out:-out}
            2  +export to=${to:-out}
     3      3   . global/common.sh
     4         -noimpl() {
     5         -	say "$1 is not currently implemented on your system. an exciting chance for you to contribute, no?"
     6         -	exit 1
     7         -}
     8         -timestamp() { date "+%H:%M:%S %A"; }
     9      4   
    10      5   if test "$os$arch$bits" = ""; then
    11      6   	say "set the following environment variables to the appropriate atoms describing your system. for help determining the appropriate atoms, see libk.md"
    12      7   	say ' - $os={lin|fbsd|hai|osx…}'
    13      8   	say ' - $arch={x86|arm|ia64|mips…}'
    14      9   	say ' - $bits={|32|64…}'
    15     10   	exit 1
................................................................................
    65     60   has clang && _cc=clang 
    66     61   has gcc && _cc=gcc # prefer gcc
    67     62   cc=${cc:-$_cc}
    68     63   has m4 && _m4=m4
    69     64   m4=${m4:-$_m4}
    70     65   has nasm && asm=nasm
    71     66   has yasm && asm=yasm # prefer yasm
           67  +export cc
           68  +export m4
    72     69   export gen=${gen:-gen}
    73     70   library=${library:-static} # {static|shared|both}
    74     71   export verbose=${verbose:-quiet} # {no|quiet|loud}
    75     72   
    76     73   doc=${doc:-yes}
    77     74   export doc_html=${doc_html:-yes}
    78     75   export doc_pdf=${doc_pdf:-yes}
................................................................................
   108    105   
   109    106   macro_compile_env="-Datom_target_arch=$arch -Datom_target_os=$os -Dtarget_posix=$posix -Dtarget_unix=$unix"
   110    107   
   111    108   if test "$bits" != ""; then
   112    109   	macro_compile_env="$macro_compile_env -Datom_target_bits=$bits"
   113    110   fi
   114    111   
   115         -if test "$COLORTERM" != ""; then
   116         -	announce() {
   117         -		test "$verbose" = "silent" && return
   118         -		color="$1" cmd="$2"; shift 2;
   119         -		printf " → [38;5;$color;1m$cmd"
   120         -		for a in "$@"; do
   121         -			if test ${a:0:1} = "-"; then
   122         -				printf " $a";
   123         -			else
   124         -				printf " $a";
   125         -			fi
   126         -		done
   127         -		echo
   128         -	}
   129         -else
   130         -	announce() { shift; echo " --> " $@; }
   131         -fi
   132         -
   133         -# the following function is called to report a command invocation
   134         -# the person compiling the library. the first argument should be
   135         -# an ansi format string; this is used to color-code the tool being
   136         -# launched and thus should be different for each one.
   137         -report() { announce $@; shift; $@; }
   138    112   comp_mac() {
   139    113   	local src=$1
   140    114   	local output=$2
   141    115   	local flags=$3
   142    116   	if test -e "$output"; then
   143    117   		if test ! "$output" -ot "$src"; then
   144    118   			return
   145    119   		fi 
   146    120   	fi
   147         -	             $m4 $macro_compile_env -I "$gen" $flags "$src"  > "$output"
   148         -	announce 207 $m4 $macro_compile_env -I "$gen" $flags "$src" \> "$output"
          121  +	          $m4 $macro_compile_env -I "$gen" $flags "$src"  > "$output"
          122  +	announce  $m4 $macro_compile_env -I "$gen" $flags "$src" \> "$output"
   149    123   	# yes, this is incredibly stupid. if you know a better way, feel
   150    124   	# free to submit a fix. the problem is there's no way to pass >
   151    125   	# to report in such a way that it'll do the right thing, and if
   152    126   	# you just write > it redirects *report's* output, instead of
   153    127   	# m4's. piece of shit that it is, m4 doesn't have any way to emit
   154    128   	# output into a fille - stdout only apparently. tl;dr i hate bash.
   155    129   }
................................................................................
   158    132   	local output=$2
   159    133   	local flags=$3
   160    134   	if test -e "$output"; then
   161    135   		if test ! "$output" -ot "$src"; then
   162    136   			return
   163    137   		fi
   164    138   	fi
   165         -	report 198 $asm $flags "-f$bin_fmt" -i "$gen" "$src" -o "$output";
          139  +	report $asm $flags "-f$bin_fmt" -i "$gen" "$src" -o "$output";
   166    140   }
   167    141   comp_co()  { comp_c $1 $2 "-c -fPIC"; }
   168    142   comp_c(){
   169    143   	local src=$1
   170    144   	local output=$2
   171    145   	local flags=$3
   172    146   	if test -e "$output"; then
   173    147   		if test ! "$output" -ot "$src"; then
   174    148   			return
   175    149   		fi
   176    150   	fi
   177    151   	# only rebuild the file if the source file is newer
   178         -	report 213 $cc $src $3 -std=c11 -isystem "$out" -isystem "$gen" -isystem "arch/" -nostdlib "-L$out" "-o$output"
          152  +	report $cc $src $3 -std=c11 -isystem "$to" -isystem "$gen" -isystem "arch/" -nostdlib "-L$to" "-o$output"
   179    153   }
   180    154   
   181         -scan() { find "$1" -name "$2"; }
   182         -
   183    155   say "commencing libk build $build at $(timestamp)"
   184    156   # set -x
   185    157   
   186    158   # get type data
   187    159   mkdir -p $gen
   188    160   $cc -D_emit_m4_include arch/typesize.c -o $gen/typesize 
   189    161   $gen/typesize > gen/typesize.m
................................................................................
   215    187   grep -h "#[ 	]*define[ 	]\+E" $p_headers_errno |
   216    188   	sed 's;^#[\t ]*define[\t ]\+\(E[A-Z0-9]\+\).*$;k_platform_error_\1 \1;' >\
   217    189   	$gen/error_names.tbl
   218    190   cat $p_headers_errno $gen/error_names.tbl | cpp -P >$gen/error_numbers.tbl
   219    191   awk -f arch/errtbl.awk <$gen/error_numbers.tbl >$gen/error_table.h
   220    192   
   221    193   # generate symbol tables for error handling functions
   222         -mkdir -p "$out/k"
   223         -awk -f global/gen-conds.awk <global/modules >$out/k/internal.egroup.h
          194  +mkdir -p "$to/k"
          195  +awk -f global/gen-conds.awk <global/modules >$to/k/internal.egroup.h
   224    196   awk -f global/gen-ident.awk <global/modules >$gen/internal.ident.c
   225         -comp_co $gen/internal.ident.c $out/internal.ident.o
          197  +comp_co $gen/internal.ident.c $to/internal.ident.o
   226    198   
   227    199   # first pass: copy all headers into place,
   228    200   # including ones we need to generate
   229    201   
   230    202   for mod in ${modules[@]}; do
   231    203   	for h in $(scan $mod '*.h'); do
   232    204   		base=$(basename $h)
   233         -		cp "$h" "$out/k/$base"
          205  +		cp "$h" "$to/k/$base"
   234    206   	done
   235    207   
   236    208   	for h in $(scan $mod '*.h.m'); do
   237    209   		base=$(basename $h)
   238    210   		dest=${base%%.m}
   239         -		comp_mac "$h" "$out/k/$dest"
          211  +		comp_mac "$h" "$to/k/$dest"
   240    212   	done
   241    213   done
   242    214   
   243    215   # second pass: generate manpage, html, and pdf
   244    216   # versions of the documentation from the md src
   245    217   
   246    218   if test "$doc" = "yes"; then
   247    219   	global/build-manpage.sh libk.md
   248    220   	for mod in ${modules[@]}; do
   249    221   		for doc in $(scan $mod '*.md'); do
   250    222   			base="$(basename $doc)"
   251    223   			stem="${base%%.md}"
   252         -			report 177 global/build-manpage.sh "$doc"
          224  +			report global/build-manpage.sh "$doc"
   253    225   		done
   254    226   	done
   255    227   fi
   256    228   
   257    229   # third pass: compile sources and save the
   258         -# resulting object files to $out, tracking
          230  +# resulting object files to $to, tracking
   259    231   # which is a runtime or function unit. exe's
   260    232   # will not be compiled until a later pass
   261    233   
   262    234   fn_objects=()
   263    235   rt_objects=()
   264         -data_objects=( $out/internal.ident.o )
          236  +data_objects=( $to/internal.ident.o )
   265    237   for mod in ${modules[@]}; do
   266    238   	for fn in $(scan $mod '*.fn.c'); do
   267    239   		base="$(basename $fn)"
   268         -		dest="$out/$mod.${base%%.c}.o"
          240  +		dest="$to/$mod.${base%%.c}.o"
   269    241   		comp_co "$fn" "$dest"
   270    242   		fn_objects+=("$dest")
   271    243   	done
   272    244   
   273    245   	for rt in $(scan $mod '*.rt.c'); do
   274    246   		base="$(basename $rt)"
   275         -		dest="$out/$mod.${base%%.c}.o"
          247  +		dest="$to/$mod.${base%%.c}.o"
   276    248   		comp_co "$rt" "$dest"
   277    249   		rt_objects+=("$dest")
   278    250   	done
   279    251   
   280    252   	for fn in $(scan $mod "*.fn.$target.s"); do
   281    253   		base="$(basename $fn)"
   282         -		dest="$out/$mod.${base%%.s}.o"
          254  +		dest="$to/$mod.${base%%.s}.o"
   283    255   		comp_asm "$fn" "$dest"
   284    256   		fn_objects+=("$dest")
   285    257   	done
   286    258   
   287    259   	for rt in $(scan $mod "*.rt.$target.s"); do
   288    260   		base="$(basename $rt)"
   289         -		dest="$out/$mod.${base%%.s}.o"
          261  +		dest="$to/$mod.${base%%.s}.o"
   290    262   		comp_asm "$rt" "$dest"
   291    263   		rt_objects+=("$dest")
   292    264   	done
   293    265   done
   294    266   
   295    267   # fourth pass: link the libraries that are
   296    268   # configured to be built
   297    269   
   298    270   if test $build_static_library == yes; then
   299    271   	for obj in ${fn_objects[@]} ${rt_objects[@]} ${data_objects[@]}; do
   300         -		report 120 ar rc $out/libk.a $obj
          272  +		report ar rc $to/libk.a $obj
   301    273   	done
   302         -	report 105 ranlib $out/libk.a
          274  +	report ranlib $to/libk.a
   303    275   fi
   304    276   
   305    277   if test $build_shared_library == yes; then
   306         -	report 216 ld -r ${rt_objects[@]} -o $out/boot.o
   307         -	report 216 ld -shared ${fn_objects[@]} -o $out/libk.so
          278  +	report ld -r ${rt_objects[@]} -o $to/boot.o
          279  +	report ld -shared ${fn_objects[@]} -o $to/libk.so
   308    280   fi
   309    281   
   310    282   # fifth pass: compile the executable tools
   311    283   # against the libraries created in pass 5
   312    284   
   313    285   for mod in ${modules[@]}; do
   314    286   	for exe in $(scan $mod '*.exe.c'); do
   315    287   		base="$(basename $exe)"
   316         -		dest="$out/$mod.${base%%.exe.c}"
          288  +		dest="$to/$mod.${base%%.exe.c}"
   317    289   		if test $build_shared_library == yes; then
   318         -			comp_c "$out/boot.o $exe" "$dest" -lk
          290  +			comp_c "$to/boot.o $exe" "$dest" -lk
   319    291   		else
   320    292   			comp_c "$exe" "$dest" -lk
   321    293   		fi
   322    294   	done
   323    295   done
   324    296   
   325    297   set +x
   326    298   say "all passes finished; build $build complete at $(timestamp)"

Modified clean.sh from [67375a0380] to [da20a1a7ee].

     1      1   #!/usr/bin/env bash
     2         -out=${out:-out}
            2  +to=${to:-out}
     3      3   gen=${gen:-gen}
     4      4   . global/common.sh
     5      5   
     6      6   say "cleaning libk build artifacts"
     7      7   
     8         -set -x
     9         -rm -r $out
    10         -rm -r $gen
            8  +report rm -r $to
            9  +report rm -r $gen

Modified global/build-manpage.sh from [5a75b066a8] to [ea0b6d880a].

     8      8   reqpack cmark "generate documentation"
     9      9   check gen "a directory for generated build dependencies"
    10     10   
    11     11   file="$1"
    12     12   filename="$(basename "$file")"
    13     13   stem=${filename%%.md}
    14     14   
    15         -mandest=${out_manpage:-"$out/doc/man"}
    16         -htmldest=${out_html:-"$out/doc/html"}
    17         -pdfdest=${out_pdf:-"$out/doc/pdf"}
           15  +mandest=${manpage_to:-"$to/doc/man"}
           16  +htmldest=${html_to:-"$to/doc/html"}
           17  +pdfdest=${pdf_to:-"$to/doc/pdf"}
    18     18   
    19     19   section=${manual_section:-4}
    20     20   man="$mandest/$stem.$section"
    21     21   html="$htmldest/$stem.html"
    22     22   pdf="$pdfdest/$stem.pdf"
    23     23   fmt="$gen/$stem.tmp"
    24     24   

Modified global/common.sh from [2fb772064d] to [0ffa5553a2].

     4      4   check() {
     5      5   	var=$1
     6      6   	test "${!var}" == "" || return 0
     7      7   	say "we were not able to detect a default value for the configuration variable \$$var. please set this variable to $2 and try again."
     8      8   	exit 1
     9      9   }
    10     10   
    11         -test "$out" = "" && {
    12         -	say "\$out environment variable must be set to your build directory - are you running this script by hand? run ./build.sh in the root directory instead!"
           11  +test "$to" = "" && {
           12  +	say "\$to environment variable must be set to your build directory - are you running this script by hand? run ./build.sh in the root directory instead!"
    13     13   	exit 2
    14     14   }
    15     15   
    16     16   reqpack() {
    17     17   	if ! has "$1"; then
    18     18   		say "to $2 for libk, install the $1 package and try again"
    19     19   		exit 3
    20     20   	fi
    21     21   }
           22  +
           23  +noimpl() {
           24  +	say "$1 is not currently implemented on your system. an exciting chance for you to contribute, no?"
           25  +	exit 1
           26  +}
           27  +
           28  +timestamp() { date "+%H:%M:%S %A"; }
           29  +
           30  +scan() { find "$1" -name "$2"; }
           31  +
           32  +if test "$COLORTERM" != ""; then
           33  +	announce() {
           34  +		test "$verbose" = "silent" && return
           35  +		local cmd="$1"; shift;
           36  +		local color=225;
           37  +		case "$cmd" in
           38  +			rm) color=196;; $asm) color=198;;
           39  +			$cc) color=213;; ar) color=120;;
           40  +			ranlib) color=105;; ld) color=216;;
           41  +			global/build-manpage.sh) color=177;;
           42  +			$m4) color=207;;
           43  +		esac
           44  +
           45  +		printf " → [38;5;$color;1m$cmd"
           46  +		for a in "$@"; do
           47  +			if test ${a:0:1} = "-"; then
           48  +				printf " $a";
           49  +			else
           50  +				printf " $a";
           51  +			fi
           52  +		done
           53  +		echo
           54  +	}
           55  +else
           56  +	announce() { shift; echo " --> " $@; }
           57  +fi
           58  +
           59  +# the following function is called to report a command invocation
           60  +# the person compiling the library. the first argument should be
           61  +# an ansi format string; this is used to color-code the tool being
           62  +# launched and thus should be different for each one.
           63  +
           64  +report() { announce $@; $@; }

Modified libk.md from [a1a4077789] to [4ccdb2100b].

   122    122   
   123    123   other assemblers will probably be necessary for the more exotic targets, however.
   124    124   
   125    125   # repository structure
   126    126   
   127    127   libk uses a strict directory structure for code, and deviations from this structure will not be tolerated without extremely good reason.
   128    128   
   129         -total segregation is maintained between source code, temporary files, and output objects. source is found in module directories (`k*/`). the destination for temporary files and output objects are retargetable via the environment variables `gen= out=`, but default to `gen/` and `out/`, which are excluded from repo with fossil's `ignore-glob` settingapproval of the maintainer herself.
          129  +total segregation is maintained between source code, temporary files, and output objects. source is found in module directories (`k*/`). the destination for temporary files and output objects are retargetable via the environment variables `gen= to=`, but default to `gen/` and `out/`, which are excluded from repo with fossil's `ignore-glob` settingapproval of the maintainer herself.
   130    130   
   131    131   all libk code is dispersed into modules: `kcore` for internals, `kio` for I/O, `kgraft` for binary packing, etc. each module has a folder in the root directory. (libk does not have submodules.) inside each module's directory should be a header with the same name as the module (see **naming conventions** above).
   132    132   
   133    133   each function should be kept in a separate file within its module's directory. the file's name should consist of the dot-separated fields [name, class, "c"] for C sources, or [name, class, arch, OS, bits, format, "s"] for assembly sources, where "name" is the name of the function without the module prefix and "class" is `rt` if the file is part of the libk runtime, or `fn` otherwise. this distinction is necessary because while the static library `libk.a` can include runtime objects, the shared library `libk.so` cannot. examples:
   134    134   
   135    135    * a C file in the module `kstr` named `kscomp` would be named `kstr/comp.fn.c`
   136    136    * a runtime assembly file called `boot` in the module `kcore` for x86-64 linux would be named `kcore/boot.rt.x86.lin.64.s`
   137    137    * the 32-bit x86 haiku version of a function called `kiowrite` defined in assembly would be named `kio/write.fn.x86.hai.32.s`.
   138    138   
   139    139   each module should have a header named the same thing as the module except without the `k` prefix. (e.g. the header for `kio` is `kio/io.h`) located in its folder. this is the header that the end-user will be importing, and should handle any user-defined flags to present the API the user has selected.
   140    140   
   141    141   each module should contain a markdown file. this file's name should be the name of the parent directory suffixed with `.md`; for instance, `kterm` should contain the file `kterm/kterm.md`. this file should document the module as thoroughly as possible 
   142    142   
   143         -each module may contain any number of files of the name `*.exe.c`. this files will be treated as *tools* by the build system and compiled as executables, rather than libraries. they should be compiled to `out/$module.$tool`
          143  +each module may contain any number of files of the name `*.exe.c`. this files will be treated as *tools* by the build system and compiled as executables, rather than libraries. they should be compiled to `$to/$module.$tool`
   144    144   
   145    145   the repository root and each module may also contain the directory `misc`. this directory may be used to store miscellaneous data such as ABI references, developer discussions, and roadmaps. if the `misc` directory is deleted, this must not affect the library or build system's function in any way - that is, nothing outside a `misc` folder may reference a `misc` folder or anything inside it, including documentation. the `misc` directory should be removed when its contents are no longer needed. in most cases, the repository wiki and forum should be used instead of the `misc` folder.
   146    146   
   147    147   the folder `arch` in the root of the repository contains syscall tables and ABI implementations for various architectures.
   148    148   
   149    149   # build system
   150    150   
................................................................................
   164    164   
   165    165    * `os={atom}` - an atom representing the operating system you are building libk for
   166    166    * `arch={atom}` - an atom representing the processor architecture you are building libk for
   167    167    * `bits={atom}` - if your processor has multiple variants with different word lengths (such as x86-32 vs. x86-64), specify the word length in this variable; otherwise, leave it unset.
   168    168   
   169    169   further optional variables may be set to control the build process and determine what targets it produces.
   170    170    * `library=static {static|shared|both}` - this variable controls whether the build process will produce `libk.a`, `libk.so`, or both.
   171         - * `out=out {path}` - an alternate path to store build artifacts in
          171  + * `to=out {path}` - an alternate path to store build artifacts in
   172    172    * `gen=gen {path}` - an alternate path to store generated source in
   173    173    * `cc=<autodetect> {executable}` - the compiler to compile C sources with
   174    174    * `m4=<autodetect> {executable}` - the m4 binary to compile the macro sources with
   175    175    * `asm=<autodetect> {executable}` - the assembler to assemble the assembly listings with. it must take Intel-syntax input and handle nasm-style macros. only `yasm` and `nasm` are likely to be viable.
   176    176    * `doc=yes {yes|no}` - whether to typeset the documentation (very slow with all three formats set to "yes")
   177    177    * `doc_html=yes {yes|no}` - enable or disable html output of the documentation
   178    178    * `doc_pdf=yes {yes|no}` - enable or disable pdf output of the documentation