Edge Impulse as a Zephyr module

Question/Issue:
Hi, I want to use Edge Impulse in an existing nRF Connect SDK project. I tried to follow this tutorial: Edge Impulse Zephyr Module Deployment - Edge Impulse Documentation using the NCS example application as a base application. I cloned the wake word detection tutorial project to have a trained impulse (as my project will eventually use a microphone), added it to the app folder, and added the following to my west.yml:

    - name: edge-impulse-sdk-zephyr
      description: Edge Impulse SDK for Zephyr
      path: modules/edge-impulse-sdk-zephyr
      west-commands: west/west-commands.yml
      revision: v1.93.27
      url: https://github.com/edgeimpulse/edge-impulse-sdk-zephyr

I also changed my CMakeLists.txt file to the following:

#-------------------------------------------------------------------------------
# Zephyr Example Application
#
# Copyright (c) 2021 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

if (WIN32)
  set(CMAKE_OBJECT_PATH_MAX 350)
endif ()

cmake_minimum_required(VERSION 3.13.1)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

list(APPEND ZEPHYR_EXTRA_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/model)

project(app LANGUAGES C)

target_sources(app PRIVATE src/main.c)

and added these lines to my prj.conf file:

# enable c++ support
CONFIG_CPP=y
CONFIG_GLIBCXX_LIBCPP=y
CONFIG_FPU=y

# Edge Impulse SDK
CONFIG_EDGE_IMPULSE_SDK=y
CONFIG_HEAP_MEM_POOL_SIZE=8192

This should make the Edge Impulse SDK compile into the application even though no application code uses edge impulse to de inferencing yet. I tried building the basic application with west build -b custom_plank app -p always but I got the following error:

[834/842] Linking CXX static library modules\edge-impulse-sdk-zephyr\edge-impulse-sdk\cmake\zephyr\libedge-impulse-sdk.a
FAILED: [code=1] modules/edge-impulse-sdk-zephyr/edge-impulse-sdk/cmake/zephyr/libedge-impulse-sdk.a 
C:\WINDOWS\system32\cmd.exe /C "cd . && ccache C:\ncs\toolchains\dcbdc366a1\opt\bin\cmake.exe -E rm -f modules\edge-impulse-sdk-zephyr\edge-impulse-sdk\cmake\zephyr\libedge-impulse-sdk.a && ccache C:\ncs\toolchains\dcbdc366a1\opt\zephyr-sdk\gnu\arm-zephyr-eabi\bin\arm-zephyr-eabi-ar.exe qc modules\edge-impulse-sdk-zephyr\edge-impulse-sdk\cmake\zephyr\libedge-impulse-sdk.a  @CMakeFiles\edge-impulse-sdk.rsp && ccache C:\ncs\toolchains\dcbdc366a1\opt\zephyr-sdk\gnu\arm-zephyr-eabi\bin\arm-zephyr-eabi-ranlib.exe modules\edge-impulse-sdk-zephyr\edge-impulse-sdk\cmake\zephyr\libedge-impulse-sdk.a && cd ."
C:\ncs\toolchains\dcbdc366a1\opt\zephyr-sdk\gnu\arm-zephyr-eabi\bin\arm-zephyr-eabi-ar.exe: modules\edge-impulse-sdk-zephyr\edge-impulse-sdk\cmake\zephyr\libedge-impulse-sdk.a: error reading modules/edge-impulse-sdk-zephyr/edge-impulse-sdk/cmake/zephyr/CMakeFiles/edge-impulse-sdk.dir/C_/Users/nicol/Documents/xiao-ble-test/modules/edge-impulse-sdk-zephyr/edge-impulse-sdk/classifier/ei_run_classifier_c.cpp.obj: No such file or directory

What can I do to get rid of this error ?

Project ID:
1065806

Expected Outcome:
Project builds successfully.

Actual Outcome:
Project does not build

Reproducibility:

  • [x] Always
  • [ ] Sometimes
  • [ ] Rarely

Environment:

  • Platform: nrf52840 DK
  • Build Environment Details: NCS v3.4.0
  • OS Version: Windows
  • Edge Impulse Version (Firmware): 1.93.27
  • Edge Impulse CLI Version: N/A
  • Project Version: N/A

Hi @NicolasGoualard

