diff --git a/.gitignore b/.gitignore
index 12fb2f857ec8709efb69de2ba35e73cc5d10b4db..a9445131bff9ac74f443e4f7865bb47e32f54769 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@
 *.map
 minichlink/minichlink
 minichlink/minichlink.so
+compile_commands.json
diff --git a/README.md b/README.md
index 59599c9385d8b74709a27d39525e522ffdfe8512..a833ad0aeec93fe21e5c967fcb0c14db8b3439d0 100644
--- a/README.md
+++ b/README.md
@@ -139,6 +139,12 @@ This project can also be built, uploaded and debugged with VSCode and the Platfo
 
 See [here](https://github.com/Community-PIO-CH32V/platform-ch32v) for further details.
 
+## clangd
+
+If the C/C++ language server clangd is unable to find `ch32v003fun.h`, the example will have to be wiped `make clean` and built once with `bear -- make build`, which will generate a `compile_commands.json`, which clangd uses to find the include paths specified in the makefiles.  
+`make clangd` does this in one step.
+`build_all_clangd.sh` does in `build scripts` does this for all examples.
+
 ## Quick Reference
  * Needed for programming/debugging: `SWIO` is on `PD1`
  * Optional (not needed, can be configured as output if fuse set): `NRST` is on `PD7`
diff --git a/build_scripts/README.md b/build_scripts/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c3da4c4607d8dc3d8b215f49dd53b2d6f41005bc
--- /dev/null
+++ b/build_scripts/README.md
@@ -0,0 +1,3 @@
+Scripts serve to build / clean all examples at once.  
+
+`build_all_clangd.sh` uses bear to additionally generate a `compile_commands.yaml` for each example so the C/C++ language server clangd can be aware of the paths in the makefiles.
diff --git a/examples/build_all.cmd b/build_scripts/build_all.cmd
similarity index 75%
rename from examples/build_all.cmd
rename to build_scripts/build_all.cmd
index aa685db2007d798187a916c262ec93c5c999a263..8621190973cef4bdba3811fb6691f3c61f1ae92e 100644
--- a/examples/build_all.cmd
+++ b/build_scripts/build_all.cmd
@@ -4,4 +4,8 @@ setlocal
 set TARGET=%1
 if [%1]==[] set TARGET=build
 
+cd ..\examples
+
 for /d %%i in (*) do make --directory=%%i %TARGET%
+
+cd ..\build_scripts
diff --git a/build_scripts/build_all.sh b/build_scripts/build_all.sh
new file mode 100755
index 0000000000000000000000000000000000000000..982db503b6d59774ea085eddff9ff6d947fd1797
--- /dev/null
+++ b/build_scripts/build_all.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+echo "this will build all examples"
+sleep 2
+
+cd ../examples
+
+for dir in */; do
+	if [ -f "${dir}Makefile" ]; then
+		echo "running 'make build' in ${dir}"
+		(cd "${dir}" && make build)
+	else
+		echo "no Makefile in ${dir}"
+	fi
+done
+
+cd ../build_scripts
diff --git a/build_scripts/build_all_clangd.sh b/build_scripts/build_all_clangd.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1331381f4dcac697583183f0267819275e799f90
--- /dev/null
+++ b/build_scripts/build_all_clangd.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+echo "this will build all examples with 'bear' to generate 'compile_commands.json'"
+echo "'clangd' relies on these files to find the include paths"
+sleep 2
+
+cd ../examples
+
+if ! command -v bear --help &> /dev/null
+then
+	echo "'bear' could not be found"
+	echo "please install it from your package manager"
+	exit
+fi
+
+for dir in */; do
+	if [ -f "${dir}Makefile" ]; then
+		echo "running 'bear -- make' in ${dir}"
+		(cd "${dir}" && make clean && make clangd_clean && make clangd)
+	else
+		echo "no Makefile in ${dir}"
+	fi
+done
+
+cd ../build_scripts
diff --git a/build_scripts/clean_all.sh b/build_scripts/clean_all.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d0bd5a72949e3605e3560ff76ea46bcf0ca184f9
--- /dev/null
+++ b/build_scripts/clean_all.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+echo "this will clean all examples"
+sleep 2
+
+cd ../examples
+
+for dir in */; do
+	if [ -f "${dir}Makefile" ]; then
+		echo "running 'make clean' in ${dir}"
+		(cd "${dir}" && make clean)
+	else
+		echo "no Makefile in ${dir}"
+	fi
+done
+
+cd ../build_scripts
diff --git a/build_scripts/clean_all_clangd.sh b/build_scripts/clean_all_clangd.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4a507edad6a91c68997f29cff85181127fabad73
--- /dev/null
+++ b/build_scripts/clean_all_clangd.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+echo "this will clean all examples and their 'compile_commands.json'"
+echo "'clangd' relies on these files to find the include paths"
+sleep 2
+
+cd ../examples
+
+for dir in */; do
+	if [ -f "${dir}Makefile" ]; then
+		echo "running 'make clean' and 'make clangd_clean' in ${dir}"
+		(cd "${dir}" && make clean && make clangd_clean)
+	else
+		echo "no Makefile in ${dir}"
+	fi
+done
+
+cd ../build_scripts
diff --git a/ch32v003fun/ch32v003fun.mk b/ch32v003fun/ch32v003fun.mk
index 56d519fb959c16c1ebbf43599eeda9b33a6e319d..70b8a44b31473138e80fafa758cdfd0c233de9a3 100644
--- a/ch32v003fun/ch32v003fun.mk
+++ b/ch32v003fun/ch32v003fun.mk
@@ -46,6 +46,13 @@ monitor :
 gdbserver : 
 	-$(MINICHLINK)/minichlink -baG
 
+clangd :
+	make clean
+	bear -- make build
+
+clangd_clean :
+	rm -f compile_commands.json
+
 cv_flash : $(TARGET).bin
 	make -C $(MINICHLINK) all
 	$(MINICHLINK)/minichlink -w $< flash -b