diff options
author | EuAndreh <eu@euandre.org> | 2024-04-22 08:32:18 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2024-04-22 08:32:18 -0300 |
commit | 9ac6ad82b37f02218203f61201931450076f4306 (patch) | |
tree | 99fd518dac230724e437fcb3e101aac33c1787f5 /bin | |
parent | bin/gc: Allow "gc_tmpdir()" to fail (diff) | |
download | dotfiles-9ac6ad82b37f02218203f61201931450076f4306.tar.gz dotfiles-9ac6ad82b37f02218203f61201931450076f4306.tar.xz |
bin/ldev: Move it to its dedicated project
Diffstat (limited to 'bin')
-rwxr-xr-x | bin/ldev | 232 |
1 files changed, 0 insertions, 232 deletions
diff --git a/bin/ldev b/bin/ldev deleted file mode 100755 index e113c7c..0000000 --- a/bin/ldev +++ /dev/null @@ -1,232 +0,0 @@ -#!/bin/sh -set -eu - - -usage() { - cat <<-'EOF' - Usage: - ldev deps FILE... - ldev -h - EOF -} - -help() { - cat <<-'EOF' - - - Options: - -h, --help show this message - - FILE toplevel entrypoint file - - - Given a list of C FILEs, generate the Makefile dependencies - between them. - - We have 2 types of object files: - - .o: plain object files; - - .to: compiled with -DTEST so it can expose its embedded unit - tests; - - We also have 1 aggregate file: - - .xa: an e**x**ecutable **a**rchive, made with ar(1), that - includes all the .o dependencies required for linking, so that - one can have only the archive as the linker input, i.e. - `cc -o example.bin example.xa`. This way we don't need - separate targets for each executable, and we can instead deal - separately with dependencies and linking, but without specific - file listing for each case. We use an ar-chive to exploit the - fact that a) it can replace existing files with the same name - and b) the $? macro in make(1) gives us all the out-of-date - dependencies, so our rule in the Makefile is usually a simple - `$(AR) $(ARFLAGS) $@ $?`. This way each .xa file lists its - dependency separately, and the building of the .xa file is - taken care of, in the same way that the linkage into an - executable is also taken care of. For running unit tests, we - include as a dependency of "$NAME.xa" the "$NAME.to" file, - which is the object code of "$NAME.c" compiled with the -DTEST - flag. This exposes a main() function for running unit tests. - - Also in order to run the unit tests without having to relink - them on each run, we have: - - .bin-check: a dedicated virtual target that does nothing but - execute the tests. In order to assert the binaries exist, - each "$NAME.bin-check" virtual target depends on the - equivalent "$NAME.check" physical target. - - There are 2 types of dependencies that are generated: - 1. self dependencies; - 2. inter dependencies. - - The self dependencies are the ones across different - manifestations of the same file so all derived assets are - correctly kept up-to-date: - - $NAME.o $NAME.to: $NAME.h - - As the .SUFFIXES rule already covers the dependency to the - orinal $NAME.c file, all we do is say that whenever the public - interface of these binaries change, they need to be - recompiled; - - - $NAME.xa: $NAME.to - - We make sure to include in each executable archive (.xa) file - its own binary with unit tests. We include the "depN.o" - dependencies later; - - - $NAME.bin-check: $NAME.bin - - Enforce that the binary exists before we run them. - - After we establish the self dependencies, we scrub each file's - content looking for `#include "..."` lines that denote - dependency to other C file. Once we do that we'll have: - - $NAME.o $NAME.to: dep1.h dep2.h ... depN.h - - We'll recompile our file when its public header changes. When - only the body of the code changes we don't recompile, only - later relink; - - - $NAME.xa: dep1.o dep2.o ... depN.o - - Make sure to include all required dependencies in the - $NAME.bin binary so that the later linking works properly. - - So if we have file1.c, file2.c and file3.c with their respective - headers, where file2.c and file3.c depend of file1.c, i.e. they - have `#include "file.h"` in their code, and file3.c depend of - file2.c, the expected output is: - - file1.o file1.to: file1.h - file2.o file2.to: file2.h - file3.o file3.to: file3.h - - file1.xa: file1.to - file2.xa: file2.to - file3.xa: file3.to - - file1.bin-check: file1.bin - file2.bin-check: file2.bin - file3.bin-check: file3.bin - - - file1.o file1.to: - file2.o file2.to: file1.h - file3.o file3.to: file1.h file2.h - - file1.xa: - file2.xa: file1.o - file3.xa: file1.o file2.o - - This ensures that only the minimal amount of files need to get - recompiled, but no less. - - - Examples: - - Get deps for all files in 'src/' but 'src/main.c': - - $ sh tools/cdeps.sh `find src/*.c -not -name 'main.c'` - - - Emit dependencies for all C files in a Git repository: - - $ sh tools/cdeps.sh `git ls-files | grep '\.c$'` - EOF -} - - -for flag in "$@"; do - case "$flag" in - (--) - break - ;; - (--help) - usage - help - exit - ;; - (*) - ;; - esac -done - -while getopts 'h' flag; do - case "$flag" in - (h) - usage - help - exit - ;; - (*) - usage >&2 - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) -shift - -FILE="${1:-}" -eval "$(assert-arg "$FILE" 'FILE')" - - - -each_f() { - fn="$1" - shift - for file in "$@"; do - f="${file%.c}" - "$fn" "$f" - done - printf '\n' -} - -self_header_deps() { - printf '%s.o\t%s.to:\t%s.h\n' "$1" "$1" "$1" -} - -self_xa_deps() { - printf '%s.xa:\t%s.to\n' "$1" "$1" -} - -self_bincheck_deps() { - printf '%s.bin-check:\t%s.bin\n' "$1" "$1" -} - -deps_for() { - ext="$2" - for file in $(awk -F'"' '/^#include "/ { print $2 }' "$1.c"); do - if [ "$file" = 'config.h' ]; then - continue - fi - if [ "$(basename "$file")" = 'tests-lib.h' ]; then - continue - fi - f="$(dirname "$1")/$file" - if [ "$f" = "$1.h" ]; then - continue - fi - printf '%s\n' "${f%.h}$2" - done -} - -rebuild_deps() { - printf '\n' - printf '%s.o\t%s.to:' "$1" "$1" - printf ' %s' $(deps_for "$1" .h) | sed 's| *$||' -} - -archive_deps() { - printf '\n' - printf '%s.xa:' "$1" - printf ' %s' $(deps_for "$1" .o) | sed 's| *$||' -} - - -each_f self_header_deps "$@" -each_f self_xa_deps "$@" -each_f self_bincheck_deps "$@" - -each_f rebuild_deps "$@" -each_f archive_deps "$@" |