Skip to content
1 change: 1 addition & 0 deletions src/ros2_medkit_cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ install(
cmake/ROS2MedkitLinting.cmake
cmake/ROS2MedkitSanitizers.cmake
cmake/ROS2MedkitTestDomain.cmake
cmake/ROS2MedkitWarnings.cmake
DESTINATION share/${PROJECT_NAME}/cmake
)

Expand Down
2 changes: 1 addition & 1 deletion src/ros2_medkit_cmake/cmake/ROS2MedkitCompat.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ macro(medkit_find_cpp_httplib)
message(STATUS "[MedkitCompat] cpp-httplib: using cmake config (source build)")
elseif(_mfch_VENDORED_DIR AND EXISTS "${_mfch_VENDORED_DIR}/httplib.h")
add_library(cpp_httplib_vendored INTERFACE)
target_include_directories(cpp_httplib_vendored INTERFACE "${_mfch_VENDORED_DIR}")
target_include_directories(cpp_httplib_vendored SYSTEM INTERFACE "${_mfch_VENDORED_DIR}")
add_library(cpp_httplib_target ALIAS cpp_httplib_vendored)
message(STATUS "[MedkitCompat] cpp-httplib: using vendored header (${_mfch_VENDORED_DIR}/httplib.h)")
else()
Expand Down
137 changes: 137 additions & 0 deletions src/ros2_medkit_cmake/cmake/ROS2MedkitWarnings.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# Copyright 2026 bburda
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

include_guard(GLOBAL)

# Production-grade compiler warning configuration for ros2_medkit packages.
# Aligned with AUTOSAR C++14, MISRA C++, OpenSSF, and Airbus SecLab guidelines.
#
# Strategy: all warnings enabled, selective -Werror=<flag> only for warnings
# that don't false-positive on external headers (STL, ROS 2, gtest, nlohmann).
# Flags that DO fire on external code remain as warnings for visibility.
#
# Provides:
# option ENABLE_WERROR (default ON) - selective warnings-as-errors
# function ros2_medkit_relax_vendor_warnings() - call after ament_add_gtest/gmock
#
# Usage:
# find_package(ros2_medkit_cmake REQUIRED)
# include(ROS2MedkitWarnings)
# ...
# if(BUILD_TESTING)
# ament_add_gtest(...)
# ros2_medkit_relax_vendor_warnings()
# endif()

option(ENABLE_WERROR "Treat select compiler warnings as errors" ON)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# -- All warnings (report everything, some as errors, rest as warnings) ------
add_compile_options(
# Core warnings
-Wall
-Wextra
-Wpedantic

# Type safety (MISRA, OpenSSF)
-Wconversion
-Wsign-conversion
-Wdouble-promotion
-Wfloat-equal # MISRA M6-2-2, AUTOSAR M6-2-2

# Shadow / hiding
-Wshadow
-Woverloaded-virtual

# OOP correctness
-Wnon-virtual-dtor
-Wold-style-cast

# Const correctness (MISRA, Airbus SecLab)
-Wcast-qual

# Memory / alignment
-Wcast-align
-Wnull-dereference

# Control flow
-Wimplicit-fallthrough
-Wswitch-enum # AUTOSAR A6-4-6

# Preprocessor (MISRA)
-Wundef

# Format strings (OpenSSF)
-Wformat=2

# Modern C++ (AUTOSAR A4-10-1)
-Wzero-as-null-pointer-constant

# Code cleanliness (AUTOSAR)
-Wextra-semi
)

# -- Selective -Werror for flags safe from external header false positives ----
# NOT promoted: -Wconversion, -Wsign-conversion, -Wdouble-promotion,
# -Wnull-dereference, -Wcast-align (false positives on STL/ROS 2/nlohmann)
if(ENABLE_WERROR)
add_compile_options(
-Werror=shadow
-Werror=switch-enum
-Werror=old-style-cast
-Werror=float-equal
-Werror=cast-qual
-Werror=undef
-Werror=zero-as-null-pointer-constant
-Werror=extra-semi
-Werror=overloaded-virtual
-Werror=non-virtual-dtor
-Werror=implicit-fallthrough
-Werror=format=2
)
endif()

# GCC-only warnings
if(CMAKE_COMPILER_IS_GNUCXX)
add_compile_options(
-Wduplicated-cond
-Wduplicated-branches
-Wlogical-op
-Wuseless-cast
)
# Note: -Wuseless-cast NOT promoted - type aliases (time_t, int64_t, size_t)
# resolve differently across distros, making casts useless on one but needed
# on another.
if(ENABLE_WERROR)
add_compile_options(
-Werror=duplicated-cond
-Werror=duplicated-branches
-Werror=logical-op
)
endif()
endif()
endif()

