diff --git a/.readthedocs.yaml b/.readthedocs.yaml
new file mode 100644
index 000000000..71e28a0e8
--- /dev/null
+++ b/.readthedocs.yaml
@@ -0,0 +1,24 @@
+# .readthedocs.yaml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+# Required
+version: 2
+
+# Set the version of Python and other tools you might need
+build:
+  os: ubuntu-22.04
+  tools:
+    python: "3.11"
+  apt_packages:
+    - libclang-dev
+
+# Build documentation in the docs/ directory with Sphinx
+sphinx:
+  configuration: docs/conf.py
+
+# We recommend specifying your dependencies to enable reproducible builds:
+# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
+python:
+  install:
+  - requirements: docs/requirements.txt
diff --git a/BSDmakefile b/BSDmakefile
index 9339f3620..5dc504035 100644
--- a/BSDmakefile
+++ b/BSDmakefile
@@ -89,7 +89,6 @@ crossbuild: check-docker
 		cmake $(CMAKE_OPT) -DPACKAGING=DEB,RPM -DDEBARCH=$(DEBARCH) -DRPMARCH=$(RPMARCH) -B$(CROSSBUILD_DIR)/$(CROSSIMG) && \
 		make VERBOSE=1 -C$(CROSSBUILD_DIR)/$(CROSSIMG) all package"
 	docker rmi $(CROSSIMG_PREFIX)$(CROSSIMG)
-	docker rmi dockcross/$(CROSSIMG)
 
 linux-armv5:
 	CROSSIMG=$@ DEBARCH=arm RPMARCH=arm make crossbuild
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fa5efcd24..08e7a7ead 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,9 +11,11 @@
 # Contributors:
 # ZettaScale Zenoh Team, <zenoh@zettascale.tech>
 #
-cmake_minimum_required(VERSION 3.8)
+cmake_minimum_required(VERSION 3.13)
 
-project(libzenohpico VERSION 0.10.0.0 LANGUAGES C)
+project(zenohpico VERSION 0.10.0.0 LANGUAGES C)
+
+include(CMakePackageConfigHelpers)
 
 option(BUILD_SHARED_LIBS "Build shared libraries if ON, otherwise build static libraries" ON)
 option(ZENOH_DEBUG "Use this to set the ZENOH_DEBUG variable." 0)
@@ -62,8 +64,14 @@ if(NOT CMAKE_BUILD_TYPE)
 endif()
 string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE)
 
+
+set(CHECK_THREADS "ON")
+
 if(CMAKE_SYSTEM_NAME MATCHES "Linux")
   add_definition(ZENOH_LINUX)
+elseif(POSIX_COMPATIBLE)
+  add_definition(ZENOH_LINUX)
+  set(CHECK_THREADS "OFF")
 elseif(CMAKE_SYSTEM_NAME MATCHES "BSD")
   add_definition(ZENOH_BSD)
 elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
@@ -103,7 +111,9 @@ if(SKBUILD)
 endif()
 
 set(THREADS_PREFER_PTHREAD_FLAG ON)
-find_package(Threads REQUIRED)
+if(CHECK_THREADS)
+  find_package(Threads REQUIRED)
+endif()
 
 if(CMAKE_BUILD_TYPE MATCHES "DEBUG")
   if(UNIX)
@@ -167,7 +177,7 @@ if(WITH_ZEPHYR)
 elseif(WITH_FREERTOS_PLUS_TCP)
   file (GLOB Sources_Freertos_Plus_TCP "src/system/freertos_plus_tcp/*.c")
   list(APPEND Sources ${Sources_Freertos_Plus_TCP})
