Skip to content

Conversation

mark-inderhees
Copy link
Contributor

@mark-inderhees mark-inderhees commented Oct 2, 2025

When working on #96892 I noticed that in some places cmake is only tracking syscall deps for those under ${ZEPHYR_BASE}/include when in reality syscalls can come from a number of places including those defined by users.

This PR updates cmake dependencies to track all inputs used in syscall generation.

I was able to verify the issue by creating an external zephyr module driver. Repo steps are somewhat complicated, as mentioned in #96892 and #96881, git is funny and will do full file delete/adds when modifying a few lines.

Repo

Part A: Setup external module

  1. git clone https://github.com/mark-inderhees/zephyr-module
  2. Stage changes to the driver syscall, save this patch as module.patch
diff --git a/include/hello_driver.h b/include/hello_driver.h
index 781b033..d3836b0 100644
--- a/include/hello_driver.h
+++ b/include/hello_driver.h
@@ -29,7 +29,7 @@ extern "C" {
  * @retval 0 On success
  * @retval -ENODEV Device not found or not ready
  */
-typedef int (*hello_driver_print_message_t)(const struct device *dev);
+typedef int (*hello_driver_print_message_t)(const struct device *dev, uint32_t foo);
 
 /**
  * @brief Hello driver API structure
@@ -47,9 +47,9 @@ struct hello_driver_api {
  * @retval -ENODEV Device not found or not ready
  * @retval -ENOSYS API not implemented
  */
-__syscall int hello_driver_print_message(const struct device *dev);
+__syscall int hello_driver_print_message(const struct device *dev, uint32_t foo);
 
-static inline int z_impl_hello_driver_print_message(const struct device *dev)
+static inline int z_impl_hello_driver_print_message(const struct device *dev, uint32_t foo)
 {
     const struct hello_driver_api *api = 
         (const struct hello_driver_api *)dev->api;
@@ -58,7 +58,7 @@ static inline int z_impl_hello_driver_print_message(const struct device *dev)
         return -ENOSYS;
     }
 
-    return api->print_message(dev);
+    return api->print_message(dev, foo);
 }
 
 /**
diff --git a/src/hello_driver.c b/src/hello_driver.c
index 2ae1dfe..d65a95e 100644
--- a/src/hello_driver.c
+++ b/src/hello_driver.c
@@ -16,8 +16,9 @@ struct hello_driver_config {
 };
 
 // Driver API implementation: print message
-static int hello_driver_api_print_message(const struct device *dev)
+static int hello_driver_api_print_message(const struct device *dev, uint32_t foo)
 {
+    (void)foo;
     if (!device_is_ready(dev)) {
         return -ENODEV;
     }
  1. Apply patch with git apply module.patch
  2. Cache those changes
cp include/hello_driver.h /tmp/hello_driver.h
cp src/hello_driver.c /tmp/hello_driver.c
  1. Revert state with
git restore include/hello_driver.h
git restore src/hello_driver.c

Part B: Setup repo

  1. Clone my fork of blinky to use my test module, based of zephyr main
git clone https://github.com/mark-inderhees/zephyr-module
git checkout test-module-broke
  1. Stage patch to use the updated syscall, save this patch as zephyr.patch
diff --git a/samples/basic/blinky/src/main.c b/samples/basic/blinky/src/main.c
index 263592497ef..870ff487026 100644
--- a/samples/basic/blinky/src/main.c
+++ b/samples/basic/blinky/src/main.c
@@ -41,7 +41,7 @@ int main(void)
 
        LOG_INF("Hello from the app, retrieved from device: %p", hello_driver_dev);
 
-       ret = hello_driver_print_message(hello_driver_dev);
+       ret = hello_driver_print_message(hello_driver_dev, 1);
        if (ret != 0) {
                LOG_ERR("Failed to print message from hello driver: %d", ret);
        }
  1. Cache the patch with cp samples/basic/blinky/src/main.c /tmp/main.c
  2. Restore the repo with git restore samples/basic/blinky/src/main.c
  3. Export the external module from Part A with export ZEPHYR_EXTRA_MODULES=<your_path>/zephyr-module
  4. Do a pristine build with west build -b nrf5340dk/nrf5340/cpuapp samples/basic/blinky -p always
  5. Apply the zephyr change to blinky with cp /tmp/main.c samples/basic/blinky/src/main.c
  6. In the external module repository, apply the staged syscall changes
cp /tmp/hello_driver.h include/hello_driver.h
cp /tmp/hello_driver.c src/hello_driver.c
  1. Back in the zephyr repository, do an incremental build and see the build failure west build -b nrf5340dk/nrf5340/cpuapp samples/basic/blinky

I verified the fix by replacing Part B step 1, checking out my branch git checkout test-module. This cherry-picks the blinky external driver integration on top of this PR's fix.

Fix issue where changing an existing syscall API does not result in
regeneration of syscalls. This causes a build break on incremental
builds. The issue comes from an incorrect assumption that file
modifications result in updates to folder timestamps on Linux. The fix
is to use the same mechanism Windows is using to track file changes,
making explicit deps on header files that have syscalls.

Signed-off-by: Mark Inderhees <[email protected]>
Currently, for syscall generation, cmake is only tracking source files
under ${ZEPHYR_BASE}/include. However, source files are actually used
from a number of different paths including those provided by clients.
This commit adds dependency tracking for all of those sources.

Signed-off-by: Mark Inderhees <[email protected]>
Currently, for syscall generation, cmake is only tracking folders
under ${ZEPHYR_BASE}/include. However, folders are actually used
from a number of different paths including those provided by clients.
This commit adds dependency tracking for all of those sources.

Signed-off-by: Mark Inderhees <[email protected]>
Copy link

sonarqubecloud bot commented Oct 3, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants