rework some header library dependencies
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f800c2f..78cc2af 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -27,6 +27,29 @@
     pico_promote_common_scope_vars()
 endfunction()
 
+# takes dependencies after the target
+function(pico_add_header_aware_library_dependency TARGET)
+    if (${ARGC} LESS 2)
+        message(FATAL_ERROR "expected a target and at least one dependency")
+    endif()
+    if (NOT TARGET ${TARGET}_headers)
+        message(FATAL_ERROR "${TARGET} does not have headers")
+    endif()
+    # library should depend on its own header
+    target_link_libraries(${TARGET} INTERFACE ${TARGET}_headers)
+    foreach(DEPENDENCY IN LISTS ARGN)
+        if (DEPENDENCY MATCHES ".*_headers")
+            message(FATAL_ERROR "should not use headers with pico_add_header_aware_library_dependency")
+        endif()
+        # note, it would be nice to only add the dependency if it exists, but we do
+        # not necessarily add libraries in reverse dependency order, so we do this
+        # unconditionally, so this function shouuld only be passed dependencies that
+        # have headers, or link will fail with a missing library -lfoo_headers
+        target_link_libraries(${TARGET}_headers INTERFACE ${DEPENDENCY}_headers)
+        target_link_libraries(${TARGET} INTERFACE ${DEPENDENCY})
+    endforeach()
+endfunction()
+
 # add a link option to wrap the given function name; i.e. -Wl:wrap=FUNCNAME for gcc
 function(pico_wrap_function TARGET FUNCNAME)
     target_link_options(${TARGET} INTERFACE "LINKER:--wrap=${FUNCNAME}")