-elseif(CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Darwin" OR CMAKE_SYSTEM_NAME MATCHES "BSD")
+elseif(CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Darwin" OR CMAKE_SYSTEM_NAME MATCHES "BSD" OR POSIX_COMPATIBLE)
   file (GLOB Sources_Unix "src/system/unix/*.c")
   list(APPEND Sources ${Sources_Unix})
 elseif(CMAKE_SYSTEM_NAME MATCHES "Emscripten")
@@ -183,7 +193,9 @@ link_directories(${LIBRARY_OUTPUT_PATH})
 
 target_sources(${Libname} PRIVATE ${Sources})
 
-target_link_libraries(${Libname} Threads::Threads)
+if(CHECK_THREADS)
+  target_link_libraries(${Libname} Threads::Threads)
+endif()
 
 if(CMAKE_SYSTEM_NAME MATCHES "Linux")
   target_link_libraries(${Libname} rt)
@@ -224,6 +236,31 @@ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/zenoh-pico
   COMPONENT Headers
 )
 
+set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/zenohpico")
+# Generate <Package>Config.cmake
+configure_package_config_file(
+  "PackageConfig.cmake.in"
+  "${CMAKE_CURRENT_BINARY_DIR}/zenohpicoConfig.cmake"
+  INSTALL_DESTINATION "${CMAKE_INSTALL_CMAKEDIR}")
+
+# Generate <Package>Version.cmake
+write_basic_package_version_file(
+  "${CMAKE_CURRENT_BINARY_DIR}/zenohpicoConfigVersion.cmake"
+  VERSION ${PROJECT_VERSION}
+  COMPATIBILITY SameMajorVersion)
+
+install(
+  FILES "${CMAKE_CURRENT_BINARY_DIR}/zenohpicoConfig.cmake"
+        "${CMAKE_CURRENT_BINARY_DIR}/zenohpicoConfigVersion.cmake"
+  DESTINATION "${CMAKE_INSTALL_CMAKEDIR}"
+  CONFIGURATIONS ${configurations}
+  COMPONENT dev)
+
+if(UNIX)
+  configure_file("${CMAKE_SOURCE_DIR}/zenohpico.pc.in" "${CMAKE_SOURCE_DIR}/zenohpico.pc" @ONLY)
+  install(FILES "${CMAKE_SOURCE_DIR}/zenohpico.pc" CONFIGURATIONS Release RelWithDebInfo DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
+endif()
+
 if(BUILD_EXAMPLES)
   add_subdirectory(examples)
 endif()
@@ -370,4 +407,4 @@ if(PACKAGING)
   include(CPack)
 endif()
 
-endif()
+endif()
\ No newline at end of file
diff --git a/GNUmakefile b/GNUmakefile
index 28f9eb062..6ea060ed9 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -89,7 +89,6 @@ crossbuild: check-docker
 		cmake $(CMAKE_OPT) -DPACKAGING=DEB,RPM -DDEBARCH=$(DEBARCH) -DRPMARCH=$(RPMARCH) -B$(CROSSBUILD_DIR)/$(CROSSIMG) && \
 		make VERBOSE=1 -C$(CROSSBUILD_DIR)/$(CROSSIMG) all package"
 	docker rmi $(CROSSIMG_PREFIX)$(CROSSIMG)
-	docker rmi dockcross/$(CROSSIMG)
 
 linux-armv5:
 	CROSSIMG=$@ DEBARCH=arm RPMARCH=arm make crossbuild
diff --git a/PackageConfig.cmake.in b/PackageConfig.cmake.in
new file mode 100644
index 000000000..7ac56c378
--- /dev/null
+++ b/PackageConfig.cmake.in
@@ -0,0 +1,28 @@
+#
+# Copyright (c) 2023 ZettaScale Technology.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Eclipse Public License 2.0 which is available at
+# http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+# which is available at https://www.apache.org/licenses/LICENSE-2.0.
+#
+# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+#
+# Contributors:
+#   ZettaScale Zenoh team, <zenoh@zettascale.tech>
+#
+
+@PACKAGE_INIT@
+
+add_library(__zenohpico_static STATIC IMPORTED GLOBAL)
+add_library(zenohpico::static ALIAS __zenohpico_static)
+set_property(TARGET __zenohpico_static PROPERTY IMPORTED_LOCATION "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/@STATICLIB@")
+
+add_library(__zenohpico_lib SHARED IMPORTED GLOBAL)
+add_library(zenohpico::lib ALIAS __zenohpico_lib)
+set_target_properties(__zenohpico_lib PROPERTIES IMPORTED_NO_SONAME TRUE)
+set_property(TARGET __zenohpico_lib PROPERTY IMPORTED_LOCATION "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/@DYLIB@")
+if(NOT ("@IMPLIB@" STREQUAL ""))
+    set_property(TARGET __zenohpico_lib PROPERTY IMPORTED_IMPLIB "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@/@IMPLIB@")
+endif()
+target_include_directories(__zenohpico_lib INTERFACE "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@")
diff --git a/docs/conf.py b/docs/conf.py
index 37ff6729d..1d5c7d92c 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -48,4 +48,4 @@
     raise ValueError("Windows not supported yet for building docs.")
 
 else:
-    Config.set_library_file('/usr/lib/llvm-6.0/lib/libclang.so.1') # Required for readthedocs
+    Config.set_library_file('/usr/lib/llvm-14/lib/libclang.so.1') # Required for readthedocs
diff --git a/examples/unix/c11/z_ping.c b/examples/unix/c11/z_ping.c
index 2472196fe..d4ff47adb 100644
--- a/examples/unix/c11/z_ping.c
+++ b/examples/unix/c11/z_ping.c
@@ -46,11 +46,32 @@ int main(int argc, char** argv) {
     _z_condvar_init(&cond);
     z_owned_config_t config = z_config_default();
     z_owned_session_t session = z_open(z_move(config));
+    if (!z_check(session)) {
+        printf("Unable to open session!\n");
+        return -1;
+    }
+
+    if (zp_start_read_task(z_loan(session), NULL) < 0 || zp_start_lease_task(z_loan(session), NULL) < 0) {
+        printf("Unable to start read and lease tasks");
+        return -1;
+    }
+
     z_keyexpr_t ping = z_keyexpr_unchecked("test/ping");
     z_keyexpr_t pong = z_keyexpr_unchecked("test/pong");
+
     z_owned_publisher_t pub = z_declare_publisher(z_loan(session), ping, NULL);
-    z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)(&pub));
+    if (!z_check(pub)) {
+        printf("Unable to declare publisher for key expression!\n");
+        return -1;
+    }
+
+    z_owned_closure_sample_t respond = z_closure(callback, drop, NULL);
     z_owned_subscriber_t sub = z_declare_subscriber(z_loan(session), pong, z_move(respond), NULL);
+    if (!z_check(sub)) {
+        printf("Unable to declare subscriber for key expression.\n");
+        return -1;
+    }
+
     uint8_t* data = z_malloc(args.size);
     for (unsigned int i = 0; i < args.size; i++) {
         data[i] = i % 10;
@@ -79,8 +100,12 @@ int main(int argc, char** argv) {
     _z_mutex_unlock(&mutex);
     z_free(results);
     z_free(data);
-    z_drop(z_move(sub));
     z_drop(z_move(pub));
+    z_drop(z_move(sub));
+
+    zp_stop_read_task(z_loan(session));
+    zp_stop_lease_task(z_loan(session));
+
     z_close(z_move(session));
 }
 
diff --git a/examples/unix/c11/z_pong.c b/examples/unix/c11/z_pong.c
index 7f0731478..c0d1cd0b0 100644
--- a/examples/unix/c11/z_pong.c
+++ b/examples/unix/c11/z_pong.c
@@ -19,13 +19,38 @@ int main(int argc, char** argv) {
     (void)argv;
     z_owned_config_t config = z_config_default();
     z_owned_session_t session = z_open(z_move(config));
-    z_keyexpr_t ping = z_keyexpr_unchecked("test/ping");
+    if (!z_check(session)) {
+        printf("Unable to open session!\n");
+        return -1;
+    }
+
+    if (zp_start_read_task(z_loan(session), NULL) < 0 || zp_start_lease_task(z_loan(session), NULL) < 0) {
+        printf("Unable to start read and lease tasks");
+        return -1;
+    }
+
     z_keyexpr_t pong = z_keyexpr_unchecked("test/pong");
     z_owned_publisher_t pub = z_declare_publisher(z_loan(session), pong, NULL);
+    if (!z_check(pub)) {
+        printf("Unable to declare publisher for key expression!\n");
+        return -1;
+    }
+
+    z_keyexpr_t ping = z_keyexpr_unchecked("test/ping");
     z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)z_move(pub));
     z_owned_subscriber_t sub = z_declare_subscriber(z_loan(session), ping, z_move(respond), NULL);
+    if (!z_check(sub)) {
+        printf("Unable to declare subscriber for key expression.\n");
+        return -1;
+    }
+
     while (getchar() != 'q') {
     }
+
     z_drop(z_move(sub));
+
+    zp_stop_read_task(z_loan(session));
+    zp_stop_lease_task(z_loan(session));
+
     z_close(z_move(session));
 }
