# Building LibCyphal

**URL:** <https://forum.opencyphal.org/t/building-libcyphal/2427>\
**Category:** LibCyphal\
**Created:** [November 5, 2025, 7:57pm UTC](https://forum.opencyphal.org/t/building-libcyphal/2427 "2025-11-05T19:57:26Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Scoeerg](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/scoeerg/32/1713_2.png) [@Scoeerg](https://forum.opencyphal.org/u/Scoeerg)\
**Post date:** [November 5, 2025, 7:57pm UTC](https://forum.opencyphal.org/t/building-libcyphal/2427/1 "2025-11-05T19:57:26Z")

</div>

Hi,

I am on my way to build my first high-level LibCyphal/CPP-based Cyphal applications. I already did libcanard on STM32, and of course PyCyphal. Finally I would like to have a `my_hello_world` top-layer cpp-application that just compiles Libcyphal as a dependency:

```bash
my_hello_world
├── build
├── CMakeLists.txt
├── Hello
├── HelloWorld.cpp
├── LICENSE
├── Libcyphal
└── README.md

```

where `HelloWorld.cpp` can just include `cyphal.hpp`. What could possibly go wrong ☹? I have been on this for two days, so I’ve done more, but I will just describe the gist here.

# Naively Cloning LibCyphal

```bash
git clone git@github.com:OpenCyphal-Garage/libcyphal.git
cd libcyphal
mkdir build
cd build 
cmake ..

```

which results in

```bash
CMake Warning at cmake/CMakeCommon.cmake:18 (message):
[...]
Cloning into 'libcanard'...
fatal: invalid reference: v4
CMake Error at /home/erics/libcyphal/build/libcanard-subbuild/libcanard-populate-prefix/tmp/libcanard-populate-gitclone.cmake:61 (message):
  Failed to checkout tag: 'v4'
[...]

-- Configuring incomplete, errors occurred!

```

Fine. So apparently cmake envokes downloading [libcanard](https://github.com/OpenCyphal/libcanard) at version 4 that does not exist. The tags are`v3.2.0`, `3.2.0`, `3.1.2` …, `3.0.0` and `2.0.0` etc. Alright, let’s try `v3.2.0` by editing `libcyhal/cmake/modules/Findlibcanard.cmake`.

which works fine

```bash
cmake .. 
CMake Warning at cmake/CMakeCommon.cmake:18 (message):
  Neither LIBCYPHAL_VERSION nor CYPHAL_PROJECT_VERSION was not set. Setting
  LIBCYPHAL_VERSION to default of 0.0.0.
Call Stack (most recent call first):
  CMakeLists.txt:8 (include)

-- Populating cetl
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/erics/libcyphal/build/cetl-subbuild
[11%] Performing update step for 'cetl-populate'
-- Fetching latest from the remote origin
[22%] No patch step for 'cetl-populate'
[33%] No configure step for 'cetl-populate'
[44%] No build step for 'cetl-populate'
[55%] No install step for 'cetl-populate'
[66%] No test step for 'cetl-populate'
[77%] Completed 'cetl-populate'
[100%] Built target cetl-populate
-- Populating libcanard
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/erics/libcyphal/build/libcanard-subbuild
[11%] Performing download step (git clone) for 'libcanard-populate'
Cloning into 'libcanard'...
HEAD is now at 551af7f ESP-IDF Component Continuous Integration (#229)
[22%] Performing update step for 'libcanard-populate'
-- Already at requested tag: v3.2.0
[33%] No patch step for 'libcanard-populate'
[44%] No configure step for 'libcanard-populate'
[55%] No build step for 'libcanard-populate'
[66%] No install step for 'libcanard-populate'
[77%] No test step for 'libcanard-populate'
[88%] Completed 'libcanard-populate'
[100%] Built target libcanard-populate
-- Found libcanard: /home/erics/libcyphal/external/libcanard
-- Populating libudpard
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/erics/libcyphal/build/libudpard-subbuild
[11%] Creating directories for 'libudpard-populate'
[22%] Performing download step (git clone) for 'libudpard-populate'
Cloning into 'libudpard'...
Switched to a new branch 'v2'
Branch 'v2' set up to track remote branch 'v2' from 'origin'.
Submodule 'submodules/unity' (https://github.com/ThrowTheSwitch/Unity) registered for path 'submodules/unity'
Cloning into '/home/erics/libcyphal/external/libudpard/submodules/unity'...
Submodule path 'submodules/unity': checked out '0b899aec14d3a9abb2bf260ac355f0f28630a6a3'
[33%] Performing update step for 'libudpard-populate'
-- Fetching latest from the remote origin
[44%] No patch step for 'libudpard-populate'
[55%] No configure step for 'libudpard-populate'
[66%] No build step for 'libudpard-populate'
[77%] No install step for 'libudpard-populate'
[88%] No test step for 'libudpard-populate'
[100%] Completed 'libudpard-populate'
[100%] Built target libudpard-populate
-- Found libudpard: /home/erics/libcyphal/external/libudpard
-- Found clangformat: /usr/bin/clang-format
-- The CXX compiler identification is GNU 11.4.0
-- The C compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Using clang-tidy: /usr/bin/clang-tidy
-- Populating public_regulated_data_types
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /home/erics/libcyphal/build/public_regulated_data_types-subbuild
[11%] Creating directories for 'public_regulated_data_types-populate'
[22%] Performing download step (git clone) for 'public_regulated_data_types-populate'
Cloning into 'public_regulated_data_types'...
HEAD is now at f9f6790 Hotfix: reduce the extent of ExecuteCommand.1.3 (#147)
[33%] Performing update step for 'public_regulated_data_types-populate'
-- Already at requested ref: f9f67906cc0ca5d7c1b429924852f6b28f313cbf
[44%] No patch step for 'public_regulated_data_types-populate'
[55%] No configure step for 'public_regulated_data_types-populate'
[66%] No build step for 'public_regulated_data_types-populate'
[77%] No install step for 'public_regulated_data_types-populate'
[88%] No test step for 'public_regulated_data_types-populate'
[100%] Completed 'public_regulated_data_types-populate'
[100%] Built target public_regulated_data_types-populate
-- Found public_regulated_data_types: /home/erics/libcyphal/external/public_regulated_data_types
-- Found Python3: /usr/bin/python3.10 (found version "3.10.12") found components: Interpreter
-- nnvg:/home/erics/.local/bin/nnvg --version: 2.3.1
-- Found nnvg: 2.3.1
CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:163 (_init_nnvg_command_args)
  CMakeLists.txt:45 (define_nunavut_support_target)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  CMakeLists.txt:50 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  CMakeLists.txt:50 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Found googletest: /home/erics/libcyphal/external/googletest
CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  test/unittest/CMakeLists.txt:20 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  test/unittest/CMakeLists.txt:20 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  docs/examples/CMakeLists.txt:27 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  docs/examples/CMakeLists.txt:27 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

-- IS_POSIX=TRUE
-- IS_LINUX=TRUE
-- EXAMPLES_PLATFORM_LIBS=examples_platform_posix;examples_platform_linux
-- Example: 0_transport/example_0_transport_1_heartbeat_getinfo_udp.cpp
-- Example: 0_transport/example_0_transport_2_heartbeat_getinfo_linux_can.cpp
-- Example: 1_presentation/example_1_presentation_0_hello_raw_pubsub_udp.cpp
-- Example: 1_presentation/example_1_presentation_1_ping_user_service_udp.cpp
-- Example: 1_presentation/example_1_presentation_2_heartbeat_getinfo_udp.cpp
-- Example: 1_presentation/example_1_presentation_3_hb_getinfo_ping_linux_can.cpp
-- Example: 2_application/example_2_application_0_node_hb_getinfo_udp.cpp
-- Found Doxygen: /usr/bin/doxygen (found version "1.9.1") found components: doxygen dot
-- TODO: add GNU/Linux demos
-- -------------------------------------------------------------------
| libcyphal
-- -------------------------------------------------------------------
    LIBCYPHAL_ROOT: /home/erics/libcyphal/
    LIBCYPHAL_INCLUDE: /home/erics/libcyphal/include
    LIBCYPHAL_VERSION: 0.0.0
    LIBCYPHAL_INTROSPECTION_TRACE_ENABLE: 0
    LIBCYPHAL_INTROSPECTION_ENABLE_ASSERT: 0
    CETLVAST_CPP_STANDARD: 14
    CMAKE_PROJECT_NAME: libcyphal
    CMAKE_SOURCE_DIR: /home/erics/libcyphal
    CMAKE_CURRENT_SOURCE_DIR: /home/erics/libcyphal
    CMAKE_BINARY_DIR: /home/erics/libcyphal/build
    CMAKE_CURRENT_BINARY_DIR: /home/erics/libcyphal/build
    CMAKE_MODULE_PATH: /home/erics/libcyphal/cmake/modules;/home/erics/libcyphal/external/cetl/cetlvast/cmake/modules
    CMAKE_MESSAGE_LOG_LEVEL: STATUS
    CMAKE_INSTALL_PREFIX: /home/erics/libcyphal/build
    CMAKE_BUILD_TYPE:                       
    FETCHCONTENT_FULLY_DISCONNECTED: OFF

CETL
    CETL_ENABLE_DEBUG_ASSERT: 0

Standard Library
    LIBCXX_ENABLE_ASSERTIONS: 0
 -- ------------------------------------------------------------------

-- [Build Kit]-------------------------------------------
    CMAKE_TOOLCHAIN_FILE: (not set)
    CETLVAST_FLAG_SET: /home/erics/libcyphal/cmake/compiler_flag_sets/default.cmake
    CMAKE_CXX_COMPILER_[ID-VER]: GNU-11.4.0
    CMAKE_C_COMPILER_[ID-VER]: GNU-11.4.0
    CMAKE_AR: /usr/bin/ar
    CMAKE_LINKER: /usr/bin/ld
    CMAKE_RANLIB: /usr/bin/ranlib
    CMAKE_[lang]_PLATFORM_ID: Linux
-----------------------------------------------------------

-- Configuring done (9.7s)
-- Generating done (0.2s)
-- Build files have been written to: /home/erics/libcyphal/build

```

Ok. But we can see nothing was actually built. So

```bash
cd build
make 

```

which fails with a ton of clang-formatted errors. So …

```bash
cd ~ # libcyphal is in home, whereever you cloned to code to
find libcyphal -name "*.hpp" -exec clang-format -i {} \;

```

and again

```bash
cd libcyphal/build
make

```

which fails again, but more spectacularly

```bash
make 
[1%] Built target canard
[5%] Built target udpard
Formatting [1/62] libcyphal/application/node.hpp
Formatting [2/62] libcyphal/application/node/get_info_provider.hpp
Formatting [3/62] libcyphal/application/node/heartbeat_producer.hpp
Formatting [4/62] libcyphal/application/node/registry_provider.hpp
Formatting [5/62] libcyphal/application/registry/register.hpp
Formatting [6/62] libcyphal/application/registry/register_impl.hpp
Formatting [7/62] libcyphal/application/registry/registry.hpp
Formatting [8/62] libcyphal/application/registry/registry_impl.hpp
Formatting [9/62] libcyphal/common/cavl/cavl.hpp
Formatting [10/62] libcyphal/common/crc.hpp
Formatting [11/62] libcyphal/config.hpp
Formatting [12/62] libcyphal/errors.hpp
Formatting [13/62] libcyphal/executor.hpp
Formatting [14/62] libcyphal/platform/single_threaded_executor.hpp
Formatting [15/62] libcyphal/platform/storage.hpp
Formatting [16/62] libcyphal/presentation/client.hpp
Formatting [17/62] libcyphal/presentation/client_impl.hpp
Formatting [18/62] libcyphal/presentation/common_helpers.hpp
Formatting [19/62] libcyphal/presentation/presentation.hpp
Formatting [20/62] libcyphal/presentation/presentation_delegate.hpp
Formatting [21/62] libcyphal/presentation/publisher.hpp
Formatting [22/62] libcyphal/presentation/publisher_impl.hpp
Formatting [23/62] libcyphal/presentation/response_promise.hpp
Formatting [24/62] libcyphal/presentation/server.hpp
Formatting [25/62] libcyphal/presentation/server_impl.hpp
Formatting [26/62] libcyphal/presentation/shared_object.hpp
Formatting [27/62] libcyphal/presentation/subscriber.hpp
Formatting [28/62] libcyphal/presentation/subscriber_impl.hpp
Formatting [29/62] libcyphal/time_provider.hpp
Formatting [30/62] libcyphal/transport/can/can_transport.hpp
Formatting [31/62] libcyphal/transport/can/can_transport_impl.hpp
Formatting [32/62] libcyphal/transport/can/delegate.hpp
Formatting [33/62] libcyphal/transport/can/media.hpp
Formatting [34/62] libcyphal/transport/can/msg_rx_session.hpp
Formatting [35/62] libcyphal/transport/can/msg_tx_session.hpp
Formatting [36/62] libcyphal/transport/can/rx_session_tree_node.hpp
Formatting [37/62] libcyphal/transport/can/svc_rx_sessions.hpp
Formatting [38/62] libcyphal/transport/can/svc_tx_sessions.hpp
Formatting [39/62] libcyphal/transport/contiguous_payload.hpp
Formatting [40/62] libcyphal/transport/errors.hpp
Formatting [41/62] libcyphal/transport/lizard_helpers.hpp
Formatting [42/62] libcyphal/transport/media_payload.hpp
Formatting [43/62] libcyphal/transport/msg_sessions.hpp
Formatting [44/62] libcyphal/transport/scattered_buffer.hpp
Formatting [45/62] libcyphal/transport/session.hpp
Formatting [46/62] libcyphal/transport/session_tree.hpp
Formatting [47/62] libcyphal/transport/svc_rx_session_base.hpp
Formatting [48/62] libcyphal/transport/svc_sessions.hpp
Formatting [49/62] libcyphal/transport/transfer_id_map.hpp
Formatting [50/62] libcyphal/transport/transport.hpp
Formatting [51/62] libcyphal/transport/types.hpp
Formatting [52/62] libcyphal/transport/udp/delegate.hpp
Formatting [53/62] libcyphal/transport/udp/media.hpp
Formatting [54/62] libcyphal/transport/udp/msg_rx_session.hpp
Formatting [55/62] libcyphal/transport/udp/msg_tx_session.hpp
Formatting [56/62] libcyphal/transport/udp/rx_session_tree_node.hpp
Formatting [57/62] libcyphal/transport/udp/svc_rx_sessions.hpp
Formatting [58/62] libcyphal/transport/udp/svc_tx_sessions.hpp
Formatting [59/62] libcyphal/transport/udp/tx_rx_sockets.hpp
Formatting [60/62] libcyphal/transport/udp/udp_transport.hpp
Formatting [61/62] libcyphal/transport/udp/udp_transport_impl.hpp
Formatting [62/62] libcyphal/types.hpp
[5%] Built target libcyphal-clang-format-check
[7%] Built target gtest
[9%] Built target dsdl_support-gen
[9%] Built target dsdl_public_types-gen
[11%] Built target dsdl_my_custom_types-gen
[12%] Built target gmock
[14%] Building CXX object test/unittest/CMakeFiles/test_get_info_provider__googletest_objlib.dir/application/node/test_get_info_provider.cpp.o
error: too many errors emitted, stopping now [clang-diagnostic-error]
/home/erics/libcyphal/build/uavcan/_register/Value_1_0.hpp:213:9: error: member initializer 'empty' does not name a non-static data member or base class [clang-diagnostic-error]
        empty{allocator},
        ^ ~~~~~~~~~~~~~~~
/home/erics/libcyphal/build/uavcan/_register/Value_1_0.hpp:214:9: error: member initializer 'string' does not name a non-static data member or base class [clang-diagnostic-error]
        string{allocator},
        ^ ~~~~~~~~~~~~~~~~
/home/erics/libcyphal/build/uavcan/_register/Value_1_0.hpp:215:9: error: member initializer 'unstructured' does not name a non-static data member or base class [clang-diagnostic-error]
        unstructured{allocator},
        ^ ~~~~~~~~~~~~~~~~~~~~~~
/home/erics/libcyphal/build/uavcan/_register/Value_1_0.hpp:216:9: error: member initializer 'bit' does not name a non-static data member or base class [clang-diagnostic-error]
        bit{allocator},
        ^ ~~~~~~~~~~~~~
/home/erics/libcyphal/build/uavcan/_register/Value_1_0.hpp:217:9: error: member initializer 'integer64' does not name a non-static data member or base class [clang-diagnostic-error]
        integer64{allocator},
        ^ ~~~~~~~~~~~~~~~~~~~
/home/erics/libcyphal/build/uavcan/_register/Value_1_0.hpp:218:9: error: member initializer 'integer32' does not name a non-static data member or base class [clang-diagnostic-error]
        integer32{allocator},
        ^ ~~~~~~~~~~~~~~~~~~~
/home/erics/libcyphal/build/uavcan/_register/Value_1_0.hpp:219:9: error: member initializer 'integer16' does not name a non-static data member or base class [clang-diagnostic-error]
        integer16{allocator},
        ^ ~~~~~~~~~~~~~~~~~~~
/home/erics/libcyphal/build/uavcan/_register/Value_1_0.hpp:220:9: error: member initializer 'integer8' does not name a non-static data member or base class [clang-diagnostic-error]
        integer8{allocator},
        ^ ~~~~~~~~~~~~~~~~~~
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:56:48: error: no matching member function for call to 'makeServer' [clang-diagnostic-error]
        auto maybe_get_info_srv = presentation.makeServer<Service>();
                                  ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
/home/erics/libcyphal/include/libcyphal/presentation/presentation.hpp:360:10: note: candidate template ignored: requirement 'detail::IsServiceTrait<uavcan::node::GetInfo_1_0, false>::value' was not satisfied [with Service = uavcan::node::GetInfo_1_0]
    auto makeServer(typename ServiceServer<Service>::OnRequestCallback::Function&& on_request_cb_fn = {})
         ^
/home/erics/libcyphal/include/libcyphal/presentation/presentation.hpp:313:10: note: candidate function template not viable: requires at least argument 'service_id', but no arguments were provided
    auto makeServer(const transport::PortId service_id,
         ^
/home/erics/libcyphal/include/libcyphal/presentation/presentation.hpp:343:10: note: candidate function template not viable: requires at least argument 'service_id', but no arguments were provided
    auto makeServer(const transport::PortId service_id,
         ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:62:56: error: use of undeclared identifier 'Server' [clang-diagnostic-error]
        return GetInfoProvider{presentation, cetl::get<Server>(std::move(maybe_get_info_srv))};
                                                       ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:62:56: error: use of undeclared identifier 'Server'; did you mean 'presentation::Server'? [clang-diagnostic-error]
        return GetInfoProvider{presentation, cetl::get<Server>(std::move(maybe_get_info_srv))};
                                                       ^ ~~~~~
                                                       presentation::Server
/home/erics/libcyphal/include/libcyphal/presentation/server.hpp:166:7: note: 'presentation::Server' declared here
class Server final : public detail::ServerBase
      ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:65:5: error: constructor does not initialize these fields: server_ [cppcoreguidelines-pro-type-member-init,hicpp-member-init,-warnings-as-errors]
    GetInfoProvider(GetInfoProvider&& other) noexcept
    ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:189:31: error: use of undeclared identifier 'ArrayCapacity' [clang-diagnostic-error]
        return setStringField<ArrayCapacity::name>(response_.name, name);
                              ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:201:31: error: use of undeclared identifier 'ArrayCapacity' [clang-diagnostic-error]
        return setStringField<ArrayCapacity::certificate_of_authenticity>(response_.certificate_of_authenticity,
                              ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:206:47: error: no type named 'ArrayCapacity' in 'uavcan::node::GetInfo::Response_1_0::_traits_' [clang-diagnostic-error]
    using ArrayCapacity = Response::_traits_::ArrayCapacity;
                          ~~~~~~~~~~~~~~~~~~~~ ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:209:5: error: constructor does not initialize these fields: server_, response_ [cppcoreguidelines-pro-type-member-init,hicpp-member-init,-warnings-as-errors]
    GetInfoProvider(presentation::Presentation& presentation, Server&& server)
    ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:209:63: error: unknown type name 'Server' [clang-diagnostic-error]
    GetInfoProvider(presentation::Presentation& presentation, Server&& server)
                                                              ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:209:72: error: parameter 'server' is unused [misc-unused-parameters,-warnings-as-errors]
    GetInfoProvider(presentation::Presentation& presentation, Server&& server)
                                                                       ^ ~~~~~
                                                                        /*server*/
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:212:21: error: no member named 'allocator_type' in 'uavcan::node::GetInfo::Response_1_0'; did you mean 'nunavut::support::options::allocator_type'? [clang-diagnostic-error]
        , response_{Response::allocator_type{&presentation.memory()}}
                    ^ ~~~~~~~~~~~~~~~~~~~~~~~
                    nunavut::support::options::allocator_type
/home/erics/libcyphal/build/nunavut/support/serialization.hpp:197:25: note: 'nunavut::support::options::allocator_type' declared here
constexpr std::uint32_t allocator_type = 247585418;
                        ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:212:45: error: expected '}' [clang-diagnostic-error]
        , response_{Response::allocator_type{&presentation.memory()}}
                                            ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:212:20: note: to match this '{'
        , response_{Response::allocator_type{&presentation.memory()}}
                   ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:242:5: error: unknown type name 'Server' [clang-diagnostic-error]
    Server server_;
    ^
/home/erics/libcyphal/include/libcyphal/application/registry/register.hpp:231:104: error: parameter 'alloc' is unused [misc-unused-parameters,-warnings-as-errors]
inline uavcan::_register::Name_1_0 makeRegisterName(const uavcan::_register::Name_1_0::allocator_type& alloc,
                                                                                                       ^ ~~~~
                                                                                                        /*alloc*/
/home/erics/libcyphal/include/libcyphal/presentation/presentation.hpp:99:7: error: destructor of 'Presentation' is public and non-virtual [cppcoreguidelines-virtual-class-destructor,-warnings-as-errors]
class Presentation final : private detail::IPresentationDelegate
      ^
/home/erics/libcyphal/include/libcyphal/presentation/presentation.hpp:99:7: note: make it public and virtual
class Presentation final : private detail::IPresentationDelegate
      ^
/home/erics/libcyphal/include/libcyphal/presentation/response_promise.hpp:342:7: error: destructor of 'ResponsePromise<void>' is public and non-virtual [cppcoreguidelines-virtual-class-destructor,-warnings-as-errors]
class ResponsePromise<void> final : public ResponsePromiseBase<transport::ScatteredBuffer, RawResponsePromiseFailure>
      ^
/home/erics/libcyphal/include/libcyphal/presentation/response_promise.hpp:342:7: note: make it public and virtual
class ResponsePromise<void> final : public ResponsePromiseBase<transport::ScatteredBuffer, RawResponsePromiseFailure>
      ^
/home/erics/libcyphal/include/libcyphal/presentation/server.hpp:284:7: error: destructor of 'RawServiceServer' is public and non-virtual [cppcoreguidelines-virtual-class-destructor,-warnings-as-errors]
class RawServiceServer final : public detail::ServerBase
      ^
/home/erics/libcyphal/include/libcyphal/presentation/server.hpp:284:7: note: make it public and virtual
class RawServiceServer final : public detail::ServerBase
      ^
/usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/type_traits:2579:44: error: no type named 'type' in 'std::enable_if<false>'; 'enable_if' cannot be used to disable this declaration [clang-diagnostic-error]
    using enable_if_t = typename enable_if<_Cond, _Tp>::type;
                                           ^ ~~~~
/home/erics/libcyphal/include/libcyphal/presentation/server.hpp:276:45: note: in instantiation of template type alias 'enable_if_t' requested here
template <typename Service, typename = std::enable_if_t<detail::IsServiceTrait<Service>::value>>
                                            ^
/home/erics/libcyphal/include/libcyphal/application/node/get_info_provider.hpp:207:41: note: in instantiation of default argument for 'ServiceServer<uavcan::node::GetInfo_1_0>' required here
    using Server = presentation::ServiceServer<Service>;
                                        ^ ~~~~~~~~~~~~~~~~~~~~~
92534 warnings and 20 errors generated.
Error while processing /home/erics/libcyphal/test/unittest/application/node/test_get_info_provider.cpp.
Suppressed 93023 warnings (92525 in non-user code, 498 NOLINT).
Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well.
7 warnings treated as errors
make[2]: *** [test/unittest/CMakeFiles/test_get_info_provider __googletest_objlib.dir/build.make:79: test/unittest/CMakeFiles/test_get_info_provider__ googletest_objlib.dir/application/node/test_get_info_provider.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:894: test/unittest/CMakeFiles/test_get_info_provider__googletest_objlib.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

```

So apparently there’s an issue generating the message header from the DSDL files. Fine. Maybe this is just not supposed to work.

1. Trying out releases

Highest release number is [v1.0.0rc-last](https://github.com/OpenCyphal-Garage/libcyphal/releases/tag/v1.0.0rc-last), might as well give it a go.

```bash
cd libcyphal && git checkout v1.0.0rc-last
mkdir build 
cd build && cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 .. # suppressing minimum cmake error
CMake Deprecation Warning at CMakeLists.txt:5 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.

-- The C compiler identification is GNU 11.4.0
-- The CXX compiler identification is GNU 11.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Deprecation Warning at libuavcan/CMakeLists.txt:5 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.

-- Using C++11 (pass UAVCAN_USE_CPP03=1 to override)
-- Release build type: RelWithDebInfo
-- Adding UAVCAN Linux platform driver
CMake Deprecation Warning at libuavcan_drivers/posix/CMakeLists.txt:5 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.

CMake Deprecation Warning at libuavcan_drivers/linux/CMakeLists.txt:5 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.

-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Using uavcan target; source dir: /home/erics/libcyphal/libuavcan
-- POSIX source dir: /home/erics/libcyphal/libuavcan_drivers/posix
-- Configuring done (0.4s)
-- Generating done (0.0s)
-- Build files have been written to: /home/erics/libcyphal/build

```

Success! Let’s build

```bash
make
[1%] Running dsdl compiler
/bin/sh: 1: PYTHON-NOTFOUND: not found
make[2]: *** [libuavcan/CMakeFiles/libuavcan_dsdlc.dir/build.make:89: libuavcan_dsdlc_run.stamp] Error 127
make[1]: *** [CMakeFiles/Makefile2:186: libuavcan/CMakeFiles/libuavcan_dsdlc.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

```

huh? Turns out `libuavcan/CMakeLists.txt` has `find_program(PYTHON python)` which does not like that we don’t have a `3` at the end, so here we go: `find_program(PYTHON python3)`

```bash
make
CMake Deprecation Warning at CMakeLists.txt:5 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.

CMake Deprecation Warning at libuavcan/CMakeLists.txt:5 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.

-- Using C++11 (pass UAVCAN_USE_CPP03=1 to override)
-- Release build type: RelWithDebInfo
-- Adding UAVCAN Linux platform driver
CMake Deprecation Warning at libuavcan_drivers/posix/CMakeLists.txt:5 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.

CMake Deprecation Warning at libuavcan_drivers/linux/CMakeLists.txt:5 (cmake_minimum_required):
  Compatibility with CMake < 3.10 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value. Or, use the <min>...<max> syntax
  to tell CMake that the project requires at least <min> but has been updated
  to work with policies introduced by <max> or earlier.

-- Using uavcan target; source dir: /home/erics/libcyphal/libuavcan
-- POSIX source dir: /home/erics/libcyphal/libuavcan_drivers/posix
-- Configuring done (0.2s)
-- Generating done (0.0s)
-- Build files have been written to: /home/erics/libcyphal/build
[1%] Running dsdl compiler
Traceback (most recent call last):
  File "/home/erics/libcyphal/libuavcan/dsdl_compiler/libuavcan_dsdlc", line 59, in <module>
    from libuavcan_dsdl_compiler import run as dsdlc_run
  File "/home/erics/libcyphal/libuavcan/dsdl_compiler/libuavcan_dsdl_compiler/ __init__.py", line 17, in <module>
    from uavcan import dsdl
ModuleNotFoundError: No module named 'uavcan'
make[2]: *** [libuavcan/CMakeFiles/libuavcan_dsdlc.dir/build.make:89: libuavcan_dsdlc_run.stamp] Error 1
make[1]: *** [CMakeFiles/Makefile2:186: libuavcan/CMakeFiles/libuavcan_dsdlc.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

```

where `uavcan` is not found. The only Python module `uavcan` I am aware of is from a transpiled DSDL-file that I get from [public\_regulated\_data\_types](https://github.com/OpenCyphal/public_regulated_data_types). Ok, quickly jump into another project where I have that shit. And …

```auto
python3
Python 3.10.12 (main, Aug 15 2025, 14:32:43) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import uavcan
>>> print(uavcan)
<module 'uavcan' from '${some_path}/python_compiled_messages/uavcan/ __init__.py'>
>>> from uavcan import dsdl
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: cannot import name 'dsdl' from 'uavcan' (${some_path}/python_compiled_messages/uavcan/ __init__.py)
>>> 

```

so there is no `dsdl` in `uavcan`? What do you want from me ☹? Ok, giving up on this so far, and follow the CI (thanks @maksim.drachov 🙂)

# Following the CI

Fresh start:

```bash
cd libcyphal && git reset --hard && git checkout main

```

which has `libcyphal/.github`-dir with a `sonar.yml` that does a bunch of stuff, including building with a build-tool. Yay 🙂. Reading it, and it seems all it does is:

```bash
python3 ./build-tools/bin/verify.py

```

which fails again:

```bash
python3 ./build-tools/bin/verify.py 
CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:163 (_init_nnvg_command_args)
  CMakeLists.txt:45 (define_nunavut_support_target)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  CMakeLists.txt:50 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  CMakeLists.txt:50 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  test/unittest/CMakeLists.txt:20 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  test/unittest/CMakeLists.txt:20 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  docs/examples/CMakeLists.txt:27 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  docs/examples/CMakeLists.txt:27 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Configuring done (4.5s)
-- Generating done (0.1s)
-- Build files have been written to: /home/erics/libcyphal/build
[0/2] Re-checking globbed directories...
[1/100] Building C object docs/examples/CMakeFiles/examples_platform_linux.dir/platform/linux/can/socketcan.c.o
FAILED: docs/examples/CMakeFiles/examples_platform_linux.dir/platform/linux/can/socketcan.c.o 
/usr/bin/gcc -DCAVL_NO_ASSERT=1 -DLIBCYPHAL_VERSION=\"0.0.0\" -I/home/erics/libcyphal/external/libcanard/libcanard -g -pedantic -Wall -Wextra -Werror -Wfloat-equal -Wconversion -Wunused-parameter -Wunused-variable -Wunused-value -Wcast-align -Wmissing-declarations -Wmissing-field-initializers -Wdouble-promotion -Wswitch-enum -Wtype-limits -Wno-error=array-bounds -O0 -DDEBUG -ggdb -MD -MT docs/examples/CMakeFiles/examples_platform_linux.dir/platform/linux/can/socketcan.c.o -MF docs/examples/CMakeFiles/examples_platform_linux.dir/platform/linux/can/socketcan.c.o.d -o docs/examples/CMakeFiles/examples_platform_linux.dir/platform/linux/can/socketcan.c.o -c /home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c
In file included from /home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:11:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.h:56:58: error: ‘struct CanardFrame’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
   56 | int16_t socketcanPush(const SocketCANFD fd, const struct CanardFrame* const frame, const CanardMicrosecond timeout_usec);
      | ^ ~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.h:70:29: error: ‘struct CanardFrame’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
   70 | struct CanardFrame* const out_frame,
      | ^ ~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:136:58: error: ‘struct CanardFrame’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
  136 | int16_t socketcanPush(const SocketCANFD fd, const struct CanardFrame* const frame, const CanardMicrosecond timeout_usec)
      | ^ ~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:136:9: error: conflicting types for ‘socketcanPush’; have ‘int16_t(const SocketCANFD, const struct CanardFrame * const, const CanardMicrosecond)’ {aka ‘short int(const int, const struct CanardFrame * const, const long unsigned int)’}
  136 | int16_t socketcanPush(const SocketCANFD fd, const struct CanardFrame* const frame, const CanardMicrosecond timeout_usec)
      | ^ ~~~~~~~~~~~~
In file included from /home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:11:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.h:56:9: note: previous declaration of ‘socketcanPush’ with type ‘int16_t(const SocketCANFD, const struct CanardFrame * const, const CanardMicrosecond)’ {aka ‘short int(const int, const struct CanardFrame * const, const long unsigned int)’}
   56 | int16_t socketcanPush(const SocketCANFD fd, const struct CanardFrame* const frame, const CanardMicrosecond timeout_usec);
      | ^ ~~~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c: In function ‘socketcanPush’:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:138:34: error: invalid use of undefined type ‘const struct CanardFrame’
  138 | if ((frame == NULL) || (frame->payload.data == NULL) || (frame->payload.size > UINT8_MAX))
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:138:67: error: invalid use of undefined type ‘const struct CanardFrame’
  138 | if ((frame == NULL) || (frame->payload.data == NULL) || (frame->payload.size > UINT8_MAX))
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:150:27: error: invalid use of undefined type ‘const struct CanardFrame’
  150 | cfd.can_id = frame->extended_can_id | CAN_EFF_FLAG;
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:151:37: error: invalid use of undefined type ‘const struct CanardFrame’
  151 | cfd.len = (uint8_t) frame->payload.size;
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:154:38: error: invalid use of undefined type ‘const struct CanardFrame’
  154 | (void) memcpy(cfd.data, frame->payload.data, frame->payload.size);
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:154:59: error: invalid use of undefined type ‘const struct CanardFrame’
  154 | (void) memcpy(cfd.data, frame->payload.data, frame->payload.size);
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:159:34: error: invalid use of undefined type ‘const struct CanardFrame’
  159 | const size_t mtu = (frame->payload.size > CAN_MAX_DLEN) ? CANFD_MTU : CAN_MTU;
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c: At top level:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:169:29: error: ‘struct CanardFrame’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
  169 | struct CanardFrame* const out_frame,
      | ^ ~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:168:9: error: conflicting types for ‘socketcanPop’; have ‘int16_t(const SocketCANFD, struct CanardFrame * const, CanardMicrosecond * const, const size_t, void * const, const CanardMicrosecond, _Bool * const)’ {aka ‘short int(const int, struct CanardFrame * const, long unsigned int * const, const long unsigned int, void * const, const long unsigned int, _Bool * const)’}
  168 | int16_t socketcanPop(const SocketCANFD fd,
      | ^ ~~~~~~~~~~~
In file included from /home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:11:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.h:69:9: note: previous declaration of ‘socketcanPop’ with type ‘int16_t(const SocketCANFD, struct CanardFrame * const, CanardMicrosecond * const, const size_t, void * const, const CanardMicrosecond, _Bool * const)’ {aka ‘short int(const int, struct CanardFrame * const, long unsigned int * const, const long unsigned int, void * const, const long unsigned int, _Bool * const)’}
   69 | int16_t socketcanPop(const SocketCANFD fd,
      | ^ ~~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c: In function ‘socketcanPop’:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:265:48: error: invalid application of ‘sizeof’ to incomplete type ‘struct CanardFrame’
  265 | (void) memset(out_frame, 0, sizeof(struct CanardFrame));
      | ^ ~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:268:18: error: invalid use of undefined type ‘struct CanardFrame’
  268 | out_frame->extended_can_id = sockcan_frame.can_id & CAN_EFF_MASK;
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:269:18: error: invalid use of undefined type ‘struct CanardFrame’
  269 | out_frame->payload.size = sockcan_frame.len;
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:270:18: error: invalid use of undefined type ‘struct CanardFrame’
  270 | out_frame->payload.data = payload_buffer;
      | ^~
cc1: all warnings being treated as errors
[11/100] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
ninja: build stopped: subcommand failed.

```

Ha, I’ve seen this before. It’s when the libcanard library is too “new” where the `CanardFrame` struct is not used this way anymore. Some breaking change a couple months back. I’ve actually not updated libcanard in my stm32 projects because of this. Ok, so we need to revert to an earlier `libcanard`-version. From my stm32 bs, I remember a specific commit-ID still worked, so let’s check it out.

```bash
cd external/libcanard
git branch -a
* (HEAD detached at v3.2.0)
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

```

Yes, breaking change was from `v2.x` to `v3.x`. So.

```bash
cd external/libcanard
git checkout 03fc5fecc2c81bd6bfc6e474af8059fca2db4647 

```

```bash
cd ~/libcyphal
python3 ./build-tools/bin/verify.py

```

which produces

```bash
CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:163 (_init_nnvg_command_args)
  CMakeLists.txt:45 (define_nunavut_support_target)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  CMakeLists.txt:50 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  CMakeLists.txt:50 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  test/unittest/CMakeLists.txt:20 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  test/unittest/CMakeLists.txt:20 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  docs/examples/CMakeLists.txt:27 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  docs/examples/CMakeLists.txt:27 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Configuring done (4.0s)
-- Generating done (0.1s)
-- Build files have been written to: /home/erics/libcyphal/build
[0/2] Re-checking globbed directories...
[1/100] Building C object docs/examples/CMakeFiles/examples_platform_linux.dir/platform/linux/can/socketcan.c.o
FAILED: docs/examples/CMakeFiles/examples_platform_linux.dir/platform/linux/can/socketcan.c.o 
/usr/bin/gcc -DCAVL_NO_ASSERT=1 -DLIBCYPHAL_VERSION=\"0.0.0\" -I/home/erics/libcyphal/external/libcanard/libcanard -g -pedantic -Wall -Wextra -Werror -Wfloat-equal -Wconversion -Wunused-parameter -Wunused-variable -Wunused-value -Wcast-align -Wmissing-declarations -Wmissing-field-initializers -Wdouble-promotion -Wswitch-enum -Wtype-limits -Wno-error=array-bounds -O0 -DDEBUG -ggdb -MD -MT docs/examples/CMakeFiles/examples_platform_linux.dir/platform/linux/can/socketcan.c.o -MF docs/examples/CMakeFiles/examples_platform_linux.dir/platform/linux/can/socketcan.c.o.d -o docs/examples/CMakeFiles/examples_platform_linux.dir/platform/linux/can/socketcan.c.o -c /home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c
In file included from /home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:11:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.h:56:58: error: ‘struct CanardFrame’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
   56 | int16_t socketcanPush(const SocketCANFD fd, const struct CanardFrame* const frame, const CanardMicrosecond timeout_usec);
      | ^ ~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.h:70:29: error: ‘struct CanardFrame’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
   70 | struct CanardFrame* const out_frame,
      | ^ ~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:136:58: error: ‘struct CanardFrame’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
  136 | int16_t socketcanPush(const SocketCANFD fd, const struct CanardFrame* const frame, const CanardMicrosecond timeout_usec)
      | ^ ~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:136:9: error: conflicting types for ‘socketcanPush’; have ‘int16_t(const SocketCANFD, const struct CanardFrame * const, const CanardMicrosecond)’ {aka ‘short int(const int, const struct CanardFrame * const, const long unsigned int)’}
  136 | int16_t socketcanPush(const SocketCANFD fd, const struct CanardFrame* const frame, const CanardMicrosecond timeout_usec)
      | ^ ~~~~~~~~~~~~
In file included from /home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:11:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.h:56:9: note: previous declaration of ‘socketcanPush’ with type ‘int16_t(const SocketCANFD, const struct CanardFrame * const, const CanardMicrosecond)’ {aka ‘short int(const int, const struct CanardFrame * const, const long unsigned int)’}
   56 | int16_t socketcanPush(const SocketCANFD fd, const struct CanardFrame* const frame, const CanardMicrosecond timeout_usec);
      | ^ ~~~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c: In function ‘socketcanPush’:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:138:34: error: invalid use of undefined type ‘const struct CanardFrame’
  138 | if ((frame == NULL) || (frame->payload.data == NULL) || (frame->payload.size > UINT8_MAX))
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:138:67: error: invalid use of undefined type ‘const struct CanardFrame’
  138 | if ((frame == NULL) || (frame->payload.data == NULL) || (frame->payload.size > UINT8_MAX))
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:150:27: error: invalid use of undefined type ‘const struct CanardFrame’
  150 | cfd.can_id = frame->extended_can_id | CAN_EFF_FLAG;
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:151:37: error: invalid use of undefined type ‘const struct CanardFrame’
  151 | cfd.len = (uint8_t) frame->payload.size;
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:154:38: error: invalid use of undefined type ‘const struct CanardFrame’
  154 | (void) memcpy(cfd.data, frame->payload.data, frame->payload.size);
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:154:59: error: invalid use of undefined type ‘const struct CanardFrame’
  154 | (void) memcpy(cfd.data, frame->payload.data, frame->payload.size);
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:159:34: error: invalid use of undefined type ‘const struct CanardFrame’
  159 | const size_t mtu = (frame->payload.size > CAN_MAX_DLEN) ? CANFD_MTU : CAN_MTU;
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c: At top level:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:169:29: error: ‘struct CanardFrame’ declared inside parameter list will not be visible outside of this definition or declaration [-Werror]
  169 | struct CanardFrame* const out_frame,
      | ^ ~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:168:9: error: conflicting types for ‘socketcanPop’; have ‘int16_t(const SocketCANFD, struct CanardFrame * const, CanardMicrosecond * const, const size_t, void * const, const CanardMicrosecond, _Bool * const)’ {aka ‘short int(const int, struct CanardFrame * const, long unsigned int * const, const long unsigned int, void * const, const long unsigned int, _Bool * const)’}
  168 | int16_t socketcanPop(const SocketCANFD fd,
      | ^ ~~~~~~~~~~~
In file included from /home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:11:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.h:69:9: note: previous declaration of ‘socketcanPop’ with type ‘int16_t(const SocketCANFD, struct CanardFrame * const, CanardMicrosecond * const, const size_t, void * const, const CanardMicrosecond, _Bool * const)’ {aka ‘short int(const int, struct CanardFrame * const, long unsigned int * const, const long unsigned int, void * const, const long unsigned int, _Bool * const)’}
   69 | int16_t socketcanPop(const SocketCANFD fd,
      | ^ ~~~~~~~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c: In function ‘socketcanPop’:
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:265:48: error: invalid application of ‘sizeof’ to incomplete type ‘struct CanardFrame’
  265 | (void) memset(out_frame, 0, sizeof(struct CanardFrame));
      | ^ ~~~~~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:268:18: error: invalid use of undefined type ‘struct CanardFrame’
  268 | out_frame->extended_can_id = sockcan_frame.can_id & CAN_EFF_MASK;
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:269:18: error: invalid use of undefined type ‘struct CanardFrame’
  269 | out_frame->payload.size = sockcan_frame.len;
      | ^~
/home/erics/libcyphal/docs/examples/platform/linux/can/socketcan.c:270:18: error: invalid use of undefined type ‘struct CanardFrame’
  270 | out_frame->payload.data = payload_buffer;
      | ^~
cc1: all warnings being treated as errors
[2/100] Building C object docs/examples/CMakeFiles/examples_platform_posix.dir/platform/posix/udp/udp.c.o
[3/100] Building C object CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o
[4/100] Building C object CMakeFiles/udpard.dir/external/libudpard/libudpard/udpard.c.o
[5/100] Running nnvg to generate headers for dsdl_support
[6/100] Running nnvg to generate headers for dsdl_my_custom_types
[7/100] Running nnvg to generate headers for dsdl_example_types
[8/100] Building CXX object _deps/googletest-build/googlemock/CMakeFiles/gmock_main.dir/src/gmock_main.cc.o
[9/100] Building CXX object _deps/googletest-build/googlemock/CMakeFiles/gmock.dir/src/gmock-all.cc.o
[10/100] Running nnvg to generate headers for dsdl_public_types
[11/100] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
ninja: build stopped: subcommand failed.

```

which has some issues with `libcanard` again, I believe. So maybe the commit was wrong. Try some other libcanard version then. Last push to `main`-branch of libcyphal was 8 months ago today (November 5th 2025), so let’s see which libcanard version was en vogue back then … Fuck it was libcanard v3.2.0 as of September 2024. So let’s checkout out `master` which is mostly updated 6 and 3 months ago.

```bash
cd libcyphal/external/libcanard
git checkout master
cd ..
python3 ./build-tools/bin/verify.py

```

which gives me

```bash
python3 ./build-tools/bin/verify.py 
CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:163 (_init_nnvg_command_args)
  CMakeLists.txt:45 (define_nunavut_support_target)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  CMakeLists.txt:50 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  CMakeLists.txt:50 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  test/unittest/CMakeLists.txt:20 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  test/unittest/CMakeLists.txt:20 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  docs/examples/CMakeLists.txt:27 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  docs/examples/CMakeLists.txt:27 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Configuring done (4.2s)
-- Generating done (0.1s)
-- Build files have been written to: /home/erics/libcyphal/build
[0/2] Re-checking globbed directories...
[1/100] Building C object CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o
FAILED: CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o 
/usr/bin/gcc -DCAVL_NO_ASSERT=1 -DLIBCYPHAL_VERSION=\"0.0.0\" -I/home/erics/libcyphal/external/libcanard/libcanard -g -fPIC -pedantic -Wall -Wextra -Werror -Wfloat-equal -Wconversion -Wunused-parameter -Wunused-variable -Wunused-value -Wcast-align -Wmissing-declarations -Wmissing-field-initializers -Wdouble-promotion -Wswitch-enum -Wtype-limits -Wno-error=array-bounds -O0 -DDEBUG -ggdb -MD -MT CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o -MF CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o.d -o CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o -c /home/erics/libcyphal/external/libcanard/libcanard/canard.c
/home/erics/libcyphal/external/libcanard/libcanard/canard.c:45:10: fatal error: cavl2.h: No such file or directory
   45 | #include <cavl2.h>
      | ^ ~~~~~~~~
compilation terminated.
[11/100] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
ninja: build stopped: subcommand failed.

```

Alright, apparently I am missing a lib?! Google-Search gives me nothing, but github-search tells me it’s some Cyphal-Specific thing, as it only appears in Cyphal code or issues. See [Github Code search for #include \<cavl2.h\>](https://github.com/search?q=%23include+%3Ccavl2.h%3E&type=code)

I tried to subsume what I did for the last two days and replicated all results exactly as described here. I also omitted my more stupid approaches. 🙂

If someone can help, please do.

---

<div class="post-metadata">

**Author:** ![scottdixon](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/scottdixon/32/39_2.png) [@scottdixon](https://forum.opencyphal.org/u/scottdixon)\
**Post date:** [November 7, 2025, 10:31pm UTC](https://forum.opencyphal.org/t/building-libcyphal/2427/2 "2025-11-07T22:31:53Z")

</div>

It looks like the cmake doesn’t install nunavut. You’ll have to install that manually:

```bash
pip install nunavut==3.0.0.dev1

```

The v4 for libcanard is a problem. it looks like there was a change to libcanard that was never published? @pavel.kirienko @SergeS147 , any guidance here?

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [November 8, 2025, 1:29pm UTC](https://forum.opencyphal.org/t/building-libcyphal/2427/3 "2025-11-08T13:29:53Z")

</div>

Sup! I should acknowledge my disappearance lately; all my attention is currently needed elsewhere. I am going to organize a bit of a hackathon-sprint with my colleagues soon to make some progress on v1.1 and a few of the older issues; I will not announce this but there will be signs when it’s done. 🙂

Yes libcanard had a v4 alpha tag at some point, which probably disappeared once the branch containing that tag was squash-merged into master. The correct fix is to simply use the master branch. We cannot really tag v4 because it’s not ready yet.

---

<div class="post-metadata">

**Author:** ![Scoeerg](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/scoeerg/32/1713_2.png) [@Scoeerg](https://forum.opencyphal.org/u/Scoeerg)\
**Post date:** [November 8, 2025, 3:30pm UTC](https://forum.opencyphal.org/t/building-libcyphal/2427/4 "2025-11-08T15:30:13Z")

</div>

Alright 🙂 Thanks all

```bash
pip install nunavut==3.0.0.dev1
# Defaulting to user installation because normal site-packages is not writeable
# Requirement already satisfied: nunavut==3.0.0.dev1 in /home/erics/.local/lib/python3.10/site-packages # (3.0.0.dev1)
# Requirement already satisfied: pydsdl>=1.22.2 in /home/erics/.local/lib/python3.10/site-packages (from nunavut==3.0.0.dev1) (1.22.2)
cd ~/libcyphal
git checkout main && git reset --hard 
cd external/libcanard && git checkout master 
cd ~/libcyphal # get back to project root
python3 build-tools/bin/verify.py

```

gets me

```bash
python3 build-tools/bin/verify.py 
CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:163 (_init_nnvg_command_args)
  CMakeLists.txt:45 (define_nunavut_support_target)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  CMakeLists.txt:50 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  CMakeLists.txt:50 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  test/unittest/CMakeLists.txt:20 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  test/unittest/CMakeLists.txt:20 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:40 (cmake_parse_arguments):
  The OUTPUT_FOLDER keyword was followed by an empty string or no value at
  all. Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_OUTPUT_FOLDER variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:228 (_init_nnvg_command_args)
  docs/examples/CMakeLists.txt:27 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

CMake Warning (dev) at cmake/modules/Findnnvg.cmake:87 (cmake_parse_arguments):
  The ADD_TO_ALL keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  ARG_ADD_TO_ALL variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/Findnnvg.cmake:298 (_define_nnvg_rules)
  docs/examples/CMakeLists.txt:27 (add_dsdl_cpp_codegen)
This warning is for project developers. Use -Wno-dev to suppress it.

-- Configuring done (3.7s)
-- Generating done (0.1s)
-- Build files have been written to: /home/erics/libcyphal/build
[0/2] Re-checking globbed directories...
[1/100] Building C object CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o
FAILED: CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o 
/usr/bin/gcc -DCAVL_NO_ASSERT=1 -DLIBCYPHAL_VERSION=\"0.0.0\" -I/home/erics/libcyphal/external/libcanard/libcanard -g -fPIC -pedantic -Wall -Wextra -Werror -Wfloat-equal -Wconversion -Wunused-parameter -Wunused-variable -Wunused-value -Wcast-align -Wmissing-declarations -Wmissing-field-initializers -Wdouble-promotion -Wswitch-enum -Wtype-limits -Wno-error=array-bounds -O0 -DDEBUG -ggdb -MD -MT CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o -MF CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o.d -o CMakeFiles/canard.dir/external/libcanard/libcanard/canard.c.o -c /home/erics/libcyphal/external/libcanard/libcanard/canard.c
/home/erics/libcyphal/external/libcanard/libcanard/canard.c:45:10: fatal error: cavl2.h: No such file or directory
   45 | #include <cavl2.h>
      | ^ ~~~~~~~~
compilation terminated.
[11/100] Building CXX object _deps/googletest-build/googletest/CMakeFiles/gtest.dir/src/gtest-all.cc.o
ninja: build stopped: subcommand failed.

```

so … missing `#include <cavl2.h>`. But since this is the way it’s supposed to work, let’s keep digging from here. Fair enough, in `libcyphal/external/libcanard/libcanard/canard.c` change line 45:

```c
#include <cavl2.h>

```

should be

```c
#include "lib/cavl2/cavl2.h"

```

and `libcyphal/modules/Findlibcanard.cmake` line 65 to 75 should be changed such that `HEADER_PATH` `LOCAL_LIBCANARD_SOURCE_DIR` becomes `libcanard_SOURCE_DIR`:

```cmake
add_project_library(
    NAME canard
    SOURCES
        ${LOCAL_LIBCANARD_SOURCE_DIR}/canard.c
    HEADER_PATH
        ${libcanard_SOURCE_DIR}
    HEADER_INCLUDE_PATTERNS
        *.h
    STATIC
    FPIC
)

```

Now, the build process at least takes a couple minutes, which I’d guess is a good sign.

```bash
python3 build-tools/bin/verify.py

```

gets me a 2900 lines build.log and fails again, see:  
[build.log](https://forum.opencyphal.org/uploads/short-url/esRGwSqQeGDxvtwSmMgjXHufgUA.log) (289.5 KB)

---

<div class="post-metadata">

**Author:** ![scottdixon](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/scottdixon/32/39_2.png) [@scottdixon](https://forum.opencyphal.org/u/scottdixon)\
**Post date:** [November 8, 2025, 10:11pm UTC](https://forum.opencyphal.org/t/building-libcyphal/2427/5 "2025-11-08T22:11:28Z")

</div>

> [@Scoeerg](#):
>
> `lib/cavl2/`

Hmm. Okay. I’ll take another pass at this tonight. I’m curious why this rotted. It worked 8-months ago when I last built it.

---

<div class="post-metadata">

**Author:** ![scottdixon](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/scottdixon/32/39_2.png) [@scottdixon](https://forum.opencyphal.org/u/scottdixon)\
**Post date:** [November 13, 2025, 5:50pm UTC](https://forum.opencyphal.org/t/building-libcyphal/2427/6 "2025-11-13T17:50:40Z")

</div>

Sorry. Obviously I did not do another pass at this that night. Got super distracted. I’ll try to take a look this weekend though. @pavel.kirienko , did you see this thread? Looks like libcyphal has code rotted?

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [November 14, 2025, 10:42pm UTC](https://forum.opencyphal.org/t/building-libcyphal/2427/7 "2025-11-14T22:42:39Z")

</div>

I fixed most of the issues here and will resume tomorrow – one issue left:

> <https://github.com/OpenCyphal-Garage/libcyphal/pull/442>
>
> This is a response to https://forum.opencyphal.org/t/building-libcyphal/2427
> 
> …TODO: update libcanard usage:
> 
> \`\`\`c
> In file included from /home/pavel/cyphal/libcyphal/test/unittest/transport/can/test\_can\_msg\_rx\_session.cpp:19:
> /home/pavel/cyphal/libcyphal/include/libcyphal/transport/can/can\_transport\_impl.hpp: In member function ‘virtual cetl::pf17::optional\<cetl::pf17::variant\<libcyphal::transport::AnonymousError, libcyphal::ArgumentError, libcyphal::MemoryError, libcyphal::transport::CapacityError, libcyphal::ImplementationCell\<libcyphal::transport::IPlatformError, cetl::unbounded\_variant\<32, true, true, 16, void\> \>, libcyphal::transport::AlreadyExistsError\> \> libcyphal::transport::can::detail::TransportImpl::sendTransfer(libcyphal::TimePoint, const CanardTransferMetadata&, libcyphal::transport::PayloadFragments)’:
> /home/pavel/cyphal/libcyphal/include/libcyphal/transport/can/can\_transport\_impl.hpp:335:55: error: too few arguments to function ‘int32\_t canardTxPush(CanardTxQueue\*, const CanardInstance\*, CanardMicrosecond, const CanardTransferMetadata\*, CanardPayload, CanardMicrosecond, uint64\_t\*)’
> 335 | const std::int32\_t result = ::canardTxPush(&media.canard\_tx\_queue(),
> | ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
> 336 | &canardInstance(),
> | ~~~~~~~~~~~~~~~~~~
> 337 | static\_cast\<CanardMicrosecond\>(deadline\_us.count()),
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 338 | &metadata,
> | ~~~~~~~~~~
> 339 | {payload.size(), payload.data()}, // NOSONAR cpp:S5356
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 340 | static\_cast\<CanardMicrosecond\>(now\_us.count()));
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> In file included from /home/pavel/cyphal/libcyphal/test/unittest/transport/can/can\_gtest\_helpers.hpp:11,
> from /home/pavel/cyphal/libcyphal/test/unittest/transport/can/test\_can\_msg\_rx\_session.cpp:6:
> /home/pavel/cyphal/libcyphal/external/libcanard/libcanard/canard.h:560:9: note: declared here
> 560 | int32\_t canardTxPush(struct CanardTxQueue\* const que,
> | ^ ~~~~~~~~~~~
> \[35%\] Built target test\_registry\_provider\_\_googletest\_objlib
> \[35%\] Building CXX object test/unittest/CMakeFiles/test\_can\_svc\_rx\_sessions\_\_googletest\_objlib.dir/transport/can/test\_can\_svc\_rx\_sessions.cpp.o
> In file included from /home/pavel/cyphal/libcyphal/test/unittest/transport/can/test\_can\_msg\_rx\_session.cpp:19:
> /home/pavel/cyphal/libcyphal/include/libcyphal/transport/can/can\_transport\_impl.hpp: In member function ‘void libcyphal::transport::can::detail::TransportImpl::pushNextFrameToMedia(libcyphal::transport::can::detail::TransportImpl::Media&)’:
> /home/pavel/cyphal/libcyphal/include/libcyphal/transport/can/can\_transport\_impl.hpp:684:36: error: too few arguments to function ‘int8\_t canardTxPoll(CanardTxQueue\*, const CanardInstance\*, CanardMicrosecond, void\*, CanardTxFrameHandler, uint64\_t\*, uint64\_t\*)’
> 684 | result = ::canardTxPoll( //
> | ~~~~~~~~~~~~~~^~~~~
> 685 | &media.canard\_tx\_queue(),
> | ~~~~~~~~~~~~~~~~~~~~~~~~~
> 686 | &canardInstance(),
> | ~~~~~~~~~~~~~~~~~~  
> 687 | static\_cast\<CanardMicrosecond\>(executor\_.now().time\_since\_epoch().count()),
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 688 | &frame\_handler, // NOSONAR cpp:S5356
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 689 | \[\](auto\* const user\_reference, const auto deadline, auto\* frame) {
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 690 | //
> | ~~              
> 691 | auto\* const frame\_handler\_ptr =
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 692 | static\_cast\<decltype(frame\_handler)\*\>(user\_reference); // NOSONAR cpp:S5356, cpp:S5357
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 693 | return (\*frame\_handler\_ptr)(deadline, \*frame);
> | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 694 | });
> | ~~                  
> \`\`\`

The root cause is that libcyphal was dependent on an unstable/unreleased version of libcanard. Stay tuned.

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [November 15, 2025, 9:31pm UTC](https://forum.opencyphal.org/t/building-libcyphal/2427/8 "2025-11-15T21:31:34Z")

</div>

![image](https://forum.opencyphal.org/uploads/default/original/2X/a/a52831abc950566b8f52b3e0df71b94c470dc2d6.png)

> <https://github.com/OpenCyphal-Garage/libcyphal/pull/442>
>
> This is a response to https://forum.opencyphal.org/t/building-libcyphal/2427
> 
> …- Added brief build instructions to the README. The point of this change is mostly to indicate that one does not need to "build" libcyphal to use it because it is header-only. Building is only needed for development or verification.
> \- Fixed broken coverage measurement and updated CI workflow dependencies. Oh boy.
> \- Fixed the missing cavl error by pulling cavl from its own repository. Libcanard does no longer ship cavl and libudpard will eventually be updated to not do that either.
> \- The libcanard reference was updated to \`master\` instead of \`v4\`, temporarily until v4 is out. The code that leverages libcanard has been doctored to accommodate API changes in v4 (still officially unstable but I am not planning on changing it so it's kinda stable after all).
> \- Treat \`NO\_STATIC\_ANALYSIS\` properly.

@Scoeerg feel free to try the `dev` branch. You don’t need to build libcyphal to use it though, just `-I` the headers and you’re all set.

---

<div class="post-metadata">

**Author:** ![Scoeerg](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/scoeerg/32/1713_2.png) [@Scoeerg](https://forum.opencyphal.org/u/Scoeerg)\
**Post date:** [November 15, 2025, 10:22pm UTC](https://forum.opencyphal.org/t/building-libcyphal/2427/9 "2025-11-15T22:22:25Z")

</div>

Thank you 🙂 Let me have a look tomorrow.
