diff --git a/include/benchmark/benchmark.h b/include/benchmark/benchmark.h index b25b0010..a17038c0 100644 --- a/include/benchmark/benchmark.h +++ b/include/benchmark/benchmark.h @@ -417,6 +417,8 @@ class Benchmark; class BenchmarkImp; class BenchmarkFamilies; +BENCHMARK_EXPORT std::map*& GetGlobalContext(); + BENCHMARK_EXPORT void UseCharPointer(char const volatile*); diff --git a/src/benchmark.cc b/src/benchmark.cc index f8c01343..e43b28d0 100644 --- a/src/benchmark.cc +++ b/src/benchmark.cc @@ -137,7 +137,11 @@ BM_DEFINE_int32(v, 0); namespace internal { -BENCHMARK_EXPORT std::map* global_context = nullptr; +std::map* global_context = nullptr; + +BENCHMARK_EXPORT std::map*& GetGlobalContext() { + return global_context; +} // FIXME: wouldn't LTO mess this up? void UseCharPointer(char const volatile*) {} diff --git a/src/benchmark_name.cc b/src/benchmark_name.cc index 4f738606..01676bbc 100644 --- a/src/benchmark_name.cc +++ b/src/benchmark_name.cc @@ -51,6 +51,7 @@ std::string join(char delimiter, const Ts&... ts) { } } // namespace +BENCHMARK_EXPORT std::string BenchmarkName::str() const { return join('/', function_name, args, min_time, min_warmup_time, iterations, repetitions, time_type, threads); diff --git a/src/check.cc b/src/check.cc index 422b9483..5f7526e0 100644 --- a/src/check.cc +++ b/src/check.cc @@ -5,7 +5,7 @@ namespace internal { static AbortHandlerT* handler = &std::abort; -AbortHandlerT*& GetAbortHandler() { return handler; } +BENCHMARK_EXPORT AbortHandlerT*& GetAbortHandler() { return handler; } } // namespace internal } // namespace benchmark diff --git a/src/commandlineflags.cc b/src/commandlineflags.cc index 9615e351..1f555b27 100644 --- a/src/commandlineflags.cc +++ b/src/commandlineflags.cc @@ -121,12 +121,14 @@ static std::string FlagToEnvVar(const char* flag) { } // namespace +BENCHMARK_EXPORT bool BoolFromEnv(const char* flag, bool default_val) { const std::string env_var = FlagToEnvVar(flag); const char* const value_str = getenv(env_var.c_str()); return value_str == nullptr ? default_val : IsTruthyFlagValue(value_str); } +BENCHMARK_EXPORT int32_t Int32FromEnv(const char* flag, int32_t default_val) { const std::string env_var = FlagToEnvVar(flag); const char* const value_str = getenv(env_var.c_str()); @@ -139,6 +141,7 @@ int32_t Int32FromEnv(const char* flag, int32_t default_val) { return value; } +BENCHMARK_EXPORT double DoubleFromEnv(const char* flag, double default_val) { const std::string env_var = FlagToEnvVar(flag); const char* const value_str = getenv(env_var.c_str()); @@ -151,12 +154,14 @@ double DoubleFromEnv(const char* flag, double default_val) { return value; } +BENCHMARK_EXPORT const char* StringFromEnv(const char* flag, const char* default_val) { const std::string env_var = FlagToEnvVar(flag); const char* const value = getenv(env_var.c_str()); return value == nullptr ? default_val : value; } +BENCHMARK_EXPORT std::map KvPairsFromEnv( const char* flag, std::map default_val) { const std::string env_var = FlagToEnvVar(flag); @@ -201,6 +206,7 @@ const char* ParseFlagValue(const char* str, const char* flag, return flag_end + 1; } +BENCHMARK_EXPORT bool ParseBoolFlag(const char* str, const char* flag, bool* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, true); @@ -213,6 +219,7 @@ bool ParseBoolFlag(const char* str, const char* flag, bool* value) { return true; } +BENCHMARK_EXPORT bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); @@ -225,6 +232,7 @@ bool ParseInt32Flag(const char* str, const char* flag, int32_t* value) { value); } +BENCHMARK_EXPORT bool ParseDoubleFlag(const char* str, const char* flag, double* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); @@ -237,6 +245,7 @@ bool ParseDoubleFlag(const char* str, const char* flag, double* value) { value); } +BENCHMARK_EXPORT bool ParseStringFlag(const char* str, const char* flag, std::string* value) { // Gets the value of the flag as a string. const char* const value_str = ParseFlagValue(str, flag, false); @@ -248,6 +257,7 @@ bool ParseStringFlag(const char* str, const char* flag, std::string* value) { return true; } +BENCHMARK_EXPORT bool ParseKeyValueFlag(const char* str, const char* flag, std::map* value) { const char* const value_str = ParseFlagValue(str, flag, false); @@ -263,10 +273,12 @@ bool ParseKeyValueFlag(const char* str, const char* flag, return true; } +BENCHMARK_EXPORT bool IsFlag(const char* str, const char* flag) { return (ParseFlagValue(str, flag, true) != nullptr); } +BENCHMARK_EXPORT bool IsTruthyFlagValue(const std::string& value) { if (value.size() == 1) { char v = value[0]; diff --git a/src/console_reporter.cc b/src/console_reporter.cc index 1711356b..3950e498 100644 --- a/src/console_reporter.cc +++ b/src/console_reporter.cc @@ -33,6 +33,7 @@ namespace benchmark { +BENCHMARK_EXPORT bool ConsoleReporter::ReportContext(const Context& context) { name_field_width_ = context.name_field_width; printed_header_ = false; @@ -52,6 +53,7 @@ bool ConsoleReporter::ReportContext(const Context& context) { return true; } +BENCHMARK_EXPORT void ConsoleReporter::PrintHeader(const Run& run) { std::string str = FormatString("%-*s %13s %15s %12s", static_cast(name_field_width_), @@ -69,6 +71,7 @@ void ConsoleReporter::PrintHeader(const Run& run) { GetOutputStream() << line << "\n" << str << "\n" << line << "\n"; } +BENCHMARK_EXPORT void ConsoleReporter::ReportRuns(const std::vector& reports) { for (const auto& run : reports) { // print the header: @@ -120,6 +123,7 @@ static std::string FormatTime(double time) { return FormatString("%10.0f", time); } +BENCHMARK_EXPORT void ConsoleReporter::PrintRunData(const Run& result) { typedef void(PrinterFn)(std::ostream&, LogColor, const char*, ...); auto& Out = GetOutputStream(); diff --git a/src/csv_reporter.cc b/src/csv_reporter.cc index 1c5e9fa6..83c94573 100644 --- a/src/csv_reporter.cc +++ b/src/csv_reporter.cc @@ -52,11 +52,13 @@ std::string CsvEscape(const std::string& s) { return '"' + tmp + '"'; } +BENCHMARK_EXPORT bool CSVReporter::ReportContext(const Context& context) { PrintBasicContext(&GetErrorStream(), context); return true; } +BENCHMARK_EXPORT void CSVReporter::ReportRuns(const std::vector& reports) { std::ostream& Out = GetOutputStream(); @@ -103,6 +105,7 @@ void CSVReporter::ReportRuns(const std::vector& reports) { } } +BENCHMARK_EXPORT void CSVReporter::PrintRunData(const Run& run) { std::ostream& Out = GetOutputStream(); Out << CsvEscape(run.benchmark_name()) << ","; diff --git a/src/json_reporter.cc b/src/json_reporter.cc index e9999e18..d55a0e6f 100644 --- a/src/json_reporter.cc +++ b/src/json_reporter.cc @@ -28,10 +28,6 @@ #include "timers.h" namespace benchmark { -namespace internal { -extern std::map* global_context; -} - namespace { std::string StrEscape(const std::string& s) { @@ -178,8 +174,11 @@ bool JSONReporter::ReportContext(const Context& context) { #endif out << indent << FormatKV("library_build_type", build_type); - if (internal::global_context != nullptr) { - for (const auto& kv : *internal::global_context) { + std::map* global_context = + internal::GetGlobalContext(); + + if (global_context != nullptr) { + for (const auto& kv : *global_context) { out << ",\n"; out << indent << FormatKV(kv.first, kv.second); } diff --git a/src/reporter.cc b/src/reporter.cc index 1d2df17b..8b5fdaff 100644 --- a/src/reporter.cc +++ b/src/reporter.cc @@ -25,9 +25,6 @@ #include "timers.h" namespace benchmark { -namespace internal { -extern std::map *global_context; -} BenchmarkReporter::BenchmarkReporter() : output_stream_(&std::cout), error_stream_(&std::cerr) {} @@ -67,8 +64,11 @@ void BenchmarkReporter::PrintBasicContext(std::ostream *out, Out << "\n"; } - if (internal::global_context != nullptr) { - for (const auto &kv : *internal::global_context) { + std::map *global_context = + internal::GetGlobalContext(); + + if (global_context != nullptr) { + for (const auto &kv : *global_context) { Out << kv.first << ": " << kv.second << "\n"; } } diff --git a/test/benchmark_gtest.cc b/test/benchmark_gtest.cc index cfc0a0f7..3873128e 100644 --- a/test/benchmark_gtest.cc +++ b/test/benchmark_gtest.cc @@ -8,7 +8,6 @@ namespace benchmark { namespace internal { -BENCHMARK_EXPORT extern std::map* global_context; namespace { @@ -134,6 +133,8 @@ TEST(AddRangeTest, Simple8) { } TEST(AddCustomContext, Simple) { + std::map *&global_context = + internal::GetGlobalContext(); EXPECT_THAT(global_context, nullptr); AddCustomContext("foo", "bar"); @@ -148,6 +149,8 @@ TEST(AddCustomContext, Simple) { } TEST(AddCustomContext, DuplicateKey) { + std::map *&global_context = + internal::GetGlobalContext(); EXPECT_THAT(global_context, nullptr); AddCustomContext("foo", "bar");