@@ -66,7 +89,7 @@
         target_include_directories(hardware_${NAME}_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
         target_link_libraries(hardware_${NAME}_headers INTERFACE pico_base_headers)
         if (NOT PICO_NO_HARDWARE)
-            target_link_libraries(hardware_${NAME}_headers INTERFACE hardware_structs hardware_claim)
+            target_link_libraries(hardware_${NAME}_headers INTERFACE hardware_structs hardware_claim_headers)
         endif()
     endif()
 endmacro()
@@ -80,13 +103,17 @@
         #   super interesting except to determine functionality as they are mostly passive accessors, however
         #   they could be useful to determine if the header is available.
         # pico_add_sdk_impl_library(hardware_${NAME})
-        add_library(hardware_${NAME} INTERFACE)
+        add_library(hardware_${NAME}_headers INTERFACE)
 
-        target_include_directories(hardware_${NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
-        target_link_libraries(hardware_${NAME} INTERFACE pico_base_headers)
+        # a headers only target should still have an explicit _headers library for consistency
+        target_include_directories(hardware_${NAME}_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
+        target_link_libraries(hardware_${NAME}_headers INTERFACE pico_base_headers)
         if (NOT PICO_NO_HARDWARE)
-            target_link_libraries(hardware_${NAME} INTERFACE hardware_structs)
+            target_link_libraries(hardware_${NAME}_headers INTERFACE hardware_structs)
         endif()
+
+        add_library(hardware_${NAME} INTERFACE)
+        target_link_libraries(hardware_${NAME} INTERFACE hardware_${NAME}_headers)
     endif()
 endmacro()
 
@@ -104,7 +131,7 @@
                 ${CMAKE_CURRENT_LIST_DIR}/${NAME}.c
                 )
 
-        target_link_libraries(hardware_${NAME} INTERFACE hardware_${NAME}_headers pico_platform)
+        target_link_libraries(hardware_${NAME} INTERFACE hardware_${NAME}_headers hardware_claim pico_platform)
     endif()
 endmacro()
 
diff --git a/src/common/pico_stdlib/CMakeLists.txt b/src/common/pico_stdlib/CMakeLists.txt
index 454ea57..7523d08 100644
--- a/src/common/pico_stdlib/CMakeLists.txt
+++ b/src/common/pico_stdlib/CMakeLists.txt
@@ -1,11 +1,5 @@
 if (NOT TARGET pico_stdlib_headers)
     add_library(pico_stdlib_headers INTERFACE)
     target_include_directories(pico_stdlib_headers INTERFACE include)
-    target_link_libraries(pico_stdlib_headers INTERFACE
-            hardware_gpio
-            hardware_uart
-            hardware_divider
-            pico_time
-            pico_util
-    )
+    # dependencies handled in implementation CMakeLists.txt
 endif()
\ No newline at end of file
diff --git a/src/common/pico_sync/CMakeLists.txt b/src/common/pico_sync/CMakeLists.txt
index 2f8bde2..61259f6 100644
--- a/src/common/pico_sync/CMakeLists.txt
+++ b/src/common/pico_sync/CMakeLists.txt
@@ -1,7 +1,9 @@
 if (NOT TARGET pico_sync_headers)
     add_library(pico_sync_headers INTERFACE)
     target_include_directories(pico_sync_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
-    target_link_libraries(pico_sync_headers INTERFACE hardware_sync pico_time)
+    target_link_libraries(pico_sync_headers INTERFACE
+            hardware_sync_headers
+            pico_time_headers)
 endif()
 
 if (NOT TARGET pico_sync_core)
diff --git a/src/common/pico_time/CMakeLists.txt b/src/common/pico_time/CMakeLists.txt
index 9e497a7..b55fe0f 100644
--- a/src/common/pico_time/CMakeLists.txt
+++ b/src/common/pico_time/CMakeLists.txt
@@ -1,9 +1,7 @@
 if (NOT TARGET pico_time_headers)
     add_library(pico_time_headers INTERFACE)
-
     target_include_directories(pico_time_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
-
-    target_link_libraries(pico_time_headers INTERFACE hardware_timer)
+    target_link_libraries(pico_time_headers INTERFACE hardware_timer_headers pico_sync_headers pico_util_headers)
 endif()
 
 if (NOT TARGET pico_time)
@@ -12,5 +10,5 @@
     target_sources(pico_time INTERFACE
             ${CMAKE_CURRENT_LIST_DIR}/time.c
             ${CMAKE_CURRENT_LIST_DIR}/timeout_helper.c)
-    target_link_libraries(pico_time INTERFACE pico_time_headers pico_sync pico_util)
+    target_link_libraries(pico_time INTERFACE pico_time_headers hardware_timer pico_sync pico_util)
 endif()
diff --git a/src/common/pico_util/CMakeLists.txt b/src/common/pico_util/CMakeLists.txt
index 3eb6998..88759f5 100644
--- a/src/common/pico_util/CMakeLists.txt
+++ b/src/common/pico_util/CMakeLists.txt
@@ -1,7 +1,7 @@
 if (NOT TARGET pico_util_headers)
     add_library(pico_util_headers INTERFACE)
     target_include_directories(pico_util_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
-    target_link_libraries(pico_util_headers INTERFACE pico_base_headers hardware_sync)
+    target_link_libraries(pico_util_headers INTERFACE pico_base_headers hardware_sync_headers)
 endif()
 
 if (NOT TARGET pico_util)
diff --git a/src/rp2_common/hardware_adc/CMakeLists.txt b/src/rp2_common/hardware_adc/CMakeLists.txt
index 291428a..16c958c 100644
--- a/src/rp2_common/hardware_adc/CMakeLists.txt
+++ b/src/rp2_common/hardware_adc/CMakeLists.txt
@@ -1,4 +1,4 @@
 pico_simple_hardware_target(adc)
 
 # additional library
-target_link_libraries(hardware_adc INTERFACE hardware_resets)
\ No newline at end of file
+pico_add_header_aware_library_dependency(hardware_adc hardware_gpio hardware_resets)
\ No newline at end of file
diff --git a/src/rp2_common/hardware_claim/CMakeLists.txt b/src/rp2_common/hardware_claim/CMakeLists.txt
index 63f4806..e0f0a93 100644
--- a/src/rp2_common/hardware_claim/CMakeLists.txt
+++ b/src/rp2_common/hardware_claim/CMakeLists.txt
@@ -1,2 +1,3 @@
 pico_simple_hardware_target(claim)
-target_link_libraries(hardware_claim INTERFACE hardware_sync)
\ No newline at end of file
+
+pico_add_header_aware_library_dependency(hardware_claim hardware_sync)
\ No newline at end of file
diff --git a/src/rp2_common/hardware_clocks/CMakeLists.txt b/src/rp2_common/hardware_clocks/CMakeLists.txt
index ceb29e2..6c3c0aa 100644
--- a/src/rp2_common/hardware_clocks/CMakeLists.txt
+++ b/src/rp2_common/hardware_clocks/CMakeLists.txt
@@ -1,6 +1,6 @@
 pico_simple_hardware_target(clocks)
 
-target_link_libraries(hardware_clocks INTERFACE
+pico_add_header_aware_library_dependency(hardware_clocks
         hardware_gpio
         hardware_irq
         hardware_resets
diff --git a/src/rp2_common/hardware_dma/CMakeLists.txt b/src/rp2_common/hardware_dma/CMakeLists.txt
index fe08541..38cb6fd 100644
--- a/src/rp2_common/hardware_dma/CMakeLists.txt
+++ b/src/rp2_common/hardware_dma/CMakeLists.txt
@@ -1,2 +1,2 @@
 pico_simple_hardware_target(dma)
-target_link_libraries(hardware_dma INTERFACE hardware_claim)
\ No newline at end of file
+pico_add_header_aware_library_dependency(hardware_dma hardware_claim)
\ No newline at end of file
diff --git a/src/rp2_common/hardware_flash/CMakeLists.txt b/src/rp2_common/hardware_flash/CMakeLists.txt
index 9682566..8a70516 100644
--- a/src/rp2_common/hardware_flash/CMakeLists.txt
+++ b/src/rp2_common/hardware_flash/CMakeLists.txt
@@ -1,2 +1,2 @@
 pico_simple_hardware_target(flash)
-target_link_libraries(hardware_flash INTERFACE pico_bootrom)
+pico_add_header_aware_library_dependency(hardware_flash pico_bootrom)
diff --git a/src/rp2_common/hardware_gpio/CMakeLists.txt b/src/rp2_common/hardware_gpio/CMakeLists.txt
index 97a9355..2e13a6a 100644
--- a/src/rp2_common/hardware_gpio/CMakeLists.txt
+++ b/src/rp2_common/hardware_gpio/CMakeLists.txt
@@ -1,2 +1,2 @@
 pico_simple_hardware_target(gpio)
-target_link_libraries(hardware_gpio INTERFACE hardware_irq)
\ No newline at end of file
+pico_add_header_aware_library_dependency(hardware_gpio hardware_irq)
\ No newline at end of file
diff --git a/src/rp2_common/hardware_irq/CMakeLists.txt b/src/rp2_common/hardware_irq/CMakeLists.txt
index c218231..475e769 100644
--- a/src/rp2_common/hardware_irq/CMakeLists.txt
+++ b/src/rp2_common/hardware_irq/CMakeLists.txt
@@ -3,4 +3,4 @@
 # additional sources/libraries
 
 target_sources(hardware_irq INTERFACE ${CMAKE_CURRENT_LIST_DIR}/irq_handler_chain.S)
-target_link_libraries(hardware_irq INTERFACE pico_sync)
\ No newline at end of file
+pico_add_header_aware_library_dependency(hardware_irq pico_sync)
\ No newline at end of file
diff --git a/src/rp2_common/hardware_pio/CMakeLists.txt b/src/rp2_common/hardware_pio/CMakeLists.txt
index ad01869..bbc779e 100644
--- a/src/rp2_common/hardware_pio/CMakeLists.txt
+++ b/src/rp2_common/hardware_pio/CMakeLists.txt
@@ -1,4 +1,4 @@
 pico_simple_hardware_target(pio)
 
 # additional libraries
-target_link_libraries(hardware_pio INTERFACE hardware_gpio hardware_claim)
\ No newline at end of file
+pico_add_header_aware_library_dependency(hardware_pio hardware_gpio hardware_claim)
\ No newline at end of file
diff --git a/src/rp2_common/hardware_timer/CMakeLists.txt b/src/rp2_common/hardware_timer/CMakeLists.txt
index 358f74c..d227476 100644
--- a/src/rp2_common/hardware_timer/CMakeLists.txt
+++ b/src/rp2_common/hardware_timer/CMakeLists.txt
@@ -1,2 +1,2 @@
 pico_simple_hardware_target(timer)
-target_link_libraries(hardware_timer INTERFACE hardware_claim)
+pico_add_header_aware_library_dependency(hardware_timer hardware_claim)
diff --git a/src/rp2_common/pico_bootrom/CMakeLists.txt b/src/rp2_common/pico_bootrom/CMakeLists.txt
index 58ea575..1d34ccb 100644
--- a/src/rp2_common/pico_bootrom/CMakeLists.txt
+++ b/src/rp2_common/pico_bootrom/CMakeLists.txt
@@ -1,8 +1,9 @@
-add_library(pico_bootrom INTERFACE)
+add_library(pico_bootrom_headers INTERFACE)
+target_include_directories(pico_bootrom_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
 
+add_library(pico_bootrom INTERFACE)
 target_sources(pico_bootrom INTERFACE
         ${CMAKE_CURRENT_LIST_DIR}/bootrom.c
         )
 
-target_include_directories(pico_bootrom INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
-target_link_libraries(pico_bootrom INTERFACE pico_base_headers)
+target_link_libraries(pico_bootrom INTERFACE pico_bootrom_headers pico_base_headers)
diff --git a/src/rp2_common/pico_lwip/include/arch/cc.h b/src/rp2_common/pico_lwip/include/arch/cc.h
index 8194dcb..b8b76f5 100644
--- a/src/rp2_common/pico_lwip/include/arch/cc.h
+++ b/src/rp2_common/pico_lwip/include/arch/cc.h
@@ -70,7 +70,7 @@
 #endif
 
 #ifndef LWIP_PLATFORM_ASSERT
-void panic(const char *fmt, ...);
+#include "pico/platform.h"
 #define LWIP_PLATFORM_ASSERT(x) panic(x)
 #endif
 
diff --git a/src/rp2_common/pico_multicore/CMakeLists.txt b/src/rp2_common/pico_multicore/CMakeLists.txt
index 2401061..647e375 100644
--- a/src/rp2_common/pico_multicore/CMakeLists.txt
+++ b/src/rp2_common/pico_multicore/CMakeLists.txt
@@ -1,12 +1,15 @@
 if (NOT TARGET pico_multicore)
+    add_library(pico_multicore_headers INTERFACE)
+    target_include_directories(pico_multicore_headers INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
+
     pico_add_impl_library(pico_multicore)
 
     target_sources(pico_multicore INTERFACE
             ${CMAKE_CURRENT_LIST_DIR}/multicore.c)
 
-    target_include_directories(pico_multicore INTERFACE ${CMAKE_CURRENT_LIST_DIR}/include)
 
-    target_link_libraries(pico_multicore INTERFACE pico_sync hardware_irq)
+    target_link_libraries(pico_multicore INTERFACE pico_multicore_headers)
+    pico_add_header_aware_library_dependency(pico_multicore pico_sync hardware_irq)
 endif()
 
 
diff --git a/src/rp2_common/pico_stdlib/CMakeLists.txt b/src/rp2_common/pico_stdlib/CMakeLists.txt
index cc48743..1e9f959 100644
--- a/src/rp2_common/pico_stdlib/CMakeLists.txt
+++ b/src/rp2_common/pico_stdlib/CMakeLists.txt
@@ -10,12 +10,19 @@
     target_sources(pico_stdlib INTERFACE
             ${CMAKE_CURRENT_LIST_DIR}/stdlib.c
     )
+    pico_add_header_aware_library_dependency(pico_stdlib
+            hardware_gpio
+            hardware_uart
+            hardware_divider
+            pico_time
+            pico_util
+            pico_platform
+            )
+
+    # these do not have _headers atm
     target_link_libraries(pico_stdlib INTERFACE
-        pico_stdlib_headers
-        pico_platform
         pico_runtime
         pico_stdio
-        pico_time
     )
 
     function(pico_enable_stdio_uart TARGET ENABLED)