\ No newline at end of file
diff --git a/examples/unix/c99/z_ping.c b/examples/unix/c99/z_ping.c
index 9bbb18695..379afd986 100644
--- a/examples/unix/c99/z_ping.c
+++ b/examples/unix/c99/z_ping.c
@@ -44,12 +44,34 @@ int main(int argc, char** argv) {
     _z_mutex_init(&mutex);
     _z_condvar_init(&cond);
     z_owned_config_t config = z_config_default();
-    z_owned_session_t session = z_open(z_move(config));
+    z_owned_session_t session = z_open(z_config_move(&config));
+    if (!z_session_check(&session)) {
+        printf("Unable to open session!\n");
+        return -1;
+    }
+
+    if (zp_start_read_task(z_session_loan(&session), NULL) < 0 ||
+        zp_start_lease_task(z_session_loan(&session), NULL) < 0) {
+        printf("Unable to start read and lease tasks");
+        return -1;
+    }
+
     z_keyexpr_t ping = z_keyexpr_unchecked("test/ping");
-    z_keyexpr_t pong = z_keyexpr_unchecked("test/pong");
     z_owned_publisher_t pub = z_declare_publisher(z_session_loan(&session), ping, NULL);
-    z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)(&pub));
-    z_owned_subscriber_t sub = z_declare_subscriber(z_session_loan(&session), pong, z_move(respond), NULL);
+    if (!z_publisher_check(&pub)) {
+        printf("Unable to declare publisher for key expression!\n");
+        return -1;
+    }
+
+    z_keyexpr_t pong = z_keyexpr_unchecked("test/pong");
+    z_owned_closure_sample_t respond = z_closure_sample(callback, drop, NULL);
+    z_owned_subscriber_t sub =
+        z_declare_subscriber(z_session_loan(&session), pong, z_closure_sample_move(&respond), NULL);
+    if (!z_subscriber_check(&sub)) {
+        printf("Unable to declare subscriber for key expression.\n");
+        return -1;
+    }
+
     uint8_t* data = z_malloc(args.size);
     for (unsigned int i = 0; i < args.size; i++) {
         data[i] = i % 10;
@@ -78,9 +100,13 @@ int main(int argc, char** argv) {
     _z_mutex_unlock(&mutex);
     z_free(results);
     z_free(data);
-    z_undeclare_subscriber(z_move(sub));
-    z_undeclare_publisher(z_move(pub));
-    z_close(z_move(session));
+    z_undeclare_subscriber(z_subscriber_move(&sub));
+    z_undeclare_publisher(z_publisher_move(&pub));
+
+    zp_stop_read_task(z_session_loan(&session));
+    zp_stop_lease_task(z_session_loan(&session));
+
+    z_close(z_session_move(&session));
 }
 
 char* getopt(int argc, char** argv, char option) {
diff --git a/examples/unix/c99/z_pong.c b/examples/unix/c99/z_pong.c
index 49c99c488..1f0955d56 100644
--- a/examples/unix/c99/z_pong.c
+++ b/examples/unix/c99/z_pong.c
@@ -19,14 +19,41 @@ int main(int argc, char** argv) {
     (void)argc;
     (void)argv;
     z_owned_config_t config = z_config_default();
-    z_owned_session_t session = z_open(z_move(config));
-    z_keyexpr_t ping = z_keyexpr_unchecked("test/ping");
+    z_owned_session_t session = z_open(z_config_move(&config));
+    if (!z_session_check(&session)) {
+        printf("Unable to open session!\n");
+        return -1;
+    }
+
+    if (zp_start_read_task(z_session_loan(&session), NULL) < 0 ||
+        zp_start_lease_task(z_session_loan(&session), NULL) < 0) {
+        printf("Unable to start read and lease tasks");
+        return -1;
+    }
+
     z_keyexpr_t pong = z_keyexpr_unchecked("test/pong");
     z_owned_publisher_t pub = z_declare_publisher(z_session_loan(&session), pong, NULL);
-    z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)z_move(pub));
-    z_owned_subscriber_t sub = z_declare_subscriber(z_session_loan(&session), ping, z_move(respond), NULL);
+    if (!z_publisher_check(&pub)) {
+        printf("Unable to declare publisher for key expression!\n");
+        return -1;
+    }
+
+    z_keyexpr_t ping = z_keyexpr_unchecked("test/ping");
+    z_owned_closure_sample_t respond = z_closure_sample(callback, drop, (void*)z_publisher_move(&pub));
+    z_owned_subscriber_t sub =
+        z_declare_subscriber(z_session_loan(&session), ping, z_closure_sample_move(&respond), NULL);
+    if (!z_subscriber_check(&sub)) {
+        printf("Unable to declare subscriber for key expression.\n");
+        return -1;
+    }
+
     while (getchar() != 'q') {
     }
-    z_undeclare_subscriber(z_move(sub));
-    z_close(z_move(session));
+
+    z_undeclare_subscriber(z_subscriber_move(&sub));
+
+    zp_stop_read_task(z_session_loan(&session));
+    zp_stop_lease_task(z_session_loan(&session));
+
+    z_close(z_session_move(&session));
 }
