diff --git a/Dockerfile.build_firmware b/Dockerfile.build_firmware index 71f012e..1583776 100644 --- a/Dockerfile.build_firmware +++ b/Dockerfile.build_firmware @@ -7,26 +7,34 @@ RUN --mount=type=bind,target=/src,source=.,readonly \ set -euo pipefail; \ mkdir -p /output; \ LIBRMCS_PROJECT_VERSION="$(.scripts/generate_version)"; \ + LIBRMCS_DEBUG_ASSERTS=1; \ + FIRMWARE_CMAKE_PRESET=debug; \ + LIBRMCS_ARTIFACT_SUFFIX=-debug; \ + if [[ "${LIBRMCS_PROJECT_VERSION}" =~ ^[0-9]+(\.[0-9]+)*$ ]]; then \ + LIBRMCS_DEBUG_ASSERTS=0; \ + FIRMWARE_CMAKE_PRESET=release; \ + LIBRMCS_ARTIFACT_SUFFIX=; \ + fi; \ for board in rmcs_board; do \ for variant in pro lite; do \ build_dir="/tmp/build-${board}-${variant}"; \ artifact_name="${board}-${variant}"; \ - cmake --preset release -S "firmware/${board}" -B "${build_dir}" -DBOARD="${variant}"; \ + cmake --preset "${FIRMWARE_CMAKE_PRESET}" -S "firmware/${board}" -B "${build_dir}" -DBOARD="${variant}" -DLIBRMCS_DEBUG_ASSERTS="${LIBRMCS_DEBUG_ASSERTS}"; \ cmake --build "${build_dir}"; \ cp "${build_dir}/bootloader/output/rmcs_board_bootloader.elf" \ - "/output/librmcs-bootloader-${artifact_name}.elf"; \ + "/output/librmcs-bootloader-${artifact_name}${LIBRMCS_ARTIFACT_SUFFIX}.elf"; \ cp "${build_dir}/app/output/rmcs_board_app.dfu" \ - "/output/librmcs-firmware-${artifact_name}-${LIBRMCS_PROJECT_VERSION}.dfu"; \ + "/output/librmcs-firmware-${artifact_name}-${LIBRMCS_PROJECT_VERSION}${LIBRMCS_ARTIFACT_SUFFIX}.dfu"; \ done; \ done; \ for board in c_board; do \ build_dir="/tmp/build-${board}"; \ - cmake --preset release -S "firmware/${board}" -B "${build_dir}"; \ + cmake --preset "${FIRMWARE_CMAKE_PRESET}" -S "firmware/${board}" -B "${build_dir}" -DLIBRMCS_DEBUG_ASSERTS="${LIBRMCS_DEBUG_ASSERTS}"; \ cmake --build "${build_dir}"; \ cp "${build_dir}/bootloader/${board}_bootloader.elf" \ - "/output/librmcs-bootloader-${board}.elf"; \ + "/output/librmcs-bootloader-${board}${LIBRMCS_ARTIFACT_SUFFIX}.elf"; \ cp "${build_dir}/app/${board}_app.dfu" \ - "/output/librmcs-firmware-${board}-${LIBRMCS_PROJECT_VERSION}.dfu"; \ + "/output/librmcs-firmware-${board}-${LIBRMCS_PROJECT_VERSION}${LIBRMCS_ARTIFACT_SUFFIX}.dfu"; \ done FROM scratch AS output diff --git a/Dockerfile.build_sdk b/Dockerfile.build_sdk index 3768097..6418d47 100644 --- a/Dockerfile.build_sdk +++ b/Dockerfile.build_sdk @@ -9,6 +9,7 @@ cmake_minimum_required(VERSION 3.28) project(librmcs_wrapper VERSION 3 LANGUAGES C CXX) set(LIBRMCS_PROJECT_VERSION "__LIBRMCS_PROJECT_VERSION_PLACEHOLDER__") set(LIBRMCS_DEBIAN_VERSION "__LIBRMCS_DEBIAN_VERSION_PLACEHOLDER__") +set(LIBRMCS_DEBUG_ASSERTS __LIBRMCS_DEBUG_ASSERTS_PLACEHOLDER__) add_subdirectory(host) EOF @@ -25,26 +26,39 @@ WORKDIR /src-full RUN --mount=type=bind,target=/src-full,source=.,readonly \ LIBRMCS_PROJECT_VERSION=$(.scripts/generate_version) \ && LIBRMCS_DEBIAN_VERSION=$(.scripts/generate_version --format debian) \ - && echo "LIBRMCS_PROJECT_VERSION=${LIBRMCS_PROJECT_VERSION}" >> /env.sh \ - && echo "LIBRMCS_DEBIAN_VERSION=${LIBRMCS_DEBIAN_VERSION}" >> /env.sh \ + && LIBRMCS_DEBUG_ASSERTS=1 \ + && SDK_CMAKE_PRESET=linux-debug \ + && LIBRMCS_ARTIFACT_SUFFIX=-debug \ + && if [[ "${LIBRMCS_PROJECT_VERSION}" =~ ^[0-9]+(\.[0-9]+)*$ ]]; then \ + LIBRMCS_DEBUG_ASSERTS=0; \ + SDK_CMAKE_PRESET=linux-release; \ + LIBRMCS_ARTIFACT_SUFFIX=; \ + fi \ + && printf 'LIBRMCS_PROJECT_VERSION=%s\n' "${LIBRMCS_PROJECT_VERSION}" >> /env.sh \ + && printf 'LIBRMCS_DEBIAN_VERSION=%s\n' "${LIBRMCS_DEBIAN_VERSION}" >> /env.sh \ + && printf 'LIBRMCS_DEBUG_ASSERTS=%s\n' "${LIBRMCS_DEBUG_ASSERTS}" >> /env.sh \ + && printf 'SDK_CMAKE_PRESET=%s\n' "${SDK_CMAKE_PRESET}" >> /env.sh \ + && printf 'LIBRMCS_ARTIFACT_SUFFIX=%s\n' "${LIBRMCS_ARTIFACT_SUFFIX}" >> /env.sh \ && cp -r core host LICENSE /src \ && sed -i "s/__LIBRMCS_PROJECT_VERSION_PLACEHOLDER__/${LIBRMCS_PROJECT_VERSION}/g" \ /src/CMakeLists.txt \ && sed -i "s/__LIBRMCS_DEBIAN_VERSION_PLACEHOLDER__/${LIBRMCS_DEBIAN_VERSION}/g" \ + /src/CMakeLists.txt \ + && sed -i "s/__LIBRMCS_DEBUG_ASSERTS_PLACEHOLDER__/${LIBRMCS_DEBUG_ASSERTS}/g" \ /src/CMakeLists.txt WORKDIR /output RUN source /env.sh \ && if [ "${WITH_SOURCE}" = "true" ]; then \ - SDK_SRC_NAME=librmcs-sdk-src-${LIBRMCS_PROJECT_VERSION}; \ + SDK_SRC_NAME=librmcs-sdk-src-${LIBRMCS_PROJECT_VERSION}${LIBRMCS_ARTIFACT_SUFFIX}; \ cp -r /src ${SDK_SRC_NAME}; \ zip -r ${SDK_SRC_NAME}.zip ${SDK_SRC_NAME}; \ rm -rf ${SDK_SRC_NAME}; \ fi RUN source /env.sh \ - && cmake --preset linux-release -DBUILD_STATIC_LIBRMCS=OFF -B build /src \ + && cmake --preset "${SDK_CMAKE_PRESET}" -DBUILD_STATIC_LIBRMCS=OFF -B build /src \ && cmake --build build \ && cd build && cpack -G DEB && cd .. \ && mv build/*.deb . \ diff --git a/core/src/utility/assert.hpp b/core/src/utility/assert.hpp index 6c92e80..b3ac411 100644 --- a/core/src/utility/assert.hpp +++ b/core/src/utility/assert.hpp @@ -4,7 +4,11 @@ #include #include -#ifndef NDEBUG +#ifndef LIBRMCS_DEBUG_ASSERTS +# error "LIBRMCS_DEBUG_ASSERTS must be defined" +#endif + +#if LIBRMCS_DEBUG_ASSERTS # include #endif @@ -19,11 +23,11 @@ namespace librmcs::core::utility { [[noreturn]] inline void assert_failed_debug(const std::source_location& location = std::source_location::current()) { -#ifdef NDEBUG +#if LIBRMCS_DEBUG_ASSERTS + assert_func(location); +#else (void)location; std::unreachable(); -#else - assert_func(location); #endif } @@ -35,11 +39,11 @@ constexpr void assert_always( constexpr void assert_debug( bool condition, const std::source_location& location = std::source_location::current()) { -#ifdef NDEBUG +#if LIBRMCS_DEBUG_ASSERTS + assert_always(condition, location); +#else [[assume(condition)]]; (void)location; -#else - assert_always(condition, location); #endif } @@ -47,11 +51,11 @@ constexpr void assert_debug( template requires std::is_nothrow_invocable_r_v inline void assert_debug_lazy( Condition&& condition, const std::source_location& location = std::source_location::current()) { -#ifdef NDEBUG - (void)condition; - (void)location; -#else +#if LIBRMCS_DEBUG_ASSERTS assert_always(static_cast(std::invoke(std::forward(condition))), location); +#else + (void)std::forward(condition); + (void)location; #endif } diff --git a/core/src/utility/stack_allocator.hpp b/core/src/utility/stack_allocator.hpp index ac7b094..d91a71c 100644 --- a/core/src/utility/stack_allocator.hpp +++ b/core/src/utility/stack_allocator.hpp @@ -86,10 +86,10 @@ class BasicStackAllocator : private BasicStackAllocator { std::size_t lifo_check_depth_ = 0; }; -#ifdef NDEBUG -using StackAllocator = BasicStackAllocator; -#else +#if LIBRMCS_DEBUG_ASSERTS using StackAllocator = BasicStackAllocator; +#else +using StackAllocator = BasicStackAllocator; #endif } // namespace librmcs::core::utility diff --git a/firmware/c_board/CMakeLists.txt b/firmware/c_board/CMakeLists.txt index 2f33267..c563332 100644 --- a/firmware/c_board/CMakeLists.txt +++ b/firmware/c_board/CMakeLists.txt @@ -49,6 +49,7 @@ function(c_board_apply_target_options target linker_file) target_compile_definitions(${target} PRIVATE LIBRMCS_PROJECT_VERSION_STRING="${LIBRMCS_PROJECT_VERSION}" + LIBRMCS_DEBUG_ASSERTS=${LIBRMCS_DEBUG_ASSERTS} $<$:NDEBUG> ) diff --git a/firmware/c_board/bootloader/src/utility/assert.hpp b/firmware/c_board/bootloader/src/utility/assert.hpp index b99eeba..73ca516 100644 --- a/firmware/c_board/bootloader/src/utility/assert.hpp +++ b/firmware/c_board/bootloader/src/utility/assert.hpp @@ -1,5 +1,9 @@ #pragma once +#ifndef LIBRMCS_DEBUG_ASSERTS +# error "LIBRMCS_DEBUG_ASSERTS must be defined" +#endif + namespace librmcs::firmware::utility { [[noreturn, gnu::always_inline]] inline void assert_failed_always() { __builtin_trap(); } @@ -10,10 +14,10 @@ namespace librmcs::firmware::utility { } [[gnu::always_inline]] inline void assert_debug(bool condition) { -#ifdef NDEBUG - [[assume(condition)]]; -#else +#if LIBRMCS_DEBUG_ASSERTS assert_always(condition); +#else + [[assume(condition)]]; #endif } diff --git a/firmware/c_board/cmake/gcc-arm-none-eabi.cmake b/firmware/c_board/cmake/gcc-arm-none-eabi.cmake index ec1b5c6..24a6368 100644 --- a/firmware/c_board/cmake/gcc-arm-none-eabi.cmake +++ b/firmware/c_board/cmake/gcc-arm-none-eabi.cmake @@ -27,9 +27,9 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TARGET_FLAGS}") set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp -MMD -MP") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fdata-sections -ffunction-sections") -set(CMAKE_C_FLAGS_DEBUG "-Og -g3") +set(CMAKE_C_FLAGS_DEBUG "-O3 -g3") set(CMAKE_C_FLAGS_RELEASE "-O3 -g0") -set(CMAKE_CXX_FLAGS_DEBUG "-Og -g3") +set(CMAKE_CXX_FLAGS_DEBUG "-O3 -g3") set(CMAKE_CXX_FLAGS_RELEASE "-O3 -g0") set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions -fno-threadsafe-statics") diff --git a/firmware/common/cmake/librmcs_firmware.cmake b/firmware/common/cmake/librmcs_firmware.cmake index e29e0ae..3edaebb 100644 --- a/firmware/common/cmake/librmcs_firmware.cmake +++ b/firmware/common/cmake/librmcs_firmware.cmake @@ -31,6 +31,19 @@ function(librmcs_setup_project_context) ) endif() + set(debug_asserts "${LIBRMCS_DEBUG_ASSERTS}") + if("${debug_asserts}" STREQUAL "") + string(TOLOWER "${CMAKE_BUILD_TYPE}" build_type_lower) + if(build_type_lower STREQUAL "release") + set(debug_asserts 0) + else() + set(debug_asserts 1) + endif() + endif() + if(NOT "${debug_asserts}" STREQUAL "0" AND NOT "${debug_asserts}" STREQUAL "1") + message(FATAL_ERROR "LIBRMCS_DEBUG_ASSERTS must be 0 or 1") + endif() + set(source_path_map "${SOURCE_PATH_MAP}") if(HOST_DEBUGGER AND "${source_path_map}" STREQUAL "") if(DEFINED ENV{HOST_WORKSPACE_FOLDER} AND NOT "$ENV{HOST_WORKSPACE_FOLDER}" STREQUAL "") @@ -53,9 +66,11 @@ function(librmcs_setup_project_context) endif() message(STATUS "Librmcs project version: ${project_version}") + message(STATUS "Librmcs debug asserts: ${debug_asserts}") set(LIBRMCS_PROJECT_ROOT "${project_root}" PARENT_SCOPE) set(LIBRMCS_PROJECT_VERSION "${project_version}" PARENT_SCOPE) + set(LIBRMCS_DEBUG_ASSERTS "${debug_asserts}" PARENT_SCOPE) set(LIBRMCS_SOURCE_PATH_MAP "${source_path_map}" PARENT_SCOPE) set(LIBRMCS_SOURCE_PATH_MAP_COMPILE_OPTIONS "${prefix_map_compile_options}" PARENT_SCOPE) endfunction() diff --git a/firmware/rmcs_board/CMakeLists.txt b/firmware/rmcs_board/CMakeLists.txt index 1cbca8f..38f2469 100644 --- a/firmware/rmcs_board/CMakeLists.txt +++ b/firmware/rmcs_board/CMakeLists.txt @@ -39,6 +39,7 @@ function(add_rmcs_board_subbuild target_name source_subdir) -DHOST_DEBUGGER=${HOST_DEBUGGER} -DSOURCE_PATH_MAP=${LIBRMCS_SOURCE_PATH_MAP} -DLIBRMCS_PROJECT_VERSION=${LIBRMCS_PROJECT_VERSION} + -DLIBRMCS_DEBUG_ASSERTS=${LIBRMCS_DEBUG_ASSERTS} ) if(CMAKE_MAKE_PROGRAM) list(APPEND configure_args -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}) diff --git a/firmware/rmcs_board/app/CMakeLists.txt b/firmware/rmcs_board/app/CMakeLists.txt index 2f9d6bf..593f871 100644 --- a/firmware/rmcs_board/app/CMakeLists.txt +++ b/firmware/rmcs_board/app/CMakeLists.txt @@ -53,10 +53,11 @@ if(LIBRMCS_SOURCE_PATH_MAP_COMPILE_OPTIONS) endif() if(CMAKE_BUILD_TYPE STREQUAL "debug") - sdk_compile_options(-Og) + sdk_compile_options(-O3) endif() sdk_compile_definitions(-DLIBRMCS_PROJECT_VERSION_STRING="${LIBRMCS_PROJECT_VERSION}") +sdk_compile_definitions(-DLIBRMCS_DEBUG_ASSERTS=${LIBRMCS_DEBUG_ASSERTS}) sdk_compile_definitions(-DCFG_TUSB_MCU=OPT_MCU_HPM) sdk_compile_definitions(-DUSB_HOST_MCU_CORE=HPM_CORE0) diff --git a/firmware/rmcs_board/bootloader/CMakeLists.txt b/firmware/rmcs_board/bootloader/CMakeLists.txt index b9b8446..74d25e1 100644 --- a/firmware/rmcs_board/bootloader/CMakeLists.txt +++ b/firmware/rmcs_board/bootloader/CMakeLists.txt @@ -47,7 +47,7 @@ if(LIBRMCS_SOURCE_PATH_MAP_COMPILE_OPTIONS) endif() if(CMAKE_BUILD_TYPE STREQUAL "debug") - sdk_compile_options(-Og) + sdk_compile_options(-O3) endif() if(NOT "${BOARD_BOOTLOADER_MODE}" STREQUAL "auto" @@ -62,6 +62,7 @@ else() endif() sdk_compile_definitions(-DLIBRMCS_PROJECT_VERSION_STRING="${LIBRMCS_PROJECT_VERSION}") +sdk_compile_definitions(-DLIBRMCS_DEBUG_ASSERTS=${LIBRMCS_DEBUG_ASSERTS}) sdk_compile_definitions(-DCFG_TUSB_MCU=OPT_MCU_HPM) sdk_compile_definitions(-DUSB_HOST_MCU_CORE=HPM_CORE0) sdk_compile_definitions(-DLIBRMCS_BOOTLOADER_MODE_AUTO=${bootloader_mode_auto}) diff --git a/firmware/rmcs_board/bootloader/src/utility/assert.hpp b/firmware/rmcs_board/bootloader/src/utility/assert.hpp index b99eeba..73ca516 100644 --- a/firmware/rmcs_board/bootloader/src/utility/assert.hpp +++ b/firmware/rmcs_board/bootloader/src/utility/assert.hpp @@ -1,5 +1,9 @@ #pragma once +#ifndef LIBRMCS_DEBUG_ASSERTS +# error "LIBRMCS_DEBUG_ASSERTS must be defined" +#endif + namespace librmcs::firmware::utility { [[noreturn, gnu::always_inline]] inline void assert_failed_always() { __builtin_trap(); } @@ -10,10 +14,10 @@ namespace librmcs::firmware::utility { } [[gnu::always_inline]] inline void assert_debug(bool condition) { -#ifdef NDEBUG - [[assume(condition)]]; -#else +#if LIBRMCS_DEBUG_ASSERTS assert_always(condition); +#else + [[assume(condition)]]; #endif } diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index a1f1bc8..2b7b957 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -14,6 +14,17 @@ if(NOT DEFINED LIBRMCS_PROJECT_VERSION OR LIBRMCS_PROJECT_VERSION STREQUAL "") endif() message(STATUS "Librmcs project version: ${LIBRMCS_PROJECT_VERSION}") +if(DEFINED LIBRMCS_DEBUG_ASSERTS AND NOT LIBRMCS_DEBUG_ASSERTS STREQUAL "") + if(NOT LIBRMCS_DEBUG_ASSERTS STREQUAL "0" AND NOT LIBRMCS_DEBUG_ASSERTS STREQUAL "1") + message(FATAL_ERROR "LIBRMCS_DEBUG_ASSERTS must be 0 or 1") + endif() + set(librmcs_debug_asserts_definition "LIBRMCS_DEBUG_ASSERTS=${LIBRMCS_DEBUG_ASSERTS}") + message(STATUS "Librmcs debug asserts: ${LIBRMCS_DEBUG_ASSERTS}") +else() + set(librmcs_debug_asserts_definition "LIBRMCS_DEBUG_ASSERTS=$,$,$>,0,1>") + message(STATUS "Librmcs debug asserts: per-config") +endif() + # Set C++ standard to C++23 set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED True) @@ -68,6 +79,7 @@ else() endif() target_compile_definitions(${PROJECT_NAME} PRIVATE LIBRMCS_PROJECT_VERSION_STRING="${LIBRMCS_PROJECT_VERSION}") +target_compile_definitions(${PROJECT_NAME} PRIVATE ${librmcs_debug_asserts_definition}) target_compile_definitions(${PROJECT_NAME} PRIVATE BUILDING_LIBRMCS) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../core/include) @@ -161,7 +173,14 @@ if(UNIX AND NOT APPLE) set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") string(TOLOWER "${CMAKE_BUILD_TYPE}" PACKAGE_BUILD_MODE) - set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${LIBRMCS_PROJECT_VERSION}-${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}-${PACKAGE_BUILD_MODE}") + if(PACKAGE_BUILD_MODE STREQUAL "release" + OR PACKAGE_BUILD_MODE STREQUAL "relwithdebinfo" + OR PACKAGE_BUILD_MODE STREQUAL "minsizerel") + set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${LIBRMCS_PROJECT_VERSION}-${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}") + else() + set(CPACK_PACKAGE_FILE_NAME + "${PROJECT_NAME}-${LIBRMCS_PROJECT_VERSION}-${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}-${PACKAGE_BUILD_MODE}") + endif() set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE") include(CPack)