diff --git a/CMakeLists.txt b/CMakeLists.txt index abb3c34a11d..0512adf26fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,15 @@ set(CMAKE_CXX_EXTENSIONS OFF) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +# Strip absolute paths from __FILE__ and std::source_location +if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + add_compile_options("-fmacro-prefix-map=${CMAKE_SOURCE_DIR}/=") + + # Optional: If you also compile generated files in your build directory + # and want them to be relative too: + add_compile_options("-fmacro-prefix-map=${CMAKE_BINARY_DIR}/=") +endif() + # Get version string in OPENROAD_VERSION if(NOT OPENROAD_VERSION) include(GetGitRevisionDescription) diff --git a/src/mpl/test/cpp/CMakeLists.txt b/src/mpl/test/cpp/CMakeLists.txt index ba4ae5b9b38..fa0a0ad2e06 100644 --- a/src/mpl/test/cpp/CMakeLists.txt +++ b/src/mpl/test/cpp/CMakeLists.txt @@ -14,7 +14,11 @@ set(TEST_LIBS add_executable(TestSnapper TestSnapper.cpp) target_link_libraries(TestSnapper ${TEST_LIBS}) -gtest_discover_tests(TestSnapper WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +gtest_discover_tests(TestSnapper + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + PROPERTIES + ENVIRONMENT "DISABLE_SOURCE_LINES=1" +) add_executable(TestBlockMacroChannels TestBlockMacroChannels.cpp) target_link_libraries(TestBlockMacroChannels ${TEST_LIBS}) diff --git a/src/tst/src/fixture.cpp b/src/tst/src/fixture.cpp index 045b9efc46a..0fe8a9b35cc 100644 --- a/src/tst/src/fixture.cpp +++ b/src/tst/src/fixture.cpp @@ -38,7 +38,7 @@ Fixture::Fixture() throw std::runtime_error("Could not create Runfiles object: " + error); } #endif - + logger_.setSourceLinesVisible(false); std::call_once(init_sta_flag, []() { sta::initSta(); }); db_ = utl::UniquePtrWithDeleter(odb::dbDatabase::create(), diff --git a/src/utl/include/utl/Logger.h b/src/utl/include/utl/Logger.h index 1ad73789831..7f08d1d2c79 100644 --- a/src/utl/include/utl/Logger.h +++ b/src/utl/include/utl/Logger.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include +#include "spdlog/common.h" #include "spdlog/details/os.h" #include "spdlog/fmt/fmt.h" #include "spdlog/fmt/ostr.h" @@ -98,6 +100,33 @@ enum ToolId SIZE // the number of tools, do not put anything after this }; +// Captures the caller's source location alongside the log message +struct LogMessage +{ + std::string message; + std::source_location loc; + bool source_lines_disabled; + + LogMessage(const char* msg, + const std::source_location& l = std::source_location::current(), + bool source_lines_off = false) + : message(msg), loc(l), source_lines_disabled(source_lines_off) + { + } + LogMessage(const std::string& msg, + const std::source_location& l = std::source_location::current(), + bool source_lines_off = false) + : message(msg), loc(l), source_lines_disabled(source_lines_off) + { + } + LogMessage(std::string_view msg, + const std::source_location& l = std::source_location::current(), + bool source_lines_off = false) + : message(msg), loc(l), source_lines_disabled(source_lines_off) + { + } +}; + class Logger { public: @@ -128,47 +157,67 @@ class Logger template void debug(ToolId tool, const char* group, - const std::string& message, + const LogMessage& log_message, const Args&... args) { - // Message counters do NOT apply to debug messages. - logger_->log( - spdlog::level::level_enum::debug, - FMT_RUNTIME("[{} {}-{}] " + message + spdlog::details::os::default_eol), - level_names[spdlog::level::level_enum::debug], - tool_names_[tool], - group, - args...); + auto formatted = fmt::format(FMT_RUNTIME(log_message.message), args...); + logger_->log(spdlog::level::level_enum::debug, + "[{} {}-{}] {} [{}:{}]{}", + level_names[spdlog::level::level_enum::debug], + tool_names_[tool], + group, + formatted, + log_message.loc.file_name(), + log_message.loc.line(), + spdlog::details::os::default_eol); logger_->flush(); } template void info(ToolId tool, int id, - const std::string& message, + const LogMessage& log_message, const Args&... args) { - log(tool, spdlog::level::level_enum::info, id, message, args...); + log(tool, + spdlog::level::level_enum::info, + id, + log_message.loc, + log_message.message, + log_message.source_lines_disabled, + args...); } template void warn(ToolId tool, int id, - const std::string& message, + const LogMessage& log_message, const Args&... args) { warning_count_++; - log(tool, spdlog::level::level_enum::warn, id, message, args...); + log(tool, + spdlog::level::level_enum::warn, + id, + log_message.loc, + log_message.message, + log_message.source_lines_disabled, + args...); } template __attribute__((noreturn)) void error(ToolId tool, int id, - const std::string& message, + LogMessage log_message, const Args&... args) { error_count_++; - log(tool, spdlog::level::err, id, message, args...); + log(tool, + spdlog::level::err, + id, + log_message.loc, + log_message.message, + log_message.source_lines_disabled, + args...); // Exception should be caught by swig error handler. throw std::runtime_error(fmt::format("{}-{:04}", tool_names_[tool], id)); } @@ -176,10 +225,16 @@ class Logger template __attribute__((noreturn)) void critical(ToolId tool, int id, - const std::string& message, + LogMessage log_message, const Args&... args) { - log(tool, spdlog::level::level_enum::critical, id, message, args...); + log(tool, + spdlog::level::level_enum::critical, + id, + log_message.loc, + log_message.message, + log_message.source_lines_disabled, + args...); exit(EXIT_FAILURE); } @@ -222,6 +277,8 @@ class Logger return (it != groups.end() && level <= it->second); } + void setSourceLinesVisible(bool visible) { source_lines_enabled_ = visible; }; + int getWarningCount() const { return warning_count_; } void startPrometheusEndpoint(uint16_t port); @@ -278,7 +335,9 @@ class Logger void log(ToolId tool, spdlog::level::level_enum level, int id, + std::source_location loc, const std::string& message, + bool per_message_source_disabled, const Args&... args) { assert(id >= 0 && id <= max_message_id); @@ -286,13 +345,27 @@ class Logger auto& counter = message_counters_[tool][id]; auto count = counter++; if (count < max_message_print) { - logger_->log(level, - FMT_RUNTIME("[{} {}-{:04d}] " + message - + spdlog::details::os::default_eol), - level_names[level], - tool_names_[tool], - id, - args...); + if (source_lines_enabled_ && !per_message_source_disabled + && level >= spdlog::level::warn) { + auto formatted = fmt::format(FMT_RUNTIME(message), args...); + logger_->log(level, + "[{} {}-{:04d}] {} [{}:{}]{}", + level_names[level], + tool_names_[tool], + id, + formatted, + loc.file_name(), + loc.line(), + spdlog::details::os::default_eol); + } else { + logger_->log(level, + FMT_RUNTIME("[{} {}-{:04d}] " + message + + spdlog::details::os::default_eol), + level_names[level], + tool_names_[tool], + id, + args...); + } return; } @@ -373,6 +446,7 @@ class Logger bool debug_on_{false}; std::atomic_int warning_count_{0}; std::atomic_int error_count_{0}; + bool source_lines_enabled_{true}; static constexpr const char* level_names[] = {"TRACE", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "OFF"}; static constexpr const char* pattern_ = "%v"; diff --git a/src/utl/src/Logger.cpp b/src/utl/src/Logger.cpp index 67242880f3c..a1ee35fd83c 100644 --- a/src/utl/src/Logger.cpp +++ b/src/utl/src/Logger.cpp @@ -53,6 +53,11 @@ Logger::Logger(const char* log_filename, const char* metrics_filename) addMetricsSink(metrics_filename); } + const char* disable_source_lines = std::getenv("DISABLE_SOURCE_LINES"); + if (disable_source_lines != nullptr) { + source_lines_enabled_ = false; + } + metrics_policies_ = MetricsPolicy::makeDefaultPolicies(); for (auto& counters : message_counters_) { diff --git a/src/utl/src/Logger.i b/src/utl/src/Logger.i index c1f418266ee..7bba8083a3d 100644 --- a/src/utl/src/Logger.i +++ b/src/utl/src/Logger.i @@ -32,7 +32,9 @@ using ord::getLogger; %include "../../Exception.i" %include "stdint.i" %import - +%ignore utl::error(utl::ToolId, int, const char*, std::source_location); +%ignore utl::warn(utl::ToolId, int, const char*, std::source_location); +%ignore utl::critical(utl::ToolId, int, const char*, std::source_location); %include "LoggerCommon.h" %inline %{ @@ -105,6 +107,18 @@ void startPrometheusEndpoint(uint16_t port) logger->startPrometheusEndpoint(port); } +void setSourceLinesOff() +{ + utl::Logger* logger = ord::getLogger(); + logger->setSourceLinesVisible(false); +} + +void setSourceLinesOn() +{ + utl::Logger* logger = ord::getLogger(); + logger->setSourceLinesVisible(true); +} + } // namespace %} // inline diff --git a/src/utl/src/LoggerCommon.cpp b/src/utl/src/LoggerCommon.cpp index 34c55e8fbbd..11f63b1bca7 100644 --- a/src/utl/src/LoggerCommon.cpp +++ b/src/utl/src/LoggerCommon.cpp @@ -4,6 +4,7 @@ #include "LoggerCommon.h" #include +#include #include #include "utl/Logger.h" @@ -38,22 +39,28 @@ void info(utl::ToolId tool, int id, const char* msg) logger->info(tool, id, "{}", msg); } -void warn(utl::ToolId tool, int id, const char* msg) +void warn(utl::ToolId tool, int id, const char* msg, std::source_location loc) { Logger* logger = getLogger(); - logger->warn(tool, id, "{}", msg); + logger->warn( + tool, id, utl::LogMessage{"{}", loc, /*source_lines_off=*/true}, msg); } -void error(utl::ToolId tool, int id, const char* msg) +void error(utl::ToolId tool, int id, const char* msg, std::source_location loc) { Logger* logger = getLogger(); - logger->error(tool, id, "{}", msg); + logger->error( + tool, id, utl::LogMessage{"{}", loc, /*source_lines_off=*/true}, msg); } -void critical(utl::ToolId tool, int id, const char* msg) +void critical(utl::ToolId tool, + int id, + const char* msg, + std::source_location loc) { Logger* logger = getLogger(); - logger->critical(tool, id, "{}", msg); + logger->critical( + tool, id, utl::LogMessage{"{}", loc, /*source_lines_off=*/true}, msg); } void open_metrics(const char* metrics_filename) diff --git a/src/utl/src/LoggerCommon.h b/src/utl/src/LoggerCommon.h index 4953fb46c40..609a3cec3c1 100644 --- a/src/utl/src/LoggerCommon.h +++ b/src/utl/src/LoggerCommon.h @@ -2,6 +2,7 @@ // Copyright (c) 2022-2025, The OpenROAD Authors #include +#include #include #include "utl/Logger.h" @@ -10,9 +11,18 @@ namespace utl { void report(const char* msg); void info(utl::ToolId tool, int id, const char* msg); -void warn(utl::ToolId tool, int id, const char* msg); -void error(utl::ToolId tool, int id, const char* msg); -void critical(utl::ToolId tool, int id, const char* msg); +void warn(utl::ToolId tool, + int id, + const char* msg, + std::source_location loc = std::source_location::current()); +void error(utl::ToolId tool, + int id, + const char* msg, + std::source_location loc = std::source_location::current()); +void critical(utl::ToolId tool, + int id, + const char* msg, + std::source_location loc = std::source_location::current()); void open_metrics(const char* metrics_filename); void close_metrics(const char* metrics_filename); void metric(const char* metric, const char* value); diff --git a/test/helpers.py b/test/helpers.py index 256de723283..23718017e28 100644 --- a/test/helpers.py +++ b/test/helpers.py @@ -97,6 +97,7 @@ def make_design(tech): if os.environ.get("TEST_SRCDIR", ""): tech.thisown = False logger = design.getLogger() + logger.setSourceLinesVisible(False) # Reading DEF file logger.suppressMessage(utl.ODB, 127) diff --git a/test/helpers.tcl b/test/helpers.tcl index cf4fbed4606..1a4be025db8 100644 --- a/test/helpers.tcl +++ b/test/helpers.tcl @@ -1,4 +1,5 @@ # Helper functions common to multiple regressions. +utl::setSourceLinesOff if { [info exists ::env(TEST_TMPDIR)] } { set test_dir $::env(TEST_TMPDIR) diff --git a/test/regression.bzl b/test/regression.bzl index 01a0f1b0728..d55d5bf45d9 100644 --- a/test/regression.bzl +++ b/test/regression.bzl @@ -32,6 +32,7 @@ export REGRESSION_TEST={REGRESSION_TEST} export TEST_GOLDEN_FILE={TEST_GOLDEN_FILE} export TEST_CHECK_LOG={TEST_CHECK_LOG} export TEST_CHECK_PASSFAIL={TEST_CHECK_PASSFAIL} +export DISABLE_SOURCE_LINES=1 export TEST_EXPECTED_EXIT_CODE={TEST_EXPECTED_EXIT_CODE} exec "{bazel_test_sh}" "$@" """.format( diff --git a/test/regression_test.sh b/test/regression_test.sh index d7d5ae6cfcc..5a77af19b31 100755 --- a/test/regression_test.sh +++ b/test/regression_test.sh @@ -5,6 +5,7 @@ set -o pipefail RESULTS_DIR="${RESULTS_DIR:-results}" LOG_FILE="${RESULTS_DIR}/$TEST_NAME-$TEST_EXT.log" +export DISABLE_SOURCE_LINES=1 mkdir -p ${RESULTS_DIR}