\ No newline at end of file
diff --git a/examples/windows/z_ping.c b/examples/windows/z_ping.c
index 1ce6759ef..fe25ed3c9 100644
--- a/examples/windows/z_ping.c
+++ b/examples/windows/z_ping.c
@@ -44,11 +44,31 @@ int main(int argc, char** argv) {
     _z_condvar_init(&cond);
     z_owned_config_t config = z_config_default();
     z_owned_session_t session = z_open(z_move(config));
+    if (!z_check(session)) {
+        printf("Unable to open session!\n");
+        return -1;
+    }
+
+    if (zp_start_read_task(z_loan(session), NULL) < 0 || zp_start_lease_task(z_loan(session), NULL) < 0) {
+        printf("Unable to start read and lease tasks");
+        return -1;
+    }
+
     z_keyexpr_t ping = z_keyexpr_unchecked("test/ping");
-    z_keyexpr_t pong = z_keyexpr_unchecked("test/pong");
     z_owned_publisher_t pub = z_declare_publisher(z_loan(session), ping, NULL);
-    z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)(&pub));
+    if (!z_check(pub)) {
+        printf("Unable to declare publisher for key expression!\n");
+        return -1;
+    }
+
+    z_keyexpr_t pong = z_keyexpr_unchecked("test/pong");
+    z_owned_closure_sample_t respond = z_closure(callback, drop, NULL);
     z_owned_subscriber_t sub = z_declare_subscriber(z_loan(session), pong, z_move(respond), NULL);
