diff --git a/.github/gen_ldscript.py b/.github/gen_ldscript.py
new file mode 100644
index 0000000000000000000000000000000000000000..48ab05a49d0bc1b854b26443583743ba40900dda
--- /dev/null
+++ b/.github/gen_ldscript.py
@@ -0,0 +1,25 @@
+from os.path import join
+Import("env")
+
+mcu_package = 1
+target_mcu = 0
+mcu_ld = 0
+linkerscript_cmd = env.Command(
+    join("$BUILD_DIR", "ldscript.ld"),  # $TARGET
+    join(env.subst("$PROJECT_DIR"), "ch32v003fun", "ch32v003fun.ld"),  # $SOURCE
+    env.VerboseAction(" ".join([
+        "$CC",
+        "-E",
+        "-P",
+        "-x",
+        "c",
+        "-DTARGET_MCU=%d" % target_mcu,
+        "-DMCU_PACKAGE=%d" % mcu_package,
+        "-DTARGET_MCU_LD=%d" % mcu_ld,
+        "$SOURCE" 
+        ">",
+        "$TARGET"
+    ]), "Generating linkerscript $BUILD_DIR/ldscript.ld")
+)
+env.Depends("$BUILD_DIR/${PROGNAME}.elf", linkerscript_cmd)
+env.Replace(LDSCRIPT_PATH=join("$BUILD_DIR", "ldscript.ld"))
\ No newline at end of file
diff --git a/platformio.ini b/platformio.ini
index 4a4e33ab76d3bb52081ec6985a570364e5ef9739..5af4840aebd10ad436dfae769ce9a892b9f04ddc 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -14,12 +14,13 @@ extends = fun_base
 
 ; for examples that use ch32v003fun as their base
 [fun_base]
-board_build.ldscript = ch32v003fun/generated_ch32v003.ld
 build_flags = -flto -Ich32v003fun -I/usr/include/newlib -lgcc -Iextralibs
 ; dynamically add "examples/$PIOENV" to the include path
-extra_scripts = .github/add_include.py
+; generate linkerscript on the fly
+extra_scripts = 
+  .github/add_include.py
+  .github/gen_ldscript.py
 build_src_filter = +<ch32v003fun>
-extra_libs_srcs = +<extralibs>
 
 ; If creating a new example:
 ; 1. Add new [env:name]
@@ -69,7 +70,7 @@ build_src_filter = ${fun_base.build_src_filter} +<examples/exti_pin_change_isr>
 build_src_filter = ${fun_base.build_src_filter} +<examples/flashtest>
 
 [env:GPIO]
-build_src_filter = ${fun_base.build_src_filter} ${fun_base.extra_libs_srcs} +<examples/GPIO>
+build_src_filter = ${fun_base.build_src_filter} +<examples/GPIO>
 
 [env:i2c_oled]
 build_src_filter = ${fun_base.build_src_filter}  +<examples/i2c_oled>
@@ -111,7 +112,7 @@ build_src_filter = ${fun_base.build_src_filter} +<examples/spi_24L01_tx>
 build_src_filter = ${fun_base.build_src_filter} +<examples/spi_dac>
 
 [env:spi_oled]
-build_src_filter = ${fun_base.build_src_filter} ${fun_base.extra_libs_srcs} +<examples/spi_oled>
+build_src_filter = ${fun_base.build_src_filter} +<examples/spi_oled>
 
 [env:standby_autowake]
 build_src_filter = ${fun_base.build_src_filter} +<examples/standby_autowake>