aboutsummaryrefslogtreecommitdiffstats
path: root/mds/lazymakefiles.txt
diff options
context:
space:
mode:
authorterminaldweller <devi@terminaldweller.com>2024-03-05 19:25:48 +0000
committerterminaldweller <devi@terminaldweller.com>2024-03-05 19:25:48 +0000
commitce567a174835644d29f3b7f4a4626f07dfb05b0a (patch)
tree4ade54ab126046515fda0dc959f6d40bbaa71607 /mds/lazymakefiles.txt
parentdowngraded mongo to v6 for now (diff)
downloadblog-ce567a174835644d29f3b7f4a4626f07dfb05b0a.tar.gz
blog-ce567a174835644d29f3b7f4a4626f07dfb05b0a.zip
added a new script to conevrt all md to asciidoc, rss feed now sends the entire asciidoc for the teaser
Diffstat (limited to 'mds/lazymakefiles.txt')
-rw-r--r--mds/lazymakefiles.txt690
1 files changed, 690 insertions, 0 deletions
diff --git a/mds/lazymakefiles.txt b/mds/lazymakefiles.txt
new file mode 100644
index 0000000..09e9960
--- /dev/null
+++ b/mds/lazymakefiles.txt
@@ -0,0 +1,690 @@
+== Lazy Makefiles
+
+I kept finding myself needing to build some C or C++ code but I just
+couldn’t be bothered to write a makefile from ground up. My life’s too
+short for that. The code was either not that big of a deal or the build
+process was not anything complicated. Yes, I’m lazy. The alternative to
+writing a makefile is just typing in gcc or clang instead of make into
+the terminal. I know. The horror. It’s 2018. What sort of a barbarian
+does that? So I just decided to write a lazy makefile so I would never
+have to type in the name of my compiler of choice ever again. Mostly
+because that’s what you do with things that you love. Forget about them
+until you need them. We’re still talking about compilers and makefiles
+for your information. Don’t go assuming things about my personal life.
+
+First off, you can find the makefiles
+https://github.com/bloodstalker/lazymakefiles[here]. They are licensed
+under the Unlicense. And I’m using plural because there’s one for C and
+one for C++. Now that we are done with the mandatory whimsical
+introduction, let’s talk about the contents of the makefiles. There are
+also a couple of things to note:
+
+* The makefiles have been written with gnu make in mind.
+* Most targets will be fine with gcc but the full functionality is
+achieved by using clang.
+* This is not a makefile 101.
+* I’m not going to try to copy the makefile contents here line by line.
+You are expected to have the makefile open while reading this.
+* I will be explaining some of the more, let’s say, esoteric behaviours
+of make which can get the beginners confused.
+* gnu make variables are considered macros by C/C++ standards. I will
+use the term ``variable'' since it’s what the gnu make documents use.
+* The makefiles are not supposed to be hands-off. I change bits here and
+there from project to project.
+* The makefile recognizes the following extensions: `.c` and `.cpp`. If
+you use different extensions, change the makefile accordingly.
+
+=== The Macros
+
+`TARGET` holds the target name. It uses the `?=` assignment operator so
+you can pass it a different value from a script, just in case. There are
+a bunch of varibales that you can assign on the terminal to replace the
+makefile’s defaults. Among those there are some that are first getting a
+default value assigned and then get the `?=` assignemnt operator so you
+can assign them values from the terminal, e.g:
+
+[source,make]
+----
+CC=clang
+CC?=clang
+----
+
+It looks a bit backwards but there is a reason for that. The reason why
+we need to do that is because those variables are called
+`implicit variables` in gnu make terminology. Implicit variables are
+already defined by your makefile even if you havent defined them so they
+get some special treatment. In order to assign them values from the
+terminal, we first assign them a value and then use the `?=` operator on
+them. We don’t really need to assign the default value here again, but I
+felt like it would be more expressive to assign the default for a second
+time.
+
+Variables `CC_FLAGS`, `CXX_FLAGS` and `LD_FLAGS` have accompanying
+variables, namely `CC_FLAGS_EXTRA`, `CXX_FLAGS_EXTRA` and
+`LD_FLAGS_EXTRA`. The extra ones use the `?=` assignment. The scheme is
+to have the first set to host the invariant options and use the second
+set, to change the options that would need changing between different
+builds, if need be.
+
+The variable `BUILD_MODE` is used for the sanitizer builds of clang.
+`ADDSAN` will build the code with the address sanitizer. `MEMSAN` will
+build the code with memory sanitizer and `UBSAN` will build the code
+with undefined behaviour sanitizers. The build mode will affect all the
+other targets, meaning you will get a dynamically-linked executable in
+debug mode with address sanitizers if you assign `MEMSAN` to
+`BUILD_MODE`.
+
+=== Targets
+
+==== default
+
+The default target is `all`. `all` depends on `TARGET`.
+
+==== all
+
+`all` is an aggregate target. calling it will build, or rather, try to
+build everything(given your source-code’s sitation, some targets might
+not make any sense).
+
+==== depend
+
+`depend` depends on `.depend` which is a file generated by the makefile
+that holds the header dependencies. This is how we are making the
+makefile sensitive to header changes. The file’s contents look like
+this:
+
+[source,make]
+----
+main.c:main.h
+myfile1.c:myfile1.h myfile2.h
+----
+
+The inclusion directive is prefixed with a `-`. That’s make lingo for
+ignore-if-error. My shell prompt has a `make -q` part in it so just
+`cd`ing into a folder will generate the `.depend` file for me.Lazy and
+Convinient.
+
+==== Objects
+
+For the objects, there are three sets. You have the normal garden
+variety objects that end in `.o`. You get the debug enabled objects that
+end in `.odbg` and you get the instrumented objectes that are to be used
+for coverage that end in `.ocov`. I made the choice of having three
+distinct sets of objects since I personally sometimes struggle to
+remember whether the current objects are normal, debug or coverage. This
+way, I don’t need to. That’s the makefile’s problem now.
+
+==== TARGET
+
+Vanilla i.e. the dynamically-linked executable.
+
+==== TARGET-static
+
+The statically-linked executable.
+
+==== TARGET-dbg
+
+The dynamically-linked executble in debug mode.
+
+==== TARGET-cov
+
+The instrumented-for-coverage executable, dynaimclly-linked.
+
+==== cov
+
+The target generates the coverage report. it depend on `runcov` which
+itself, in turn, depends on `$(TARGET)-cov` so if you change `runcov` to
+how your executable should run, cov will handle rebuilding the objects
+and then running and generating the coverage report.
+
+==== covrep
+
+The exact same as above but generates coverage report in a different
+format.
+
+==== ASM
+
+Generates the assembly files for your objects, in intel style.
+
+==== SO
+
+Will try to build your target as a shared object.
+
+==== A
+
+Will try to build your target as an archive, i.e. static library.
+
+==== TAGS
+
+Depends on the `tags` target, generates a tags file. The tags file
+includes tags from the header files included by your source as well.
+
+==== valgrind
+
+Depends on `$(TARGET)` by default, runs valgrind with
+`--leak-check=yes`. You probably need to change this for the makefile to
+run your executable correctly.
+
+==== format
+
+Runs clang-format on all your source files and header files and ***EDITS
+THEM IN PLACE***. Expects a clang format file to be present in the
+directory.
+
+==== js
+
+Builds the target using emscripten and generates a javascript file.
+
+==== clean and deepclean
+
+`clean` cleans almost everything. `deepclean` depends on `clean`.
+basically a two level scheme so you can have two different sets of clean
+commands.
+
+==== help
+
+prints out the condensed version of what I’ve been trying to put into
+words.
+
+Well that’s about it. Below you can find the current(at the time of
+writing) versio of both the C and the Cpp makefiles. You can always find
+the latest versions
+https://raw.githubusercontent.com/terminaldweller/scripts/main/makefilec[here]
+for C and
+https://raw.githubusercontent.com/terminaldweller/scripts/main/makefilecpp[here]
+for Cpp.
+
+=== C
+
+[source,make]
+----
+TARGET?=main
+SHELL=bash
+SHELL?=bash
+CC=clang
+CC?=clang
+ifdef OS
+CC_FLAGS=
+else
+CC_FLAGS=-fpic
+endif
+CC_EXTRA?=
+CTAGS_I_PATH?=./
+LD_FLAGS=
+EXTRA_LD_FLAGS?=
+ADD_SANITIZERS_CC= -g -fsanitize=address -fno-omit-frame-pointer
+ADD_SANITIZERS_LD= -g -fsanitize=address
+MEM_SANITIZERS_CC= -g -fsanitize=memory -fno-omit-frame-pointer
+MEM_SANITIZERS_LD= -g -fsanitize=memory
+UB_SANITIZERS_CC= -g -fsanitize=undefined -fno-omit-frame-pointer
+UB_SANITIZERS_LD= -g -fsanitize=undefined
+FUZZ_SANITIZERS_CC= -fsanitize=fuzzer,address -g -fno-omit-frame-pointer
+FUZZ_SANITIZERS_LD= -fsanitize=fuzzer,address -g -fno-omit-frame-pointer
+COV_CC= -fprofile-instr-generate -fcoverage-mapping
+COV_LD= -fprofile-instr-generate
+# BUILD_MODES are=RELEASE(default), DEBUG,ADDSAN,MEMSAN,UBSAN,FUZZ
+BUILD_MODE?=RELEASE
+#EXCLUSION_LIST='(\bdip)|(\bdim)'
+EXCLUSION_LIST='xxxxxx'
+OBJ_LIST:=$(patsubst %.c, %.o, $(shell find . -name '*.c' | grep -Ev $(EXCLUSION_LIST)))
+OBJ_COV_LIST:=$(patsubst %.c, %.ocov, $(shell find . -name '*.c' | grep -Ev $(EXCLUSION_LIST)))
+OBJ_DBG_LIST:=$(patsubst %.c, %.odbg, $(shell find . -name '*.c' | grep -Ev $(EXCLUSION_LIST)))
+ASM_LIST:=$(patsubst %.c, %.s, $(shell find . -name '*.c' | grep -Ev $(EXCLUSION_LIST)))
+WASM_LIST:=$(patsubst %.c, %.wasm, $(shell find . -name '*.c' | grep -Ev $(EXCLUSION_LIST)))
+WAST_LIST:=$(patsubst %.c, %.wast, $(shell find . -name '*.c' | grep -Ev $(EXCLUSION_LIST)))
+IR_LIST:=$(patsubst %.c, %.ir, $(shell find . -name '*.c' | grep -Ev $(EXCLUSION_LIST)))
+JS_LIST:=$(patsubst %.c, %.js, $(shell find . -name '*.c' | grep -Ev $(EXCLUSION_LIST)))
+AST_LIST:=$(patsubst %.c, %.ast, $(shell find . -name '*.c' | grep -Ev $(EXCLUSION_LIST)))
+
+ifeq ($(BUILD_MODE), ADDSAN)
+ifeq ($(CC), gcc)
+$(error This build mode is only useable with clang.)
+endif
+CC_EXTRA+=$(ADD_SANITIZERS_CC)
+EXTRA_LD_FLAGS+=$(ADD_SANITIZERS_LD)
+endif
+
+ifeq ($(BUILD_MODE), MEMSAN)
+ifeq ($(CC), gcc)
+$(error This build mode is only useable with clang.)
+endif
+CC_EXTRA+=$(MEM_SANITIZERS_CC)
+EXTRA_LD_FLAGS+=$(MEM_SANITIZERS_LD)
+endif
+
+ifeq ($(BUILD_MODE), UBSAN)
+ifeq ($(CC), gcc)
+$(error This build mode is only useable with clang.)
+endif
+CC_EXTRA+=$(UB_SANITIZERS_CC)
+EXTRA_LD_FLAGS+=$(UB_SANITIZERS_LD)
+endif
+
+ifeq ($(BUILD_MODE), FUZZ)
+ifeq ($(CXX), g++)
+$(error This build mode is only useable with clang++.)
+endif
+CXX_EXTRA+=$(FUZZ_SANITIZERS_CC)
+EXTRA_LD_FLAGS+=$(FUZZ_SANITIZERS_LD)
+endif
+
+SRCS:=$(wildcard *.c)
+HDRS:=$(wildcard *.h)
+CC_FLAGS+=$(CC_EXTRA)
+LD_FLAGS+=$(EXTRA_LD_FLAGS)
+
+.DEFAULT:all
+
+.PHONY:all clean help ASM SO TAGS WASM JS IR WAST A ADBG AST cppcheck DOCKER
+
+all:$(TARGET)
+
+everything:$(TARGET) A ASM SO $(TARGET)-static $(TARGET)-dbg ADBG TAGS $(TARGET)-cov WASM JS IR WAST AST DOCKER
+
+depend:.depend
+
+.depend:$(SRCS)
+ rm -rf .depend
+ $(CC) -MM $(CC_FLAGS) $^ > ./.depend
+ echo $(patsubst %.o:, %.odbg:, $(shell $(CC) -MM $(CC_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.odbg/\n&/g' >> ./.depend
+ echo $(patsubst %.o:, %.ocov:, $(shell $(CC) -MM $(CC_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.ocov/\n&/g' >> ./.depend
+
+-include ./.depend
+
+.c.o:
+ $(CC) $(CC_FLAGS) -c $< -o $@
+
+%.odbg:%.c
+ $(CC) $(CC_FLAGS) -g -c $< -o $@
+
+%.ocov:%.c
+ $(CC) $(CC_FLAGS) $(COV_CC) -c $< -o $@
+
+$(TARGET): $(OBJ_LIST)
+ $(CC) $(LD_FLAGS) $^ -o $@
+
+$(TARGET)-static: $(OBJ_LIST)
+ $(CC) $(LD_FLAGS) $^ -static -o $@
+
+$(TARGET)-dbg: $(OBJ_DBG_LIST)
+ $(CC) $(LD_FLAGS) $^ -g -o $@
+
+$(TARGET)-cov: $(OBJ_COV_LIST)
+ $(CC) $(LD_FLAGS) $^ $(COV_LD) -o $@
+
+cov: runcov
+ @llvm-profdata merge -sparse ./default.profraw -o ./default.profdata
+ @llvm-cov show $(TARGET)-cov -instr-profile=default.profdata
+
+covrep: runcov
+ @llvm-profdata merge -sparse ./default.profraw -o ./default.profdata
+ @llvm-cov report $(TARGET)-cov -instr-profile=default.profdata
+
+ASM:$(ASM_LIST)
+
+SO:$(TARGET).so
+
+A:$(TARGET).a
+
+ADBG:$(TARGET).adbg
+
+IR:$(IR_LIST)
+
+WASM:$(WASM_LIST)
+
+WAST:$(WAST_LIST)
+
+JS:$(JS_LIST)
+
+AST:$(AST_LIST)
+
+TAGS:tags
+
+#https://github.com/rizsotto/Bear
+BEAR: clean
+ bear -- make
+
+tags:$(SRCS)
+ $(shell $(CC) -c -I $(CTAGS_I_PATH) -M $(SRCS)|\
+ sed -e 's/[\\ ]/\n/g'|sed -e '/^$$/d' -e '/\.o:[ \t]*$$/d'|\
+ ctags -L - --c++-kinds=+p --fields=+iaS --extra=+q)
+
+%.s: %.c
+ $(CC) -S $< -o $@
+ # objdump -r -d -M intel -S $< > $@
+
+%.ir: %.c
+ $(CC) -emit-llvm -S -o $@ $<
+
+%.wasm: %.c
+ emcc $< -o $@
+
+%.wast: %.wasm
+ wasm2wat $< > $@
+
+%.js: %.c
+ emcc $< -s FORCE_FILESYSTEM=1 -s EXIT_RUNTIME=1 -o $@
+
+%.ast: %.c
+ $(CC) -Xclang -ast-dump -fsyntax-only $< > $@
+
+$(TARGET).so: $(OBJ_LIST)
+ $(CC) $(LD_FLAGS) $^ -shared -o $@
+
+$(TARGET).a: $(OBJ_LIST)
+ ar rcs $(TARGET).a $(OBJ_LIST)
+
+$(TARGET).adbg: $(OBJ_DBG_LIST)
+ ar rcs $(TARGET).adbg $(OBJ_DBG_LIST)
+
+runcov: $(TARGET)-cov
+ "./$(TARGET)-cov"
+
+test: $(TARGET)
+ "./$(TARGET)"
+
+run: $(TARGET)
+ "./$(TARGET)"
+
+valgrind: $(TARGET)
+ - valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all "./$(TARGET)"
+
+cppcheck:
+ cppcheck $(SRCS)
+
+rundbg: $(TARGET)-dbg
+ gdb --batch --command=./debug.dbg --args "./$(TARGET)-dbg"
+
+format:
+ - clang-format -i $(SRCS) $(HDRS)
+
+DOCKER: Dockerfile
+ docker build -t proto ./
+
+clean:
+ - rm -f *.o *.s *.odbg *.ocov *.js *.ir *~ $(TARGET) $(TARGET).so $(TARGET)-static \
+ $(TARGET)-dbg $(TARGET).a $(TARGET)-cov *.wasm *.wast $(TARGET).adbg *.ast
+
+deepclean: clean
+ - rm tags
+ - rm .depend
+ - rm ./default.profraw ./default.profdata
+ - rm vgcore.*
+ - rm compile_commands.json
+ - rm *.gch
+
+help:
+ @echo "--all is the default target, runs $(TARGET) target"
+ @echo "--everything will build everything"
+ @echo "--SO will generate the so"
+ @echo "--ASM will generate assembly files"
+ @echo "--TAGS will generate tags file"
+ @echo "--BEAR will generate a compilation database"
+ @echo "--IR will generate llvm IR"
+ @echo "--JS will make the js file"
+ @echo "--AST will make the llvm ast file"
+ @echo "--WASM will make the wasm file"
+ @echo "--WAST will make the wasm text debug file"
+ @echo "--$(TARGET) builds the dynamically-linked executable"
+ @echo "--$(TARGET)-dbg will generate the debug build. BUILD_MODE should be set to DEBUG to work"
+ @echo "--$(TARGET)-static will statically link the executable to the libraries"
+ @echo "--$(TARGET)-cov is the coverage build"
+ @echo "--cov will print the coverage report"
+ @echo "--covrep will print the line coverage report"
+ @echo "--A will build the static library"
+ @echo "--TAGS will build the tags file"
+ @echo "--clean"
+ @echo "--deepclean will clean almost everything"
+----
+
+=== Cpp
+
+[source,make]
+----
+TARGET?=main
+SHELL=bash
+SHELL?=bash
+CXX=clang++
+CXX?=clang++
+ifdef OS
+CXX_FLAGS=-std=c++20
+else
+CXX_FLAGS=-std=c++20 -fpic
+endif
+CXX_EXTRA?=
+CTAGS_I_PATH?=./
+LD_FLAGS= -include-pch header.hpp.gch
+EXTRA_LD_FLAGS?=
+ADD_SANITIZERS_CC= -g -fsanitize=address -fno-omit-frame-pointer
+ADD_SANITIZERS_LD= -g -fsanitize=address
+MEM_SANITIZERS_CC= -g -fsanitize=memory -fno-omit-frame-pointer
+MEM_SANITIZERS_LD= -g -fsanitize=memory
+UB_SANITIZERS_CC= -g -fsanitize=undefined -fno-omit-frame-pointer
+UB_SANITIZERS_LD= -g -fsanitize=undefined
+FUZZ_SANITIZERS_CC= -fsanitize=fuzzer,address -g -fno-omit-frame-pointer
+FUZZ_SANITIZERS_LD= -fsanitize=fuzzer,address -g -fno-omit-frame-pointer
+COV_CXX= -fprofile-instr-generate -fcoverage-mapping
+COV_LD= -fprofile-instr-generate
+# BUILD_MODES are=RELEASE(default), DEBUG,ADDSAN,MEMSAN,UBSAN,FUZZ
+BUILD_MODE?=RELEASE
+#EXCLUSION_LIST='(\bdip)|(\bdim)'
+EXCLUSION_LIST='xxxxxx'
+OBJ_LIST:=$(patsubst %.cpp, %.o, $(shell find . -name '*.cpp' | grep -Ev $(EXCLUSION_LIST)))
+OBJ_COV_LIST:=$(patsubst %.cpp, %.ocov, $(shell find . -name '*.cpp' | grep -Ev $(EXCLUSION_LIST)))
+OBJ_DBG_LIST:=$(patsubst %.cpp, %.odbg, $(shell find . -name '*.cpp' | grep -Ev $(EXCLUSION_LIST)))
+ASM_LIST:=$(patsubst %.cpp, %.s, $(shell find . -name '*.cpp' | grep -Ev $(EXCLUSION_LIST)))
+WASM_LIST:=$(patsubst %.cpp, %.wasm, $(shell find . -name '*.cpp' | grep -Ev $(EXCLUSION_LIST)))
+WAST_LIST:=$(patsubst %.cpp, %.wast, $(shell find . -name '*.cpp' | grep -Ev $(EXCLUSION_LIST)))
+IR_LIST:=$(patsubst %.cpp, %.ir, $(shell find . -name '*.cpp' | grep -Ev $(EXCLUSION_LIST)))
+JS_LIST:=$(patsubst %.cpp, %.js, $(shell find . -name '*.cpp' | grep -Ev $(EXCLUSION_LIST)))
+AST_LIST:=$(patsubst %.cpp, %.ast, $(shell find . -name '*.cpp' | grep -Ev $(EXCLUSION_LIST)))
+
+ifeq ($(BUILD_MODE), ADDSAN)
+ifeq ($(CXX), g++)
+$(error This build mode is only useable with clang++.)
+endif
+CXX_EXTRA+=$(ADD_SANITIZERS_CC)
+EXTRA_LD_FLAGS+=$(ADD_SANITIZERS_LD)
+endif
+
+ifeq ($(BUILD_MODE), MEMSAN)
+ifeq ($(CXX), g++)
+$(error This build mode is only useable with clang++.)
+endif
+CXX_EXTRA+=$(MEM_SANITIZERS_CC)
+EXTRA_LD_FLAGS+=$(MEM_SANITIZERS_LD)
+endif
+
+ifeq ($(BUILD_MODE), UBSAN)
+ifeq ($(CXX), g++)
+$(error This build mode is only useable with clang++.)
+endif
+CXX_EXTRA+=$(UB_SANITIZERS_CC)
+EXTRA_LD_FLAGS+=$(UB_SANITIZERS_LD)
+endif
+
+ifeq ($(BUILD_MODE), FUZZ)
+ifeq ($(CXX), g++)
+$(error This build mode is only useable with clang++.)
+endif
+CXX_EXTRA+=$(FUZZ_SANITIZERS_CC)
+EXTRA_LD_FLAGS+=$(FUZZ_SANITIZERS_LD)
+endif
+
+SRCS:=$(wildcard *.cpp)
+HDRS:=$(wildcard *.h)
+CXX_FLAGS+=$(CXX_EXTRA)
+LD_FLAGS+=$(EXTRA_LD_FLAGS)
+
+.DEFAULT:all
+
+.PHONY:all clean help ASM SO TAGS WASM JS exe IR WAST A ADBG AST cppcheck DOCKER
+
+all:exe
+
+everything:$(TARGET) A ASM SO $(TARGET)-static $(TARGET)-dbg ADBG TAGS $(TARGET)-cov WASM JS IR WAST AST DOCKER
+
+depend:.depend
+
+.depend:$(SRCS)
+ rm -rf .depend
+ $(CXX) -MM $(CXX_FLAGS) $^ > ./.depend
+ echo $(patsubst %.o:, %.odbg:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.odbg/\n&/g' >> ./.depend
+ echo $(patsubst %.o:, %.ocov:, $(shell $(CXX) -MM $(CXX_FLAGS) $^)) | sed -r 's/[A-Za-z0-9\-\_]+\.ocov/\n&/g' >> ./.depend
+
+-include ./.depend
+
+.cpp.o: header.hpp.gch
+ $(CXX) $(CXX_FLAGS) -c $< -o $@
+
+%.odbg:%.cpp
+ $(CXX) $(CXX_FLAGS) -g -c $< -o $@
+
+%.ocov:%.cpp
+ $(CXX) $(CXX_FLAGS) $(COV_CXX) -c $< -o $@
+
+header.hpp.gch:header.hpp
+ $(CXX) $(CXX_FLAGS) -c $< -o $@
+
+exe: header.hpp.gch $(TARGET)
+
+$(TARGET): $(OBJ_LIST)
+ $(CXX) $(LD_FLAGS) $^ -o $@
+
+$(TARGET)-static: $(OBJ_LIST)
+ $(CXX) $(LD_FLAGS) $^ -static -o $@
+
+$(TARGET)-dbg: $(OBJ_DBG_LIST)
+ $(CXX) $(LD_FLAGS) $^ -g -o $@
+
+$(TARGET)-cov: $(OBJ_COV_LIST)
+ $(CXX) $(LD_FLAGS) $^ $(COV_LD) -o $@
+
+cov: runcov
+ @llvm-profdata merge -sparse ./default.profraw -o ./default.profdata
+ @llvm-cov show $(TARGET)-cov -instr-profile=default.profdata
+
+covrep: runcov
+ @llvm-profdata merge -sparse ./default.profraw -o ./default.profdata
+ @llvm-cov report $(TARGET)-cov -instr-profile=default.profdata
+
+ASM:$(ASM_LIST)
+
+SO:$(TARGET).so
+
+A:$(TARGET).a
+
+ADBG:$(TARGET).adbg
+
+IR:$(IR_LIST)
+
+WASM:$(WASM_LIST)
+
+WAST:$(WAST_LIST)
+
+JS:$(JS_LIST)
+
+AST:$(AST_LIST)
+
+TAGS:tags
+
+#https://github.com/rizsotto/Bear
+BEAR: clean
+ bear -- make
+
+tags:$(SRCS)
+ $(shell $(CXX) -c -I $(CTAGS_I_PATH) -M $(SRCS)|\
+ sed -e 's/[\\ ]/\n/g'|sed -e '/^$$/d' -e '/\.o:[ \t]*$$/d'|\
+ ctags -L - --c++-kinds=+p --fields=+iaS --extra=+q)
+
+%.s: %.cpp
+ $(CXX) -S $< -o $@
+ # objdump -r -d -M intel -S $< > $@
+
+%.ir: %.cpp
+ $(CXX) -emit-llvm -S -o $@ $<
+
+%.wasm: %.cpp
+ em++ $< -o $@
+
+%.wast: %.wasm
+ wasm2wat $< > $@
+
+%.js: %.cpp
+ em++ $< -s FORCE_FILESYSTEM=1 -s EXIT_RUNTIME=1 -o $@
+
+%.ast: %.cpp
+ $(CXX) -Xclang -ast-dump -fsyntax-only $< > $@
+
+$(TARGET).so: $(OBJ_LIST)
+ $(CXX) $(LD_FLAGS) $^ -shared -o $@
+
+$(TARGET).a: $(OBJ_LIST)
+ ar rcs $(TARGET).a $(OBJ_LIST)
+
+$(TARGET).adbg: $(OBJ_DBG_LIST)
+ ar rcs $(TARGET).adbg $(OBJ_DBG_LIST)
+
+runcov: $(TARGET)-cov
+ "./$(TARGET)-cov"
+
+test: $(TARGET)
+ "./$(TARGET)"
+
+run: $(TARGET)
+ "./$(TARGET)"
+
+valgrind: $(TARGET)
+ - valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all "./$(TARGET)"
+
+cppcheck:
+ cppcheck $(SRCS)
+
+rundbg: $(TARGET)-dbg
+ gdb --batch --command=./debug.dbg --args "./$(TARGET)-dbg"
+
+format:
+ - clang-format -i $(SRCS) $(HDRS)
+
+DOCKER: Dockerfile
+ docker buld -t proto ./
+
+clean:
+ - rm -f *.o *.dis *.odbg *.ocov *.js *.ir *~ $(TARGET) $(TARGET).so $(TARGET)-static \
+ $(TARGET)-dbg $(TARGET).a $(TARGET)-cov *.wasm *.wast $(TARGET).adbg *.ast
+
+deepclean: clean
+ - rm tags
+ - rm .depend
+ - rm ./default.profraw ./default.profdata
+ - rm vgcore.*
+ - rm compile_commands.json
+ - rm *.gch
+
+help:
+ @echo "--all is the default target, runs $(TARGET) target"
+ @echo "--everything will build everything"
+ @echo "--SO will generate the so"
+ @echo "--ASM will generate assembly files"
+ @echo "--TAGS will generate tags file"
+ @echo "--BEAR will generate a compilation database"
+ @echo "--IR will generate llvm IR"
+ @echo "--$(TARGET) builds the dynamically-linked executable"
+ @echo "--$(TARGET)-dbg will generate the debug build. BUILD_MODE should be set to DEBUG to work"
+ @echo "--$(TARGET)-static will statically link the executable to the libraries"
+ @echo "--$(TARGET)-cov is the coverage build"
+ @echo "--cov will print the coverage report"
+ @echo "--covrep will print the line coverage report"
+ @echo "--A will build the static library"
+ @echo "--TAGS will build the tags file"
+ @echo "--clean"
+ @echo "--deepclean will clean almost everything"
+----
+
+timestamp:1705630055
+
+version:1.1.0
+
+https://blog.terminaldweller.com/rss/feed
+
+https://raw.githubusercontent.com/terminaldweller/blog/main/mds/lazymakefiles.md