+    if (!z_check(sub)) {
+        printf("Unable to declare subscriber for key expression.\n");
+        return -1;
+    }
+
     uint8_t* data = z_malloc(args.size);
     for (unsigned int i = 0; i < args.size; i++) {
         data[i] = i % 10;
@@ -77,8 +97,12 @@ int main(int argc, char** argv) {
     _z_mutex_unlock(&mutex);
     z_free(results);
     z_free(data);
-    z_drop(z_move(sub));
     z_drop(z_move(pub));
+    z_drop(z_move(sub));
+
+    zp_stop_read_task(z_loan(session));
+    zp_stop_lease_task(z_loan(session));
+
     z_close(z_move(session));
 }
 
diff --git a/examples/windows/z_pong.c b/examples/windows/z_pong.c
index 7f0731478..c0d1cd0b0 100644
--- a/examples/windows/z_pong.c
+++ b/examples/windows/z_pong.c
@@ -19,13 +19,38 @@ int main(int argc, char** argv) {
     (void)argv;
     z_owned_config_t config = z_config_default();
     z_owned_session_t session = z_open(z_move(config));
-    z_keyexpr_t ping = z_keyexpr_unchecked("test/ping");
+    if (!z_check(session)) {
+        printf("Unable to open session!\n");
+        return -1;
+    }
+
+    if (zp_start_read_task(z_loan(session), NULL) < 0 || zp_start_lease_task(z_loan(session), NULL) < 0) {
+        printf("Unable to start read and lease tasks");
+        return -1;
+    }
+
     z_keyexpr_t pong = z_keyexpr_unchecked("test/pong");
     z_owned_publisher_t pub = z_declare_publisher(z_loan(session), pong, NULL);
+    if (!z_check(pub)) {
+        printf("Unable to declare publisher for key expression!\n");
+        return -1;
+    }
+
+    z_keyexpr_t ping = z_keyexpr_unchecked("test/ping");
     z_owned_closure_sample_t respond = z_closure(callback, drop, (void*)z_move(pub));
     z_owned_subscriber_t sub = z_declare_subscriber(z_loan(session), ping, z_move(respond), NULL);
+    if (!z_check(sub)) {
+        printf("Unable to declare subscriber for key expression.\n");
+        return -1;
+    }
+
     while (getchar() != 'q') {
     }
+
     z_drop(z_move(sub));
+
+    zp_stop_read_task(z_loan(session));
+    zp_stop_lease_task(z_loan(session));
+
     z_close(z_move(session));
 }
\ No newline at end of file
diff --git a/extra_script.py b/extra_script.py
index c454607cc..391eb8047 100644
--- a/extra_script.py
+++ b/extra_script.py
@@ -28,7 +28,7 @@
                   "-<system/mbed/>",
                   "-<system/unix/>",
                   "-<system/windows/>"]