I tried to replicate your setup but using zephyr and not nrf, on mac and linux and it compiles and links just fine.
Maybe the issue is related to long path ? I know in win sometime it’s a problem.
If you check, the file is present ?
Theoretically the CMAKE_OBJECT_PATH_MAX should avoid this problem.

regards,
fv

1 Like

Hi @ei_francesco, thanks for your reply.

I did indeed have warnings about long filenames, but removing the limitation in Powershell and increasing CMAKE_OBJECT_PATH_MAX removed the warning.

The file is present in the build files, which is weird.

Best regards,
Nicolas Goualard

I asked AI for some help on the matter, and here is what it spit out. Either this solution (editing the .west config file), or manually adding -- -DCMAKE_OBJECT_PATH_MAX=250 at the end of the build command seems to solve the problem for me.

Issue: arm-zephyr-eabi-ar.exe “No such file or directory” on Windows

Environment:

  • nRF Connect SDK v3.4.0
  • Windows 10/11 with Windows Long Paths enabled (LongPathsEnabled = 1)
  • Project workspace at a deep directory path (e.g. C:\Users\<name>\Documents\xiao-ble-test\)

Error message

C:\ncs\toolchains\...\arm-zephyr-eabi-ar.exe:
  modules\edge-impulse-sdk-zephyr\edge-impulse-sdk\cmake\zephyr\libedge-impulse-sdk.a:
  error reading modules/edge-impulse-sdk-zephyr/edge-impulse-sdk/cmake/zephyr/
  CMakeFiles/edge-impulse-sdk.dir/C_/Users/<name>/Documents/xiao-ble-test/
  modules/edge-impulse-sdk-zephyr/edge-impulse-sdk/classifier/
  ei_run_classifier_c.cpp.obj: No such file or directory

Root cause

When CMake builds a source file whose path is outside the build tree (which is always the case for west-managed modules), it “mirrors” the full absolute source path into the build directory to create a unique object file name. On Windows, the drive letter colon (:) is replaced with an underscore (_).

For the Edge Impulse SDK, this results in a path like:

<build-dir>\app\modules\edge-impulse-sdk-zephyr\edge-impulse-sdk\cmake\zephyr\
CMakeFiles\edge-impulse-sdk.dir\
C_\Users\<name>\Documents\xiao-ble-test\modules\edge-impulse-sdk-zephyr\
edge-impulse-sdk\classifier\ei_run_classifier_c.cpp.obj

In my case this totalled 287 characters, exceeding Windows’ traditional MAX_PATH limit of 260 characters.

Although Windows has a LongPathsEnabled registry key that allows paths beyond 260 characters, this only benefits applications that explicitly declare long-path awareness in their manifest. The arm-zephyr-eabi-ar.exe binary in the Zephyr SDK toolchain is a MinGW-compiled tool that does not declare this awareness, so it fails to open any file whose path exceeds 260 characters — even if Windows can otherwise create it.

CMake has a built-in mitigation for this: CMAKE_OBJECT_PATH_MAX. When a generated object file path exceeds this value, CMake automatically replaces the mirrored source path with a short hash (e.g. be0ac18c.obj), keeping the final path well under 260 characters. However, this variable must be set as a CMake cache variable (via -D on the command line) rather than a regular set() in CMakeLists.txt, because the Edge Impulse SDK module contains its own cmake_minimum_required() call which scopes it away from inheriting normal variables set in the application’s cmake context.


Fix

Add the following to your project’s .west/config file (located in the west workspace root, one level above the manifest repository):

[build]
cmake-args = -DCMAKE_OBJECT_PATH_MAX=250

Setting the limit to 250 ensures any object file whose full absolute path would exceed 250 characters gets a hashed name, keeping all paths within the 260-character limit accessible to arm-zephyr-eabi-ar.exe.

Then do a full pristine rebuild:

west build -b <your_board> app -p always

Notes for the Edge Impulse team

The underlying issue could be mitigated upstream by adding this to the edge-impulse-sdk-zephyr root CMakeLists.txt:

if(WIN32)
  set(CMAKE_OBJECT_PATH_MAX 250 CACHE STRING "Max object file path length" FORCE)
endif()

The CACHE ... FORCE ensures it is set globally even if the parent cmake has not set it, protecting Windows users regardless of their workspace depth.

2 Likes

Thank you for your findings @NicolasGoualard and the solution!

I’ll test it and if it’s working I’ll add it!

fv