# Suppress strict warnings on gtest/gmock vendor targets.
# ament_add_gtest/ament_add_gmock build gtest/gmock sources as subdirectory
# targets, which inherit add_compile_options flags. Vendored code may trigger
# promoted warnings (-Werror=switch-enum, -Werror=useless-cast, etc.).
# Call this once at the end of the BUILD_TESTING block.
function(ros2_medkit_relax_vendor_warnings)
foreach(_target gmock gmock_main gtest gtest_main)
if(TARGET ${_target})
target_compile_options(${_target} PRIVATE -w)
endif()
endforeach()
endfunction()
3 changes: 2 additions & 1 deletion src/ros2_medkit_cmake/cmake/ros2_medkit_cmake-extras.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# Adds the installed cmake module directory to CMAKE_MODULE_PATH so that
# include(ROS2MedkitCompat), include(ROS2MedkitCcache),
# include(ROS2MedkitLinting), include(ROS2MedkitSanitizers),
# and include(ROS2MedkitTestDomain) work transparently.
# include(ROS2MedkitTestDomain), and include(ROS2MedkitWarnings)
# work transparently.

list(APPEND CMAKE_MODULE_PATH "${ros2_medkit_cmake_DIR}")
6 changes: 2 additions & 4 deletions src/ros2_medkit_diagnostic_bridge/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ find_package(ros2_medkit_cmake REQUIRED)
include(ROS2MedkitCcache)
include(ROS2MedkitSanitizers)
include(ROS2MedkitLinting)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Wshadow -Wconversion)
endif()
include(ROS2MedkitWarnings)

# Code coverage option
option(ENABLE_COVERAGE "Enable code coverage reporting" OFF)
Expand Down Expand Up @@ -130,6 +127,7 @@ if(BUILD_TESTING)
TARGET test_integration
TIMEOUT 60
)
ros2_medkit_relax_vendor_warnings()
endif()

ament_package()
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
cmake_minimum_required(VERSION 3.8)
project(ros2_medkit_beacon_common)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Wshadow -Wconversion)
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

Expand All @@ -27,6 +23,7 @@ find_package(ros2_medkit_cmake REQUIRED)
include(ROS2MedkitCompat)
include(ROS2MedkitCcache)
include(ROS2MedkitSanitizers)
include(ROS2MedkitWarnings)

find_package(ament_cmake REQUIRED)
find_package(ros2_medkit_msgs REQUIRED)
Expand Down Expand Up @@ -102,6 +99,7 @@ if(BUILD_TESTING)
ament_add_gtest(test_beacon_entity_mapper test/test_beacon_entity_mapper.cpp)
target_link_libraries(test_beacon_entity_mapper beacon_common_lib)
medkit_target_dependencies(test_beacon_entity_mapper ros2_medkit_gateway)
ros2_medkit_relax_vendor_warnings()
endif()

ament_package()
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ include(ROS2MedkitCompat)
include(ROS2MedkitCcache)
include(ROS2MedkitSanitizers)
include(ROS2MedkitLinting)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Wshadow -Wconversion)
endif()
include(ROS2MedkitWarnings)

find_package(ament_cmake REQUIRED)
find_package(ros2_medkit_gateway REQUIRED)
Expand Down Expand Up @@ -95,6 +92,7 @@ if(BUILD_TESTING)
target_link_libraries(test_systemd_plugin medkit_linux_utils)
target_include_directories(test_systemd_plugin PRIVATE ${ros2_medkit_gateway_INCLUDE_DIRS})
medkit_target_dependencies(test_systemd_plugin nlohmann_json)
ros2_medkit_relax_vendor_warnings()
endif()

ament_package()
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
cmake_minimum_required(VERSION 3.8)
project(ros2_medkit_param_beacon)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Wshadow -Wconversion)
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

Expand All @@ -27,6 +23,7 @@ find_package(ros2_medkit_cmake REQUIRED)
include(ROS2MedkitCompat)
include(ROS2MedkitCcache)
include(ROS2MedkitSanitizers)
include(ROS2MedkitWarnings)

find_package(ament_cmake REQUIRED)
find_package(ros2_medkit_beacon_common REQUIRED)
Expand Down Expand Up @@ -93,6 +90,7 @@ if(BUILD_TESTING)
nlohmann_json::nlohmann_json
ros2_medkit_beacon_common::beacon_common_lib)
medkit_set_test_domain(test_param_beacon_plugin)
ros2_medkit_relax_vendor_warnings()
endif()

ament_package()
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
cmake_minimum_required(VERSION 3.8)
project(ros2_medkit_topic_beacon)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Wshadow -Wconversion)
endif()

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

Expand All @@ -27,6 +23,7 @@ find_package(ros2_medkit_cmake REQUIRED)
include(ROS2MedkitCompat)
include(ROS2MedkitCcache)
include(ROS2MedkitSanitizers)
include(ROS2MedkitWarnings)

find_package(ament_cmake REQUIRED)
find_package(ros2_medkit_beacon_common REQUIRED)
Expand Down Expand Up @@ -98,6 +95,7 @@ if(BUILD_TESTING)
nlohmann_json::nlohmann_json
ros2_medkit_beacon_common::beacon_common_lib)
medkit_set_test_domain(test_topic_beacon_plugin)
ros2_medkit_relax_vendor_warnings()
endif()

