diff --git a/CMakeLists.txt b/CMakeLists.txt index 71e5b7a0..be9c76bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,17 @@ cmake_minimum_required(VERSION 3.25) project(mrover VERSION 2025.0.0 LANGUAGES C CXX) +# Supress ROS CMake warning about Python. +cmake_policy(SET CMP0148 OLD) + set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Generate compile_commands.json for clangd language server. # Can be used by VSCode, CLion, VIM, etc. set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +option(MROVER_CLANG_TIDY "Enable static analysis with Clang tidy" OFF) + if (APPLE) # Ensures that homebrew packages are never used over miniforge packages. set(CMAKE_IGNORE_PATH /opt/homebrew) @@ -15,6 +20,21 @@ if (APPLE) link_libraries(${PYTHON_LIBRARIES}) endif () +if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic -Wno-missing-field-initializers -Wno-deprecated-declarations) + + if (NOT APPLE) + # Try to use LLD instead of the system linker (which is usually GNU ld). + # LLD is faster and uses less memory. + # Could look into using mold which should be even faster. + find_program(LLD_PROGRAM lld) + if (LLD_PROGRAM) + message(STATUS "Using lld linker") + add_link_options(-fuse-ld=lld-18) + endif() + endif () +endif () + # Ccache is a compiler cache. # It speeds up recompilation by caching previous compilations and detecting when the same compilation is being done again. # It is global, so even if you delete the build directory, it will still work. @@ -26,20 +46,6 @@ if (CCACHE_FOUND) set(CMAKE_CUDA_COMPILER_LAUNCHER ccache) endif () -if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - add_compile_options(-Wall -Wextra -Wpedantic -Wno-missing-field-initializers -Wno-deprecated-declarations) - - # Try to use LLD instead of the system linker (which is usually GNU ld). - # LLD is faster and uses less memory. - # Could look into using mold which should be even faster. - find_program(LLD_18_FOUND lld-18) - if (LLD_18_FOUND) - message(STATUS "Using lld-18 linker") - add_link_options(-fuse-ld=lld-18) - endif() -endif () - - ## Dependencies diff --git a/cmake/macros.cmake b/cmake/macros.cmake index 28c22e4f..8328a2bf 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -1,28 +1,45 @@ +find_program(CLANG_TIDY_PROGRAM clang-tidy-18) + +# General macro to enable properties for MRover targets (and not 3rd party). +macro(mrover_target name) + if (MROVER_CLANG_TIDY) + if (NOT CLANG_TIDY_PROGRAM) + message(FATAL_ERROR "Clang tidy requested but executable not found") + endif () + message(STATUS "Enabling static analysis for target ${name}") + set_target_properties(${name} PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY_PROGRAM}") + endif () +endmacro() + macro(mrover_add_header_only_library name includes) add_library(${name} INTERFACE) + mrover_target(${name}) target_include_directories(${name} INTERFACE ${includes}) endmacro() macro(mrover_add_library name sources includes) file(GLOB_RECURSE LIBRARY_SOURCES CONFIGURE_DEPENDS ${sources}) add_library(${name} ${ARGV3} ${LIBRARY_SOURCES}) + mrover_target(${name}) target_include_directories(${name} PUBLIC ${includes}) endmacro() macro(mrover_add_component name sources includes) file(GLOB_RECURSE LIBRARY_SOURCES CONFIGURE_DEPENDS ${sources}) add_library(${name} SHARED ${ARGV3} ${LIBRARY_SOURCES}) + mrover_target(${name}) target_compile_definitions(${name} PRIVATE "COMPOSITION_BUILDING_DLL") - -endmacro() +endmacro() macro(mrover_add_node name sources) file(GLOB_RECURSE NODE_SOURCES CONFIGURE_DEPENDS ${sources}) add_executable(${name} ${NODE_SOURCES}) + mrover_target(${name}) if (ARGV3) target_precompile_headers(${name} PRIVATE ${ARGV3}) endif () - rosidl_target_interfaces(${name} ${PROJECT_NAME} rosidl_typesupport_cpp) + rosidl_get_typesupport_target(cpp_typesupport_target ${PROJECT_NAME} rosidl_typesupport_cpp) + target_link_libraries(${name} ${cpp_typesupport_target}) install( TARGETS ${name} DESTINATION lib/${PROJECT_NAME} diff --git a/esw/can_bridge/can_net_link.cpp b/esw/can_bridge/can_net_link.cpp index 922d75aa..f0b4f343 100644 --- a/esw/can_bridge/can_net_link.cpp +++ b/esw/can_bridge/can_net_link.cpp @@ -2,7 +2,7 @@ namespace mrover { - CanNetLink::CanNetLink(rclcpp::Logger logger, std::string interface) + CanNetLink::CanNetLink(rclcpp::Logger const& logger, std::string interface) : mInterface{std::move(interface)} { try { diff --git a/esw/can_bridge/can_net_link.hpp b/esw/can_bridge/can_net_link.hpp index 6b1901a8..762d32a7 100644 --- a/esw/can_bridge/can_net_link.hpp +++ b/esw/can_bridge/can_net_link.hpp @@ -8,7 +8,7 @@ namespace mrover { CanNetLink() = default; - CanNetLink(rclcpp::Logger logger, std::string); + CanNetLink(rclcpp::Logger const& logger, std::string); CanNetLink(CanNetLink const&) = delete; auto operator=(CanNetLink const&) -> CanNetLink& = delete; diff --git a/simulator/simulator.hpp b/simulator/simulator.hpp index 9c91f5d8..395ec81f 100644 --- a/simulator/simulator.hpp +++ b/simulator/simulator.hpp @@ -70,7 +70,7 @@ namespace mrover { // https://en.cppreference.com/w/cpp/thread/future std::future asyncMeshesLoader; - Model(Simulator& logger, std::string_view uri); + Model(Simulator& simulator, std::string_view uri); auto waitMeshes() -> void; diff --git a/simulator/simulator.render.cpp b/simulator/simulator.render.cpp index b46ab4e0..a81ea767 100644 --- a/simulator/simulator.render.cpp +++ b/simulator/simulator.render.cpp @@ -449,6 +449,7 @@ namespace mrover { auto Simulator::renderModels(wgpu::RenderPassEncoder& pass) -> void { for (auto& [_, urdf]: mUrdfs) { + // NOLINTNEXTLINE(misc-no-recursion) auto renderLink = [&](auto&& self, urdf::LinkConstSharedPtr const& link) -> void { for (std::size_t visualIndex = 0; urdf::VisualSharedPtr const& visual: link->visual_array) { if (auto urdfMesh = std::dynamic_pointer_cast(visual->geometry)) { @@ -476,6 +477,7 @@ namespace mrover { for (auto& [_, urdf]: mUrdfs) { + // NOLINTNEXTLINE(misc-no-recursion) auto renderLink = [&](auto&& self, urdf::LinkConstSharedPtr const& link) -> void { URDF::LinkMeta& meta = urdf.linkNameToMeta.at(link->name);