Hi all,
I've got an existing OpenThread project for my workplace's metering product which currently is written for a TI CC2538 and I'm porting it across to run on a nRF52840 which we plan to use in the next generation of the product. The existing project uses CMake, and the tricky bit is I want to retain the ability to build for both systems, as we'll need to backport fixes and changes to the existing fleet of devices (sadly, I cannot make a CC2538+CC2592 sprout a nRF52840+nRF21540 by over-the-air software update). I don't use a development environment, my coding uses the command line and gVim.
Our existing project has a root-level CMakeLists.txt, with three sub-directories:
- hal: Hardware abstraction layer, this houses drivers for all the various hardware bits and pieces. The top-level directory here contains drivers and code relevant to both hardware platforms, platform-specific HAL code is in sub-directories (let's call it hal/cc2538 and hal/nrf52840).
- hub: Main application
- boot: A bootloader
boot will probably remain for the existing fleet, with the new code using mcuboot. There are some bits of hal that will be relevant to both boards, hub is relevant to both boards.
I found through experiment with ncs-example-application, that I could move some things around to make the example application better fit the structure of the existing project:
- scripts got dropped, since those features weren't needed for building the example
- the app/, boards/, drivers/, dts/, include/ and lib/ directories got moved beneath the zephyr/ directory
- the doc/, tests/ and miscellaneous root-level files got deleted
I could then modify zephyr/module.yml to point to the new locations:
ncs-example-application$ git diff main..HEAD -- zephyr/module.yml
diff --git a/zephyr/module.yml b/zephyr/module.yml
index 7d53dfd..0792892 100644
--- a/zephyr/module.yml
+++ b/zephyr/module.yml
@@ -5,20 +5,16 @@ build:
# Path to the Kconfig file that will be sourced into Zephyr Kconfig tree under
# Zephyr > Modules > example-application. Path is relative from root of this
# repository.
- kconfig: Kconfig
+ kconfig: zephyr/Kconfig
# Path to the folder that contains the CMakeLists.txt file to be included by
# Zephyr build system. The `.` is the root of this repository.
- cmake: .
+ cmake: zephyr
settings:
# Additional roots for boards and DTS files. Zephyr will use the
# `<board_root>/boards` for additional boards. The `.` is the root of this
# repository.
- board_root: .
+ board_root: zephyr
# Zephyr will use the `<dts_root>/dts` for additional dts files and
# `<dts_root>/dts/bindings` for additional dts binding files. The `.` is
# the root of this repository.
- dts_root: .
-runners:
- # Additional runners, Zephyr will import these when discovering
- # subclasses of the `ZephyrBinaryRunner` class.
- - file: scripts/example_runner.py
+ dts_root: zephyr
That got me a bare-minimum project that built, and would neatly slot into the existing project. I copied the resulting zephyr/ directory to my firmware project directory. Then I updated the app/CMakeLists.txt to point it at my firmware project.
firmware$ cat zephyr/app/CMakeLists.txt
#-------------------------------------------------------------------------------
# Zephyr Example Application
#
# Copyright (c) 2021 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
set(
THIRD_PARTY_SRC_DIR
${CMAKE_CURRENT_LIST_DIR}/../../third_party
CACHE PATH "Third-party modules"
)
set(
NRFXLIB_DIR
${THIRD_PARTY_SRC_DIR}/nrfxlib
CACHE PATH "Nordic Semiconductor nrfxlib directory"
)
set(
OPENTHREAD_SRC_DIR
${NRFXLIB_DIR}/openthread
CACHE PATH "OpenThread source directory"
)
set(
MBEDTLS_DIR
${THIRD_PARTY_SRC_DIR}/mbedtls
CACHE PATH "mbedTLS source directory"
)
project(app LANGUAGES C)
target_compile_definitions(
app PRIVATE
# Alias sniprintf and iprintf
sniprintf=snprintf
iprintf=printf
)
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../.." "${CMAKE_CURRENT_BINARY_DIR}/app")
This seemed to work, but I note certain conditions trigger the nRF Connect SDK build system to call my CMakeLists.txt in the root twice:
firmware$ nrfutil toolchain-manager launch -- west build -p always -b hub_mk3 zephyr/app -- west build: making build dir /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/build pristine -- west build: generating a build system Loading Zephyr module(s) (Zephyr base): sysbuild_default -- Found Python3: /opt/nordicsemi/ncs/toolchains/7cbc0036f4/usr/local/bin/python3.12 (found suitable version "3.12.4", minimum required is "3.10") found components: Interpreter -- Cache files will be written to: /home/stuartl/.cache/zephyr -- Found west (found suitable version "1.2.0", minimum required is "0.14.0") -- Board: hub_mk3, qualifiers: nrf52840 Parsing /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/zephyr/share/sysbuild/Kconfig Loaded configuration '/home/stuartl/vrt/projects/widesky/hub/firmware/build/_sysbuild/empty.conf' Merged configuration '/home/stuartl/vrt/projects/widesky/hub/firmware/build/_sysbuild/empty.conf' Configuration saved to '/home/stuartl/vrt/projects/widesky/hub/firmware/build/zephyr/.config' Kconfig header saved to '/home/stuartl/vrt/projects/widesky/hub/firmware/build/_sysbuild/autoconf.h' -- ************************* * Running CMake for app * ************************* Loading Zephyr default modules (Zephyr base). -- Application: /home/stuartl/vrt/projects/widesky/hub/firmware/zephyr/app -- CMake version: 3.21.0 -- Found Python3: /opt/nordicsemi/ncs/toolchains/7cbc0036f4/usr/local/bin/python (found suitable version "3.12.4", minimum required is "3.10") found components: Interpreter -- Cache files will be written to: /home/stuartl/.cache/zephyr -- Zephyr version: 4.0.99 (/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/third_party/zephyr) -- Found west (found suitable version "1.2.0", minimum required is "0.14.0") -- Board: hub_mk3, qualifiers: nrf52840 -- Found host-tools: zephyr 0.17.0 (/opt/nordicsemi/ncs/toolchains/7cbc0036f4/opt/zephyr-sdk) -- Found toolchain: zephyr 0.17.0 (/opt/nordicsemi/ncs/toolchains/7cbc0036f4/opt/zephyr-sdk) -- Found Dtc: /opt/nordicsemi/ncs/toolchains/7cbc0036f4/usr/bin/dtc (found suitable version "1.5.0", minimum required is "1.4.6") -- Found BOARD.dts: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/boards/widesky/hub_mk3/hub_mk3.dts -- Generated zephyr.dts: /home/stuartl/vrt/projects/widesky/hub/firmware/build/app/zephyr/zephyr.dts -- Generated pickled edt: /home/stuartl/vrt/projects/widesky/hub/firmware/build/app/zephyr/edt.pickle -- Generated zephyr.dts: /home/stuartl/vrt/projects/widesky/hub/firmware/build/app/zephyr/zephyr.dts -- Generated devicetree_generated.h: /home/stuartl/vrt/projects/widesky/hub/firmware/build/app/zephyr/include/generated/zephyr/devicetree_generated.h -- Including generated dts.cmake file: /home/stuartl/vrt/projects/widesky/hub/firmware/build/app/zephyr/dts.cmake Parsing /home/stuartl/vrt/projects/widesky/hub/firmware/zephyr/app/Kconfig Loaded configuration '/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/boards/widesky/hub_mk3/hub_mk3_defconfig' Merged configuration '/home/stuartl/vrt/projects/widesky/hub/firmware/zephyr/app/prj.conf' Merged configuration '/home/stuartl/vrt/projects/widesky/hub/firmware/build/app/zephyr/.config.sysbuild' Configuration saved to '/home/stuartl/vrt/projects/widesky/hub/firmware/build/app/zephyr/.config' Kconfig header saved to '/home/stuartl/vrt/projects/widesky/hub/firmware/build/app/zephyr/include/generated/zephyr/autoconf.h' -- Found GnuLd: /opt/nordicsemi/ncs/toolchains/7cbc0036f4/opt/zephyr-sdk/arm-zephyr-eabi/arm-zephyr-eabi/bin/ld.bfd (found version "2.38") -- The C compiler identification is GNU 12.2.0 -- The CXX compiler identification is GNU 12.2.0 -- The ASM compiler identification is GNU -- Found assembler: /opt/nordicsemi/ncs/toolchains/7cbc0036f4/opt/zephyr-sdk/arm-zephyr-eabi/bin/arm-zephyr-eabi-gcc Loading Zephyr default modules (Zephyr base (cached)). -- Found Python3: /opt/nordicsemi/ncs/toolchains/7cbc0036f4/usr/local/bin/python (found version "3.12.4") found components: Interpreter Source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware HAL directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/hal Configuration directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/config Third-party module directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party OpenThread Source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/nrfxlib/openthread mbedTLS source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/mbedtls NTP client source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/ntp_client CCAN module source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/ccan SPIFFS source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/spiffs/repo TinyCBOR directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/tinycbor/repo Firmware version to build: 1.8.9-alpha.56+250806T0125-0e43bd67 Firmware version for CMake: 1.8.9.56 Building for platform: H30 -- Building as Zephyr application -- -- Skipping stand-alone definitions -- -- Using ccache: /opt/nordicsemi/ncs/toolchains/7cbc0036f4/usr/bin/ccache Source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware HAL directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/hal Configuration directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/config Third-party module directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party OpenThread Source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/nrfxlib/openthread mbedTLS source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/mbedtls NTP client source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/ntp_client CCAN module source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/ccan SPIFFS source directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/spiffs/repo TinyCBOR directory: /home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app/../../third_party/tinycbor/repo Firmware version to build: 1.8.9-alpha.56+250806T0125-0e43bd67 Firmware version for CMake: 1.8.9.56 Building for platform: H30 -- Building as Zephyr application -- CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/ccan/CMakeLists.txt:4 (add_library): add_library cannot create target "ccan" because another target with the same name already exists. The existing target is a static library created in source directory "/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/third_party/ccan". See documentation for policy CMP0002 for more details. CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/ccan/CMakeLists.txt:33 (file): file problem touching file: /home/stuartl/vrt/projects/widesky/hub/firmware/build/app/include/ccan/../../../../firmware/third_party/ccan/build_assert/config.h CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/ccan/CMakeLists.txt:33 (file): file problem touching file: /home/stuartl/vrt/projects/widesky/hub/firmware/build/app/include/ccan/../../../../firmware/third_party/ccan/check_type/config.h CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/ccan/CMakeLists.txt:33 (file): file problem touching file: /home/stuartl/vrt/projects/widesky/hub/firmware/build/app/include/ccan/../../../../firmware/third_party/ccan/container_of/config.h CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/ccan/CMakeLists.txt:33 (file): file problem touching file: /home/stuartl/vrt/projects/widesky/hub/firmware/build/app/include/ccan/../../../../firmware/third_party/ccan/stringbuilder/config.h CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/spiffs/CMakeLists.txt:4 (add_library): add_library cannot create target "spiffs" because another target with the same name already exists. The existing target is a static library created in source directory "/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/third_party/spiffs". See documentation for policy CMP0002 for more details. CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/tinycbor/CMakeLists.txt:4 (add_library): add_library cannot create target "tinycbor" because another target with the same name already exists. The existing target is a static library created in source directory "/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/third_party/tinycbor". See documentation for policy CMP0002 for more details. CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/ntp_client/CMakeLists.txt:4 (add_library): add_library cannot create target "ntpclient" because another target with the same name already exists. The existing target is a static library created in source directory "/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/third_party/ntp_client". See documentation for policy CMP0002 for more details. CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/hal/CMakeLists.txt:1 (add_library): add_library cannot create target "widesky-boot-hal" because another target with the same name already exists. The existing target is a static library created in source directory "/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/hal". See documentation for policy CMP0002 for more details. CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/hal/CMakeLists.txt:2 (add_library): add_library cannot create target "widesky-hub-hal" because another target with the same name already exists. The existing target is a static library created in source directory "/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/hal". See documentation for policy CMP0002 for more details. CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/hal/mk3/CMakeLists.txt:1 (add_library): add_library cannot create target "widesky-boot-hal-mk3" because another target with the same name already exists. The existing target is a static library created in source directory "/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/hal/mk3". See documentation for policy CMP0002 for more details. CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/hal/mk3/CMakeLists.txt:2 (add_library): add_library cannot create target "widesky-hub-hal-mk3" because another target with the same name already exists. The existing target is a static library created in source directory "/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/hal/mk3". See documentation for policy CMP0002 for more details. CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/hal/CMakeLists.txt:21 (add_custom_target): add_custom_target cannot create target "widesky-hub-hal-txptable" because another target with the same name already exists. The existing target is a custom target created in source directory "/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/hal". See documentation for policy CMP0002 for more details. CMake Error at /home/stuartl/vrt/projects/widesky/hub/firmware/hub/CMakeLists.txt:3 (add_custom_target): add_custom_target cannot create target "widesky-hub-application-wshversion" because another target with the same name already exists. The existing target is a custom target created in source directory "/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/hub". See documentation for policy CMP0002 for more details. -- Skipping stand-alone definitions -- -- Configuring incomplete, errors occurred! See also "/home/stuartl/vrt/projects/widesky/hub/firmware/build/app/CMakeFiles/CMakeOutput.log". See also "/home/stuartl/vrt/projects/widesky/hub/firmware/build/app/CMakeFiles/CMakeError.log". CMake Error at cmake/modules/sysbuild_extensions.cmake:514 (message): CMake configure failed for Zephyr project: app Location: /home/stuartl/vrt/projects/widesky/hub/firmware/zephyr/app Call Stack (most recent call first): cmake/modules/sysbuild_images.cmake:43 (ExternalZephyrProject_Cmake) cmake/modules/sysbuild_default.cmake:21 (include) /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:75 (include) /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate) /home/stuartl/vrt/projects/widesky/hub/firmware/third_party/zephyr/share/sysbuild-package/cmake/SysbuildConfig.cmake:8 (include) template/CMakeLists.txt:10 (find_package) -- Configuring incomplete, errors occurred! See also "/home/stuartl/vrt/projects/widesky/hub/firmware/build/CMakeFiles/CMakeOutput.log". FATAL ERROR: command exited with status 1: /opt/nordicsemi/ncs/toolchains/7cbc0036f4/usr/local/bin/cmake -DWEST_PYTHON=/opt/nordicsemi/ncs/toolchains/7cbc0036f4/usr/local/bin/python3.12 -B/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/build -GNinja -DBOARD=hub_mk3 -S/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/third_party/zephyr/share/sysbuild -DAPP_DIR:PATH=/home/stuartl/vrt/projects/widesky/hub/workspace/firmware/zephyr/app Error: Launched process exited with non-zero status: 1
Is there a reason why the build system feels it necessary to double-include the project top-level CMakeFile.txt?