ament_package()
6 changes: 2 additions & 4 deletions src/ros2_medkit_fault_manager/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@ include(ROS2MedkitCompat)
include(ROS2MedkitCcache)
include(ROS2MedkitSanitizers)
include(ROS2MedkitLinting)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Wshadow -Wconversion)
endif()
include(ROS2MedkitWarnings)

# Code coverage option
option(ENABLE_COVERAGE "Enable code coverage reporting" OFF)
Expand Down Expand Up @@ -220,6 +217,7 @@ if(BUILD_TESTING)
TIMEOUT 60
)
set_tests_properties(test_entity_thresholds_integration PROPERTIES LABELS "integration")
ros2_medkit_relax_vendor_warnings()
endif()

ament_package()
6 changes: 4 additions & 2 deletions src/ros2_medkit_fault_manager/src/fault_manager_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <yaml-cpp/yaml.h>

#include <cctype>
#include <cinttypes>
#include <filesystem>
#include <fstream>
#include <nlohmann/json.hpp>
Expand Down Expand Up @@ -108,9 +109,10 @@ FaultManagerNode::FaultManagerNode(const rclcpp::NodeOptions & options) : Node("
snapshot_recapture_cooldown_sec_);
snapshot_recapture_cooldown_sec_ = 0.0;
}
int max_snapshots = declare_parameter<int>("snapshots.max_per_fault", 10);
auto max_snapshots = declare_parameter<int>("snapshots.max_per_fault", 10);
if (max_snapshots < 0) {
RCLCPP_WARN(get_logger(), "snapshots.max_per_fault should be >= 0, got %d. Disabling limit.", max_snapshots);
RCLCPP_WARN(get_logger(), "snapshots.max_per_fault should be >= 0, got %" PRId64 ". Disabling limit.",
static_cast<int64_t>(max_snapshots));
max_snapshots = 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/ros2_medkit_fault_manager/src/sqlite_fault_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ bool SqliteFaultStorage::report_fault_event(const std::string & fault_code, uint
int64_t existing_count = check_stmt.column_int64(1);
std::string sources_json = check_stmt.column_text(2);
std::string current_status = check_stmt.column_text(3);
int32_t debounce_counter = static_cast<int32_t>(check_stmt.column_int(4));
int32_t debounce_counter = check_stmt.column_int(4);

// CLEARED faults can be reactivated by FAILED events
bool is_reactivation = false;
Expand Down
6 changes: 2 additions & 4 deletions src/ros2_medkit_fault_reporter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@ find_package(ros2_medkit_cmake REQUIRED)
include(ROS2MedkitCcache)
include(ROS2MedkitSanitizers)
include(ROS2MedkitLinting)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Wshadow -Wconversion)
endif()
include(ROS2MedkitWarnings)

# Code coverage option
option(ENABLE_COVERAGE "Enable code coverage reporting" OFF)
Expand Down Expand Up @@ -113,6 +110,7 @@ if(BUILD_TESTING)
TARGET test_integration
TIMEOUT 60
)
ros2_medkit_relax_vendor_warnings()
endif()

ament_package()
7 changes: 2 additions & 5 deletions src/ros2_medkit_gateway/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ include(ROS2MedkitCompat)
include(ROS2MedkitCcache)
include(ROS2MedkitSanitizers)
include(ROS2MedkitLinting)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Wshadow -Wconversion)
endif()
include(ROS2MedkitWarnings)

# Code coverage option
option(ENABLE_COVERAGE "Enable code coverage reporting" OFF)
Expand Down Expand Up @@ -778,7 +775,7 @@ if(BUILD_TESTING)
target_link_options(${_target} PRIVATE --coverage)
endforeach()
endif()

ros2_medkit_relax_vendor_warnings()
endif()

# Export include directories for downstream packages (plugins)
Expand Down
3 changes: 2 additions & 1 deletion src/ros2_medkit_gateway/src/aggregation/peer_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ constexpr size_t MAX_ENTITIES_PER_COLLECTION = 1000;
std::string encode_query_param(const std::string & value) {
std::string result;
result.reserve(value.size());
for (unsigned char c : value) {
for (char ch : value) {
auto c = static_cast<unsigned char>(ch);
if (std::isalnum(c) || c == '-' || c == '.' || c == '_' || c == '~') {
result += static_cast<char>(c);
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/ros2_medkit_gateway/src/configuration_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,8 @@ rclcpp::ParameterValue ConfigurationManager::json_to_parameter_value(const json
return rclcpp::ParameterValue(value.get<std::vector<std::string>>());
}
break;
case rclcpp::ParameterType::PARAMETER_NOT_SET:
case rclcpp::ParameterType::PARAMETER_BYTE_ARRAY:
default:
break;
}
Expand Down
Loading
Loading