-    CPPDEFINES = ["ZENOH_ZEPHYR", "ZENOH_PIO"]
+    CPPDEFINES = ["ZENOH_ZEPHYR"]
 
 elif FRAMEWORK == 'arduino':
     PLATFORM = env.get("PIOPLATFORM")
diff --git a/include/zenoh-pico/system/platform/zephyr.h b/include/zenoh-pico/system/platform/zephyr.h
index ca3924e11..4b318c9d9 100644
--- a/include/zenoh-pico/system/platform/zephyr.h
+++ b/include/zenoh-pico/system/platform/zephyr.h
@@ -15,9 +15,14 @@
 #ifndef ZENOH_PICO_SYSTEM_ZEPHYR_TYPES_H
 #define ZENOH_PICO_SYSTEM_ZEPHYR_TYPES_H
 
-#if defined(ZENOH_PIO)
+#include <version.h>
+
+#if KERNEL_VERSION_MAJOR == 2
 #include <kernel.h>
+#elif KERNEL_VERSION_MAJOR == 3
+#include <zephyr/kernel.h>
 #else
+#pragma "This Zephyr version might not be supported."
 #include <zephyr/kernel.h>
 #endif
 
diff --git a/src/system/unix/network.c b/src/system/unix/network.c
index 8a71d1d82..cde8766e6 100644
--- a/src/system/unix/network.c
+++ b/src/system/unix/network.c
@@ -316,6 +316,7 @@ int8_t _z_open_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoin
                 ret = _Z_ERR_GENERIC;
             }
 
+#ifndef UNIX_NO_MULTICAST_IF
             if (lsockaddr->sa_family == AF_INET) {
                 if ((ret == _Z_RES_OK) &&
                     (setsockopt(sock->_fd, IPPROTO_IP, IP_MULTICAST_IF, &((struct sockaddr_in *)lsockaddr)->sin_addr,
@@ -331,6 +332,7 @@ int8_t _z_open_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpoin
             } else {
                 ret = _Z_ERR_GENERIC;
             }
+#endif
 
             // Create lep endpoint
             if (ret == _Z_RES_OK) {
diff --git a/src/system/zephyr/network.c b/src/system/zephyr/network.c
index 0f34432d8..f0842dc08 100644
--- a/src/system/zephyr/network.c
+++ b/src/system/zephyr/network.c
@@ -12,7 +12,9 @@
 //   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
 //
 
-#if defined(ZENOH_PIO)
+#include <version.h>
+
+#if KERNEL_VERSION_MAJOR == 2
 #include <drivers/uart.h>
 #else
 #include <zephyr/drivers/uart.h>
@@ -404,14 +406,22 @@ int8_t _z_listen_udp_multicast(_z_sys_net_socket_t *sock, const _z_sys_net_endpo
                     if (!mcast) {
                         ret = _Z_ERR_GENERIC;
                     }
+#if KERNEL_VERSION_MAJOR == 3 && KERNEL_VERSION_MINOR > 3
+                    net_if_ipv4_maddr_join(ifa, mcast);
+#else
                     net_if_ipv4_maddr_join(mcast);
+#endif
                 } else if (rep._iptcp->ai_family == AF_INET6) {
                     struct net_if_mcast_addr *mcast = NULL;
                     mcast = net_if_ipv6_maddr_add(ifa, &((struct sockaddr_in6 *)rep._iptcp->ai_addr)->sin6_addr);
                     if (!mcast) {
                         ret = _Z_ERR_GENERIC;
                     }
+#if KERNEL_VERSION_MAJOR == 3 && KERNEL_VERSION_MINOR > 3
+                    net_if_ipv6_maddr_join(ifa, mcast);
+#else
                     net_if_ipv6_maddr_join(mcast);
+#endif
                 } else {
                     ret = _Z_ERR_GENERIC;
                 }
@@ -439,7 +449,11 @@ void _z_close_udp_multicast(_z_sys_net_socket_t *sockrecv, _z_sys_net_socket_t *
         if (rep._iptcp->ai_family == AF_INET) {
             mcast = net_if_ipv4_maddr_add(ifa, &((struct sockaddr_in *)rep._iptcp->ai_addr)->sin_addr);
             if (mcast != NULL) {
+#if KERNEL_VERSION_MAJOR == 3 && KERNEL_VERSION_MINOR > 3
+                net_if_ipv4_maddr_leave(ifa, mcast);
+#else
                 net_if_ipv4_maddr_leave(mcast);
+#endif
                 net_if_ipv4_maddr_rm(ifa, &((struct sockaddr_in *)rep._iptcp->ai_addr)->sin_addr);
             } else {
                 // Do nothing. The socket will be closed in any case.
@@ -447,7 +461,11 @@ void _z_close_udp_multicast(_z_sys_net_socket_t *sockrecv, _z_sys_net_socket_t *
         } else if (rep._iptcp->ai_family == AF_INET6) {
             mcast = net_if_ipv6_maddr_add(ifa, &((struct sockaddr_in6 *)rep._iptcp->ai_addr)->sin6_addr);
             if (mcast != NULL) {
+#if KERNEL_VERSION_MAJOR == 3 && KERNEL_VERSION_MINOR > 3
+                net_if_ipv6_maddr_leave(ifa, mcast);
+#else
                 net_if_ipv6_maddr_leave(mcast);
+#endif
                 net_if_ipv6_maddr_rm(ifa, &((struct sockaddr_in6 *)rep._iptcp->ai_addr)->sin6_addr);
             } else {
                 // Do nothing. The socket will be closed in any case.
@@ -531,7 +549,7 @@ size_t _z_send_udp_multicast(const _z_sys_net_socket_t sock, const uint8_t *ptr,
                              _z_sys_net_endpoint_t rep) {
     return sendto(sock._fd, ptr, len, 0, rep._iptcp->ai_addr, rep._iptcp->ai_addrlen);
 }
-#endif
+#endif  // Z_LINK_UDP_MULTICAST == 1
 
 #if Z_LINK_SERIAL == 1
 int8_t _z_open_serial_from_pins(_z_sys_net_socket_t *sock, uint32_t txpin, uint32_t rxpin, uint32_t baudrate) {
diff --git a/src/system/zephyr/system.c b/src/system/zephyr/system.c
index 37c2333f1..2670ae9cb 100644
--- a/src/system/zephyr/system.c
+++ b/src/system/zephyr/system.c
@@ -12,11 +12,11 @@
 //   ZettaScale Zenoh Team, <zenoh@zettascale.tech>
 //
 
-#if defined(ZENOH_PIO)
-#include <kernel.h>
+#include <version.h>
+
+#if KERNEL_VERSION_MAJOR == 2
 #include <random/rand32.h>
 #else
-#include <zephyr/kernel.h>
 #include <zephyr/random/rand32.h>
 #endif
 
diff --git a/tests/api.sh b/tests/api.sh
index cd84c0860..7be9183b3 100644
--- a/tests/api.sh
+++ b/tests/api.sh
@@ -34,7 +34,7 @@ if [ ! -f zenohd ]; then
     if [ -n "$ZENOH_BRANCH" ]; then
         git switch "$ZENOH_BRANCH"
     fi
-    cargo build
+    cargo build --lib --bin zenohd
     cp ./target/debug/zenohd "$TESTDIR"/
     cd "$TESTDIR"|| exit
 fi
@@ -46,7 +46,7 @@ for LOCATOR in $(echo "$LOCATORS" | xargs); do
     sleep 1
 
     echo "> Running zenohd ... $LOCATOR"
-    RUST_LOG=debug ./zenohd -l "$LOCATOR" > zenohd."$1".log 2>&1 &
+    RUST_LOG=debug ./zenohd --plugin-search-dir "$TESTDIR/zenoh-git/target/debug" -l "$LOCATOR" > zenohd."$1".log 2>&1 &
     ZPID=$!
 
     sleep 5
diff --git a/tests/routed.sh b/tests/routed.sh
index 0558efb96..72659e075 100644
--- a/tests/routed.sh
+++ b/tests/routed.sh
@@ -34,7 +34,7 @@ if [ ! -f zenohd ]; then
     if [ -n "$ZENOH_BRANCH" ]; then
         git switch "$ZENOH_BRANCH"
     fi
-    cargo build
+    cargo build --lib --bin zenohd
     cp ./target/debug/zenohd "$TESTDIR"/
     cd "$TESTDIR" || exit
 fi
@@ -46,7 +46,7 @@ for LOCATOR in $(echo "$LOCATORS" | xargs); do
     sleep 1
 
     echo "> Running zenohd ... $LOCATOR"
-    RUST_LOG=debug ./zenohd -l "$LOCATOR" > zenohd."$1".log 2>&1 &
+    RUST_LOG=debug ./zenohd --plugin-search-dir "$TESTDIR/zenoh-git/target/debug" -l "$LOCATOR" > zenohd."$1".log 2>&1 &
     ZPID=$!
 
     sleep 5
diff --git a/zenohpico.pc.in b/zenohpico.pc.in
new file mode 100644
index 000000000..95b80270f
--- /dev/null
+++ b/zenohpico.pc.in
@@ -0,0 +1,8 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+
+Name: @PROJECT_NAME@
+Description: @CMAKE_PROJECT_DESCRIPTION@
+URL: @CMAKE_PROJECT_HOMEPAGE_URL@
+Version: @PROJECT_VERSION@
+Cflags: -I${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
+Libs: -L${prefix}/@CMAKE_INSTALL_LIBDIR@ -lzenohpico@LIBNAME_POSTFIX@
\ No newline at end of file